The file is a manually created linker config file for the binaries in
the APEX. This is discouraged since such a manually created linker
config is error-prone and hard to maintain. Since the per-APEX
linker config file is automatically created by the linkerconfig tool as
/linkerconfig/<name>/ld.config.txt, we can safely deprecated the
fallback path.
There currently are two APEXes using these hand-crafted configs. They
can (and should) keep the configs for backwards compatibility; in case
when they run on older devices where the auto-generated configs are not
available. But for newer platforms, the files are simply ignored and no
new APEX should be using that.
Bug: 218933083
Test: m
Change-Id: I84bd8850b626a8506d53af7ebb86b158f6e6414a
This is important for enabling the error about unsupported TLS
relocations to local symbols. The fast path tends to skip this error,
because it fails during lookup_symbol(). Add a test for this error.
I didn't see a performance regression in the linker_relocation
benchmark.
Bug: http://b/226978634
Test: m bionic-unit-tests
Change-Id: Ibef9bde2973cf8c2d420ecc9e8fe2c69a5097ce2
This flag means "$ORIGIN processing required", and since we always
do that, we can claim support for it.
Change-Id: If60ef331963f6bc1e1818d7fa2ee57c1aa8fa343
For convenience, builds against musl libc currently use the
linux_glibc properties because they are almost always linux-specific
and not glibc-specific. In preparation for removing this hack,
tweak the linux_glibc properties by either moving them to host_linux,
which will apply to linux_glibc, linux_musl and linux_bionic, or
by setting appropriate musl or linux_musl properties. Properties
that must not be repeated while musl uses linux_musl and also still
uses the linux_glibc properties are moved to glibc properties, which
don't apply to musl. Whether these stay as glibc properties or get
moved back to linux_glibc later once the musl hack is removed is TBD.
Bug: 223257095
Test: m checkbuild
Test: m USE_HOST_MUSL=true host-native
Change-Id: I809bf1ba783dff02f6491d87fbdc9fa7fc0975b0
For a 32-bit userspace, `struct LinkedListEntry` takes 8 bytes for
storing the two pointers, a default block allocator size alignment of
16-bytes would waste 50% of memory. By changing the alignment to size
of a pointer, it saves >1MB memory postboot on wembley device.
Bug: http://b/206889551
Test: bionic-unit-tests
Change-Id: Ie92399c9bb3971f631396ee09bbbfd7eb17dc1a7
This change is to allocate `head_` and `tail_` outside of LinkedList
and only keep a readonly pointer there. By doing this, all updates
of the list touches memory other than the LinkedList itself, thus
preventing copy-on-write pages being allocated in child processes
when the list changes.
The other approach is to make the LinkedList a singly-linked list,
however, that approach would cause a full list traversal to add
one item to the list. And preliminary number shows there are ~60K
calls to `soinfo::add_secondary_namespace` during Android bootup
on a wembley device, where a singly-linked approach could be
hurting performance.
NOTE: the header is allocated and initialized upon first use instead
of being allocated in the constructor, the latter ends up in crash.
This is likely caused by static initialization order in the linker,
e.g. g_soinfo_list_allocator is a static object, and if this linked
list is embedded into some other static objects, there's no guarantee
the allocator will be available.
Bug: http://b/206889551
Test: bionic-unit-tests
Change-Id: Ic6f053881f85f9dc5d249bb7d7443d7a9a7f214f
Clang cannot build ifunc with LTO. This is a KI: https://bugs.llvm.org/show_bug.cgi?id=46488
Move the LTO: never down to libc itself, so that we can have LTO for the
rest of linker.
Test: m GLOBAL_THINLTO=true linker
Change-Id: I483fc3944e340638a664fb390279e211c2ae224b
This also effectively re-enables linker_wrapper, which may have been
independently fixed some time ago.
Test: mixed_droid.sh
Change-Id: I9bc7e099fe3c5da1c4da12c79128baf6f807354a
A recent change to lld [1] made it so that the __rela?_iplt_*
symbols are no longer defined for PIEs and shared libraries. Since
the linker is a PIE, this prevents it from being able to look up
its own relocations via these symbols. We don't need these symbols
to find the relocations however, as their location is available via
the dynamic table. Therefore, start using the dynamic table to find
the relocations instead of using the symbols.
Previously landed in r.android.com/1801427 and reverted in
r.android.com/1804876 due to linux-bionic breakage. This time,
search .rela.dyn as well as .rela.plt, since the linker may put the
relocations in either location (see [2]).
[1] f8cb78e99a
[2] https://reviews.llvm.org/D65651
Bug: 197420743
Change-Id: I5bef157472e9893822e3ca507ef41a15beefc6f1
This reverts commit 65bdf655c4.
Reason for revert: checking the failure of avd/avd_boot_test
Bug: 197781964
Change-Id: I70eb03b45cdfbd87ef6edb03b74ad6d1970dc08c
A recent change to lld [1] made it so that the __rela?_iplt_*
symbols are no longer defined for PIEs and shared libraries. Since
the linker is a PIE, this prevents it from being able to look up
its own relocations via these symbols. We don't need these symbols
to find the relocations however, as their location is available via
the dynamic table. Therefore, start using the dynamic table to find
the relocations instead of using the symbols.
[1] f8cb78e99a
Change-Id: I4a12ae9f5ffd06d0399e05ec3ecc4211c7be2880
In order to support demangling of rust symbols by the linker, we are
adding a small Rust component. Rust expects `memalign` to be present in
hosted environments, and it doesn't appear costly to enable it.
Bug: 178565008
Test: m, killall -11 keystore2 produced mangled names in tombstone
Change-Id: I8fc749000fa02a3b760c8cc55be3348b9964d931
Now that linker_wrapper.o does not use objcopy --prefix-symbols=__dlwrap_
it can reference the _start symbol of the original binary without
colliding with its own __dlwrap__start symbol, which means
host_bionic_inject is no longer necessary.
Test: build and run host bionic binary
Change-Id: I1752efa39fa73a092fab039771bf59c99b7b5974
The only symbol that actually needs a prefix to avoid a collision is
_start, and that can be handled with a copy of begin.S that uses a
"#define" to rename _start to __dlwrap__start. Removing the prefixed
symbols will also allow simplifying the host bionic build process by
letting it directly reference the real _start.
Test: build and run host bionic binary
Change-Id: I50be786c16fe04b7f05c14ebfb74f710c7446ed9
To take advantage of file-backed huge pages for the text segments of key
shared libraries (go/android-hugepages), the dynamic linker must load
candidate ELF files at an appropriately aligned address and mark
executable segments with MADV_HUGEPAGE.
This patches uses segments' p_align values to determine when a file is
PMD aligned (2MB alignment), and performs load operations accordingly.
Bug: 158135888
Test: Verified PMD aligned libraries are backed with huge pages on
supporting kernel versions.
Change-Id: Ia2367fd5652f663d50103e18f7695c59dc31c7b9
Introduces a cc_defaults category hugepage_aligned that passes the
requisite linker flags to produce shared object files with 2MB-aligned
sections. This enables supporting platforms to back the text segments of
these libraries with hugepages.
Bug: 158135888
Test: Built and confirmed ELF layout
Change-Id: I5c8ce35d8f8bf6647ec19d58398740bd494cc89c
This works around buggy applications that read a few bytes past the
end of their allocation, which would otherwise cause a segfault with
the concurrent Scudo change that aligns large allocations to the right.
Because the implementation of
android_set_application_target_sdk_version() lives in the linker,
we need to introduce a hook so that libc is notified when the target
SDK version changes.
Bug: 181344545
Change-Id: Id4be6645b94fad3f64ae48afd16c0154f1de448f
Otherwise if a 32bit copy of a library used by Toybox
exists on LD_LIBRARY_PATH then file(1) will fail.
Bug: 181666541
Test: Manually copied to device and verified correct behaviour
Change-Id: I7d729927b1b433ec953c266920489613fc096e03
Auto-generate NOTICE files for all the directories, and for each one
individually rather than mixing libc and libm together.
Test: N/A
Change-Id: I7e251194a8805c4ca78fcc5675c3321bcd5abf0a
With this change we can report memory errors involving secondary
allocations. Update the existing crasher tests to also test
UAF/overflow/underflow on allocations with sizes sufficient to trigger
the secondary allocator.
Bug: 135772972
Change-Id: Ic8925c1f18621a8f272e26d5630e5d11d6d34d38
These lines shouldn't actually matter, because the DSOs are using
version scripts to allow-list exported symbols.
Bug: none
Test: bionic unit tests
Change-Id: I39d3df8c4f8053624f862b3c6994e30c693e928c
During "step 1" of find_libraries, the linker finds the transitive
closure of dependencies, in BFS order. As it finds each library, it
adds the library to its primary namespace (so that, if some other
library also depends on it, find_loaded_library_by_soname can find the
library in the process of being loaded).
LD_PRELOAD libraries are automatically marked DF_1_GLOBAL, and any
DF_1_GLOBAL library is added to every linker namespace. Previously,
this secondary namespace registration happened after step 1. The result
is that across different namespaces, the order of libraries could vary.
In general, a namespace's primary members will all appear before
secondary members. This is undesirable for libsigchain.so, which we
want to have appear before any other non-preloaded library.
Instead, when an soinfo is added to its primary namespace, immediately
add it to all the other namespaces, too. This ensures that the order of
soinfo objects is the same across namespaces.
Expand the dl.exec_with_ld_config_file_with_ld_preload and
dl.exec_with_ld_config_file tests to cover the new behavior. Mark
lib1.so DF_1_GLOBAL and use a "foo" symbol to mimic the behavior of a
signal API interposed by (e.g.) libsigchain.so and a ASAN preload.
Test: bionic unit tests
Bug: http://b/143219447
Change-Id: I9fd90f6f0d14caf1aca6d414b3e9aab77deca3ff
No-one seems to understand that a crash in a random .so from call_array()
in the linker isn't a linker bug. They _seem_ to understand (or at least
claim to) when we explain that this is just the linker calling their ELF
constructors --- despite the fact that the caller of call_array() is
call_constructors().
One experiment we can try though is to inline call_array() to elide that
frame from the crash dumps. I do also wonder whether renaming
call_constructors() to call_elf_constructors() would help/hinder/make no
difference. For now I'm leaning toward "hinder" because I suspect most
people don't understand "ELF constructor" and C++ folks at least will
probably be influenced in a not wholly incorrect direction when they
hear "constructor" (whereas "ELF constructor" might mislead them back in
the direction of "strange linker magic, not my fault" again)...
(The reformatting is clang-format's decision, not mine.)
Test: treehugger
Change-Id: I65ab95ceb2e988fd053c48c66f51afba17ccfa61
For libc.so, use a special build of libunwind.a whose symbols aren't
hidden ("libunwind-exported"), because libc.so exports the _Unwind_*
APIs.
Bug: http://b/153025717
Test: bionic unit tests
Change-Id: I7435e076ec8cc4410e3e6086d3cf5d2c6011c80c
Setting the linker's soname ("ld-android.so") can allocate heap memory
now that the name uses an std::string, and it's probably a good idea to
defer doing this until after the linker has relocated itself (and after
it has called C++ constructors for global variables.)
Bug: none
Test: bionic unit tests
Test: verify that dlopen("ld-android.so", RTLD_NOLOAD) works
Change-Id: I6b9bd7552c3ae9b77e3ee9e2a98b069b8eef25ca
Once upon a time (and, indeed, to this very day if you're on LP32) the
soinfo struct used a fixed-length buffer for the soname. This caused
some issues, mainly with app developers who accidentally included a full
Windows "C:\My Computer\...\libfoo.so" style path. To avoid all this we
switched to just pointing into the ELF file itself, where the DT_SONAME
is already stored as a NUL-terminated string. And all was well for many
years.
Now though, we've seen a bunch of slow startup traces from dogfood where
`dlopen("libnativebridge.so")` in a cold start takes 125-200ms on a recent
device, despite no IO contention. Even though libnativebridge.so is only
20KiB.
Measurement showed that every library whose soname we check required
pulling in a whole page just for the (usually) very short string. Worse,
there's readahead. In one trace we saw 18 pages of libhwui.so pulled
in just for `"libhwui.so\0"`. In fact, there were 3306 pages (~13MiB)
added to the page cache during `dlopen("libnativebridge.so")`. 13MiB for
a 20KiB shared library!
This is the obvious change to use a std::string to copy the sonames
instead. This will dirty slightly more memory, but massively improve
locality.
Testing with the same pathological setup took `dlopen("libnativebridge.so")`
down from 192ms to 819us.
Bug: http://b/177102905
Test: tested with a pathologically modified kernel
Change-Id: I33837f4706adc25f93c6fa6013e8ba970911dfb9
Use a note in executables to specify
(none|sync|async) heap tagging level. To be extended with (heap x stack x
globals) in the future. A missing note disables all tagging.
Bug: b/135772972
Test: bionic-unit-tests (in a future change)
Change-Id: Iab145a922c7abe24cdce17323f9e0c1063cc1321