Ordinary executables have a PT_INTERP path of /system/bin/linker[64], but:
- executables using bootstrap Bionic use /system/bin/bootstrap/linker[64]
- ASAN executables use /system/bin/linker_asan[64]
gdb appears to use the PT_INTERP path for debugging the dynamic linker
before the linker has initialized the r_debug module list. If the linker's
l_name differs from PT_INTERP, then gdb assumes that the linker has been
unloaded and searches for a new solib using the linker's l_name path.
gdb may print a warning like:
warning: Temporarily disabling breakpoints for unloaded shared library "$OUT/symbols/system/bin/linker64"
If I'm currently debugging the linker when this happens, gdb apparently
doesn't load debug symbols for the linker. This can be worked around with
gdb's "sharedlibrary" command, but it's better to avoid it.
Previously, when PT_INTERP was the bootstrap linker, but l_name was
"/system/bin/linker[64]", gdb would find the default non-bootstrap linker
binary and (presumably) get confused about symbol addresses.
(Also, remove the "static std::string exe_path" variable because the
soinfo::realpath_ field is a std::string that already lasts until exit. We
already use it for link_map_head.l_name in notify_gdb_of_load.)
Bug: http://b/134183407
Test: manual
Change-Id: I9a95425a3a5e9fd01e9dd272273c6ed3667dbb9a
Rearrange the st_dev and st_ino checks to reduce the number of
comparison needed.
Test: Ran cameraserver on a Go device. Measured time spent in the linker
and saw ~1% speed-up.
Change-Id: I8e977ff37925eae3ba8348e7c4a01ce8af3b9b6d
A linker namespace lives longer than its caller. It is never deleted
once created in a process. Currently, the pointer to the name is simply
copied which results dangling reference when the name is actually from
temporary objects like std::object. Fixing the issue by strdup'ing the
name upon namespace creation.
Bug: 130388701
Test: atest CtsJniTestCases; the log does not show broken error messages
like
unexpected dlerror: dlopen failed: library "/system/lib64/android.frameworks.cameraservice.common@2.0.so" needed or dlopened by "/data/app/android.jni.cts-HP6GyGXYy5honHQAffUXgw==/lib/arm64/libjnitest.so" is not accessible for the namespace " mT?"
Change-Id: I25d9d76f8520f490755c189ded5659e6c9741f79
When parsing ld.config.txt, paths in *.search.paths properties are
resolved using resolved_paths(). This is causing a number of newfstatat
system calls during a process start-up and is contributing about 3.6%
of the entire linker initialization time.
Optimize the overhead by not resolving already resolved paths; resolved
paths are cached.
Bug: 132348336
Test: strace -C -e newfstatat ls shows the number of the syscalls is
reduced from 131 to 99
Test: simpleperf record --call-graph fp -f 10000000 -o /data/perf.data ls
simpleperf report -g -i /data/perf.data
shows percentage of get_paths() from 2.9% to 2.5%
Change-Id: I79823255a89f6e2a63b80c74e6768850276ab536
A proposed set of changes:
https://android-review.googlesource.com/q/topic:"no-dup-hwasans"
will cause the HWASAN runtime to be moved from /system/lib64 to
/system/lib64/bootstrap. This causes a problem in the case where libc is built
with HWASAN but init is not built with HWASAN. In this case, libc.so will have
a DT_NEEDED dependency on the HWASAN runtime but init will not. Currently,
init and other bootstrap executables arrange to load bootstrap libraries by
setting rpath, but rpath only has an effect on libraries directly depended
on by the main executable, not libraries indirectly depended on by it. This
means that the loading of the HWASAN runtime will fail.
Instead of relying on rpath to find the bootstrap libraries, modify the
bootstrap linker so that it searches the bootstrap library directory after
searching the rpath.
Change-Id: I297be32e04ecd316ee12b8e694588e1249e2bb89
Creating two huge buffers with std::vector, as it is now, is very
expensive, because it ends up being satisfied with mmap()/munmap().
Instead, we statically allocate a large string buffer while resizing
the other one to be a smaller and more appropriate size so that it can
be placed on the stack.
Note that this does mean that we increase linker data segment by 4KB
and that increases the overall system memory usage by about 400KB.
However, since that additional page is mostly zeroed with only some
ASCII text, it should be fairly easy to compress when it's swapped out
to ZRAM.
Test: Run with strace and observe no mmap/munmap around readlinkat().
Test: Measure average linker time of starting cameraserver on a Go
device and see ~3% speed-up.
Bug: 132783386
Change-Id: I600cc7a92be316ef67440a9a28c05d18de229f6c
Given that we have both linker and linker64, I didn't really want to have
to have ldd and ldd64, so this change just adds the --list option to the
linkers and a shell script wrapper "ldd" that calls the appropriate
linker behind the scenes.
Test: adb shell linker --list `which app_process32`
Test: adb shell linker64 --list `which date`
Test: adb shell ldd `which app_process32`
Test: adb shell ldd `which date`
Change-Id: I33494bda1cc3cafee54e091f97c0f2ae52d1f74b
Enable native bridge support for bionic libraries.
Makes it possible to use them in binaries for translated
architectures.
Bug: http://b/77159578
Test: make
Change-Id: Iccd4ad7aecfa5260cc15f09ca975d2e18987278a
The libstdc++ directory has no copyright headers, so it was a no-op
anyway.
The interesting part will be switching libc and libm over to genrules...
Test: N/A
Change-Id: Iec92562af40c451fdcb4a7468984878ec5dba2ce
ANDROID_DLEXT_WRITE_RELRO was inadvertently writing out the RELRO
section of all libraries loaded during a given dlopen() call instead of
only the main library; since the other libraries are loaded at
unpredictable addresses this additional data is rarely useful.
Fix this to only happen when the
ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE flag is being used.
Bug: 128623590
Test: DlExtRelroSharingTest.CheckRelroSizes
Change-Id: I05e8651d06ce2de77b8c85fe2b6238f9c09691ad
ANDROID_DLEXT_WRITE_RELRO was causing the GNU RELRO sections of
libraries to become corrupted if more than one library was being loaded
at once (i.e. if the root library has DT_NEEDED entries for libraries
that weren't already loaded). The file offset was not being correctly
propagated between calls, so after writing out the (correct) RELRO data
to the file, it was mapping the data at file offset 0 for all libraries,
which corrupted the data for all but one of the libraries.
Fix this by passing file_offset as a pointer the same way that
phdr_table_map_gnu_relro does.
Bug: 128623590
Test: tbd
Change-Id: I196cd336bd5a67454e89fd85487356b1c7856871
Also update an rvalue reference to lvalue reference where it's
unnecessary to make it clearer.
Test: Build and boot cuttlefish.
Change-Id: Ib799666ab075523e6446f34c7da2b1eb311f98ab
In order to enable no-vendor-variant VNDK, we need a way to restrict a
namespace to only a list of whitelisted libraries. We add a new
"whitelisted" property for this. If the property is not set, all
libraries in the search paths are available in a namespace. If the
property is set, only the libraries named are available.
Bug: 119423884
Test: Boot with no-vendor-variant VNDK enabled using the new property.
Change-Id: Id808c1733c8e2c2c3462b04c72461f9698403571
- Show which executable is being linked, which linker config file is
being read, and which section in it is being used with, enabled on
$LD_DEBUG>=1.
- Show more info to follow the dlopen() process, enabled with "dlopen"
in the debug.ld.xxx property.
Test: Flash, boot, and look at logcat after "adb shell setprop debug.ld.all dlopen"
Bug: 120430775
Change-Id: I5441c8ced26ec0e2f04620c3d2a1ae860b792154
The *.mountpoint targets that installs /bionic/lib/lib*.so and
/bionic/bin/linker* are no longer needed.
Now, /system/lib/lib*.so and /system/bin/linker* are simply symlinks to
the corresponding files in the runtime apex. For example,
/system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
This is made possible because we now activate APEXes even before the
data partition is mounted. Before the data partition mounting, the
APEXes from the system partition are ativated. After the data partition
is mounted, updated APEXes in the partition (if any) are activated. As a
result, the symlink always points to the valid path regardless of
whether /data is mounted or not.
Bug: 125549215
Test: device boots
Change-Id: Ie7d83686abe00b3c436f9f9db75d4244200a0fc9
Make the num_free_blocks calculation clearer. There are
sizeof(page->bytes) bytes available for blocks, which is equal to
(kAllocateSize - 16). The previous calculation overestimates the amount
of space by 8 or 12 bytes, but that doesn't change the result because
both kAllocateSize and block_size_ are multiples of 16.
Bug: none
Test: boot device, bionic unit tests
Change-Id: Ia880cd5abc2a7bb4e9e6a8c0441d985f4df8fdc4
The tlsdesc_resolver_dynamic function is only defined on arm64, but the
code was taking its address on all targets. (Apparently the optimizer was
removing the entire deferred_tlsdesc_relocs loop?)
Bug: none
Test: bionic unit tests
Test: add -O0 to cc_defaults in linker/Android.bp, device boots
Change-Id: I899c78018cbe82aeaca7856c9f7b04300c1d3196
It's possible and sometimes beneficial for a library to have disjoint mappings
and for other libraries to be mapped into the gap between the mappings using
ANDROID_DLEXT_RESERVED_ADDRESS. See for example the proposal for partitioning
in lld [1].
Because the find_containing_library and do_dl_unwind_find_exidx functions use
a simple bounds check to figure out whether a pointer belongs to a library
they will, given a pointer into a library mapped into the gap of a library
with disjoint mappings, return a pointer to the soinfo for the outer library
instead of the inner one, because the outer library will appear before the
inner one in the solist.
From a user perspective this means that we won't be able to unwind the inner
library's frames on 32-bit ARM with libgcc, dladdr() will return information
for the outer library given a pointer to the inner one and dlopen() et al will
use the linker namespace of the outer library when called from the inner one
(although they will usually be the same).
To make this work correctly, make it so that once find_containing_library
sees a match for the bounds check, it examines the library's PT_LOADs to
make sure that there is a mapping for the given address. This is similar
to how libgcc and libunwind_llvm already handle finding the PT_GNU_EH_FRAME
on non-ARM32 platforms [2,3]. do_dl_unwind_find_exidx is reimplemented in
terms of find_containing_library.
[1] http://lists.llvm.org/pipermail/llvm-dev/2019-February/130583.html
[2] e739ac0e25/libunwind/src/AddressSpace.hpp (L523)
[3] https://android.googlesource.com/toolchain/gcc/+/master/gcc-4.9/libgcc/unwind-dw2-fde-dip.c#294
Test: /data/nativetest{,64}/bionic-unit-tests/bionic-unit-tests on walleye-userdebug
Change-Id: I368fe6ad3c470b3dff80f7d9b04253566d63a7d2
Introduce a new flag ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE which
instructs the linker to use the reserved address space to load all of
the newly-loaded libraries required by a dlopen() call instead of only
the main library. They will be loaded consecutively into that region if
they fit. The RELRO sections of all the loaded libraries will also be
considered for reading/writing shared RELRO data.
This will allow the WebView implementation to potentially consist of
more than one .so file while still benefiting from the RELRO sharing
optimisation, which would otherwise only apply to the "root" .so file.
Test: bionic-unit-tests (existing and newly added)
Bug: 110790153
Change-Id: I61da775c29fd5017d9a1e2b6b3757c3d20a355b3
Life is easier if we just keep test code in the same directory as the
stuff it's testing...
Test: tests still build and pass
Change-Id: I9b35d689098bdc28a71d69645b0ca9fdd6ea0108
The log priorities and ids are in an NDK header, available to everyone.
Move CHECK into its own header for now. This would be better if it was
more like the <android-base/logging.h> CHECK family, but I don't have an
easy way to do that without lots of copy & paste, so punting for now.
Bug: https://issuetracker.google.com/issues/119713191
Test: boots
Change-Id: I4566be8a0a024fede0e2d257c98b908ec67af2a8
Bug: http://b/116873221
The coverage library, which depends on libc, cannot link with libraries
since they opt of libc.
Test: m NATIVE_COVERAGE=true COVERAGE_PATHS=bionic
Change-Id: Iaaca8bc30c8ba59e5d4f7092b1a0fce8e8c14c72
The change is a workaround of app compat issue until the app fixes the
issue.
Likely, the app does not only dlopen(), but open() the libicuuc.so
with the absolute path.
Note that platform uses the stub libandroidicu.so, not libicuuc directly.
This CL topic moves (not duplicates) libandroidicu from /system to
/apex. Even though /system/lib/libicuuc.so is kept in the default
namespace, but no one should be using it.
Some debug info after this CL:
$ adb shell cat /proc/<zygote pid>/maps | grep libicuuc
$ adb shell cat /proc/<app pid>/maps | grep libicuuc
Only /apex/com.android.runtime/lib64/libicuuc.so is found, not the
/system.
Bug: 124218500
Test: The app can be launched successfully
Test: CtsJniTestCases
Change-Id: I67a50f0ad934be567a63d4038215546c9b4e5f7e
Some of the greylist libraries can be in directories other than
/system/lib. For example, libnativehelper.so is moved from the directory
to /apex/com.android.runtime/lib.
Previous behavior for greylist libraries is to find the lib under
/system/lib while "within" the current namespace which is usually the
classloader-namespace. Since the libs no longer exist there, linker
fails to load it and no further attempt is made.
This change fixes the problem by loading the greylist libs "from" the
default namespace. Since there is a link from the default namespace to
the namespace where the moved libraries are intended to be loaded (e.g.,
the 'runtime' namespace for libnativehelper.so), the call is successful.
Bug: 124201397
Test: bionic-unit-tests
Change-Id: I11d15993d18896bdf663c408f9e40d8a607c9b80
When the linker is invoked on itself, (`linker64 /system/bin/linker64`),
the linker prints an error, because self-invocation isn't allowed. The
current method for detecting self-invocation fails because the second
linker instance can crash in a constructor function before reaching
__linker_init.
Fix the problem by moving the error check into a constructor function,
which finishes initializing libc sufficiently to call async_safe_fatal.
The only important thing missing is __libc_sysinfo on 32-bit x86. The aux
vector isn't readily accessible, so use the fallback int 0x80.
Bug: http://b/123637025
Test: bionic unit tests (32-bit x86)
Change-Id: I8be6369e8be3938906628ae1f82be13e6c510119
This reverts commit 1906e77665
and fixes dlopen(nullptr)
It's enabled for the following .so libraries
libicuuc.so
libicui18n.so
This CL does not move the .so files into a APEX.
Thus, no visible effect before moving .so files.
Bug: 121248172
Test: dlfcn#dlopen_from_nullptr
Test: Perform the following test after moving libicuuc to /apex
dlopen("/system/lib64/libicuuc.so") for targetSdkVersion < Q
Change-Id: Ia310ea566485fe00ca28e2203f4bffbd92243638
It's enabled for the following .so libraries
libicuuc.so
libicui18n.so
This CL does not move the .so files into a APEX.
Thus, no visible effect before moving .so files.
Bug: 121248172
Test: Perform the following test after moving libicuuc to /apex
dlopen("/system/lib64/libicuuc.so") for targetSdkVersion < Q
Change-Id: Ic00d281d59de924c01582c48d2a946e3f5f33a09
This is the second attempt to purge linker block allocators. Unlike the
previously reverted change which purge allocators whenever all objects
are freed, we only purge right before control leaves the linker. This
limits the performance impact to one munmap() call per dlopen(), in
most cases.
Bug: 112073665
Test: Boot and check memory usage with 'showmap'.
Test: Run camear cold start performance test.
Change-Id: I02c7c44935f768e065fbe7ff0389a84bd44713f0
The dynamic linker installed to /system partition is only for
bootstraping, i.e. to be used only by early processes. The existing path
/system/bin/linker[64] will be a symlink to the mount pointpoint
/bionic/bin/linker[64] which will be bind-mounted with either the
bootstrap linker or the default linker in the runtime APEX. Since the
path is taken by the symlink, bootstrap linker is moved to ./boostrap
subdirectory.
Bug: 120266448
Test: m linker; the linker is found under /system/bin/bootstrap/
Change-Id: I163e0c8a1738b94565a6b60f48e65841ba058a91
This change adds following files and symlinks:
Files:
/bionic/lib[64]/lib{c|dl|m}.so
/bionic/bin/linker[64]
Symlinks:
/system/lib[64]/lib{c|dl|m}.so -> /bionic/lib[64]/lib{c|dl|m}.so
/system/bin/linker[64] -> /bionic/bin/linker[64]
/system/bin/linker_asan[64] -> /bionic/bin/linker[64]
The files serve as mount points for either the bootstrap Bionic or the
default Bionic from the runtime APEX. init does the bind-mounting during
booting.
The symlinks are there to not change the ordinary paths to the bionic
files; there are many places that the paths are implied or hard-coded,
e.g., dlopen("/system/lib/libc.so") or DT_INTERP pointing to
/system/bin/linker in the vendor prebuilts.
Bug: 120266448
Test: m blueline, cf_x86, aosp_arm
The aforementioned files and symlinks are found
Change-Id: I97e38c29409ac0610dde285db8df6e94a7930094
Each TLSDESC relocation relocates a 2-word descriptor in the GOT that
contains:
- the address of a TLS resolver function
- an argument to pass (indirectly) to the resolver function
(Specifically, the address of the 2-word descriptor is passed to the
resolver.)
The loader resolves R_GENERIC_TLSDESC relocations using one of three
resolver functions that it defines:
- tlsdesc_resolver_static
- tlsdesc_resolver_dynamic
- tlsdesc_resolver_unresolved_weak
The resolver functions are written in assembly because they have a
restrictive calling convention. They're only allowed to modify x0 and
(apparently) the condition codes.
For a relocation to memory in static TLS (i.e. the executable or an solib
loaded initially), the loader uses a simple resolver function,
tlsdesc_resolver_static, that returns the static offset it receives from
the loader.
For relocations to dynamic TLS memory (i.e. memory in a dlopen'ed solib),
the loader uses tlsdesc_resolver_dynamic, which allocates TLS memory on
demand. It inlines the fast path of __tls_get_addr, then falls back to
__tls_get_addr when it needs to allocate memory. The loader handles these
dynamic TLS relocations in two passes:
- In the first pass, it allocates a table of TlsDynamicResolverArg
objects, one per dynamic TLSDESC relocation.
- In the second pass, once the table is finalized, it writes the
addresses of the TlsDynamicResolverArg objects into the TLSDESC
relocations.
tlsdesc_resolver_unresolved_weak returns a negated thread pointer so that
taking the address of an unresolved weak TLS symbols produces NULL.
The loader handles R_GENERIC_TLSDESC in a target-independent way, but
only for arm64, because Bionic has only implemented the resolver functions
for arm64.
Bug: http://b/78026329
Test: bionic unit tests
Test: check that backtrace works inside a resolver function and inside
__tls_get_addr called from a resolver
(gdbclient.py, b __tls_get_addr, bt)
Merged-In: I752e59ff986292449892c449dad2546e6f0ff7b6
Change-Id: I752e59ff986292449892c449dad2546e6f0ff7b6
Initialize a thread's DTV to an empty zeroed DTV. Allocate the DTV and
any ELF module's TLS segment on-demand in __tls_get_addr. Use a generation
counter, incremented in the linker, to signal when threads should
update/reallocate their DTV objects.
A generation count of 0 always indicates the constant zero DTV.
Once a DTV is allocated, it isn't freed until the thread exits, because
a signal handler could interrupt the fast path of __tls_get_addr between
accessing the DTV slot and reading a field of the DTV. Bionic keeps a
linked list of DTV objects so it can free them at thread-exit.
Dynamic TLS memory is allocated using a BionicAllocator instance in
libc_shared_globals. For async-signal safety, access to the
linker/libc-shared state is protected by first blocking signals, then by
acquiring the reader-writer lock, TlsModules::rwlock. A write lock is
needed to allocate or free memory.
In pthread_exit, unconditionally block signals before freeing dynamic
TLS memory or freeing the shadow call stack.
ndk_cruft.cpp: Avoid including pthread_internal.h inside an extern "C".
(The header now includes a C++ template that doesn't compile inside
extern "C".)
Bug: http://b/78026329
Bug: http://b/123094171
Test: bionic unit tests
Change-Id: I3c9b12921c9e68b33dcc1d1dd276bff364eff5d7
Generalize the omitted symbol and missing-TLS-segment behaviors to all TLS
relocations.
R_GENERIC_TLS_DTPMOD is a module ID, which starts at 1 for the executable.
R_GENERIC_TLS_DTPREL is an offset from the start of a module to a specific
TLS symbol.
binutils currently disagrees with Bionic about the values of
R_AARCH64_TLS_DTPMOD64 and R_AARCH64_TLS_DTPREL64, so disable
DTPMOD/DTPREL for now on arm64.
Bug: http://b/78026329
Test: bionic unit tests (Tests for dynamic TLS will be added later)
Change-Id: I05c28d6a1036bdd6127f605036679b7475689445
These dynamic table entries are used for lazy relocation of TLSDESC
relocations. Bionic relocates everything eagerly and can ignore these
entries.
Bug: http://b/78026329
Test: bionic unit tests
Test: manual
Change-Id: I788c4a95041fae66de2fbeab3babe0205631999c
Rename LinkerMemoryAllocator -> BionicAllocator
Rename LinkerSmallObjectAllocator -> BionicSmallObjectAllocator
libc and the linker need to share an instance of the allocator for
allocating and freeing dynamic ELF TLS memory (DTVs and segments). The
linker also continues to use this allocator.
Bug: http://b/78026329
Test: /data/nativetest/bionic-unit-tests-static
Test: /data/nativetest64/bionic-unit-tests-static
Test: /data/nativetest/linker-unit-tests/linker-unit-tests32
Test: /data/nativetest64/linker-unit-tests/linker-unit-tests64
Change-Id: I2da037006ddf8041a75f3eba2071a8fcdcc223ce
The <async_safe/log.h> include in linker_allocator.h was made
unnecessary when the STL dependency was removed.
Replace the linker_*.h header includes with private/bionic_*.h
includes.
This change prepares LinkerMemoryAllocator for use in libc allocating
dynamic ELF TLS memory.
Bug: http://b/78026329
Test: bionic unit tests
Change-Id: I6ad62bd513e71dd3f91a4b724a92b19a1eb6c3b4
Suppress the SELinux denial log spam by not calling realpath(3) when the
path does not exist or is not accessible for read, and then not auditing
access(2) failure.
Bug: 120996057
Test: copy ping to /data/local/tmp, run it, verify no errors
Test: run bionic-unit-tests, the tests pass
Change-Id: Ie6058bfc9524a9b5c50fc7183fdddea6a8fb9200
In addition to ORIGIN, LIB is now expanded to either lib or lib64
depending on the ABI in the DT_RUNPATH.
Test: To be added (can't be added to AOSP directly since there are
internal tests that have to be updated as well)
Change-Id: I34a8316f1765a27c731bc270ee25c0ce287d7eed
Given that the block allocator does not free allocated memory unless
all objects are freed, we can allocate a large chunk of memory at a
time. This gives us:
1. Higher space efficiency, especially when the objects being
allocated has a large size.
2. Much less mmap()/prctl() calls.
3. Much less vm_area_struct objects.
While this increases the size of virtual memory allocated, the number
of dirty pages would be unchanged or less.
Test result on a Go device:
- Zygote starts 24ms faster on average.
- Kernel vm_area_struct usage 138KB less, across the entire system.
Bug: 112073665
Test: Boot and check the result from 'showmap'.
Change-Id: Iece631a5081151dd1e5bf25dbddac9b264bcdcff
If all allocated memory from a block allocator is freed, it is a good
opportunity to purge all the pages allocated to reduce lingering dirty
pages.
Memory saving varies with the platform and what processes are running.
Measuring right after boot, this saves ~1.8MB on cuttelfish and ~1.3MB
on a 32-bit ARM device.
Bug: 112073665
Test: Boot and check memory usage with 'showmap'.
Change-Id: I53769e0ec9699f0b3645cdf281a2c0bbffb98676
The field was pointing into an element of an std::vector, but the address
of a vector element is invalidated when the vector is resized.
This bug was caught by the new elftls.shared_ie and
elftls_dl.dlopen_shared_var_ie tests.
Bug: http://b/78026329
Test: bionic unit tests
Change-Id: I7232f6d703a9e339fe8966a95b7a68bae2c9c420
* changes:
Handle R_GENERIC_TLS_TPREL relocations
Avoid a dlopen abort on an invalid TLS alignment
Initialize static TLS memory using module list
Record TLS modules and layout static TLS memory
StaticTlsLayout: add exe/tcb and solib layout
Avoids some unnecessary work during dlopen/dlclose/dlsym for most
cases.
Bug: 122471935
Test: fewer page faults during app startup
Change-Id: Ie886e1e671066af3c6f3a895f9a8126f209d6660
This relocation is used for static TLS's initial-exec (IE) accesses.
A TLS symbol's value is its offset from the start of the ELF module's
TLS segment. It doesn't make sense to add the load_bias to this value,
so skip the call to soinfo::resolve_symbol_address.
Allow TLS relocations to refer to an unresolved weak symbol. In that case,
sym will be non-zero, but lsi will be nullptr. The dynamic linker resolves
the TPREL relocation to 0, making &missing_weak_symbol equal the thread
pointer.
Recognize Gold-style relocations to STB_LOCAL TLS symbols/sections and
issue an error.
Remove the "case R_AARCH64_TLS_TPREL64", because the R_GENERIC_TLS_TPREL
case handles it.
Remove the no-op R_AARCH64_TLSDESC handler. It's better to issue an error.
dlopen_library_with_ELF_TLS now fails with a consistent error about an
unimplemented dynamic TLS relocation.
Bug: http://b/78026329
Test: bionic unit tests (elftls tests are added in a later CL)
Change-Id: Ia08e1b5c8098117e12143d3b4ebb4dfaa5ca46ec
If the alignment of a TLS segment in a shared object is invalid, return
an error through dlerror() rather than aborting the process.
Bug: http://b/78026329
Test: bionic unit tests
Change-Id: I60e589ddd8ca897f485d55af089f08bd3ff5b1fa
It can happen e.g. if android_dlopen_ext is called with an absolute path to
a file that is not accessible in the current namespace. The first
load_library call in find_library_internal will then open the file and
assign its fd to the task and return false. Then linked namespaces are
searched, and load_library gets called again and opens the same file and
overwrites the fd in the task without closing it first. (In one of the later
calls the namespace config might very well allow the file to be loaded and
the android_dlopen_ext call eventually returns successfully, and the process
continues with the leaked fd.)
The code could perhaps be changed to avoid opening the file repeatedly in
these cases, but the LoadTask class should arguably keep its state clean
anyway.
Bug: 113373927
Test: Flash and boot device with (and without) http://r.android.com/812674,
which moves libart.so to the runtime namespace and thus makes it load
/system/framework/*/boot*.oat files across the namespace boundary from
runtime to default.
Change-Id: Iae91b7c743c5f3f973506153ba52898ae72e6fee
Replace reserve_tcb with reserve_exe_segment_and_tcb, which lays out both
the TCB and the executable's TLS segment, accounting for the difference in
layout between variant 1 and variant 2 targets.
The function isn't actually called with a non-null TlsSegment* yet.
Bug: http://b/78026329
Test: bionic unit tests
Change-Id: Ibd6238577423a7d0451f36da7e64912046959796
This macro is necessary for using stdatomic.h and <atomic> in the same
libc++-based program. <atomic> is used implicitly by other STL headers,
and stdatomic.h is used (or will be used) in headers shared with libc.
libc only has access to stdatomic.h because it can't use an STL.
Bug: http://b/78026329
Test: bionic unit tests
Change-Id: I89b128df08b478287ef4e2867319e74dbcc30d4e
For ELF TLS "local-exec" accesses, the static linker assumes that an
executable's TLS segment is located at a statically-known offset from the
thread pointer (i.e. "variant 1" for ARM and "variant 2" for x86).
Because these layouts are incompatible, Bionic generally needs to allocate
its TLS slots differently between different architectures.
To allow per-architecture TLS slots:
- Replace the TLS_SLOT_xxx enumerators with macros. New ARM slots are
generally negative, while new x86 slots are generally positive.
- Define a bionic_tcb struct that provides two things:
- a void* raw_slots_storage[BIONIC_TLS_SLOTS] field
- an inline accessor function: void*& tls_slot(size_t tpindex);
For ELF TLS, it's necessary to allocate a temporary TCB (i.e. TLS slots),
because the runtime linker doesn't know how large the static TLS area is
until after it has loaded all of the initial solibs.
To accommodate Golang, it's necessary to allocate the pthread keys at a
fixed, small, positive offset from the thread pointer.
This CL moves the pthread keys into bionic_tls, then allocates a single
mapping per thread that looks like so:
- stack guard
- stack [omitted for main thread and with pthread_attr_setstack]
- static TLS:
- bionic_tcb [exec TLS will either precede or succeed the TCB]
- bionic_tls [prefixed by the pthread keys]
- [solib TLS segments will be placed here]
- guard page
As before, if the new mapping includes a stack, the pthread_internal_t
is allocated on it.
At startup, Bionic allocates a temporary bionic_tcb object on the stack,
then allocates a temporary bionic_tls object using mmap. This mmap is
delayed because the linker can't currently call async_safe_fatal() before
relocating itself.
Later, Bionic allocates a stack-less thread mapping for the main thread,
and copies slots from the temporary TCB to the new TCB.
(See *::copy_from_bootstrap methods.)
Bug: http://b/78026329
Test: bionic unit tests
Test: verify that a Golang app still works
Test: verify that a Golang app crashes if bionic_{tls,tcb} are swapped
Merged-In: I6543063752f4ec8ef6dc9c7f2a06ce2a18fc5af3
Change-Id: I6543063752f4ec8ef6dc9c7f2a06ce2a18fc5af3
(cherry picked from commit 1e660b70da)
When parsing a dir.${section} line in ld.config.txt, the linker uses
realpath() to resolve each directory path. If realpath() fails, the linker
uses the non-resolved path instead. Previously, it issued a warning to
stderr and logcat, but realpath() is expected to fail on /postinstall when
running a binary in /data/local/tmp, so downgrade the warning to an INFO()
notice.
Bug: http://b/120996057
Test: copy ping to /data/local/tmp, run it, verify no errors
Test: bionic unit tests
Change-Id: I2104084e12ea18840230997408559299bf3bddac
This includes:
- Blocks allocated by small object allocators are now aligned to
their block size.
- Remove redundant free_blocks_cnt and allocated_blocks_cnt, as they
sum up to a fixed number.
- Remove a redundant padding word in small_object_page_info on 32-bit
platform.
Test: Build and boot cuttlefish.
Change-Id: Ib922d7af739e3709e8a162c7f68e7f99bf95a914
The current implementation of LinkerSmallObjectAllocator keeps record
of pages in a vector, which uses its own page(s). This is at least a
page overhead per LinkerSmallObjectAllocator.
This change removes the page record vector by managing the pages in a
doubly linked list.
We also fix a bug where we are actually keeping up to 2 free pages
instead of just one.
The memory used by small objects when running 'dd', before this change:
72 KB [anon:linker_alloc_small_objects]
28 KB [anon:linker_alloc_vector]
After this change:
60 KB [anon:linker_alloc_small_objects]
Test: Boot cuttlefish and check memory used by linker.
Change-Id: I3468fa4d853c78b4bc02bfb84a3531653f74fb17
Instead of passing the address of a KernelArgumentBlock to libc.so for
initialization, use __loader_shared_globals() to initialize globals.
Most of the work happened in the previous CLs. This CL switches a few
KernelArgumentBlock::getauxval calls to [__bionic_]getauxval and stops
routing the KernelArgumentBlock address through the libc init functions.
Bug: none
Test: bionic unit tests
Change-Id: I96c7b02c21d55c454558b7a5a9243c682782f2dd
Merged-In: I96c7b02c21d55c454558b7a5a9243c682782f2dd
(cherry picked from commit 746ad15912)
Split __libc_init_main_thread into __libc_init_main_thread_early and
__libc_init_main_thread_late. The early function is called very early in
the startup of the dynamic linker and static executables. It initializes
the global auxv pointer and enough TLS memory to do system calls, access
errno, and run -fstack-protector code (but with a zero cookie because the
code for generating a cookie is complex).
After the linker is relocated, __libc_init_main_thread_late finishes
thread initialization.
Bug: none
Test: bionic unit tests
Change-Id: I6fcd8d7587a380f8bd649c817b40a3a6cc1d2ee0
Merged-In: I6fcd8d7587a380f8bd649c817b40a3a6cc1d2ee0
(cherry picked from commit 39bc44bb0e)
It was discovered that we were building some objects inconsistently due
to an optimization in cc_library to only build objects once and use them
for both the static and shared libraries. But static libraries didn't
get system_shared_libs set automatically, and we didn't notice that we
would have built the objects differently.
So static libraries now get the default system_shared_libs, we allow
adjusting that for static vs shared in a cc_library, and we disable the
optimization if the linked libraries are configured differently between
static and shared in a single cc_library.
This triggers dependency cycles for static libraries that libc/libdl
use, so fix those cycles here.
Test: treehugger
Change-Id: I3cf7fda161a05ec32e0c1e871999720d12a4d38e
* changes:
Use shared globals to init __progname + environ
Move the abort message to libc_shared_globals
Expose libc_shared_globals to libc.so with symbol
Initialize the __progname and environ global variables using
libc_shared_globals rather than KernelArgumentBlock.
Also: suppose the linker is invoked on an executable:
linker prog [args...]
The first argument passed to main() and constructor functions is "prog"
rather than "linker". For consistency, this CL changes the BSD
__progname global from "linker" to "prog".
Bug: none
Test: bionic unit tests
Change-Id: I376d76953c9436706dbc53911ef6585c1acc1c31
__libc_shared_globals() is available in dynamic modules as soon as
relocation has finished (i.e. after ifuncs run). Before ifuncs have run,
the android_set_abort_message() function already doesn't work because it
calls public APIs via the PLT. (If this matters, we can use a static
bool variable to enable android_set_abort_message after libc
initialization).
__libc_shared_globals() is hidden, so it's available in the linker
immediately (i.e. before relocation). TLS memory (e.g. errno) currently
isn't accessible until after relocation, but a later patch fixes that.
Bug: none
Test: bionic unit tests
Change-Id: Ied4433758ed2da9ee404c6158e319cf502d05a53
Previously, the address of the global variable was communicated from the
dynamic linker to libc.so using a field of KernelArgumentBlock, which is
communicated using the TLS_SLOT_BIONIC_PREINIT slot.
As long as this function isn't called during relocations (i.e. while
executing an ifunc), it always return a non-NULL value. If it's called
before its PLT entry is relocated, I expect a crash.
I removed the __libc_init_shared_globals function. It's currently empty,
and I don't think there's one point in libc's initialization where
shared globals should be initialized.
Bug: http://b/25751302
Test: bionic unit tests
Change-Id: I614d25e7ef5e0d2ccc40d5c821dee10f1ec61c2e
Free pages count should be incremented by 1 when a new page is
allocated. Without this fix, free pages count underflows and the
allocator ends up freeing a free page whenever the last object in that
page is freed. In other words, it doesn't hold onto a free page as
expected and thus we may see more mmap/munmap calls.
Test: Set breakpoint at the end of __linker_init and check
free_pages_cnt values are either 0 or 1.
Change-Id: I259a3a27329aab6835c21b4aa7ddda89dac9655b
These modules have issues running with execute-only memory. Disable it
in them until we can resolve the issues.
Bug: 77958880
Test: No more XOM-related crashes in these binaries
Change-Id: Ie6c957731155566c2bbe7dbb7a91b9583d9aff93
__sanitize_environment_variables is only called when getauxval(AT_SECURE)
is true.
Instead of scanning __libc_auxv, reuse getauxval. If the entry is missing,
getauxval will set errno to ENOENT.
Reduce the number of times that __libc_sysinfo and __libc_auxv are
initialized. (Previously, __libc_sysinfo was initialized 3 times for the
linker's copy). The two variables are initialized in these places:
- __libc_init_main_thread for libc.a (including the linker copy)
- __libc_preinit_impl for libc.so
- __linker_init: the linker's copy of __libc_sysinfo is still initialized
twice, because __libc_init_main_thread runs after relocation. A later
CL consolidates the linker's two initializations.
Bug: none
Test: bionic unit tests
Change-Id: I196f4c9011b0d803ee85c07afb415fcb146f4d65
When /foo/bar/baz is added to the search paths and if getattr (stat())
is not allowed on one of its parent paths, i.e., /foo and /foo/baz, the
path was thought as non-existent and wasn't added to the search paths of
the namespace.
Fixing the bug by adding the path if the path (though not the parents)
does exist.
Bug: 119656753
Test: m apex.test; m; device boots.
Change-Id: I21bca1fee9aa20688ce9b72192d3173821ad91a3
Change three things regarding the work around to the fact that init is
special:
1) Only first stage init is special, so we change the check to include
accessing /proc/self/exe, which if is available, means that we're
not first stage init and do not need any work arounds.
2) Fix the fact that /init may be a symlink and may need readlink()
3) Suppress errors from realpath_fd() since these are expected to fail
due to /proc not being mounted.
Bug: 80395578
Test: sailfish boots without the audit generated from calling stat()
on /init and without the errors from realpath_fd()
Change-Id: I266f1486b142cb9a41ec791eba74122bdf38cf12
This reverts commit 73de62e461.
Reason for revert: bug was fixed upstream and included into AOSP lld
Bug: 78115263
Test: make checkbuild
Change-Id: Ib9e4af1efdcdb547c7bd65cce4ce48d7f09ed217
When executing an executable in an APEX (i.e., /apex/<name>/bin),
ld.config.txt file is read from the same APEX, not from /system/etc.
Bug: 115787633
Test: m apex.test; adb push ...apex.test.apex /data/apex; adb reboot
Test: adb root; adb shell /apex/com.android.example.apex/bin/dex2oat
is runnable.
Change-Id: I6400251f99d24f2379dbaf655ecd84da02490617
Use <android-base/macros.h> instead where possible, and move the bionic
macros out of the way of the libbase ones. Yes, there are folks who manage
to end up with both included at once (thanks OpenGL!), and cleaning that
up doesn't seem nearly as practical as just making this change.
Bug: N/A
Test: builds
Change-Id: I23fc544f39d5addf81dc61471771a5438778895b
We don't have a host bionic version of
libclang_rt.asan-x86_64-android.so, so I'm using the android version,
which can't load liblog.so, since it's missing DT_RUNPATH that would
normally load liblog.so from a relative path to the .so.
Bug: 118058804
Test: run ASAN host_bionic
Change-Id: I58badcd5ed35bd1c7b786b4f1e2367a1011ff08d
This is use by Host Bionic to bootstrap into an embedded copy of the
linker by tweaking the AT_* values before calling in to the linker entry.
Similarly to 9729f35922, get the base
address from AT_PHDR, so that we're not relying on the relative offset
before relocation, which doesn't work with lld (at least with the
standard flags).
To find the offset to the linker code, we can still use an absolute
symbol created by extract_linker (which is currently hardcoded to 0x1000).
Instead of relying on something similar for the linker entry point,
we're now just reading the entry point from the linker's ELF header.
Then we get the address to the real _start function using
host_bionic_inject, which injects the value into a global variable after
the link step is finished. It also uses that opportunity to verify that
the linker is embedded as we expect it to be.
Bug: 31559095
Test: build with host bionic
Change-Id: I9d81ea77c51c079de06905da1ebe421fead1dc3b
The executable can be inside a zip file using the same syntax used for
shared objects: path.zip!/libentry.so.
The linker currently requires an absolute path. This restriction could be
loosened, but it didn't seem important? If it allowed non-absolute paths,
we'd need to decide how to handle:
- foo/bar (relative to CWD?)
- foo (search PATH / LD_LIBRARY_PATH, or also relative to CWD?)
- foo.zip!/bar (normalize_path() requires an absolute path)
The linker adjusts the argc/argv passed to main() and to constructor
functions to hide the initial linker argument, but doesn't adjust the auxv
vector or files like /proc/self/{exe,cmdline,auxv,stat}. Those files will
report that the kernel loaded the linker as an executable.
I think the linker_logger.cpp change guarding against (g_argv == NULL)
isn't actually necessary, but it seemed like a good idea given that I'm
delaying initialization of g_argv until after C++ constructors have run.
Bug: http://b/112050209
Test: bionic unit tests
Change-Id: I846faf98b16fd34218946f6167e8b451897debe5
Currently it normalizes the path to a string with a single uninitialized
byte. It should instead normalize it to "/".
Bug: none
Test: /data/nativetest/linker-unit-tests/linker-unit-tests32
Test: /data/nativetest64/linker-unit-tests/linker-unit-tests64
Change-Id: I06e0f7598d16acfa21875dad53efbc293cfeb44d
The argument to CloseArchive has type ZipArchiveHandle, but we're
passing it a ZipArchiveHandle*. The compiler doesn't detect the type
mismatch because ZipArchiveHandle is a typedef for void*.
Remove a duplicate close() call:
The fourth argument to OpenArchiveFd is "bool assume_ownership = true".
Even if the function fails, ownership of the fd is still transferred to
a ZipArchive object that's deleted when this code calls CloseArchive.
AFAIK, this code path is rarely or never hit.
Bug: none
Test: manual (eventually, 'linker64 /system!/foo')
Change-Id: I95d79809b6e118fb3c39c7b98b8055c8e324db1a
Originally a BSD extension, now in glibc too. We've used it internally
for a while.
(cherry-pick of e4b13f7e3ca68edfcc5faedc5e7d4e13c4e8edb9.)
Bug: http://b/112163459
Test: ran tests
Change-Id: I813c3a62b13ddb91ba41e32a5a853d09207ea6bc
Merged-In: I813c3a62b13ddb91ba41e32a5a853d09207ea6bc
Move source files to filegroup and extract c/ldflags and
version-script to linker_defaults.
Bug: http://b/71494052
Test: make
Change-Id: Ic82885e1c006f91a8446978fabd214f87cd20510
We've copied & pasted these to too many places. And if we're going to
have another go at upstreaming these, that's probably yet another reason
to have the *values* in just one place. (Even if upstream wants different
names, we'll likely keep the legacy names around for a while for source
compatibility.)
Bug: http://b/111903542
Test: ran tests
Change-Id: I8ccc557453d69530e5b74f865cbe0b458c84e3ba
* Initialize the exe's l_ld correctly, and initialize its l_addr field
earlier.
* Copy the phdr/phnum fields from the linker's temporary soinfo to its
final soinfo. This change ensures that dl_iterate_phdr shows the phdr
table for the linker.
* Change init_linker_info_for_gdb a little: use an soinfo's fields to
init the soinfo::link_map_head field, then reuse the new
init_link_map_head function to handle the linker and the executable.
Test: manual
Test: bionic-unit-tests
Bug: https://issuetracker.google.com/112627083
Bug: http://b/110967431
Change-Id: I40fad2c4d48f409347aaa1ccb98d96db89da1dfe
gdbserver assumes that the first entry is the exe, so it must come
first.
Fixes debugging of executables with gdb.
Bug: https://issuetracker.google.com/112627083
Bug: http://b/110967431
Test: gdbclient.py -r toybox
Change-Id: I7b30398d679c3f8b92d8d02572f9073ae0fce798
* Allow sanitization of libc (excluding existing global sanitizers)
and disallow sanitization of linker. The latter has not been
necessary before because HWASan is the first sanitizer to support
static binaries (with the exception of CFI, which is not used
globally).
* Static binary startup: initialize HWASan shadow very early so that
almost entire libc can be sanitized. The rest of initialization is
done in a global constructor; until that is done sanitized code can
run but can't report errors (will simply crash with SIGTRAP).
* Switch malloc_common from je_* to __sanitizer_*.
* Call hwasan functions when entering and leaving threads. We can not
intercept pthread_create when libc depends on libclang_rt.hwasan.
An alternative to this would be a callback interface like requested
here:
https://sourceware.org/glibc/wiki/ThreadPropertiesAPI
All of the above is behind a compile-time check
__has_feature(hwaddress_sanitizer). This means that HWASan actually
requires libc to be instrumented, and would not work otherwise. It's
an implementation choice that greatly reduces complexity of the tool.
Instrumented libc also guarantees that hwasan is present and
initialized in every process, which allows piecemeal sanitization
(i.e. library w/o main executable, or even individual static
libraries), unlike ASan.
Change-Id: If44c46b79b15049d1745ba46ec910ae4f355d19c
This code path is/was a workaround for poorly-behaved apps. AFAIK it isn't
needed anymore.
The (needed != nullptr) condition should have been (needed == nullptr), so
rather than unload a library, it tends to do nothing instead. If it can't
find the library, it would segfault.
Bug: http://b/112154263
Test: /data/nativetest/bionic-unit-tests/bionic-unit-tests
Test: /data/nativetest/linker-unit-tests/linker-unit-tests32
Test: apply patch to pi-dev, verify that apps from b/72143978 still work
Change-Id: Ic598cb3dcead9f88005764a9b8746ed6b35f5f38
arm32: Add a relocation for TLS descriptors (e.g. gcc's
-mtls-dialect=gnu2).
arm64: Add all the dynamic TLS relocations.
Two of the relocations here are obsolete:
- ARM documents R_ARM_SWI24 as an obsolete static relocation without
saying what it did. It's been replaced by R_ARM_TLS_DESC, a dynamic
relocation. We could probably remove it, but I left it because arm32
is old, and I see the macro in other libc's. It's probably analogous
to R_ARM_THM_SWI8, which is also an obsolete relocation reserved for
a future dynamic relocation.
- I couldn't find any ARM documentation at all for
R_AARCH64_TLS_DTPREL32. It seems to have been part of three
relocations:
- R_AARCH64_TLS_DTPREL32 1031
- R_AARCH64_TLS_DTPMOD32 1032
- R_AARCH64_TLS_TPREL32 1033
Bug: b/78026329
Test: run bionic unit tests
Change-Id: I5e7432f6e3e906152dc489be5e812fd8defcbafd
When the linker is invoked directly, rather than as an interpreter for a
real program, the AT_BASE value is 0. To find the linker's base address,
the linker currently relies on the static linker populating the target of
a RELA relocation with an offset rather than leaving it zero. (With lld,
it will require a special flag, --apply-dynamic-relocs.)
Instead, do something more straightforward: the linker already finds the
executable's base address using its PHDR table, so do the same thing when
the linker is run by itself.
Bug: http://b/72789859
Test: boots, run linker/linker64 by itself
Change-Id: I4da5c346ca164ea6f4fbc011f8c3db4e6a829456
Add two functions to allow objects that own a file descriptor to
enforce that only they can close their file descriptor.
Use them in FILE* and DIR*.
Bug: http://b/110100358
Test: bionic_unit_tests
Test: aosp/master boots without errors
Test: treehugger
Change-Id: Iecd6e8b26c62217271e0822dc3d2d7888b091a45
Some directories (e.g., /product/bin, etc.) in ld.config.txt may
not exist in some devices. Since many of them are optional directories,
don't emit warning when realpath() gives ENOENT for the paths.
Test: m -j
Change-Id: Ic4fa7db05bde53d3aa5df47291e83b4cdc09aa1f
Some devices place some of their partitions under /system. If the linker
resolves that paths, verboseness of ld.config.txt will be reduced as we
don't need to add both /system/{partition} and /{partition}.
Bug: http://b/80422611
Test: m -j, boot on taimen, atest
Change-Id: I6b712170bb89229b764026e2cc517c426e6e6063
init is now built as a dynamic executable, so the dynamic linker has to
be able to run in the init process. However, since init is launched so
early, even /dev/* and /proc/* file systems are not mounted and thus
some APIs that rely on the paths do not work. The dynamic linker now
goes alternative path when it is running in the init process.
For example, /proc/self/exe is not read for the init since we always now
the path of the init (/init). Also, arc4random* APIs are not used since
the APIs rely on /dev/urandom. Linker now does not randomize library
loading order and addresses when running in the init process.
Bug: 80454183
Test: `adb reboot recovery; adb devices` shows the device ID
Change-Id: I29b6d70e4df5f7f690876126d5fe81258c1d3115
In order to support shared libraries in the recovery mode, the dynamic
linker is now built with recovery_available: true option.
In addition, a few more modules (such as libasync, etc.) are also marked
as recovery_available: true as they are transitive dependencies of the
dynamic linker.
Bug: 63673171
Test: `adb reboot recovery; adb devices` shows the device ID
Test: `adb root && adb shell` and then
$ lsof -p `pidof adbd` shows that libm.so, libc.so, etc. are loaded from
the /lib directory.
Change-Id: Idd981d8cf25568a85b24032cf78e50adfd5f4a7f
A GOT lookup happening prior to soinfo::link_image causes a segfault. With
-O0, the compiler moves GOT lookups from after __linker_init's link_image
call to the start of __linker_init.
Rename the existing __linker_init_post_relocation to linker_main, then
extract the existing post-link_image code to a new
__linker_init_post_relocation function.
Bug: http://b/80503879
Test: /data/nativetest64/bionic-unit-tests/bionic-unit-tests
Test: manual
Change-Id: If8a470f8360acbe35e2a308b0fbff570de6131cf
__libc_sysinfo is hidden, so accessing it doesn't require a relocated GOT.
It is important not to have a relocatable initializer on __libc_sysinfo,
because if it did have one, and if we initialized it before relocating the
linker, then on 32-bit x86 (which uses REL rather than RELA), the
relocation step would calculate the wrong addend and overwrite
__libc_sysinfo with garbage.
Asides:
* It'd be simpler to keep the __libc_sysinfo initializer for static
executables, but the loader pulls in libc_init_static (even though it
uses almost none of the code in that file, like __libc_init).
* The loader has called __libc_init_sysinfo three times by the time it
has relocated itself. A static executable calls it twice, while libc.so
calls it only once.
Bug: none
Test: lunch aosp_x86-userdebug ; emulator
Test: adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
Test: adb shell /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
Change-Id: I5944f57847db7191608f4f83dde22b49e279e6cb
- It is only needed for dynamic executables, so move the initialization
out of __libc_init_main_thread and just before the solib constructor
calls. For static executables, the slot was initialized, then never
used or cleared. Instead, leave it clear.
- For static executables, __libc_init_main_thread already initialized the
stack guard, so remove the redundant __init_thread_stack_guard call.
- Simplify the slot access/clearing a bit in __libc_preinit.
- Remove the "__libc_init_common() will change the TLS area so the old one
won't be accessible anyway." comment. AFAICT, it's incorrect -- the
main thread's TLS area in a dynamic executable is initialized to a
static pthread_internal_t object in the linker, then reused by libc.so.
Test: adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
Test: adb shell /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
Change-Id: Ie2da6f5be3ad563fa65b38eaadf8ba6ecc6a64b6
The tls_nodelete state should apply to load_group not
isolated soinfo. This actually also means that multiple
soinfos may have tls_counter on their dso_handles.
This change replaces TLS_NODELETE flag with secondary counter.
Note that access to the secondary counter (located inside soinfo)
is pretty expensive because it requires soinfo lookup by dso_handle
whereas dso_handle counter is much faster. This is why it is updated
only when dso_handle counter starts or hits 0.
Bug: http://b/80278285
Test: bionic-unit-tests --gtest_filter=dl*
Change-Id: I535583f6714e45fa2a7eaf7bb3126da20ee7cba9
Libraries that are direct or indirect dependencies of modules installed
to recovery partition (e.g. toybox) are marked as recovery_available:
true. This allows a recovery variant of the lib is created when it is
depended by other recovery or recovery_available modules.
Bug: 67916654
Bug: 64960723
Bug: 63673171
Bug: 29921292
Test: m -j
Change-Id: I59bf859a10a218af6591025a0fe7d1853e328405
vdso should be available in all namespaces when present. This
bug went undetected because the way libc currently uses vdso (it
does all the lookups itself). This makes it available for the
programs that want to take advantage by dlopening it.
Bug: http://b/73105445
Bug: http://b/79561555
Test: adb shell /data/nativetest/arm/bionic-unit-tests/bionic-unit-tests --gtest_filter=dl.exec_with_ld_config_file
Test: adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests --gtest_filter=dl*
Change-Id: I8eae0c9848f256190d1c9ec85d10dc6ce383a8bc
(cherry picked from commit 69c68c46ac)
When linker tries to check if a library without dt_soname is accessible
it crashes. This change fixes this problem to return false instead
(making them inaccessible from other namespaces)
This went unnoticed because vendor libraries on current
devices all have dt_soname set. This was only discovered
on one of the newer devices which has a vendor prebuilt
library without a soname.
Bug: http://b/78661414
Bug: https://issuetracker.google.com/77287902
Test: cts-tradefed run commandAndExit cts -m CtsJniTestCases
Change-Id: Idb192b4ed7a810840ba2a9177bad2360ffbb75e2
(cherry picked from commit 94f7a87510)
* Specify "nocrt: true" to avoid calling __cxa_finalize.
* Define a dummy __aeabi_unwind_cpp_pr0 for arm32.
Bug: b/62815515
Bug: b/73873002
Test: boot AOSP hikey960-userdebug
Test: run ndk_cxa_example in special /system/bin/debug namespace
Test: run Bionic unit tests
Change-Id: I59bcb100a2753286b59c51a47d7a183507219a07
Explicitly say "warning" for warnings, explicitly say what action
we're going to take (such as "(ignoring)"), always provide a link to
our documentation when there is one, explicitly say what API level the
behavior changes at, and explicitly say why we're allowing the misbehavior
for now.
Bug: http://b/71852862
Test: ran tests, looked at logcat
Change-Id: I1795a5af45deb904332b866d7d666690dae4340b
RTLD_NEXT/DEFAULT lookup should not skip handle lookup
in the case when the load group is RTLD_GLOBAL.
Note that there is a difference between load group is local group.
The local group includes externally referenced libraries where
the load group does not. The external reference in this context is a
DT_NEEDED library that belongs to a previously loaded group.
Bug: http://b/72237367
Test: bionic-unit-tests --gtest_filter=dl*
Change-Id: I8997cc961c13a5396f1756161798b45ed1cab16c
We've been using #pragma once for new internal files, but let's be more bold.
Bug: N/A
Test: builds
Change-Id: I7e2ee2730043bd884f9571cdbd8b524043030c07
Every other architecture already uses an assembly file here.
The previous code aligned ESP incorrectly, but it doesn't really matter
because everything is built with Clang's -mstackrealign, which realigns
ESP in every function prologue.
Bug: http://b/73140672#comment4
Test: lunch aosp_x86-eng; m; emulator; device boots
Test: manual
Change-Id: I921fd7848cdc611b4f8f13d1176d1983ffea952d
This change modifies the encoding used in SHT_RELR sections to a simpler
version that gives better results. This encoding was suggested by Andrew
Grieve and is described in this post on generic-abi@googlegroups.com:
https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
Bug: None
Test: Built image for marlin, flashed on device, ran arm and
aarch64 binaries containing '.relr.dyn' sections using
the new encoding.
Change-Id: I266affe0fbad91dc375995985a221cb02499447b
This commit allows users to create a link without soname filters between
two linker namespaces.
The motivation is to establish one-way shared library isolation. For
example, assume that there are two linker namespaces `default` and
`vndk`. We would like to limit the shared libraries that can be used by
the `default` namespace. In the meanwhile, we would like to allow the
`vndk` namespace to use shared libs from the `default` namespace if the
soname cannot be find in the search path or loaded sonames of the `vndk`
namespace.
shared_libs = %VNDK_CORE_LIBRARIES%
shared_libs += %VNDK_SAMEPROCESS_LIBRARIES%
vndk <-------------------------------------------- default
\_______________________________________________/^
allow_all_shared_libs = true
android_link_namespaces_all_libs() is added to libdl, but it is
versioned as LIBC_PRIVATE. android_link_namespaces_all_libs() is only
for unit tests.
Bug: 69824336
Test: adb shell /data/nativetest/linker-unit-tests/linker-unit-tests32
Test: adb shell /data/nativetest64/linker-unit-tests/linker-unit-tests64
Test: adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
Test: adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests
Test: Update /system/etc/ld.config*.txt and check whether the vndk
linker namespace of the vendor process can access the shared libs from
the default linker namespace.
Change-Id: I2879f0c5f5af60c7e56f8f743ebd2872e552286b
This change adds experimental support for SHT_RELR sections, proposed
here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
Definitions for the new ELF section type and dynamic array tags, as well
as the encoding used in the new section are all under discussion and are
subject to change. Use with caution!
Bug: None
Test: Built image for marlin, flashed on device, ran arm and
aarch64 binaries containing '.relr.dyn' sections.
Change-Id: I2953ae932d3c42ae394e71f8fa058013758a1778
There were a bunch more unreasonable/incorrect ones, but these ones
seemed legit. Nothing very interesting, though.
Bug: N/A
Test: ran tests, benchmarks
Change-Id: If66971194d4a7b4bf6d0251bedb88e8cdc88a76f
Introduce new flag to mark soinfo as TLS_NODELETE when
there are thread_local dtors associated with dso_handle
belonging to it.
Test: bionic-unit-tests --gtest_filter=dl*
Test: bionic-unit-tests-glibc --gtest_filter=dl*
Bug: https://github.com/android-ndk/ndk/issues/360
Change-Id: I724ef89fc899788f95c47e6372c38b3313f18fed
ld-android.so exports exact same set of symbols
as linker. Since it is not supposed to be loaded
every symbol points to fail() method.
Test: make
Test: bionic-unit-tests --gtest_filter=dl*
Change-Id: I23bec365b302ce4ddf5f08832e665ae2b181cf8a
This will allow us to apply linker's version script to the "fake"
version of ld-android.so.
Test: make
Change-Id: I55645cc0fc90e6c65e2269ba2340a908aeed1eaa
C++17 removed a handful of things that are used in the libclang
headers, which are used by the versioner. Enable the flag that
re-exposes these until we have a C++17 compatible libclang.
Add a stub posix_memalign to the linker. libc++abi uses posix_memalign
when allocating exceptions, which the linker does not use.
Test: make checkbuild
Bug: None
Change-Id: I32f9d0591ef99a610f27efed90a5c9fd150f0d3e
This change addresses multiple problems introduced by
02586a2a34
1. In the case of unsuccessful dlopen the failure guard is triggered
for two namespaces which leads to double unload.
2. In the case where load_tasks includes libraries from 3 and more
namespaces it results in incorrect linking of libraries shared between
second and third/forth and so on namespaces.
The root cause of these problems was recursive call to find_libraries.
It does not do what it is expected to do. It does not form new load_tasks
list and immediately jumps to linking local_group. Not only this skips
reference counting it also will include unlinked but accessible library
from third (and fourth and fifth) namespaces in invalid local group. The
best case scenario here is that for 3 or more namesapces this will
fail to link. The worse case scenario it will link the library
incorrectly with will lead to very hard to catch bugs.
This change removes recursive call and replaces it with explicit list of
local_groups which should be linked. It also revisits the way we do
reference counting - with this change the reference counts are updated after
after libraries are successfully loaded.
Also update soinfo_free to abort in case when linker tries to free same
soinfo for the second time - this makes linker behavior less undefined.
Test: bionic-unit-tests
Bug: http://b/69787209
Change-Id: Iea25ced181a98c6503cce6e2b832c91d697342d5
When ro.vndk.version is set to a specific version, not "current",
use ld.config.$VER.txt as a linker namespace configuration file,
where $VER is the VNDK version set by ro.vndk.version.
Because ro.vndk.version is set by the vendor partition, the
configuration file will be automatically selected by the VNDK version
of vendor patition.
If ro.vndk.version is current or not set, ld.config.txt will be used
as before.
Bug: 69531793
Test: Build for a Pixel2 device.
In the out/target/product/<device> directory,
rename system/etc/ld.config.txt to system/etc/ld.config.27.1.0.txt
rename system/lib[64]/vndk to system/lib[64]/vndk-27.1.0
copy system/lib[64]/vndk-sp to system/lib[64]/vndk-sp-27.1.0
set ro.vndk.version to 27.1.0 in vendor/default.prop
Build system and vendor images with "make snod" and "make vnod".
Disble vbmeta using avbtool.
Flash a device and check boot.
Change-Id: Ic55bb0a741d434e5fa93e109be15df9d9de3f105
ld.config.txt currently does not support split line. As the file gets
larger, this limitation makes the file very unreadable. Now, long lines
can be avoided by breaking one line into multiple lines using +=
operator.
ex)
namespace.default.search.paths = /system/${LIB}
namespace.default.search.paths += /system/${LIB}
Delimitor (':' for *.paths and *.shared_libs, and ',' for *.links) is
automatically added.
Bug: 69888716
Test: linker-unit-tests passes
Change-Id: I4b94fd4e7f8a76d59db8d1096c86aa2118e46625
If libraries are on the odm partition they will fail to load
This patch adds the odm path as a search path for linker.
Test: libraries load from the odm partition
Change-Id: Ia7786e047cc565d74d25c025dacf9266b3763650
Signed-off-by: Alin Jerpelea <alin.jerpelea@son.com>
This reverts commit 58554ccb8a.
causes /vendor/bin/qseecomd to hit the new abort:
[ 8.983301] c5 603 DEBUG: Abort message: 'soinfo=0x7147894cd0 is not in soinfo_list (double unload?)'
Bug: http://b/69909887
Bug: http://b/69787209
Change-Id: Ied38f797e0a071a1acc5ed41adf1b45e855143c7
In the case of unsuccessful dlopen the failure guard is triggered
for two namespaces which leads to double unload.
Also update soinfo_free to abort in case when linker tries to free same
soinfo for the second time - this makes linker behavior less undefined.
Test: bionic-unit-tests
Bug: http://b/69787209
Change-Id: I886787ee021b050667f967bce7aa2708390886ea
Bug: http://b/29458203
Bug: http://b/68262627
Test: make && run bionic-unit-tests
Test: set debug.ld.all to dlopen and check the logs
Change-Id: I9a5495843a4145f267cc3a4714294d05b1e1fe90
Added a test to make sure linker produces correct error message
when user attempts to load a library in a linked namespace and fails.
Bug: http://b/67866190
Bug: http://b/64950640
Bug: http://b/64888291
Test: bionic-unit-test --gtest_filter=dlext*
Change-Id: I5b5c2070d1388eff123118350b2b5c8fc7571a29
vector::erase(iterator) erases the element that that iterator points
to, vector::erase(iterator a, iterator b) erases the range [a, b), with
a == b being a no-op.
Test: LD_PRELOAD=libc.so sh
Change-Id: I6a85c1cfaa8eb67756cb75d421f332d5c9a43a33
The permitted and search paths should be changed according to VNDK
version for VNDK snapshot. So, {VNDK_VER} value is added in ld.config.txt
file and this value is set through the linker.
If ro.vndk.version is not set, search paths are vndk and vndk-sp as
before.
Bug: 66074376
Test: build & run
Change-Id: I266b66fe1bc95d8925053ef497db11ac0a57c082
std::remove_if moves removed elements to the end, without actually
resizing the collection. To do so, you have to call erase on its
returned iterator.
Test: mma
Change-Id: Iae7f2f194166408f2b101d0c1cfc95202d8bbe63