Compare commits

...

103 Commits

Author SHA1 Message Date
Dmitriy Ivanov
d717b1a3e5 Merge "Add functions to provide target sdk version" 2015-05-27 22:44:28 +00:00
Dmitriy Ivanov
79fd668bb4 Add functions to provide target sdk version
Bug: http://b/21364029
Change-Id: I8648d1bff6c8fd6e7cd12da7f128e048b9f2829a
2015-05-27 14:31:36 -07:00
Simon Baldwin
560aacee84 Merge "Fix unit tests, and extend for other architectures" 2015-05-27 16:42:38 +00:00
Simon Baldwin
1011e1a402 Fix unit tests, and extend for other architectures
On unpacking, reinstate any p_align values that packing reduced to
page size.  Ensures a round-trip pack and unpack is bit-equivalent
to the original input.
https://android-review.googlesource.com/#/c/148492/

Extend unit tests to include ia32, x64, and mips32.

Recreate test data for arm32 and arm64.  Generate new test data for
ia32, x64, and mips32.

Bug: http://b/20687795
Bug: http://b/18051137
Change-Id: Ifbca8e206ef447297ba4f19272b813702be27a35
2015-05-27 13:20:00 +01:00
Dmitriy Ivanov
fad15145f8 Merge "Remove LOCAL_CONLY_FLAGS it is no-op." 2015-05-26 20:56:37 +00:00
Dmitriy Ivanov
41c99cdbb9 Remove LOCAL_CONLY_FLAGS it is no-op.
Change-Id: Ib52b85d176dc9d46d7550f01537b2635e873d6ad
2015-05-26 11:38:59 -07:00
Dmitriy Ivanov
aaafbe128f Merge "Fix RTLD_NEXT lookup for the local_group" 2015-05-22 22:22:22 +00:00
Dmitriy Ivanov
b96ac41b32 Fix RTLD_NEXT lookup for the local_group
Linker used to skip RTLD_NEXT within local_group when
  caller->next is nullptr (which represents load order
  but not the order within local_group dependency tree)

Bug: http://b/21380474
Change-Id: I178fc4657b19bceb871635b177c1df67855b1708
2015-05-22 19:46:11 +00:00
Dan Albert
ffe01a3de6 Merge "Fix error handling for negative size in ftruncate." 2015-05-21 20:41:25 +00:00
Yabin Cui
4fc106d34b Merge "Fix pthread_attr_getstack__main_thread failure on glibc." 2015-05-20 22:52:38 +00:00
Yabin Cui
b0c6f2dba2 Fix pthread_attr_getstack__main_thread failure on glibc.
Move test of bionic specific implementation into bionic ifdef.

Bug: 19805726
Change-Id: Idf369b16e7f41f060c75b0aaf34e05cf3c161aa9
2015-05-20 14:41:15 -07:00
Dan Albert
c05554ec5c Fix error handling for negative size in ftruncate.
Bug: 21309901
Change-Id: I54692ab8105dd09db6af7a2c0894a17bdd118aa0
2015-05-20 14:20:33 -07:00
Yabin Cui
c02bdc76a2 Merge "Hide rt_sigqueueinfo." 2015-05-18 20:29:44 +00:00
Yabin Cui
40a8f214a5 Hide rt_sigqueueinfo.
Bug: 19358804
Change-Id: I38a53ad64c81d0eefdd1d24599e769fd8a477a56
2015-05-18 11:29:20 -07:00
Dmitriy Ivanov
a42b5bcd89 Merge "Apply work around b/19059885 to x86" 2015-05-16 16:56:49 +00:00
Dmitriy Ivanov
9185e04f72 Apply work around b/19059885 to x86
Bug: http://b/19059885
Bug: http://b/21203348
Change-Id: Ic375e9f877d68de8f866d17362879a7dde638465
(cherry picked from commit 69a5fb951d)
2015-05-15 18:42:14 -07:00
Elliott Hughes
882283e9e2 Merge "Don't use TEMP_FAILURE_RETRY on close in bionic." 2015-05-15 23:24:12 +00:00
Elliott Hughes
4e8ef698d0 Don't use TEMP_FAILURE_RETRY on close in bionic.
Bug: http://b/20501816
Change-Id: Id64b5109cc2b165fa0351b6edbb865a5e5058008
2015-05-15 16:20:07 -07:00
Dmitriy Ivanov
1d52b8b07c Merge "Remove -z global workaround for target x86" 2015-05-15 17:30:02 +00:00
John Reck
b00c23a8db Merge "Fix regression in crash reporting" 2015-05-15 16:29:42 +00:00
John Reck
e77e335b54 Fix regression in crash reporting
Bug: 19532651

Partial revert of be0e43b776

Change-Id: I99e220328aff985facb920ebcd84ac1a016759b5
(cherry picked from commit d7ad443cfd)
2015-05-15 09:28:10 -07:00
Dmitriy Ivanov
933332462d Remove -z global workaround for target x86
Change-Id: I08e75a1c7437c97e4af59316d2c14c7fa3f65e03
2015-05-14 21:28:21 -07:00
Elliott Hughes
0378d8f651 Merge "ScopedFd: Don't use TEMP_FAILURE_RETRY() with close()" 2015-05-14 00:27:46 +00:00
Elliott Hughes
706eafc9b0 Merge "Fix unused result errors in bionic." 2015-05-13 21:09:42 +00:00
Spencer Low
0346ad7a4f ScopedFd: Don't use TEMP_FAILURE_RETRY() with close()
According to the comments in Posix_close(), TEMP_FAILURE_RETRY() should
not be used with close():

462bdac45c%5E%21/#F12

Kill ScopedFd by simplifying the single caller.

Change-Id: I248c40b8c2fc95f1938a6edfc245c81847fc44af
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-05-13 13:27:11 -07:00
Elliott Hughes
c217373bd6 Fix unused result errors in bionic.
This lets us use _FORTIFY_SOURCE=2 on the host.

Change-Id: I69f5ff9834bfd595aae6584104bee10c4d8a5eeb
2015-05-13 13:18:04 -07:00
Dmitriy Ivanov
fe77d2d003 Merge "Improved dlsym tests and fixes to linker" 2015-05-12 20:48:17 +00:00
Dmitriy Ivanov
697bd9fd38 Improved dlsym tests and fixes to linker
Answers the question: what if dependent library
 was preloaded with RTLD_LOCAL flag.

 Also add test for RTLD_NEXT within local_group.

Bug: http://b/17512583
Change-Id: I79e081e68b3a8c0ed8980d4275a06515fea94ec9
2015-05-12 13:46:40 -07:00
Elliott Hughes
d0763ba076 Merge "Update NOTICE files (the second time today)." 2015-05-12 17:47:05 +00:00
Elliott Hughes
f58ac87182 Update NOTICE files (the second time today).
Change-Id: Ifb031d29ee697ee0682bd651e0081493e8016e67
2015-05-12 10:44:37 -07:00
Elliott Hughes
3ff027e550 Merge "Update NOTICE files." 2015-05-12 17:43:46 +00:00
Elliott Hughes
7e54c762fc Update NOTICE files.
(cherry-pick of f0bd92db8966b04062fda0986dacf80891e1a378.)
Change-Id: I4e170118abf452dd87ffe79d343ba1e2b53955de
2015-05-12 10:33:20 -07:00
Elliott Hughes
8a330cad8d Merge "Simplify three copyright headers." 2015-05-12 17:27:04 +00:00
Elliott Hughes
c69ace87ec Simplify three copyright headers.
There's no reason to have multiple years in our own copyright headers,
and given the stupidity of our NOTICE file generation, it just creates
more junk.

Change-Id: I065a3811c2e2584e3b649a18ad9460286bc72b92
2015-05-12 10:10:01 -07:00
Chih-Hung Hsieh
972d7fe63a Merge "Use unified syntax to compile with both llvm and gcc." 2015-05-12 04:31:10 +00:00
Chih-Hung Hsieh
33f33515b5 Use unified syntax to compile with both llvm and gcc.
All arch-arm and arch-arm64 .S files were compiled
by gcc with and without this patch. The output object files
were identical. When compiled with llvm and this patch,
the output files were also identical to gcc's output.

BUG: 18061004
Change-Id: I458914d512ddf5496e4eb3d288bf032cd526d32b
2015-05-11 17:15:03 -07:00
Elliott Hughes
c9310266dc Merge "Fix various bugs in the check-symbols script." 2015-05-11 20:28:57 +00:00
Elliott Hughes
ec738d9494 Fix various bugs in the check-symbols script.
It had bitrotted away during the last release cycle.

Change-Id: I20f0a3b409af4530b81f26299bef9de01530c9fd
2015-05-11 12:10:40 -07:00
Andres Morales
75f2dfca65 Merge "remove rootdir build.prop" 2015-05-08 22:13:44 +00:00
Andres Morales
4e8cda641a remove rootdir build.prop
merge with default.prop

Change-Id: I6cff4527dec2b31bdde42ec26c42ef2782f8deb4
2015-05-08 22:13:15 +00:00
Dmitriy Ivanov
267f39bf63 Merge "Switch libc/libcstdc++/libm to hash-style=both" 2015-05-08 21:07:09 +00:00
Dmitriy Ivanov
88e777d6f4 Switch libc/libcstdc++/libm to hash-style=both
Bug: http://b/19059885
Change-Id: Ie42703d91f291fd689a1cf9c35bcab5c487b9a84
2015-05-08 12:06:20 -07:00
Dan Albert
11fc3f47af Merge "Apply same URL workaround to clean build." 2015-05-08 17:15:31 +00:00
Dan Albert
a924d4ba26 Merge changes from topic 'volantis-blobs'
* changes:
  Revert "Fix volantis boot."
  Revert "Fix clang build."
  Revert "Try again to fix clang build."
2015-05-08 16:35:13 +00:00
Dmitriy Ivanov
7d6b8db28e Merge "Add definitions of Elf32_Sxword and ELFXX_R_INFO" 2015-05-08 06:49:05 +00:00
Dmitriy Ivanov
ce16a53d39 Add definitions of Elf32_Sxword and ELFXX_R_INFO
Bug: http://b/17056684
Change-Id: If35302245ac3ab40d1c80fb2b04620778c114f87
2015-05-07 23:10:16 -07:00
Yabin Cui
f9eeea6d65 Merge "Remove pthread_detach_no_leak test." 2015-05-08 01:36:30 +00:00
Yabin Cui
2957cc5f10 Remove pthread_detach_no_leak test.
This test has lost its purpose as we are using mmap/munmap for pthread_internal_t. And it is a flaky test.

Bug: 20860440
Change-Id: I7cbb6bc3fd8a2ca430415beab5ee27a856ce4ea7
2015-05-07 16:53:25 -07:00
Dan Albert
ded34ce94f Apply same URL workaround to clean build.
Change-Id: I63e63f6ffb879f49e36ee2d09821fc6fc47952c8
2015-05-07 16:33:42 -07:00
Dan Albert
7c2c01d681 Revert "Fix volantis boot."
Bug: http://b/20065774
This reverts commit 76e1cbca75.
2015-05-07 15:12:24 -07:00
Dan Albert
6f0d7005f9 Revert "Fix clang build."
Bug: http://b/20065774
This reverts commit 0975a5d9d2.
2015-05-07 15:12:16 -07:00
Dan Albert
f920f821e2 Revert "Try again to fix clang build."
Bug: http://b/20065774
This reverts commit dffd3c5838.

Change-Id: I5dd095ff4ab133baa2afcbd4c79fbee55d05c459
2015-05-07 15:11:48 -07:00
Dmitriy Ivanov
dc10b077ea Merge "Properly align init/fini_arrays for crtend.o" 2015-05-07 19:55:25 +00:00
Dmitriy Ivanov
e543c7612e Properly align init/fini_arrays for crtend.o
Also remove them from crtend_so.o

Bug: http://b/20532404
Change-Id: I56a0f80c4b3a83cf11d28bbf17791ff4ce10c5d2
2015-05-07 11:57:53 -07:00
Dmitriy Ivanov
9c1894186c Merge "Use realpath for log and error messages" 2015-05-07 17:55:39 +00:00
Dmitriy Ivanov
3edb9182ff Use realpath for log and error messages
Bug: http://b/20885931
Change-Id: Ida8ab7982ca75fa73da13c4cb10a6b2e53bc2c8e
2015-05-07 10:48:00 -07:00
Dmitriy Ivanov
fff06e624d Merge "Move pthread_atfork_dlclose test out of static lib" 2015-05-06 23:47:22 +00:00
Dmitriy Ivanov
5624a6a1e5 Move pthread_atfork_dlclose test out of static lib
Bug: http://b/20858755
Change-Id: I0d84e8b43dc33902d75af18db6b7c8e0b619d718
2015-05-06 14:15:28 -07:00
Dmitriy Ivanov
c95a9e9dad Merge "VersionTracker: Ignore libraries without soname" 2015-05-06 19:06:20 +00:00
Dmitriy Ivanov
406d99665c VersionTracker: Ignore libraries without soname
Bug: http://b/20872443
Change-Id: I7bd076885c1feae39af6ea64c9442bcc5ae5a1dc
(cherry picked from commit 8264afb377)
2015-05-06 12:04:57 -07:00
Dmitriy Ivanov
f3392791bc Merge "Fix protected symbol lookups for mips" 2015-05-05 22:39:20 +00:00
Dmitriy Ivanov
dbe26fdcc7 Fix protected symbol lookups for mips
Bug: http://b/20694161
Change-Id: I5cc58034f9776e1db9cddc34abe48ef85f6048f4
2015-05-04 19:30:49 -07:00
Dmitriy Ivanov
2c3d8d8b2c Merge "Do not adjust PT_GNU_STACK segment" 2015-05-04 19:35:51 +00:00
Dmitriy Ivanov
4637f3d66d Do not adjust PT_GNU_STACK segment
Bug: http://b/20687795
Bug: http://b/18051137
Change-Id: Ie8af3892cfbebcc0249e7981284c4ad97ff40317
(cherry picked from commit 064a9800f3)
2015-05-04 12:34:42 -07:00
Christopher Ferris
64a8698809 Modify test to avoid race condition.
automerge: 3da136a

* commit '3da136aa47e2d1608b98abb2580f024b36f92831':
  Modify test to avoid race condition.
2015-05-04 16:45:13 +00:00
Dmitriy Ivanov
7fbd6355ae Merge changes I28bd3bc4,I6860013d
* changes:
  Lookup version info when relocating mips got
  Refactoring: move VersionTracker to link_image
2015-05-01 22:43:36 +00:00
Dmitriy Ivanov
f39cb63603 Lookup version info when relocating mips got
Bug: http://b/20693971
Bug: http://b/20139821
Change-Id: I28bd3bc44dafe048761b2c598facfe20320128c4
2015-04-30 20:17:03 -07:00
Dmitriy Ivanov
7e4bbbae4a Refactoring: move VersionTracker to link_image
Use one instance of VersionTracker per link (instead of 2).

Change-Id: I6860013df65f5969975c82ebdae8bd90a82e0a82
2015-04-30 19:49:19 -07:00
Dmitriy Ivanov
788ea593ec Merge "Refactoring: extract lookup_version_info(..)" 2015-05-01 00:40:59 +00:00
Dmitriy Ivanov
31b408d2c2 Refactoring: extract lookup_version_info(..)
Change-Id: I47f9c21a1738dc520fd83281c8227dc3a7e79650
2015-04-30 16:12:32 -07:00
Mark Salyzyn
033a68f1ac Merge "bionic: fortify comments in _system_properties.h" 2015-04-30 20:57:49 +00:00
Dan Albert
6a4c9d9bf9 Merge "Define char16_t and char32_t to make gcc 5.1 happy" 2015-04-30 19:29:47 +00:00
Dmitriy Ivanov
df877d7b28 Merge "Adjust DT_MIPS_RLD_MAP2 value" 2015-04-30 05:07:40 +00:00
Dmitriy Ivanov
18c935ceab Adjust DT_MIPS_RLD_MAP2 value
DT_MIPS_RLD_MAP2 stores the difference between dynamic
  entry address and the address of the _r_debug (used by GDB)
  since the dynamic section and target address are on the
  different sides of the hole it needs to be adjusted accordingly

Bug: http://b/20658994
Bug: http://b/18051137
Change-Id: I4c5e379e8a4c68f029467df6dc660f81a7013a09
2015-04-29 19:53:31 -07:00
Dmitriy Ivanov
f29640c2d8 Merge "linker: initialize system properties" 2015-04-29 23:44:57 +00:00
Dmitriy Ivanov
c6b9b254dc Merge "Fix mips relocation to use load_bias as intended" 2015-04-29 21:58:57 +00:00
Dmitriy Ivanov
0373d4f473 Fix mips relocation to use load_bias as intended
Bug: http://b/20658994
Change-Id: I5a15605fe34db359e26d563e13841ae993083c4a
2015-04-29 14:41:06 -07:00
Mark Salyzyn
c3f4c964a3 bionic: fortify comments in _system_properties.h
Change-Id: I2ef8fb7ae5ae03d5d2a50b5a417d585710099760
2015-04-29 13:57:42 -07:00
Neil Fuller
fa6f649607 Merge "Update to tzdata 2015d" 2015-04-29 10:42:16 +00:00
Dmitriy Ivanov
e1a61f5e93 Merge "Fix LD_PRELOAD for dlopen()" 2015-04-29 01:59:53 +00:00
Jeff Brown
0bf650373e Merge "Add float support to binary event log." 2015-04-29 01:42:49 +00:00
Jeff Brown
11331f60dd Add float support to binary event log.
Bug: 20664753
Change-Id: I6e43c07daa727c19d87f5192bb719af63dd93654
2015-04-28 18:20:22 -07:00
Dmitriy Ivanov
f8093a9485 Fix LD_PRELOAD for dlopen()
We did not set DF_1_GLOBAL flag for LD_PRELOADed
 libraries which led to the situation when ld_preloads
 where ignored during on dlopen()

Change-Id: I696b3b2506a8ed4c0984ad2c803210a7a4f8e686
2015-04-28 18:09:53 -07:00
Dmitriy Ivanov
b4e5067cab linker: initialize system properties
Bug: http://b/20567629
Bug: https://code.google.com/p/chromium/issues/detail?id=478886
Change-Id: I8d2d89b749015e7fcd6e7ea646911f2e617dd1ba
2015-04-28 15:52:52 -07:00
Mark Salyzyn
b904afa16e Merge "bionic: add __system_property_area_serial()" 2015-04-28 22:11:52 +00:00
Dmitriy Ivanov
9f0d99d298 Merge "Do not pack relocations for libc.so" 2015-04-28 22:06:43 +00:00
Dmitriy Ivanov
62d6533c1a Do not pack relocations for libc.so
Bug: http://b/20645321
Bug: http://b/20655855
(cherry picked from commit 452742d2bf)

Change-Id: Ic9125cc1bc4c9ba9eb20d030de72e3ce1fb86fa6
2015-04-28 15:05:20 -07:00
Dmitriy Ivanov
bed7a7e5eb Merge "linker: use libc's environ variable to store envp" 2015-04-28 21:35:59 +00:00
Dmitriy Ivanov
a85bcc2e99 linker: use libc's environ variable to store envp
This is to make getenv() work correctly.

Bug: http://b/20567629
Change-Id: I148627e1efea1649fb0822c95876811652fb4082
2015-04-28 14:21:36 -07:00
Christopher Ferris
6fa65e7cd5 Merge "cortex-a9: Fix reference to __memcpy_base_aligned." 2015-04-28 20:28:42 +00:00
Kyle Repinski
e0905c94d3 cortex-a9: Fix reference to __memcpy_base_aligned.
With a different memcpy, __memcpy_base_aligned ceased to exist.
Instead, point to the name defined by whatever includes memcpy_base.S

Change-Id: I242cf49cbada35337ba155d7f170e86a905ff55f
2015-04-28 14:29:15 -05:00
Neil Fuller
520cbf51b1 Update to tzdata 2015d
Changes affecting future time stamps

    Egypt will not observe DST in 2015 and will consider canceling it
    permanently.  For now, assume no DST indefinitely.
    (Thanks to Ahmed Nazmy and Tim Parenti.)

  Changes affecting past time stamps

    America/Whitehorse switched from UTC-9 to UTC-8 on 1967-05-28, not
    1966-07-01.  Also, Yukon's time zone history is documented better.
    (Thanks to Brian Inglis and Dennis Ferguson.)

  Change affecting past and future time zone abbreviations

    The abbreviations for Hawaii-Aleutian standard and daylight times
    have been changed from HAST/HADT to HST/HDT, as per US Government
    Printing Office style.  This affects only America/Adak since 1983,
    as America/Honolulu was already using the new style.

Bug: 20551453
Change-Id: I02364f15ca4ae20ed1a3b327f8517214bee938e5
2015-04-28 17:11:03 +01:00
Dmitriy Ivanov
42d7468f99 Merge "Reduce p_align for program header to page size." 2015-04-28 03:38:27 +00:00
Dmitriy Ivanov
b293969c6d Reduce p_align for program header to page size.
Having p_align > page_size leads to the situation when striping
 packed executables results in unnecessary p_vaddr adjustments.
 And it also may result (with probability 1 - 1/sizeof(uintptr_t)) in
 misaligned segments following .dynstr

Bug: http://b/20629834
Bug: http://b/18051137
Change-Id: I1c5da4911e4409d63cb09f6b6b0a16ef54f6501b
2015-04-27 20:37:17 -07:00
Dmitriy Ivanov
032907d8c7 Merge "Remove outdated warning" 2015-04-27 18:28:31 +00:00
Dmitriy Ivanov
2ea504fed1 Remove outdated warning
It is ok to use malloc in linker.

Bug: http://b/20567629
Change-Id: I54183dbe8ebcd223a44e710e511c339688a65dba
2015-04-27 11:24:36 -07:00
Chih-Hung Hsieh
59bce688c7 Merge "Fix opcode to compile with both gcc and llvm." 2015-04-27 17:17:45 +00:00
Mark Salyzyn
bfd65279a5 bionic: add __system_property_area_serial()
Adds a new _internal_ function. Provide a global serial number to
support more efficient private caching algorithms. This allows
to skip re-running the __system_property_find() call on misses until
there is a global change in the properties. This call is a read
barrier, the property data to be read following this call will be
read sequentially and up to date.

Bug: 19544788
Change-Id: I58e6a92baa0f3e8e7b9ec79b10af6d56407dab48
2015-04-27 07:44:03 -07:00
Neil Fuller
682a240c5d Merge "Update to tzdata 2015c" 2015-04-27 08:19:16 +00:00
Bernhard Rosenkränzer
6f88821e5d Define char16_t and char32_t to make gcc 5.1 happy
gcc 5.1 doesn't define char16_t and char32_t (unless in C++ mode),
causing compile failures.

Change-Id: I08dcd13cdf8cd59a4a2f191864bedf4c0d1bb313
Signed-off-by: Bernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org>
2015-04-24 16:21:38 +02:00
Neil Fuller
d2177404e2 Update to tzdata 2015c
Changes affecting future time stamps

    Egypt's spring-forward transition is at 24:00 on April's last Thursday,
    not 00:00 on April's last Friday.  2015's transition will therefore be on
    Thursday, April 30 at 24:00, not Friday, April 24 at 00:00.  Similar fixes
    apply to 2026, 2037, 2043, etc.  (Thanks to Steffen Thorsen.)

  Changes affecting past time stamps

    The following changes affect some pre-1991 Chile-related time stamps
    in America/Santiago, Antarctica/Palmer, and Pacific/Easter.

      The 1910 transition was January 10, not January 1.

      The 1918 transition was September 10, not September 1.

      The UTC-4 time observed from 1932 to 1942 is now considered to be
      standard time, not year-round DST.

      Santiago observed DST (UTC-3) from 1946-07-15 through 1946-08-31,
      then reverted to standard time, then switched its time zone to
      UTC-5 on 1947-04-01.

      Assume transitions before 1968 were at 00:00, since we have no data
      saying otherwise.

      The spring 1988 transition was 1988-10-09, not 1988-10-02.
      The fall 1990 transition was 1990-03-11, not 1990-03-18.

      Assume no UTC offset change for Pacific/Easter on 1890-01-01,
      and omit all transitions on Pacific/Easter from 1942 through 1946
      since we have no data suggesting that they existed.

    One more zone has been turned into a link, as it differed
    from an existing zone only for older time stamps.  As usual,
    this change affects UTC offsets in pre-1970 time stamps only.
    The zone's old contents have been moved to the 'backzone' file.
    The affected zone is America/Montreal.

Bug: 20287125
Change-Id: I8512c4e9ab09725395b256aba59ca34a23d1c995
2015-04-24 13:56:11 +01:00
Chih-Hung Hsieh
0a93df369c Fix opcode to compile with both gcc and llvm.
BUG: 17302991

Change-Id: I31febd9ad24312388068803ce247b295bd73b607
2015-04-23 21:40:31 +00:00
Christopher Ferris
3da136aa47 Modify test to avoid race condition.
There is a possible race if a timer is set to trigger at nearly the same
time as it is set. Since nobody uses the timers like this, modify the test
so this doesn't happen. The race that this can provoke has been fixed in
aosp.

Bug: 19423618
Change-Id: I21084c99da5ae46f404936d673dae6bad7c82caa
2015-02-18 17:45:50 -08:00
84 changed files with 1224 additions and 823 deletions

View File

@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <benchmark/Benchmark.h>
@@ -73,7 +74,7 @@ static void FopenFgetsFclose(int iters, bool no_locking) {
for (int i = 0; i < iters; ++i) {
FILE* fp = fopen("/proc/version", "re");
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
fgets(buf, sizeof(buf), fp);
if (fgets(buf, sizeof(buf), fp) == nullptr) abort();
fclose(fp);
}
}

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "utils.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
@@ -21,7 +23,7 @@
#include <string>
#include "utils.h"
#include <base/stringprintf.h>
int Round(int n) {
int base = 1;
@@ -72,10 +74,7 @@ std::string PrettyInt(long value, size_t base) {
break;
}
}
char* s = NULL;
asprintf(&s, "%s%" PRId64 "%s", (negative_number ? "-" : ""),
count / kAmountPerUnit[i], kUnitStrings[i]);
std::string result(s);
free(s);
return result;
return android::base::StringPrintf("%s%" PRId64 "%s",
negative_number ? "-" : "",
count / kAmountPerUnit[i], kUnitStrings[i]);
}

View File

@@ -131,6 +131,7 @@ libc_bionic_ndk_src_files := \
bionic/ffs.cpp \
bionic/flockfile.cpp \
bionic/fpclassify.cpp \
bionic/ftruncate.cpp \
bionic/futimens.cpp \
bionic/getcwd.cpp \
bionic/gethostname.cpp \
@@ -941,13 +942,6 @@ LOCAL_SRC_FILES := $(libc_bionic_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# ssse3-strcmp-slm.S does not compile with Clang.
LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -975,13 +969,6 @@ LOCAL_SRC_FILES := $(libc_bionic_ndk_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# ssse3-strcmp-slm.S does not compile with Clang.
LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -1030,13 +1017,6 @@ LOCAL_SRC_FILES := $(libc_pthread_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# ssse3-strcmp-slm.S does not compile with Clang.
LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes)
@@ -1361,6 +1341,9 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \
# meaningful name resolution.
LOCAL_STRIP_MODULE := keep_symbols
# Do not pack libc.so relocations; see http://b/20645321 for details.
LOCAL_PACK_MODULE_RELOCATIONS := false
# WARNING: The only library libc.so should depend on is libdl.so! If you add other libraries,
# make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries. This
# ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
@@ -1385,11 +1368,11 @@ LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
# We'd really like to do this for all architectures, but since this wasn't done
# before, these symbols must continue to be exported on LP32 for binary
# compatibility.
# TODO: disabled for http://b/20065774.
#LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
@@ -1519,7 +1502,8 @@ LOCAL_CFLAGS := $(libc_common_cflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
LOCAL_MODULE:= libstdc++

View File

@@ -307,34 +307,6 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2008-2010 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -454,22 +426,6 @@ Android adaptation and tweak by Jim Huang <jserv@0xlab.org>.
-------------------------------------------------------------------
Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------
Copyright (C) 2011 The Android Open Source Project
All rights reserved.
@@ -688,6 +644,50 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------
Copyright (C) 2015 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 1980, 1983, 1988, 1993
The Regents of the University of California. All rights reserved.
@@ -2550,33 +2550,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 1995, 1996 Carnegie-Mellon University.
All rights reserved.
Author: Chris G. Demetriou
Permission to use, copy, modify and distribute this software and
its documentation is hereby granted, provided that both the copyright
notice and this permission notice appear in all copies of the
software, derivative works or modified versions, and any portions
thereof, and that both notices appear in supporting documentation.
CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
Carnegie Mellon requests users of this software to return to
Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
School of Computer Science
Carnegie Mellon University
Pittsburgh PA 15213-3890
any improvements or extensions that they make and grant Carnegie the
rights to redistribute these changes.
-------------------------------------------------------------------
Copyright (c) 1996 by Internet Software Consortium.
Permission to use, copy, modify, and distribute this software for any
@@ -3795,6 +3768,22 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-------------------------------------------------------------------
Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-------------------------------------------------------------------
Copyright (c) 2007-2008 Michael G Schwern
This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
@@ -4733,31 +4722,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright 2000 David E. O'Brien, John D. Polstra.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright 2008 Android Open Source Project (source port randomization)
Copyright (c) 1985, 1989, 1993
The Regents of the University of California. All rights reserved.

View File

@@ -151,7 +151,6 @@ int utimensat(int, const char*, const struct timespec times[2], int) all
off_t lseek(int, off_t, int) arm,mips,x86
int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
off_t lseek|lseek64(int, off_t, int) arm64,mips64,x86_64
int ftruncate(int, off_t) arm,mips,x86
int ftruncate64(int, off64_t) arm,mips,x86
int ftruncate|ftruncate64(int, off_t) arm64,mips64,x86_64
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) arm,mips,x86
@@ -223,7 +222,7 @@ int __rt_sigpending:rt_sigpending(sigset_t*, size_t) all
int __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all
int __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t) all
int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, struct timespec_t*, size_t) all
int __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int __signalfd4:signalfd4(int, const sigset_t*, size_t, int) all
# sockets

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2010 The Android Open Source Project
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -44,7 +44,7 @@ ENTRY_PRIVATE(MEMCPY_BASE)
/* check if buffers are aligned. If so, run arm-only version */
eor r3, r0, r1
ands r3, r3, #0x3
beq __memcpy_base_aligned
beq MEMCPY_BASE_ALIGNED
/* Check the upper size limit for Neon unaligned memory access in memcpy */
cmp r2, #224

View File

@@ -35,6 +35,7 @@
*/
.fpu neon
.syntax unified
ENTRY(__memset_chk)
cmp r2, r3
@@ -100,9 +101,9 @@ ENTRY(memset)
1: bge 2f
vst1.32 {d0[0]}, [r0]!
2: movs ip, r2, lsl #31
strmib r1, [r0], #1
strcsb r1, [r0], #1
strcsb r1, [r0], #1
strbmi r1, [r0], #1
strbcs r1, [r0], #1
strbcs r1, [r0], #1
ldmfd sp!, {r0}
bx lr
END(memset)
@@ -131,11 +132,11 @@ ENTRY_PRIVATE(__memset_large_copy)
orr r1, r1, r1, lsr #16
movs r12, r3, lsl #31
strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
strcsb r1, [r0], #1
strmib r1, [r0], #1
strbcs r1, [r0], #1 /* can't use strh (alignment unknown) */
strbcs r1, [r0], #1
strbmi r1, [r0], #1
subs r2, r2, r3
ldmlsfd sp!, {r0, r4-r7, lr} /* return */
popls {r0, r4-r7, lr} /* return */
bxls lr
/* align the destination to a cache-line */
@@ -155,9 +156,9 @@ ENTRY_PRIVATE(__memset_large_copy)
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
stmcsia r0!, {r1, lr}
stmcsia r0!, {r1, lr}
stmmiia r0!, {r1, lr}
stmcs r0!, {r1, lr}
stmcs r0!, {r1, lr}
stmmi r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
@@ -172,13 +173,13 @@ ENTRY_PRIVATE(__memset_large_copy)
/* conditionally stores 0 to 31 bytes */
movs r2, r2, lsl #28
stmcsia r0!, {r1,r3,r12,lr}
stmmiia r0!, {r1, lr}
stmcs r0!, {r1,r3,r12,lr}
stmmi r0!, {r1, lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
strmih r1, [r0], #2
strhmi r1, [r0], #2
movs r2, r2, lsl #2
strcsb r1, [r0]
strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, lr}
bx lr
END(__memset_large_copy)

View File

@@ -40,6 +40,8 @@
* Optimized memcmp() for Cortex-A9.
*/
.syntax unified
ENTRY(memcmp)
pld [r0, #(CACHE_LINE_SIZE * 0)]
pld [r0, #(CACHE_LINE_SIZE * 1)]
@@ -161,25 +163,25 @@ ENTRY(memcmp)
eors r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eoreqs r0, r0, lr
eorseq r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
eoreqs r0, r0, ip
eorseq r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eoreqs r0, r0, lr
eorseq r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
eoreqs r0, r0, ip
eorseq r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eoreqs r0, r0, lr
eorseq r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
eoreqs r0, r0, ip
eorseq r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eoreqs r0, r0, lr
eorseq r0, r0, lr
bne 2f
subs r2, r2, #32
bhs 0b
@@ -263,17 +265,17 @@ ENTRY(memcmp)
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
eoreqs r0, r0, ip
eorseq r0, r0, ip
moveq ip, lr, lsr #16
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
eoreqs r0, r0, ip
eorseq r0, r0, ip
moveq ip, lr, lsr #16
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
eoreqs r0, r0, ip
eorseq r0, r0, ip
bne 7f
subs r2, r2, #16
bhs 6b
@@ -317,7 +319,7 @@ ENTRY(memcmp)
ldreq r7, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, r7, lsl r6
eoreqs r0, r0, ip
eorseq r0, r0, ip
bne 7f
subs r2, r2, #8
bhs 6b

View File

@@ -37,6 +37,8 @@
* so we have to preserve R0.
*/
.syntax unified
ENTRY(__memcpy_chk)
cmp r2, r3
bhi __memcpy_chk_fail
@@ -81,12 +83,12 @@ ENTRY(memcpy)
*/
movs r12, r3, lsl #31
sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
ldrmib r3, [r1], #1
ldrcsb r4, [r1], #1
ldrcsb r12,[r1], #1
strmib r3, [r0], #1
strcsb r4, [r0], #1
strcsb r12,[r0], #1
ldrbmi r3, [r1], #1
ldrbcs r4, [r1], #1
ldrbcs r12,[r1], #1
strbmi r3, [r0], #1
strbcs r4, [r0], #1
strbcs r12,[r0], #1
.Lsrc_aligned:
@@ -109,10 +111,10 @@ ENTRY(memcpy)
/* conditionally copies 0 to 7 words (length in r3) */
movs r12, r3, lsl #28
ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmiia r1!, {r8, r9} /* 8 bytes */
stmcsia r0!, {r4, r5, r6, r7}
stmmiia r0!, {r8, r9}
ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmi r1!, {r8, r9} /* 8 bytes */
stmcs r0!, {r4, r5, r6, r7}
stmmi r0!, {r8, r9}
tst r3, #0x4
ldrne r10,[r1], #4 /* 4 bytes */
strne r10,[r0], #4
@@ -177,18 +179,18 @@ ENTRY(memcpy)
/* conditionnaly copies 0 to 31 bytes */
movs r12, r2, lsl #28
ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmiia r1!, {r8, r9} /* 8 bytes */
stmcsia r0!, {r4, r5, r6, r7}
stmmiia r0!, {r8, r9}
ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmi r1!, {r8, r9} /* 8 bytes */
stmcs r0!, {r4, r5, r6, r7}
stmmi r0!, {r8, r9}
movs r12, r2, lsl #30
ldrcs r3, [r1], #4 /* 4 bytes */
ldrmih r4, [r1], #2 /* 2 bytes */
ldrhmi r4, [r1], #2 /* 2 bytes */
strcs r3, [r0], #4
strmih r4, [r0], #2
strhmi r4, [r0], #2
tst r2, #0x1
ldrneb r3, [r1] /* last byte */
strneb r3, [r0]
ldrbne r3, [r1] /* last byte */
strbne r3, [r0]
/* we're done! restore everything and return */
1: ldmfd sp!, {r5-r11}
@@ -228,11 +230,11 @@ ENTRY(memcpy)
* becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
*/
movs r5, r5, lsl #31
strmib r3, [r0], #1
strbmi r3, [r0], #1
movmi r3, r3, lsr #8
strcsb r3, [r0], #1
strbcs r3, [r0], #1
movcs r3, r3, lsr #8
strcsb r3, [r0], #1
strbcs r3, [r0], #1
movcs r3, r3, lsr #8
cmp r2, #4
@@ -363,23 +365,23 @@ ENTRY(memcpy)
.Lpartial_word_tail:
/* we have a partial word in the input buffer */
movs r5, lr, lsl #(31-3)
strmib r3, [r0], #1
strbmi r3, [r0], #1
movmi r3, r3, lsr #8
strcsb r3, [r0], #1
strbcs r3, [r0], #1
movcs r3, r3, lsr #8
strcsb r3, [r0], #1
strbcs r3, [r0], #1
/* Refill spilled registers from the stack. Don't update sp. */
ldmfd sp, {r5-r11}
.Lcopy_last_3_and_return:
movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
ldrmib r2, [r1], #1
ldrcsb r3, [r1], #1
ldrcsb r12,[r1]
strmib r2, [r0], #1
strcsb r3, [r0], #1
strcsb r12,[r0]
ldrbmi r2, [r1], #1
ldrbcs r3, [r1], #1
ldrbcs r12,[r1]
strbmi r2, [r0], #1
strbcs r3, [r0], #1
strbcs r12,[r0]
/* we're done! restore sp and spilled registers and return */
add sp, sp, #28

View File

@@ -35,6 +35,8 @@
* memset() returns its first argument.
*/
.syntax unified
ENTRY(__memset_chk)
cmp r2, r3
bls done
@@ -76,11 +78,11 @@ ENTRY(memset)
orr r1, r1, r1, lsr #16
movs r12, r3, lsl #31
strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
strcsb r1, [r0], #1
strmib r1, [r0], #1
strbcs r1, [r0], #1 /* can't use strh (alignment unknown) */
strbcs r1, [r0], #1
strbmi r1, [r0], #1
subs r2, r2, r3
ldmlsfd sp!, {r0, r4-r7, lr} /* return */
popls {r0, r4-r7, lr} /* return */
bxls lr
/* align the destination to a cache-line */
@@ -100,9 +102,9 @@ ENTRY(memset)
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
stmcsia r0!, {r1, lr}
stmcsia r0!, {r1, lr}
stmmiia r0!, {r1, lr}
stmcs r0!, {r1, lr}
stmcs r0!, {r1, lr}
stmmi r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
@@ -117,13 +119,13 @@ ENTRY(memset)
/* conditionally stores 0 to 31 bytes */
movs r2, r2, lsl #28
stmcsia r0!, {r1,r3,r12,lr}
stmmiia r0!, {r1, lr}
stmcs r0!, {r1,r3,r12,lr}
stmmi r0!, {r1, lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
strmih r1, [r0], #2
strhmi r1, [r0], #2
movs r2, r2, lsl #2
strcsb r1, [r0]
strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, lr}
bx lr
END(memset)

View File

@@ -32,6 +32,8 @@
#include <machine/cpu-features.h>
#include <private/bionic_asm.h>
.syntax unified
ENTRY(strcpy)
pld [r1, #0]
eor r2, r0, r1
@@ -108,15 +110,15 @@ ENTRY(strcpy)
#ifdef __ARMEB__
tst r2, #0xff00
iteet ne
strneh r2, [ip], #2
strhne r2, [ip], #2
lsreq r2, r2, #8
streqb r2, [ip]
strbeq r2, [ip]
tstne r2, #0xff
#else
tst r2, #0xff
itet ne
strneh r2, [ip], #2
streqb r2, [ip]
strhne r2, [ip], #2
strbeq r2, [ip]
tstne r2, #0xff00
#endif
bne 5b

View File

@@ -37,6 +37,7 @@
*/
.fpu neon
.syntax unified
ENTRY(__memset_chk)
cmp r2, r3
@@ -98,9 +99,9 @@ ENTRY(memset)
1: bge 2f
vst1.32 {d0[0]}, [r0]!
2: movs ip, r2, lsl #31
strmib r1, [r0], #1
strcsb r1, [r0], #1
strcsb r1, [r0], #1
strbmi r1, [r0], #1
strbcs r1, [r0], #1
strbcs r1, [r0], #1
ldmfd sp!, {r0}
bx lr
END(memset)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
ENTRY(___rt_sigqueueinfo)
mov ip, r7
ldr r7, =__NR_rt_sigqueueinfo
swi #0
@@ -11,4 +11,5 @@ ENTRY(__rt_sigqueueinfo)
bxls lr
neg r0, r0
b __set_errno_internal
END(__rt_sigqueueinfo)
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo

View File

@@ -1,14 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(ftruncate)
mov ip, r7
ldr r7, =__NR_ftruncate
swi #0
mov r7, ip
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno_internal
END(ftruncate)

View File

@@ -40,8 +40,6 @@ libc_bionic_src_files_arm64 += \
arch-arm64/bionic/syscall.S \
arch-arm64/bionic/vfork.S \
# Work around for http://b/20065774.
libc_bionic_src_files_arm64 += arch-arm64/bionic/libgcc_compat.c
libc_crt_target_cflags_arm64 := \
-I$(LOCAL_PATH)/arch-arm64/include

View File

@@ -1,15 +0,0 @@
/* STOPSHIP: remove this once the flounder blobs have been rebuilt (http://b/20065774). */
#if !defined(__clang__)
extern void __clear_cache(char*, char*);
extern char _Unwind_Backtrace;
extern char _Unwind_GetIP;
void* __bionic_libgcc_compat_symbols[] = {
&__clear_cache,
&_Unwind_Backtrace,
&_Unwind_GetIP,
};
#endif

View File

@@ -101,7 +101,7 @@ ENTRY(memchr)
and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
addp vend.16b, vhas_chr1.16b, vhas_chr2.16b /* 256->128 */
addp vend.16b, vend.16b, vend.16b /* 128->64 */
mov synd, vend.2d[0]
mov synd, vend.d[0]
/* Clear the soff*2 lower bits */
lsl tmp, soff, #1
lsr synd, synd, tmp
@@ -121,7 +121,7 @@ ENTRY(memchr)
/* Use a fast check for the termination condition */
orr vend.16b, vhas_chr1.16b, vhas_chr2.16b
addp vend.2d, vend.2d, vend.2d
mov synd, vend.2d[0]
mov synd, vend.d[0]
/* We're not out of data, loop if we haven't found the character */
cbz synd, .Lloop
@@ -131,7 +131,7 @@ ENTRY(memchr)
and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
addp vend.16b, vhas_chr1.16b, vhas_chr2.16b /* 256->128 */
addp vend.16b, vend.16b, vend.16b /* 128->64 */
mov synd, vend.2d[0]
mov synd, vend.d[0]
/* Only do the clear for the last possible block */
b.hi .Ltail

View File

@@ -109,7 +109,7 @@ ENTRY(strchr)
addp vend1.16b, vend1.16b, vend2.16b // 128->64
lsr tmp1, tmp3, tmp1
mov tmp3, vend1.2d[0]
mov tmp3, vend1.d[0]
bic tmp1, tmp3, tmp1 // Mask padding bits.
cbnz tmp1, .Ltail
@@ -124,7 +124,7 @@ ENTRY(strchr)
orr vend2.16b, vhas_nul2.16b, vhas_chr2.16b
orr vend1.16b, vend1.16b, vend2.16b
addp vend1.2d, vend1.2d, vend1.2d
mov tmp1, vend1.2d[0]
mov tmp1, vend1.d[0]
cbz tmp1, .Lloop
/* Termination condition found. Now need to establish exactly why
@@ -138,7 +138,7 @@ ENTRY(strchr)
addp vend1.16b, vend1.16b, vend2.16b // 256->128
addp vend1.16b, vend1.16b, vend2.16b // 128->64
mov tmp1, vend1.2d[0]
mov tmp1, vend1.d[0]
.Ltail:
/* Count the trailing zeros, by bit reversing... */
rbit tmp1, tmp1

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
ENTRY(___rt_sigqueueinfo)
mov x8, __NR_rt_sigqueueinfo
svc #0
@@ -11,5 +11,5 @@ ENTRY(__rt_sigqueueinfo)
b.hi __set_errno_internal
ret
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo

View File

@@ -28,9 +28,9 @@
#ifdef __LP64__
# define ASM_PTR_SIZE(x) .quad x
# define ASM_ALIGN(x)
# define ASM_ALIGN_TO_PTR_SIZE .balign 8
#else
# define ASM_PTR_SIZE(x) .long x
# define ASM_ALIGN(x) .align x
# define ASM_ALIGN_TO_PTR_SIZE .balign 4
#endif

View File

@@ -29,12 +29,15 @@
#include "asm_multiarch.h"
.section .preinit_array, "aw"
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
.section .init_array, "aw"
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
.section .fini_array, "aw"
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
#if defined(__linux__) && defined(__ELF__)
@@ -42,7 +45,9 @@
#endif
#if defined(__i386__) || defined(__x86_64__)
.section .eh_frame,"a",@progbits
ASM_ALIGN(4)
#if defined(__i386__)
.balign 4
#endif
.type __FRAME_END__, @object
.size __FRAME_END__, 4
__FRAME_END__:

View File

@@ -26,22 +26,14 @@
* SUCH DAMAGE.
*/
#include "asm_multiarch.h"
#ifndef __arm__
.section .init_array, "aw"
ASM_PTR_SIZE(0)
.section .fini_array, "aw"
ASM_PTR_SIZE(0)
#endif
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#if defined(__i386__) || defined(__x86_64__)
.section .eh_frame,"a",@progbits
ASM_ALIGN(4)
#if defined(__i386__)
.balign 4
#endif
.type __FRAME_END__, @object
.size __FRAME_END__, 4
__FRAME_END__:

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2015 The Android Open Source Project
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
ENTRY(___rt_sigqueueinfo)
.set noreorder
.cpload t9
li v0, __NR_rt_sigqueueinfo
@@ -16,4 +16,5 @@ ENTRY(__rt_sigqueueinfo)
j t9
nop
.set reorder
END(__rt_sigqueueinfo)
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo

View File

@@ -1,19 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(ftruncate)
.set noreorder
.cpload t9
li v0, __NR_ftruncate
syscall
bnez a3, 1f
move a0, v0
j ra
nop
1:
la t9,__set_errno_internal
j t9
nop
.set reorder
END(ftruncate)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
ENTRY(___rt_sigqueueinfo)
.set push
.set noreorder
li v0, __NR_rt_sigqueueinfo
@@ -22,5 +22,5 @@ ENTRY(__rt_sigqueueinfo)
j t9
move ra, t0
.set pop
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
ENTRY(___rt_sigqueueinfo)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
@@ -28,4 +28,5 @@ ENTRY(__rt_sigqueueinfo)
popl %ecx
popl %ebx
ret
END(__rt_sigqueueinfo)
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo

View File

@@ -1,26 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(ftruncate)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
pushl %ecx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ecx, 0
mov 12(%esp), %ebx
mov 16(%esp), %ecx
movl $__NR_ftruncate, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno_internal
addl $4, %esp
1:
popl %ecx
popl %ebx
ret
END(ftruncate)

View File

@@ -1897,8 +1897,8 @@ L(strcmp_exitz):
.p2align 4
L(Byte0):
movzx (%rsi), %ecx
movzx (%rdi), %eax
movzbl (%rsi), %ecx
movzbl (%rdi), %eax
sub %ecx, %eax
ret

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
ENTRY(___rt_sigqueueinfo)
movl $__NR_rt_sigqueueinfo, %eax
syscall
cmpq $-MAX_ERRNO, %rax
@@ -12,5 +12,5 @@ ENTRY(__rt_sigqueueinfo)
call __set_errno_internal
1:
ret
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo

28
libc/bionic/ftruncate.cpp Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <sys/cdefs.h>
#include <unistd.h>
#if !defined(__USE_FILE_OFFSET64) && !defined(__LP64__)
// The kernel's implementation of ftruncate uses an unsigned long for the length
// parameter, so it will not catch negative values. On the other hand
// ftruncate64 does check for this, so just forward the call.
int ftruncate(int filedes, off_t length) {
return ftruncate64(filedes, length);
}
#endif

View File

@@ -56,6 +56,7 @@ enum AndroidEventLogType {
EVENT_TYPE_LONG = 1,
EVENT_TYPE_STRING = 2,
EVENT_TYPE_LIST = 3,
EVENT_TYPE_FLOAT = 4,
};
struct BufferOutputStream {

View File

@@ -31,7 +31,7 @@
#include <sys/types.h>
#include <unistd.h>
extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*);
extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
int sigqueue(pid_t pid, int signo, const sigval value) {
siginfo_t info;
@@ -42,5 +42,5 @@ int sigqueue(pid_t pid, int signo, const sigval value) {
info.si_uid = getuid();
info.si_value = value;
return __rt_sigqueueinfo(pid, signo, &info);
return ___rt_sigqueueinfo(pid, signo, &info);
}

View File

@@ -598,6 +598,16 @@ int __system_property_area_init()
return map_prop_area_rw();
}
unsigned int __system_property_area_serial()
{
prop_area *pa = __system_property_area__;
if (!pa) {
return -1;
}
// Make sure this read fulfilled before __system_property_serial
return atomic_load_explicit(&(pa->serial), memory_order_acquire);
}
const prop_info *__system_property_find(const char *name)
{
if (__predict_false(compat_mode)) {

View File

@@ -34,6 +34,11 @@
#include <machine/elf_machdep.h>
#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))
typedef __s64 Elf32_Sxword;
typedef struct {
__u32 a_type;
union {
@@ -187,6 +192,11 @@ typedef struct {
#define STT_LOPROC 13
#define STT_HIPROC 15
#define STV_DEFAULT 0
#define STV_INTERNAL 1
#define STV_HIDDEN 2
#define STV_PROTECTED 3
/* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */
#define NT_FPREGSET NT_PRFPREG

View File

@@ -81,7 +81,6 @@ struct prop_msg
#define PROP_PATH_RAMDISK_DEFAULT "/default.prop"
#define PROP_PATH_SYSTEM_BUILD "/system/build.prop"
#define PROP_PATH_VENDOR_BUILD "/vendor/build.prop"
#define PROP_PATH_BOOTIMAGE_BUILD "/build.prop"
#define PROP_PATH_LOCAL_OVERRIDE "/data/local.prop"
#define PROP_PATH_FACTORY "/factory/factory.prop"
@@ -98,6 +97,30 @@ int __system_property_set_filename(const char *filename);
*/
int __system_property_area_init();
/* Read the global serial number of the system properties
**
** Called to predict if a series of cached __system_property_find
** objects will have seen __system_property_serial values change.
** But also aids the converse, as changes in the global serial can
** also be used to predict if a failed __system_property_find
** could in-turn now find a new object; thus preventing the
** cycles of effort to poll __system_property_find.
**
** Typically called at beginning of a cache cycle to signal if _any_ possible
** changes have occurred since last. If there is, one may check each individual
** __system_property_serial to confirm dirty, or __system_property_find
** to check if the property now exists. If a call to __system_property_add
** or __system_property_update has completed between two calls to
** __system_property_area_serial then the second call will return a larger
** value than the first call. Beware of race conditions as changes to the
** properties are not atomic, the main value of this call is to determine
** whether the expensive __system_property_find is worth retrying to see if
** a property now exists.
**
** Returns the serial number on success, -1 on error.
*/
unsigned int __system_property_area_serial();
/* Add a new system property. Can only be done by a single
** process that has write access to the property area, and
** that process must handle sequencing to ensure the property

View File

@@ -34,6 +34,11 @@
__BEGIN_DECLS
#if defined(__GNUC__) && __GNUC__ >= 5 && !defined(__cplusplus)
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
#endif
#define __STD_UTF_16__ 1
#define __STD_UTF_32__ 1

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SCOPED_FD_H
#define SCOPED_FD_H
#include <unistd.h>
#include "bionic_macros.h"
// A smart pointer that closes the given fd on going out of scope.
// Use this when the fd is incidental to the purpose of your function,
// but needs to be cleaned up on exit.
class ScopedFd {
public:
explicit ScopedFd(int fd) : fd(fd) {
}
~ScopedFd() {
reset();
}
int get() const {
return fd;
}
int release() __attribute__((warn_unused_result)) {
int localFd = fd;
fd = -1;
return localFd;
}
void reset(int new_fd = -1) {
if (fd != -1) {
TEMP_FAILURE_RETRY(close(fd));
}
fd = new_fd;
}
private:
int fd;
// Disallow copy and assignment.
DISALLOW_COPY_AND_ASSIGN(ScopedFd);
};
#endif // SCOPED_FD_H

View File

@@ -86,5 +86,5 @@ __sseek(void *cookie, fpos_t offset, int whence)
int
__sclose(void *cookie)
{
return TEMP_FAILURE_RETRY(close(((FILE *)cookie)->_file));
return close(((FILE *)cookie)->_file);
}

View File

@@ -13,9 +13,21 @@ arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
sys.stderr.write('Checking symbols for arch "%s"...\n' % arch)
def GetSymbols(library, functions_or_variables):
global api
global arch
api = '9'
if library == 'libm' and arch == 'arm':
api = '3'
# There were no 64-bit ABIs before API level 21.
if '64' in arch:
api = '21'
# What GCC calls aarch64, Android calls arm64.
if arch == 'aarch64':
arch = 'arm64'
path = '%s/development/ndk/platforms/android-%s/arch-%s/symbols/%s.so.%s.txt' % (os.environ['ANDROID_BUILD_TOP'], api, arch, library, functions_or_variables)
symbols = set()
for line in open(path, 'r'):
@@ -26,7 +38,11 @@ def GetSymbols(library, functions_or_variables):
def CheckSymbols(library, functions_or_variables):
expected_symbols = GetSymbols(library, functions_or_variables)
so_file = '%s/system/lib/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], library)
lib_dir = 'lib'
if '64' in arch:
lib_dir = 'lib64'
so_file = '%s/system/%s/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], lib_dir, library)
# Example readelf output:
# 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf
@@ -38,7 +54,7 @@ def CheckSymbols(library, functions_or_variables):
r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
actual_symbols = set()
for line in subprocess.check_output(['readelf', '--dyn-syms', so_file]).split('\n'):
for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'):
m = r.match(line)
if m:
if m.group(1) == 'FUNC' and functions_or_variables == 'functions':
@@ -54,6 +70,12 @@ def CheckSymbols(library, functions_or_variables):
for miss in sorted(missing):
sys.stderr.write(' %s\n' % miss)
extra = actual_symbols - expected_symbols
if len(extra) > 0:
sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch))
for s in sorted(extra):
sys.stderr.write(' %s\n' % s)
return len(missing) == 0
CheckSymbols("libc", "functions")

View File

@@ -1,9 +1,4 @@
LIBC {
global:
/* Work-around for http://b/20065774. */
__clear_cache;
_Unwind_Backtrace;
_Unwind_GetIP;
local:
_ZSt7nothrow;
_ZdaPv;

Binary file not shown.

View File

@@ -15,7 +15,7 @@ include $(CLEAR_VARS)
#
# DO NOT REMOVE --exclude-libs!
LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a
LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a -Wl,--version-script=$(LOCAL_PATH)/libdl.map
# for x86, exclude libgcc_eh.a for the same reasons as above
LOCAL_LDFLAGS_x86 := -Wl,--exclude-libs=libgcc_eh.a

View File

@@ -17,6 +17,7 @@
#include <dlfcn.h>
#include <link.h>
#include <stdlib.h>
#include <stdbool.h>
#include <android/dlext.h>
// These are stubs for functions that are actually defined
@@ -38,3 +39,6 @@ void android_get_LD_LIBRARY_PATH(char* buffer __unused, size_t buffer_size __unu
void android_update_LD_LIBRARY_PATH(const char* ld_library_path __unused) { }
void* android_dlopen_ext(const char* filename __unused, int flag __unused, const android_dlextinfo* extinfo __unused) { return 0; }
void android_set_application_target_sdk_version(uint32_t target __unused) { }
uint32_t android_get_application_target_sdk_version() { return 0; }

39
libdl/libdl.map Normal file
View File

@@ -0,0 +1,39 @@
#
# Copyright (C) 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LIBC {
global:
android_dlopen_ext;
dl_iterate_phdr;
# begin arm-only
dl_unwind_find_exidx;
# end arm-only
dladdr;
dlclose;
dlerror;
dlopen;
dlsym;
local:
*;
};
LIBC_PRIVATE {
global:
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
} LIBC;

View File

@@ -501,9 +501,6 @@ LOCAL_CFLAGS += \
-fno-builtin-rintf \
-fno-builtin-rintl \
LOCAL_CONLY_FLAGS := \
-std=c99 \
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
LOCAL_ADDRESS_SANITIZER := false
include $(BUILD_STATIC_LIBRARY)
@@ -514,7 +511,8 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_MODULE := libm
LOCAL_CLANG := $(libm_clang)

View File

@@ -1002,6 +1002,114 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
Johhnny Qiu <joqiu@nvidia.com>
Shu Zhang <chazhang@nvidia.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
Johnny Qiu <joqiu@nvidia.com>
Shu Zhang <chazhang@nvidia.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 2014, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright 2015, The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------
From: @(#)s_ilogb.c 5.1 93/09/24
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.

View File

@@ -7,6 +7,7 @@ LOCAL_SRC_FILES:= \
dlfcn.cpp \
linker.cpp \
linker_allocator.cpp \
linker_sdk_versions.cpp \
linker_block_allocator.cpp \
linker_environ.cpp \
linker_libc_support.c \
@@ -35,6 +36,9 @@ LOCAL_CFLAGS += \
-fvisibility=hidden \
-Wall -Wextra -Wunused -Werror \
LOCAL_CFLAGS_arm += -D__work_around_b_19059885__
LOCAL_CFLAGS_x86 += -D__work_around_b_19059885__
LOCAL_CONLYFLAGS += \
-std=gnu99 \

View File

@@ -42,62 +42,6 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2008, 2009 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2008-2010 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2010 The Android Open Source Project
All rights reserved.
@@ -214,3 +158,47 @@ limitations under the License.
-------------------------------------------------------------------
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------
Copyright (C) 2015 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------

View File

@@ -205,15 +205,6 @@ static bool have_siginfo(int signum) {
}
static void send_debuggerd_packet(siginfo_t* info) {
if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) {
// process has disabled core dumps and PTRACE_ATTACH, and does not want to be dumped.
// Honor that intention by not connecting to debuggerd and asking it
// to dump our internal state.
__libc_format_log(ANDROID_LOG_INFO, "libc",
"Suppressing debuggerd output because prctl(PR_GET_DUMPABLE)==0");
return;
}
// Mutex to prevent multiple crashing threads from trying to talk
// to debuggerd at the same time.
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;

View File

@@ -157,6 +157,14 @@ int dlclose(void* handle) {
return 0;
}
void android_set_application_target_sdk_version(uint32_t target) {
set_application_target_sdk_version(target);
}
uint32_t android_get_application_target_sdk_version() {
return get_application_target_sdk_version();
}
// name_offset: starting index of the name in libdl_info.strtab
#define ELF32_SYM_INITIALIZER(name_offset, value, shndx) \
{ name_offset, \
@@ -176,19 +184,21 @@ int dlclose(void* handle) {
/* st_size */ 0, \
}
static const char ANDROID_LIBDL_STRTAB[] =
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 99999
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 56789
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_it"
// 00000000001 1111111112222222222 3333333333444444444455555555556666666666777 777777788888888889999999999
// 01234567890 1234567890123456789 0123456789012345678901234567890123456789012 345678901234567890123456789
"erate_phdr\0android_dlopen_ext\0android_set_application_target_sdk_version\0android_get_application_tar"
// 0000000000111111
// 0123456789012345
"get_sdk_version\0"
#if defined(__arm__)
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 9999900000000001 1111111112222222222 333333333344444444445
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 5678901234567890 1234567890123456789 012345678901234567890
# define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_iterate_phdr\0android_dlopen_ext\0dl_unwind_find_exidx\0"
#elif defined(__aarch64__) || defined(__i386__) || defined(__mips__) || defined(__x86_64__)
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 9999900000000001 1111111112222222222
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 5678901234567890 1234567890123456789
# define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_iterate_phdr\0android_dlopen_ext\0"
#else
# error Unsupported architecture. Only arm, arm64, mips, mips64, x86 and x86_64 are presently supported.
// 216
"dl_unwind_find_exidx\0"
#endif
;
static ElfW(Sym) g_libdl_symtab[] = {
// Total length of libdl_info.strtab, including trailing 0.
@@ -205,8 +215,10 @@ static ElfW(Sym) g_libdl_symtab[] = {
ELFW(SYM_INITIALIZER)( 67, &android_get_LD_LIBRARY_PATH, 1),
ELFW(SYM_INITIALIZER)( 95, &dl_iterate_phdr, 1),
ELFW(SYM_INITIALIZER)(111, &android_dlopen_ext, 1),
ELFW(SYM_INITIALIZER)(130, &android_set_application_target_sdk_version, 1),
ELFW(SYM_INITIALIZER)(173, &android_get_application_target_sdk_version, 1),
#if defined(__arm__)
ELFW(SYM_INITIALIZER)(130, &dl_unwind_find_exidx, 1),
ELFW(SYM_INITIALIZER)(216, &dl_unwind_find_exidx, 1),
#endif
};
@@ -223,9 +235,9 @@ static ElfW(Sym) g_libdl_symtab[] = {
// Note that adding any new symbols here requires stubbing them out in libdl.
static unsigned g_libdl_buckets[1] = { 1 };
#if defined(__arm__)
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 };
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 };
#else
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 };
#endif
static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));

View File

@@ -47,7 +47,6 @@
#include "private/bionic_tls.h"
#include "private/KernelArgumentBlock.h"
#include "private/ScopedPthreadMutexLocker.h"
#include "private/ScopedFd.h"
#include "private/ScopeGuard.h"
#include "private/UniquePtr.h"
@@ -61,21 +60,6 @@
#include "linker_reloc_iterators.h"
#include "ziparchive/zip_archive.h"
/* >>> IMPORTANT NOTE - READ ME BEFORE MODIFYING <<<
*
* Do NOT use malloc() and friends or pthread_*() code here.
* Don't use printf() either; it's caused mysterious memory
* corruption in the past.
* The linker runs before we bring up libc and it's easiest
* to make sure it does not depend on any complex libc features
*
* open issues / todo:
*
* - cleaner error reporting
* - after linking, set as much stuff as possible to READONLY
* and NOEXEC
*/
// Override macros to use C++ style casts
#undef ELF_ST_TYPE
#define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
@@ -267,7 +251,7 @@ static void soinfo_free(soinfo* si) {
soinfo *prev = nullptr, *trav;
TRACE("name %s: freeing soinfo @ %p", si->get_soname(), si);
TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
for (trav = solist; trav != nullptr; trav = trav->next) {
if (trav == si) {
@@ -278,7 +262,7 @@ static void soinfo_free(soinfo* si) {
if (trav == nullptr) {
// si was not in solist
DL_ERR("name \"%s\"@%p is not in solist!", si->get_soname(), si);
DL_ERR("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
return;
}
@@ -443,7 +427,7 @@ static bool for_each_verdef(const soinfo* si, F functor) {
if (verdef->vd_version != 1) {
DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
i, verdef->vd_version, si->get_soname());
i, verdef->vd_version, si->get_realpath());
return false;
}
@@ -513,7 +497,7 @@ static bool is_symbol_global_and_defined(const soinfo* si, const ElfW(Sym)* s) {
return s->st_shndx != SHN_UNDEF;
} else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
DL_WARN("unexpected ST_BIND value: %d for '%s' in '%s'",
ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_soname());
ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
}
return false;
@@ -546,12 +530,12 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
*symbol_index = 0;
TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
// test against bloom filter
if ((1 & (bloom_word >> (hash % bloom_mask_bits)) & (bloom_word >> (h2 % bloom_mask_bits))) == 0) {
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
return true;
}
@@ -561,7 +545,7 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
if (n == 0) {
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
return true;
}
@@ -589,7 +573,7 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
is_symbol_global_and_defined(this, s)) {
TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(s->st_value),
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
static_cast<size_t>(s->st_size));
*symbol_index = n;
return true;
@@ -597,7 +581,7 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
} while ((gnu_chain_[n++] & 1) == 0);
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
return true;
}
@@ -608,7 +592,7 @@ bool soinfo::elf_lookup(SymbolName& symbol_name,
uint32_t hash = symbol_name.elf_hash();
TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
symbol_name.get_name(), get_soname(),
symbol_name.get_name(), get_realpath(),
reinterpret_cast<void*>(base), hash, hash % nbucket_);
ElfW(Versym) verneed = 0;
@@ -629,7 +613,7 @@ bool soinfo::elf_lookup(SymbolName& symbol_name,
strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
is_symbol_global_and_defined(this, s)) {
TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
symbol_name.get_name(), get_soname(),
symbol_name.get_name(), get_realpath(),
reinterpret_cast<void*>(s->st_value),
static_cast<size_t>(s->st_size));
*symbol_index = n;
@@ -638,7 +622,7 @@ bool soinfo::elf_lookup(SymbolName& symbol_name,
}
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
symbol_name.get_name(), get_soname(),
symbol_name.get_name(), get_realpath(),
reinterpret_cast<void*>(base), hash, hash % nbucket_);
*symbol_index = 0;
@@ -718,7 +702,7 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
* relocations for -Bsymbolic linked dynamic executables.
*/
if (si_from->has_DT_SYMBOLIC) {
DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_soname(), name);
DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
return false;
}
@@ -733,7 +717,7 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
bool error = false;
global_group.visit([&](soinfo* global_si) {
DEBUG("%s: looking up %s in %s (from global group)",
si_from->get_soname(), name, global_si->get_soname());
si_from->get_realpath(), name, global_si->get_realpath());
if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
error = true;
return false;
@@ -762,7 +746,7 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
}
DEBUG("%s: looking up %s in %s (from local group)",
si_from->get_soname(), name, local_si->get_soname());
si_from->get_realpath(), name, local_si->get_realpath());
if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
error = true;
return false;
@@ -784,8 +768,8 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
if (s != nullptr) {
TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
"found in %s, base = %p, load bias = %p",
si_from->get_soname(), name, reinterpret_cast<void*>(s->st_value),
(*si_found_in)->get_soname(), reinterpret_cast<void*>((*si_found_in)->base),
si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
(*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
reinterpret_cast<void*>((*si_found_in)->load_bias));
}
@@ -933,13 +917,17 @@ static bool walk_dependencies_tree(soinfo* root_soinfos[], size_t root_soinfos_s
}
// This is used by dlsym(3). It performs symbol lookup only within the
// specified soinfo object and its dependencies in breadth first order.
const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) {
static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until,
soinfo** found, SymbolName& symbol_name) {
const ElfW(Sym)* result = nullptr;
SymbolName symbol_name(name);
bool skip_lookup = skip_until != nullptr;
walk_dependencies_tree(&root, 1, [&](soinfo* current_soinfo) {
if (skip_lookup) {
skip_lookup = current_soinfo != skip_until;
return true;
}
walk_dependencies_tree(&si, 1, [&](soinfo* current_soinfo) {
if (!current_soinfo->find_symbol_by_name(symbol_name, nullptr, &result)) {
result = nullptr;
return false;
@@ -956,6 +944,13 @@ const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* nam
return result;
}
// This is used by dlsym(3). It performs symbol lookup only within the
// specified soinfo object and its dependencies in breadth first order.
const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) {
SymbolName symbol_name(name);
return dlsym_handle_lookup(si, nullptr, found, symbol_name);
}
/* This is used by dlsym(3) to performs a global symbol lookup. If the
start value is null (for RTLD_DEFAULT), the search starts at the
beginning of the global solist. Otherwise the search starts at the
@@ -970,7 +965,7 @@ const ElfW(Sym)* dlsym_linear_lookup(const char* name,
soinfo* start = solist;
if (handle == RTLD_NEXT) {
if (caller == nullptr || caller->next == nullptr) {
if (caller == nullptr) {
return nullptr;
} else {
start = caller->next;
@@ -993,31 +988,13 @@ const ElfW(Sym)* dlsym_linear_lookup(const char* name,
}
}
// If not found - look into local_group unless
// caller is part of the global group in which
// If not found - use dlsym_handle_lookup for caller's
// local_group unless it is part of the global group in which
// case we already did it.
if (s == nullptr && caller != nullptr &&
(caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
soinfo* local_group_root = caller->get_local_group_root();
if (handle == RTLD_DEFAULT) {
start = local_group_root;
}
for (soinfo* si = start; si != nullptr; si = si->next) {
if (si->get_local_group_root() != local_group_root) {
break;
}
if (!si->find_symbol_by_name(symbol_name, nullptr, &s)) {
return nullptr;
}
if (s != nullptr) {
*found = si;
break;
}
}
return dlsym_handle_lookup(caller->get_local_group_root(),
(handle == RTLD_NEXT) ? caller : nullptr, found, symbol_name);
}
if (s != nullptr) {
@@ -1232,29 +1209,10 @@ static void for_each_dt_needed(const soinfo* si, F action) {
}
}
static soinfo* load_library(LoadTaskList& load_tasks,
static soinfo* load_library(int fd, off64_t file_offset,
LoadTaskList& load_tasks,
const char* name, int rtld_flags,
const android_dlextinfo* extinfo) {
int fd = -1;
off64_t file_offset = 0;
ScopedFd file_guard(-1);
if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
fd = extinfo->library_fd;
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
file_offset = extinfo->library_fd_offset;
}
} else {
// Open the file.
fd = open_library(name, &file_offset);
if (fd == -1) {
DL_ERR("library \"%s\" not found", name);
return nullptr;
}
file_guard.reset(fd);
}
if ((file_offset % PAGE_SIZE) != 0) {
DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
return nullptr;
@@ -1330,6 +1288,29 @@ static soinfo* load_library(LoadTaskList& load_tasks,
return si;
}
static soinfo* load_library(LoadTaskList& load_tasks,
const char* name, int rtld_flags,
const android_dlextinfo* extinfo) {
if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
off64_t file_offset = 0;
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
file_offset = extinfo->library_fd_offset;
}
return load_library(extinfo->library_fd, file_offset, load_tasks, name, rtld_flags, extinfo);
}
// Open the file.
off64_t file_offset;
int fd = open_library(name, &file_offset);
if (fd == -1) {
DL_ERR("library \"%s\" not found", name);
return nullptr;
}
soinfo* result = load_library(fd, file_offset, load_tasks, name, rtld_flags, extinfo);
close(fd);
return result;
}
static soinfo *find_loaded_library_by_soname(const char* name) {
// Ignore filename with path.
if (strchr(name, '/') != nullptr) {
@@ -1513,7 +1494,7 @@ static void soinfo_unload(soinfo* root) {
}
if (!root->can_unload()) {
TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_soname());
TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_realpath());
return;
}
@@ -1536,7 +1517,9 @@ static void soinfo_unload(soinfo* root) {
if (si->has_min_version(0)) {
soinfo* child = nullptr;
while ((child = si->get_children().pop_front()) != nullptr) {
TRACE("%s@%p needs to unload %s@%p", si->get_soname(), si, child->get_soname(), child);
TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
child->get_realpath(), child);
if (local_unload_list.contains(child)) {
continue;
} else if (child->is_linked() && child->get_local_group_root() != root) {
@@ -1546,20 +1529,20 @@ static void soinfo_unload(soinfo* root) {
}
}
} else {
#if !defined(__arm__)
__libc_fatal("soinfo for \"%s\"@%p has no version", si->get_soname(), si);
#if !defined(__work_around_b_19059885__)
__libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
#else
PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_soname(), si);
PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
for_each_dt_needed(si, [&] (const char* library_name) {
TRACE("deprecated (old format of soinfo): %s needs to unload %s",
si->get_soname(), library_name);
si->get_realpath(), library_name);
soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
if (needed != nullptr) {
// Not found: for example if symlink was deleted between dlopen and dlclose
// Since we cannot really handle errors at this point - print and continue.
PRINT("warning: couldn't find %s needed by %s on unload.",
library_name, si->get_soname());
library_name, si->get_realpath());
return;
} else if (local_unload_list.contains(needed)) {
// already visited
@@ -1589,7 +1572,8 @@ static void soinfo_unload(soinfo* root) {
soinfo_unload(si);
}
} else {
TRACE("not unloading '%s' group, decrementing ref_count to %zd", root->get_soname(), ref_count);
TRACE("not unloading '%s' group, decrementing ref_count to %zd",
root->get_realpath(), ref_count);
}
}
@@ -1701,12 +1685,12 @@ bool VersionTracker::init_verneed(const soinfo* si_from) {
const char* target_soname = si_from->get_string(verneed->vn_file);
// find it in dependencies
soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
return strcmp(si->get_soname(), target_soname) == 0;
return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
});
if (target_si == nullptr) {
DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
target_soname, i, si_from->get_soname());
target_soname, i, si_from->get_realpath());
return false;
}
@@ -1743,6 +1727,27 @@ bool VersionTracker::init(const soinfo* si_from) {
return init_verneed(si_from) && init_verdef(si_from);
}
bool soinfo::lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
const char* sym_name, const version_info** vi) {
const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
if (sym_ver != VER_NDX_LOCAL && sym_ver != VER_NDX_GLOBAL) {
*vi = version_tracker.get_version_info(sym_ver);
if (*vi == nullptr) {
DL_ERR("cannot find verneed/verdef for version index=%d "
"referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
return false;
}
} else {
// there is no version info
*vi = nullptr;
}
return true;
}
#if !defined(__mips__)
#if defined(USE_RELA)
static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) {
@@ -1759,14 +1764,8 @@ static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
#endif
template<typename ElfRelIteratorT>
bool soinfo::relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
VersionTracker version_tracker;
if (!version_tracker.init(this)) {
return false;
}
bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
if (rel == nullptr) {
@@ -1781,7 +1780,7 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& globa
const char* sym_name = nullptr;
ElfW(Addr) addend = get_addend(rel, reloc);
DEBUG("Processing '%s' relocation at index %zd", get_soname(), idx);
DEBUG("Processing '%s' relocation at index %zd", get_realpath(), idx);
if (type == R_GENERIC_NONE) {
continue;
}
@@ -1791,32 +1790,21 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& globa
if (sym != 0) {
sym_name = get_string(symtab_[sym].st_name);
const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
const version_info* vi = nullptr;
if (sym_ver == VER_NDX_LOCAL || sym_ver == VER_NDX_GLOBAL) {
// there is no version info for this one
if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
return false;
}
} else {
const version_info* vi = version_tracker.get_version_info(sym_ver);
if (vi == nullptr) {
DL_ERR("cannot find verneed/verdef for version index=%d "
"referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_soname());
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
if (s == nullptr) {
// We only allow an undefined symbol if this is a weak reference...
s = &symtab_[sym];
if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_soname());
DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
return false;
}
@@ -2012,7 +2000,7 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& globa
* R_AARCH64_COPY may only appear in executable objects where e_type is
* set to ET_EXEC.
*/
DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_soname());
DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
return false;
case R_AARCH64_TLS_TPREL64:
TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
@@ -2069,7 +2057,7 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& globa
* R_ARM_COPY may only appear in executable objects where e_type is
* set to ET_EXEC.
*/
DL_ERR("%s R_ARM_COPY relocations are not supported", get_soname());
DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
return false;
#elif defined(__i386__)
case R_386_32:
@@ -2101,7 +2089,7 @@ void soinfo::call_array(const char* array_name __unused, linker_function_t* func
return;
}
TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_soname());
TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_realpath());
int begin = reverse ? (count - 1) : 0;
int end = reverse ? -1 : count;
@@ -2112,7 +2100,7 @@ void soinfo::call_array(const char* array_name __unused, linker_function_t* func
call_function("function", functions[i]);
}
TRACE("[ Done calling %s for '%s' ]", array_name, get_soname());
TRACE("[ Done calling %s for '%s' ]", array_name, get_realpath());
}
void soinfo::call_function(const char* function_name __unused, linker_function_t function) {
@@ -2120,9 +2108,9 @@ void soinfo::call_function(const char* function_name __unused, linker_function_t
return;
}
TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_soname());
TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_realpath());
function();
TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_soname());
TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_realpath());
}
void soinfo::call_pre_init_constructors() {
@@ -2151,14 +2139,14 @@ void soinfo::call_constructors() {
if (!is_main_executable() && preinit_array_ != nullptr) {
// The GNU dynamic linker silently ignores these, but we warn the developer.
PRINT("\"%s\": ignoring %zd-entry DT_PREINIT_ARRAY in shared library!",
get_soname(), preinit_array_count_);
get_realpath(), preinit_array_count_);
}
get_children().for_each([] (soinfo* si) {
si->call_constructors();
});
TRACE("\"%s\": calling constructors", get_soname());
TRACE("\"%s\": calling constructors", get_realpath());
// DT_INIT should be called before DT_INIT_ARRAY if both are present.
call_function("DT_INIT", init_func_);
@@ -2169,7 +2157,7 @@ void soinfo::call_destructors() {
if (!constructors_called) {
return;
}
TRACE("\"%s\": calling destructors", get_soname());
TRACE("\"%s\": calling destructors", get_realpath());
// DT_FINI_ARRAY must be parsed in reverse order.
call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true);
@@ -2267,7 +2255,7 @@ void soinfo::set_dt_flags_1(uint32_t dt_flags_1) {
}
const char* soinfo::get_realpath() const {
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
if (has_min_version(2)) {
return realpath_.c_str();
} else {
@@ -2279,7 +2267,7 @@ const char* soinfo::get_realpath() const {
}
const char* soinfo::get_soname() const {
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
if (has_min_version(2)) {
return soname_;
} else {
@@ -2329,7 +2317,7 @@ ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
const char* soinfo::get_string(ElfW(Word) index) const {
if (has_min_version(1) && (index >= strtab_size_)) {
__libc_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d",
get_soname(), strtab_size_, index);
get_realpath(), strtab_size_, index);
}
return strtab_ + index;
@@ -2426,8 +2414,7 @@ static int nullify_closed_stdio() {
/* If /dev/null is not one of the stdio file descriptors, close it. */
if (dev_null > 2) {
TRACE("[ Closing /dev/null file-descriptor=%d]", dev_null);
status = TEMP_FAILURE_RETRY(close(dev_null));
if (status == -1) {
if (close(dev_null) == -1) {
DL_ERR("close failed: %s", strerror(errno));
return_value = -1;
}
@@ -2444,13 +2431,13 @@ bool soinfo::prelink_image() {
/* We can't log anything until the linker is relocated */
bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
if (!relocating_linker) {
INFO("[ linking %s ]", get_soname());
INFO("[ linking %s ]", get_realpath());
DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
}
if (dynamic == nullptr) {
if (!relocating_linker) {
DL_ERR("missing PT_DYNAMIC in \"%s\"", get_soname());
DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
}
return false;
} else {
@@ -2817,7 +2804,7 @@ bool soinfo::prelink_image() {
for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
if (d->d_tag == DT_SONAME) {
soname_ = get_string(d->d_un.d_val);
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
strlcpy(old_name_, soname_, sizeof(old_name_));
#endif
break;
@@ -2834,15 +2821,15 @@ bool soinfo::prelink_image() {
}
if (nbucket_ == 0 && gnu_nbucket_ == 0) {
DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
"(new hash type from the future?)", get_soname());
"(new hash type from the future?)", get_realpath());
return false;
}
if (strtab_ == 0) {
DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_soname());
DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
return false;
}
if (symtab_ == 0) {
DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_soname());
DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
return false;
}
return true;
@@ -2856,15 +2843,21 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
local_group_root_ = this;
}
VersionTracker version_tracker;
if (!version_tracker.init(this)) {
return false;
}
#if !defined(__LP64__)
if (has_text_relocations) {
// Make segments writable to allow text relocations to work properly. We will later call
// phdr_table_protect_segments() after all of them are applied and all constructors are run.
DL_WARN("%s has text relocations. This is wasting memory and prevents "
"security hardening. Please fix.", get_soname());
"security hardening. Please fix.", get_realpath());
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
get_soname(), strerror(errno));
get_realpath(), strerror(errno));
return false;
}
}
@@ -2877,13 +2870,14 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
android_relocs_[1] == 'P' &&
android_relocs_[2] == 'S' &&
android_relocs_[3] == '2') {
DEBUG("[ android relocating %s ]", get_soname());
DEBUG("[ android relocating %s ]", get_realpath());
bool relocated = false;
const uint8_t* packed_relocs = android_relocs_ + 4;
const size_t packed_relocs_size = android_relocs_size_ - 4;
relocated = relocate(
version_tracker,
packed_reloc_iterator<sleb128_decoder>(
sleb128_decoder(packed_relocs, packed_relocs_size)),
global_group, local_group);
@@ -2899,46 +2893,50 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
#if defined(USE_RELA)
if (rela_ != nullptr) {
DEBUG("[ relocating %s ]", get_soname());
if (!relocate(plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
DEBUG("[ relocating %s ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
return false;
}
}
if (plt_rela_ != nullptr) {
DEBUG("[ relocating %s plt ]", get_soname());
if (!relocate(plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
DEBUG("[ relocating %s plt ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
return false;
}
}
#else
if (rel_ != nullptr) {
DEBUG("[ relocating %s ]", get_soname());
if (!relocate(plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
DEBUG("[ relocating %s ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
return false;
}
}
if (plt_rel_ != nullptr) {
DEBUG("[ relocating %s plt ]", get_soname());
if (!relocate(plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
DEBUG("[ relocating %s plt ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
return false;
}
}
#endif
#if defined(__mips__)
if (!mips_relocate_got(global_group, local_group)) {
if (!mips_relocate_got(version_tracker, global_group, local_group)) {
return false;
}
#endif
DEBUG("[ finished linking %s ]", get_soname());
DEBUG("[ finished linking %s ]", get_realpath());
#if !defined(__LP64__)
if (has_text_relocations) {
// All relocations are done, we can protect our segments back to read-only.
if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
DL_ERR("can't protect segments for \"%s\": %s",
get_soname(), strerror(errno));
get_realpath(), strerror(errno));
return false;
}
}
@@ -2947,7 +2945,7 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
/* We can also turn on GNU RELRO protection */
if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
get_soname(), strerror(errno));
get_realpath(), strerror(errno));
return false;
}
@@ -2956,14 +2954,14 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
extinfo->relro_fd) < 0) {
DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
get_soname(), strerror(errno));
get_realpath(), strerror(errno));
return false;
}
} else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
extinfo->relro_fd) < 0) {
DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
get_soname(), strerror(errno));
get_realpath(), strerror(errno));
return false;
}
}
@@ -3037,6 +3035,8 @@ static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
insert_soinfo_into_debug_map(linker_soinfo_for_gdb);
}
extern "C" int __system_properties_init(void);
/*
* This code is called after the linker has linked itself and
* fixed it's own GOT. It is safe to make references to externs
@@ -3051,6 +3051,9 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
// Initialize environment functions, and get to the ELF aux vectors table.
linker_env_init(args);
// Initialize system properties
__system_properties_init(); // may use 'environ'
// If this is a setuid/setgid program, close the security hole described in
// ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
if (get_AT_SECURE()) {
@@ -3150,6 +3153,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
for (const auto& ld_preload_name : g_ld_preload_names) {
needed_library_name_list.push_back(ld_preload_name.c_str());
++needed_libraries_count;
++ld_preloads_count;
}
for_each_dt_needed(si, [&](const char* name) {
@@ -3232,7 +3236,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
fflush(stdout);
#endif
TRACE("[ Ready to execute '%s' @ %p ]", si->get_soname(), reinterpret_cast<void*>(si->entry));
TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
return si->entry;
}
@@ -3248,7 +3252,8 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
*/
static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) {
ElfW(Addr) offset = elf->e_phoff;
const ElfW(Phdr)* phdr_table = reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
const ElfW(Phdr)* phdr_table =
reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
const ElfW(Phdr)* phdr_end = phdr_table + elf->e_phnum;
for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_end; phdr++) {

View File

@@ -97,7 +97,7 @@
#define SOINFO_VERSION 2
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
#define SOINFO_NAME_LEN 128
#endif
@@ -172,7 +172,7 @@ class VersionTracker {
struct soinfo {
public:
typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
private:
char old_name_[SOINFO_NAME_LEN];
#endif
@@ -183,13 +183,13 @@ struct soinfo {
ElfW(Addr) base;
size_t size;
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
uint32_t unused1; // DO NOT USE, maintained for compatibility.
#endif
ElfW(Dyn)* dynamic;
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
uint32_t unused2; // DO NOT USE, maintained for compatibility
uint32_t unused3; // DO NOT USE, maintained for compatibility
#endif
@@ -247,7 +247,9 @@ struct soinfo {
uint32_t mips_symtabno_;
uint32_t mips_local_gotno_;
uint32_t mips_gotsym_;
bool mips_relocate_got(const soinfo_list_t& global_group, const soinfo_list_t& local_group);
bool mips_relocate_got(const VersionTracker& version_tracker,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
#endif
size_t ref_count_;
@@ -303,7 +305,7 @@ struct soinfo {
bool is_gnu_hash() const;
bool inline has_min_version(uint32_t min_version __unused) const {
#if defined(__arm__)
#if defined(__work_around_b_19059885__)
return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
#else
return true;
@@ -338,11 +340,14 @@ struct soinfo {
bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
ElfW(Sym)* gnu_addr_lookup(const void* addr);
bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
const char* sym_name, const version_info** vi);
void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
void call_function(const char* function_name, linker_function_t function);
template<typename ElfRelIteratorT>
bool relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group, const soinfo_list_t& local_group);
private:
// This part of the structure is only available
@@ -424,4 +429,7 @@ extern "C" void notify_gdb_of_libraries();
char* linker_get_error_buffer();
size_t linker_get_error_buffer_size();
void set_application_target_sdk_version(uint32_t target);
uint32_t get_application_target_sdk_version();
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2010 The Android Open Source Project
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -36,7 +36,6 @@
#include "private/KernelArgumentBlock.h"
static char** _envp;
static bool _AT_SECURE_value = true;
bool get_AT_SECURE() {
@@ -150,8 +149,8 @@ static bool __is_unsafe_environment_variable(const char* name) {
}
static void __sanitize_environment_variables() {
char** src = _envp;
char** dst = _envp;
char** src = environ;
char** dst = environ;
for (; src[0] != nullptr; ++src) {
if (!__is_valid_environment_variable(src[0])) {
continue;
@@ -168,7 +167,7 @@ static void __sanitize_environment_variables() {
void linker_env_init(KernelArgumentBlock& args) {
// Store environment pointer - can't be null.
_envp = args.envp;
environ = args.envp;
__init_AT_SECURE(args);
__sanitize_environment_variables();
@@ -179,7 +178,7 @@ const char* linker_env_get(const char* name) {
return nullptr;
}
for (char** p = _envp; p[0] != nullptr; ++p) {
for (char** p = environ; p[0] != nullptr; ++p) {
const char* val = env_match(p[0], name);
if (val != nullptr) {
if (val[0] == '\0') {

View File

@@ -32,25 +32,22 @@
#include "linker_reloc_iterators.h"
#include "linker_sleb128.h"
template bool soinfo::relocate<plain_reloc_iterator>(plain_reloc_iterator&& rel_iterator,
template bool soinfo::relocate<plain_reloc_iterator>(const VersionTracker& version_tracker,
plain_reloc_iterator&& rel_iterator,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
template bool soinfo::relocate<packed_reloc_iterator<sleb128_decoder>>(
const VersionTracker& version_tracker,
packed_reloc_iterator<sleb128_decoder>&& rel_iterator,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
template <typename ElfRelIteratorT>
bool soinfo::relocate(ElfRelIteratorT&& rel_iterator,
bool soinfo::relocate(const VersionTracker& version_tracker,
ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
VersionTracker version_tracker;
if (!version_tracker.init(this)) {
return false;
}
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
@@ -75,26 +72,14 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator,
if (sym != 0) {
sym_name = get_string(symtab_[sym].st_name);
const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
const version_info* vi = nullptr;
if (sym_ver == VER_NDX_LOCAL || sym_ver == VER_NDX_GLOBAL) {
// there is no version info for this one
if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
return false;
}
} else {
const version_info* vi = version_tracker.get_version_info(sym_ver);
if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
return false;
}
if (vi == nullptr) {
DL_ERR("cannot find verneed/verdef for version index=%d "
"referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_soname());
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
if (s == nullptr) {
@@ -128,7 +113,7 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator,
if (s != nullptr) {
*reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
} else {
*reinterpret_cast<ElfW(Addr)*>(reloc) += base;
*reinterpret_cast<ElfW(Addr)*>(reloc) += load_bias;
}
break;
default:
@@ -139,7 +124,8 @@ bool soinfo::relocate(ElfRelIteratorT&& rel_iterator,
return true;
}
bool soinfo::mips_relocate_got(const soinfo_list_t& global_group,
bool soinfo::mips_relocate_got(const VersionTracker& version_tracker,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
ElfW(Addr)** got = plt_got_;
if (got == nullptr) {
@@ -163,22 +149,42 @@ bool soinfo::mips_relocate_got(const soinfo_list_t& global_group,
}
// Now for the global GOT entries...
ElfW(Sym)* sym = symtab_ + mips_gotsym_;
got = plt_got_ + mips_local_gotno_;
for (size_t g = mips_gotsym_; g < mips_symtabno_; g++, sym++, got++) {
for (ElfW(Word) sym = mips_gotsym_; sym < mips_symtabno_; sym++, got++) {
// This is an undefined reference... try to locate it.
const char* sym_name = get_string(sym->st_name);
const ElfW(Sym)* local_sym = symtab_ + sym;
const char* sym_name = get_string(local_sym->st_name);
soinfo* lsi = nullptr;
const ElfW(Sym)* s = nullptr;
if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
ElfW(Word) st_visibility = (local_sym->st_other & 0x3);
if (st_visibility == STV_DEFAULT) {
const version_info* vi = nullptr;
if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
} else if (st_visibility == STV_PROTECTED) {
if (local_sym->st_value == 0) {
DL_ERR("%s: invalid symbol \"%s\" (PROTECTED/UNDEFINED) ", get_soname(), sym_name);
return false;
}
s = local_sym;
lsi = this;
} else {
DL_ERR("%s: invalid symbol \"%s\" visibility: 0x%x", get_soname(), sym_name, st_visibility);
return false;
}
if (s == nullptr) {
// We only allow an undefined symbol if this is a weak reference.
s = &symtab_[g];
if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
DL_ERR("cannot locate \"%s\"...", sym_name);
if (ELF_ST_BIND(local_sym->st_info) != STB_WEAK) {
DL_ERR("%s: cannot locate \"%s\"...", get_soname(), sym_name);
return false;
}
*got = 0;

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "linker.h"
#include <atomic>
static std::atomic<uint32_t> g_target_sdk_version;
void set_application_target_sdk_version(uint32_t target) {
g_target_sdk_version = target;
}
uint32_t get_application_target_sdk_version() {
return g_target_sdk_version;
}

View File

@@ -49,6 +49,9 @@ endif
test_cppflags = \
-std=gnu++11 \
libBionicStandardTests_src_files_target := \
libdl_test.cpp \
libBionicStandardTests_src_files := \
arpa_inet_test.cpp \
buffer_tests.cpp \
@@ -269,6 +272,7 @@ bionic-unit-tests_src_files := \
dlext_test.cpp \
__cxa_thread_atexit_test.cpp \
dlfcn_test.cpp \
pthread_dlfcn_test.cpp \
bionic-unit-tests_cflags := $(test_cflags)
@@ -346,6 +350,7 @@ bionic-unit-tests-glibc_src_files := \
atexit_test.cpp \
dlfcn_test.cpp \
dl_test.cpp \
pthread_dlfcn_test.cpp \
bionic-unit-tests-glibc_shared_libraries := \
libdl_preempt_test_1 \

View File

@@ -71,23 +71,80 @@ TEST(dlfcn, dlsym_from_sofile) {
void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_LAZY | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
// check that we cant find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
// check that we can't find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
ASSERT_TRUE(symbol == nullptr);
ASSERT_SUBSTR("undefined symbol: test_dlsym_symbol", dlerror());
typedef int* (*fn_t)();
fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr) << dlerror();
ASSERT_TRUE(fn != nullptr) << dlerror();
int* ptr = fn();
int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(42, *ptr);
fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(44, *ptr);
fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_NEXT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(43, *ptr);
dlclose(handle);
}
TEST(dlfcn, dlsym_from_sofile_with_preload) {
void* preload = dlopen("libtest_dlsym_from_this_grandchild.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(preload != nullptr) << dlerror();
void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
// check that we can't find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
ASSERT_TRUE(symbol == nullptr);
ASSERT_SUBSTR("undefined symbol: test_dlsym_symbol", dlerror());
typedef int* (*fn_t)();
fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr) << dlerror();
int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(42, *ptr);
fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(44, *ptr);
fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_NEXT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(43, *ptr);
dlclose(handle);
dlclose(preload);
}
TEST(dlfcn, dlsym_with_dependencies) {
void* handle = dlopen("libtest_with_dependency.so", RTLD_NOW);
ASSERT_TRUE(handle != NULL);

32
tests/libdl_test.cpp Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
extern "C" uint32_t android_get_application_target_sdk_version();
extern "C" void android_set_application_target_sdk_version(uint32_t target);
TEST(libdl, application_sdk_versions_smoke) {
// Check initial values
ASSERT_EQ(0U, android_get_application_target_sdk_version());
android_set_application_target_sdk_version(20U);
ASSERT_EQ(20U, android_get_application_target_sdk_version());
android_set_application_target_sdk_version(22U);
ASSERT_EQ(22U, android_get_application_target_sdk_version());
}

View File

@@ -355,10 +355,7 @@ include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
libdl_test_df_1_global_src_files := dl_df_1_global.cpp
libdl_test_df_1_global_ldflags := -Wl,-z,global
# TODO (dimitry): x86* toolchain does not support -z global - switch to bfd
ifeq ($(filter $(TARGET_ARCH),x86 x86_64),$(TARGET_ARCH))
libdl_test_df_1_global_ldflags_target := -fuse-ld=bfd
endif
# TODO (dimitry): host ld.gold does not yet support -z global
# remove this line once it is updated.
libdl_test_df_1_global_ldflags_host := -fuse-ld=bfd
@@ -385,11 +382,26 @@ include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
# Library to check RTLD_LOCAL with dlsym in 'this'
# -----------------------------------------------------------------------------
libtest_dlsym_from_this_src_files := dlsym_from_this.cpp
libtest_dlsym_from_this_src_files := dlsym_from_this_symbol.cpp
libtest_dlsym_from_this_shared_libraries_target := libdl
libtest_dlsym_from_this_shared_libraries := libtest_dlsym_from_this_child
module := libtest_dlsym_from_this
libtest_dlsym_from_this_shared_libraries_target := libdl
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
libtest_dlsym_from_this_child_src_files := dlsym_from_this_functions.cpp
libtest_dlsym_from_this_child_shared_libraries := libtest_dlsym_from_this_grandchild
module := libtest_dlsym_from_this_child
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
libtest_dlsym_from_this_grandchild_src_files := dlsym_from_this_symbol2.cpp
module := libtest_dlsym_from_this_grandchild
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dlfcn.h>
#include <stdio.h>
extern int test_dlsym_symbol;
int test_dlsym_symbol = -1;
extern "C" int* lookup_dlsym_symbol_using_RTLD_DEFAULT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}
extern "C" int* lookup_dlsym_symbol2_using_RTLD_DEFAULT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol2"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}
extern "C" int* lookup_dlsym_symbol_using_RTLD_NEXT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_NEXT, "test_dlsym_symbol"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,18 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dlfcn.h>
#include <stdio.h>
int test_dlsym_symbol = 42;
extern "C" int* lookup_dlsym_symbol_using_RTLD_DEFAULT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
int test_dlsym_symbol = 43;
int test_dlsym_symbol2 = 44;

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <dlfcn.h>
static int g_atfork_prepare_calls = 0;
static void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 1; }
static void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 2; }
static void AtForkPrepare3() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 3; }
static void AtForkPrepare4() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 4; }
static int g_atfork_parent_calls = 0;
static void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 1; }
static void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 2; }
static void AtForkParent3() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 3; }
static void AtForkParent4() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 4; }
static int g_atfork_child_calls = 0;
static void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 1; }
static void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 2; }
static void AtForkChild3() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 3; }
static void AtForkChild4() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 4; }
TEST(pthread, pthread_atfork_with_dlclose) {
ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
void* handle = dlopen("libtest_pthread_atfork.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
typedef int (*fn_t)(void (*)(void), void (*)(void), void (*)(void));
fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "proxy_pthread_atfork"));
ASSERT_TRUE(fn != nullptr) << dlerror();
// the library registers 2 additional atfork handlers in a constructor
ASSERT_EQ(0, fn(AtForkPrepare2, AtForkParent2, AtForkChild2));
ASSERT_EQ(0, fn(AtForkPrepare3, AtForkParent3, AtForkChild3));
ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
int pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(1234, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(1234, g_atfork_parent_calls);
ASSERT_EQ(4321, g_atfork_prepare_calls);
EXPECT_EQ(0, dlclose(handle));
g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
int status;
ASSERT_EQ(pid, waitpid(pid, &status, 0));
pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(14, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(14, g_atfork_parent_calls);
ASSERT_EQ(41, g_atfork_prepare_calls);
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}

View File

@@ -16,7 +16,6 @@
#include <gtest/gtest.h>
#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
@@ -459,42 +458,6 @@ TEST(pthread, pthread_detach__no_such_thread) {
ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
}
TEST(pthread, pthread_detach_no_leak) {
size_t initial_bytes = 0;
// Run this loop more than once since the first loop causes some memory
// to be allocated permenantly. Run an extra loop to help catch any subtle
// memory leaks.
for (size_t loop = 0; loop < 3; loop++) {
// Set the initial bytes on the second loop since the memory in use
// should have stabilized.
if (loop == 1) {
initial_bytes = mallinfo().uordblks;
}
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
std::vector<pthread_t> threads;
for (size_t i = 0; i < 32; ++i) {
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
threads.push_back(t);
}
sleep(1);
for (size_t i = 0; i < 32; ++i) {
ASSERT_EQ(0, pthread_detach(threads[i])) << i;
}
}
size_t final_bytes = mallinfo().uordblks;
int leaked_bytes = (final_bytes - initial_bytes);
ASSERT_EQ(0, leaked_bytes);
}
TEST(pthread, pthread_getcpuclockid__clock_gettime) {
SpinFunctionHelper spinhelper;
@@ -1019,62 +982,6 @@ TEST(pthread, pthread_atfork_smoke) {
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}
static void AtForkPrepare3() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 3; }
static void AtForkPrepare4() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 4; }
static void AtForkParent3() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 3; }
static void AtForkParent4() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 4; }
static void AtForkChild3() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 3; }
static void AtForkChild4() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 4; }
TEST(pthread, pthread_atfork_with_dlclose) {
ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
void* handle = dlopen("libtest_pthread_atfork.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
typedef int (*fn_t)(void (*)(void), void (*)(void), void (*)(void));
fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "proxy_pthread_atfork"));
ASSERT_TRUE(fn != nullptr) << dlerror();
// the library registers 2 additional atfork handlers in a constructor
ASSERT_EQ(0, fn(AtForkPrepare2, AtForkParent2, AtForkChild2));
ASSERT_EQ(0, fn(AtForkPrepare3, AtForkParent3, AtForkChild3));
ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
int pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(1234, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(1234, g_atfork_parent_calls);
ASSERT_EQ(4321, g_atfork_prepare_calls);
EXPECT_EQ(0, dlclose(handle));
g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
int status;
ASSERT_EQ(pid, waitpid(pid, &status, 0));
pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(14, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(14, g_atfork_parent_calls);
ASSERT_EQ(41, g_atfork_prepare_calls);
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}
TEST(pthread, pthread_attr_getscope) {
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
@@ -1247,6 +1154,7 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
// The two methods of asking for the stack size should agree.
EXPECT_EQ(stack_size, stack_size2);
#if defined(__BIONIC__)
// What does /proc/self/maps' [stack] line say?
void* maps_stack_hi = NULL;
FILE* fp = fopen("/proc/self/maps", "r");
@@ -1263,15 +1171,18 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
}
fclose(fp);
// The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
// Remember that the stack grows down (and is mapped in on demand), so the low address of the
// region isn't very interesting.
EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
// The stack size should correspond to RLIMIT_STACK.
rlimit rl;
ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
uint64_t original_rlim_cur = rl.rlim_cur;
#if defined(__BIONIC__)
if (rl.rlim_cur == RLIM_INFINITY) {
rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
}
#endif
EXPECT_EQ(rl.rlim_cur, stack_size);
auto guard = make_scope_guard([&rl, original_rlim_cur]() {
@@ -1279,11 +1190,6 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
});
// The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
// Remember that the stack grows down (and is mapped in on demand), so the low address of the
// region isn't very interesting.
EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
//
// What if RLIMIT_STACK is smaller than the stack's current extent?
//
@@ -1311,6 +1217,7 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
EXPECT_EQ(stack_size, stack_size2);
ASSERT_EQ(6666U, stack_size);
#endif
}
static void pthread_attr_getstack_18908062_helper(void*) {

View File

@@ -456,11 +456,11 @@ TEST(time, timer_delete_from_timer_thread) {
ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
itimerspec ts;
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 100;
ts.it_value.tv_sec = 1;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ASSERT_EQ(0, timer_settime(tdd.timer_id, TIMER_ABSTIME, &ts, NULL));
ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
time_t cur_time = time(NULL);
while (!tdd.complete && (time(NULL) - cur_time) < 5);

View File

@@ -176,6 +176,15 @@ TEST(unistd, ftruncate64) {
ASSERT_EQ(123, sb.st_size);
}
TEST(unistd, ftruncate_negative) {
TemporaryFile tf;
errno = 0;
int rc = ftruncate(tf.fd, -123);
int err = errno;
ASSERT_EQ(-1, rc);
ASSERT_EQ(EINVAL, err);
}
static bool g_pause_test_flag = false;
static void PauseTestSignalHandler(int) {
g_pause_test_flag = true;

View File

@@ -73,8 +73,10 @@ def clean_project(dry_run):
build = 'clean-bionic-presubmit'
if build in jenkins:
if not dry_run:
job = jenkins[build].invoke()
url = job.get_build().baseurl
_ = jenkins[build].invoke()
# https://issues.jenkins-ci.org/browse/JENKINS-27256
# url = job.get_build().baseurl
url = 'URL UNAVAILABLE'
else:
url = 'DRY_RUN_URL'
logging.info('Cleaning: %s %s', build, url)

View File

@@ -95,3 +95,9 @@ $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_x64.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_x64_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32_packed.so))

View File

@@ -37,11 +37,13 @@ static constexpr int32_t DT_ANDROID_RELASZ = DT_LOOS + 5;
static constexpr uint32_t SHT_ANDROID_REL = SHT_LOOS + 1;
static constexpr uint32_t SHT_ANDROID_RELA = SHT_LOOS + 2;
static const size_t kPageSize = 4096;
// Alignment to preserve, in bytes. This must be at least as large as the
// largest d_align and sh_addralign values found in the loaded file.
// Out of caution for RELRO page alignment, we preserve to a complete target
// page. See http://www.airs.com/blog/archives/189.
static constexpr size_t kPreserveAlignment = 4096;
static const size_t kPreserveAlignment = kPageSize;
// Get section data. Checks that the section has exactly one data entry,
// so that the section size and the data size are the same. True in
@@ -300,16 +302,85 @@ static void AdjustSectionHeadersForHole(Elf* elf,
}
}
// Helper for ResizeSection(). Adjust the offsets of any program headers
// that have offsets currently beyond the hole start.
// Helpers for ResizeSection(). On packing, reduce p_align for LOAD segments
// to 4kb if larger. On unpacking, restore p_align for LOAD segments if
// packing reduced it to 4kb. Return true if p_align was changed.
template <typename ELF>
static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
static bool ClampLoadSegmentAlignment(typename ELF::Phdr* program_header) {
CHECK(program_header->p_type == PT_LOAD);
// If large, reduce p_align for a LOAD segment to page size on packing.
if (program_header->p_align > kPageSize) {
program_header->p_align = kPageSize;
return true;
}
return false;
}
template <typename ELF>
static bool RestoreLoadSegmentAlignment(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Phdr* program_header) {
CHECK(program_header->p_type == PT_LOAD);
// If p_align was reduced on packing, restore it to its previous value
// on unpacking. We do this by searching for a different LOAD segment
// and setting p_align to that of the other LOAD segment found.
//
// Relies on the following observations:
// - a packable ELF executable has more than one LOAD segment;
// - before packing all LOAD segments have the same p_align;
// - on packing we reduce only one LOAD segment's p_align.
if (program_header->p_align == kPageSize) {
for (size_t i = 0; i < count; ++i) {
typename ELF::Phdr* other_header = &program_headers[i];
if (other_header->p_type == PT_LOAD && other_header != program_header) {
program_header->p_align = other_header->p_align;
return true;
}
}
LOG(WARNING) << "Cannot find a LOAD segment from which to restore p_align";
}
return false;
}
template <typename ELF>
static bool AdjustLoadSegmentAlignment(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Off hole_start,
typename ELF::Phdr* program_header,
ssize_t hole_size) {
CHECK(program_header->p_type == PT_LOAD);
bool status = false;
if (hole_size < 0) {
status = ClampLoadSegmentAlignment<ELF>(program_header);
} else if (hole_size > 0) {
status = RestoreLoadSegmentAlignment<ELF>(program_headers,
count,
program_header);
}
return status;
}
// Helper for ResizeSection(). Adjust the offsets of any program headers
// that have offsets currently beyond the hole start, and adjust the
// virtual and physical addrs (and perhaps alignment) of the others.
template <typename ELF>
static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Off hole_start,
ssize_t hole_size) {
int alignment_changes = 0;
for (size_t i = 0; i < count; ++i) {
typename ELF::Phdr* program_header = &program_headers[i];
// Do not adjust PT_GNU_STACK - it confuses gdb and results
// in incorrect unwinding if the executable is stripped after
// packing.
if (program_header->p_type == PT_GNU_STACK) {
continue;
}
if (program_header->p_offset > hole_start) {
// The hole start is past this segment, so adjust offset.
program_header->p_offset += hole_size;
@@ -318,9 +389,24 @@ static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
} else {
program_header->p_vaddr -= hole_size;
program_header->p_paddr -= hole_size;
// If packing, clamp LOAD segment alignment to 4kb to prevent strip
// from adjusting it unnecessarily if run on a packed file. If
// unpacking, attempt to restore a reduced alignment to its previous
// value. Ensure that we do this on at most one LOAD segment.
if (program_header->p_type == PT_LOAD) {
alignment_changes += AdjustLoadSegmentAlignment<ELF>(program_headers,
count,
program_header,
hole_size);
LOG_IF(FATAL, alignment_changes > 1)
<< "Changed p_align on more than one LOAD segment";
}
VLOG(1) << "phdr[" << i
<< "] p_vaddr adjusted to "<< program_header->p_vaddr
<< "; p_paddr adjusted to "<< program_header->p_paddr;
<< "; p_paddr adjusted to "<< program_header->p_paddr
<< "; p_align adjusted to "<< program_header->p_align;
}
}
}
@@ -370,10 +456,10 @@ static void RewriteProgramHeadersForHole(Elf* elf,
target_load_header->p_memsz += hole_size;
// Adjust the offsets and p_vaddrs
AdjustProgramHeaderOffsets<ELF>(elf_program_header,
program_header_count,
hole_start,
hole_size);
AdjustProgramHeaderFields<ELF>(elf_program_header,
program_header_count,
hole_start,
hole_size);
}
// Helper for ResizeSection(). Locate and return the dynamic section.
@@ -466,6 +552,16 @@ void ElfFile<ELF>::AdjustDynamicSectionForHole(Elf_Scn* dynamic_section,
<< " d_val adjusted to " << dynamic->d_un.d_val;
}
// Special case: DT_MIPS_RLD_MAP2 stores the difference between dynamic
// entry address and the address of the _r_debug (used by GDB)
// since the dynamic section and target address are on the
// different sides of the hole it needs to be adjusted accordingly
if (tag == DT_MIPS_RLD_MAP2) {
dynamic->d_un.d_val += hole_size;
VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
<< " d_val adjusted to " << dynamic->d_un.d_val;
}
// Ignore DT_RELCOUNT and DT_RELACOUNT: (1) nobody uses them and
// technically (2) the relative relocation count is not changed.

View File

@@ -183,6 +183,18 @@ TEST(ElfFile, PackRelocationsArm64) {
RunPackRelocationsTestFor("arm64");
}
TEST(ElfFile, PackRelocationsMips32) {
RunPackRelocationsTestFor("mips32");
}
TEST(ElfFile, PackRelocationsIa32) {
RunPackRelocationsTestFor("ia32");
}
TEST(ElfFile, PackRelocationsX64) {
RunPackRelocationsTestFor("x64");
}
TEST(ElfFile, UnpackRelocationsArm32) {
RunUnpackRelocationsTestFor("arm32");
}
@@ -191,4 +203,16 @@ TEST(ElfFile, UnpackRelocationsArm64) {
RunUnpackRelocationsTestFor("arm64");
}
TEST(ElfFile, UnpackRelocationsMips32) {
RunUnpackRelocationsTestFor("mips32");
}
TEST(ElfFile, UnpackRelocationsIa32) {
RunUnpackRelocationsTestFor("ia32");
}
TEST(ElfFile, UnpackRelocationsX64) {
RunUnpackRelocationsTestFor("x64");
}
} // namespace relocation_packer

View File

@@ -10,6 +10,10 @@
#include "elf.h"
#include "libelf.h"
#if !defined(DT_MIPS_RLD_MAP2)
#define DT_MIPS_RLD_MAP2 0x70000035
#endif
// ELF is a traits structure used to provide convenient aliases for
// 32/64 bit Elf types and functions, depending on the target file.