summaryrefslogtreecommitdiff
path: root/linker/linker.cpp
AgeCommit message (Collapse)Author
2021-01-22Ensure same order of global group members in all NS'sRyan Prichard
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
2021-01-13Delay setting linker soname until post-reloc and post-ctorRyan Prichard
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
2021-01-11Store soname as a std::string.Elliott Hughes
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
2020-11-06linker: add ld.config.txt parse time to systrace.Elliott Hughes
Bug: http://b/172640358 Test: treehugger Change-Id: I9d6b7c1e200d2effb737508d3c282063edefa888
2020-09-23Enable BTI in bionic linkerTamas Petz
This patch adds support to load BTI-enabled objects. According to the ABI, BTI is recorded in the .note.gnu.property section. The new parser evaluates the property section, if exists. It searches for .note section with NT_GNU_PROPERTY_TYPE_0. Once found it tries to find GNU_PROPERTY_AARCH64_FEATURE_1_AND. The results are cached. The main change in linker is when protection of loaded ranges gets applied. When BTI is requested and the platform also supports it the prot flags have to be amended with PROT_BTI for executable ranges. Failing to add PROT_BTI flag would disable BTI protection. Moreover, adding the new PROT flag for shared objects without BTI compatibility would break applications. Kernel does not add PROT_BTI to a loaded ELF which has interpreter. Linker handles this case too. Test: 1. Flame boots 2. Tested on FVP with BTI enabled Change-Id: Iafdf223b74c6e75d9f17ca90500e6fe42c4c1218
2020-08-03Rename linker greylist to exempt-listRyan Prichard
Update a comment in android-changes-for-ndk-developers.md about the removed debug.ld.greylist_disabled system property. Update language to comply with Android's inclusive language guidance #inclusivefixit See https://source.android.com/setup/contribute/respectful-code for reference Bug: http://b/162536543 Test: bionic-unit-tests Change-Id: I760ee14bce14d9d799926c43d2c14fd8ffbc6968
2020-08-02Merge "linker: Cleanup for Android's inclusive language guidance"Treehugger Robot
2020-07-31linker: Cleanup for Android's inclusive language guidanceLuke Huang
1. Cleanup for #inclusivefixit. (whitelisted -> allowed_libs) 2. Support the old term for backwards compatibility. (Also update test.) 3. Fix the formatting errors found by clang-format. See https://source.android.com/setup/contribute/respectful-code for reference. Bug: 161896447 Test: atest linker-unit-tests linker-benchmarks Change-Id: I19dbed27a6d874ac0049cb7b67d2cb0f75369c1b
2020-07-30Remove debug.ld.greylist_disabled propertyRyan Prichard
This property provided a way to disable the greylist, for testing whether an app targeting < 24 still works. Instead of turning off the greylist, though, an app developer should simply target a newer API. (If app developers really need this property for testing, they can still use it on versions of Android between N and R, inclusive.) Update language to comply with Android's inclusive language guidance See https://source.android.com/setup/contribute/respectful-code for reference #inclusivefixit Bug: http://b/162536543 Test: bionic-unit-tests Change-Id: Id1eb2807fbb7436dc9ed7fe47e15b7d165a26789
2020-07-21Changes for #inclusivefixit.Elliott Hughes
Test: treehugger Change-Id: I7ff0496c5c2792a41781e74634247f55b0548213
2020-07-16Pagetable-friendly shared library address randomization.Evgenii Stepanov
Add inaccessible gaps between shared libraries to make it harder for the attackers to defeat ASLR by random probing. To avoid excessive page table bloat, only do this when a library is about to cross a huge page boundary, effectively allowing several smaller libraries to be lumped together. Bug: 158113540 Test: look at /proc/$$/maps Change-Id: I39c0100b81f72447e8b3c6faafa561111492bf8c
2020-07-06Merge "Revert "Add randomized padding around shared library mappings.""Evgenii Stepanov
2020-07-06Revert "Add randomized padding around shared library mappings."Evgenii Stepanov
This reverts commit a8cf3fef2aa2201014c35c3487da222ccfedfc1c. Reason for revert: memory regression due to the fragmentation of the page tables Bug: 159810641 Bug: 158113540 Change-Id: I6212c623ff440c7f6889f0a1e82cf7a96200a411
2020-06-30Disable warning message for missing linker config in some casesKiyoung Kim
There are some special cases - such as init process - when linker configuration is not expected to exist. This change disables warning message that generated linker configuration does not exist in those cases. Bug: 158800902 Test: Tested from cuttlefish that warning message is not generated from init Change-Id: Ie2fbb5210175cf1e6f2b7e638f57c3b74d395368
2020-06-17Add randomized padding around shared library mappings.Evgenii Stepanov
Improve ASLR by increasing the randomly sized gaps between shared library mappings, and keep them mapped PROT_NONE. Bug: 158113540 Test: look at /proc/$$/maps Change-Id: Ie72c84047fb624fe2ac8b7744b2a2d0d255ea974
2020-05-15Allow native_bridge linker to use different APEX from native oneVictor Khimenko
Bug: http://b/156397945 Test: dlfcn.dlopen_system_libicuuc_android_api_level_28 with native_bridge Change-Id: I3ecd929a0c31dda8cd424795f21f6ef472776557
2020-05-07Move libicuuc.so into com.android.i18n module.Victor Chang
Change the location set in the linker Bug: 130219528 Bug: 138994281 Test: atest CtsBionicTestCases Test: atest CtsJniTestCases Change-Id: I215a8e023ccc4d5ffdd7df884c809f8d12050c8f
2020-03-27Fix bootstrap linker library searchingRyan Prichard
For the bootstrap linker, insert /system/${LIB}/bootstrap in front of /system/${LIB} in any namespace search path. Bug: http://b/152572170 Test: bionic unit tests Change-Id: Ia359d9f2063f4b6fff3f79b51b500ba968a18247
2020-03-27Remove dangling soinfo* from elf_readers_map_Ryan Prichard
If ElfReader::Read fails, then it is hazardous to leave the invalid ElfReader in the soinfo*->ElfReader table, because a future soinfo object could happen to have the same address, then reuse the invalid ElfReader. I'm not sure whether this can break anything, because the linker would call ElfReader::Read on the invalid object and overwrite its previous value. Test: bionic unit tests Bug: none Change-Id: Ibabbf559443441b9caeacc34ca165feaafe5e3a7
2020-03-27Fix DL_WARN_documented_change URLRyan Prichard
The doc_link argument is really a URL fragment within the android-changes-for-ndk-developers.md document, not a filename at the root of the bionic repository. Test: manual Bug: none Change-Id: I1b542e47aca132ce43ba1d50d83db1bf3c7b10c6
2020-03-27remove search_linked_namespaces paramRyan Prichard
The search_linked_namespaces parameter to find_library_internal is always true. Bug: none Test: bionic tests Change-Id: I4b6f48afefca4f52b34ca2c9e0f4335fa895ff34
2020-03-27Refactor linker lookup code a bitRyan Prichard
Add a few _Nonnull / _Nullable annotations. Clang may use them to issue warnings but violating the annotation isn't undefined behavior. Bug: none Test: bionic tests Change-Id: I82e442f06a2c59c69bc0008f0f686785695cdd02
2020-03-17Update linkerconfig missing message to warningKiyoung Kim
Update message that generated linker configuration is missing to from into to warning again. Also do not raise this message from host environment which is expected. Bug: 146386369 Test: m -j passed Change-Id: Ia5c2969d77fbc70e0406fbb449920080989a1ea8
2020-02-18Merge "Deprecate sys.linker.use_generated_config property"Kiyoung Kim
2020-02-15Deprecate sys.linker.use_generated_config propertyKiyoung Kim
sys.linker.use_generated_config property was introduced at the beginning of linkerconfig development to skip this generated configuration if it does not work properly during dev. However, linkerconfig development is now completed and is working properly from most of devices, so this property is no longer in use. Therefore deprecating this property as this would not be used. Bug: 149335054 Test: m -j passed Test: No linking error from Cuttlefish and Crosshatch Change-Id: I0a1b3f36b69872862196b1613718a75d482e0a92
2020-02-13Remove unused mips/mips64 code from the linker.Elliott Hughes
Test: treehugger Change-Id: I42f1e4c492ac644cf78e7c1196ba9b3518f9c8f8
2020-02-12Adjust the documentation of `get_ld_config_file_apex_path`.Roland Levillain
Test: n/a Bug: 147987608 Change-Id: I479a63a2fa7e0975db80fcfdda78d2ee154c53cb
2020-02-07Merge "Use generated linker config for APEX binaries"Kiyoung Kim
2020-02-03Use generated linker config for APEX binariesKiyoung Kim
LinkerConfig will start to generate linker configuration for APEX binaries. Linker should check if this generated file exists first, and use it if exists and otherwise use ld.config.txt under APEX etc. Bug: 147987608 Test: m -j passed Test: Tested with adbd and SWCodec from Cuttlefish and Crosshatch Change-Id: I5a0c28ee1a427adface3e67c8af062e1b2ef6197
2020-01-31Rename dlsym_handle_lookup:6 to dlsym_handle_lookup_implRyan Prichard
Rearrange a function to remove a forward declaration. Test: m linker Change-Id: I014eac3319bd6f4c10f8bba50f8006f96bb33dce
2020-01-24Modernize SHT_RELR support.Elliott Hughes
Until now we've only supported RELR with our own OS-private-use constants. Add support for the official numbers (while maintaining support for the historical numbers). Add tests to ensure we continue to support both indefinitely. We can't yet flip the build system over to using the official constants because the old GNU binutils objcopy we still use in most cases (for the mini-debug section) only supports the historical constants. Bug: http://b/147452927 Test: treehugger Change-Id: If214fce7fade4316115947e90b78ab40864b61f2
2020-01-13Optimize GNU hash linking for large inputsRyan Prichard
Symbol lookup is O(L) where L is the number of libraries to search (e.g. in the global and local lookup groups). Factor out the per-DSO work into soinfo_do_lookup_impl, and optimize for the situation where all the DSOs are using DT_GNU_HASH (rather than SysV hashes). To load a set of libraries, the loader first constructs an auxiliary list of libraries (SymbolLookupList, containing SymbolLookupLib objects). The SymbolLookupList is reused for each DSO in a load group. (-Bsymbolic is accommodated by modifying the SymbolLookupLib at the front of the list.) To search for a symbol, soinfo_do_lookup_impl has a small loop that first scans a vector of GNU bloom filters looking for a possible match. There was a slight improvement from templatizing soinfo_do_lookup_impl and skipping the does-this-DSO-lack-GNU-hash check. Rewrite the relocation processing loop to be faster. There are specialized functions that handle the expected relocation types in normal relocation sections and in PLT relocation sections. This CL can reduce the initial link time of large programs by around 40-50% (e.g. audioserver, cameraserver, etc). On the linker relocation benchmark (64-bit walleye), it reduces the time from 131.6ms to 71.9ms. Bug: http://b/143577578 (incidentally fixed by this CL) Test: bionic-unit-tests Change-Id: If40a42fb6ff566570f7280b71d58f7fa290b9343
2020-01-10Merge changes I578d36a1,Id17508ab,I385f312bRyan Prichard
* changes: Create linker_log[_va_list] functions Validate defined versions in prelink_image Prelink each library only once
2020-01-07Merge "Do not add duplicate soinfos to g_default_namespace"Ryan Prichard
2020-01-06Validate defined versions in prelink_imageRyan Prichard
Validate the list of defined versions explicitly, during library prelinking, rather than implicitly as part of constructing the VersionTracker in soinfo::link_image. Doing the validation upfront allows removing the symbol lookup failure code paths, which only happen on a library with invalid version information. Helps on the walleye 64-bit linker relocation benchmark (146.2ms -> 131.6ms) Bug: none Test: bionic unit tests Change-Id: Id17508aba3af2863909f0526897c4277419322b7
2020-01-02Prelink each library only onceRyan Prichard
Previously, during a find_libraries call that loaded a library, a library was prelinked once for each DT_NEEDED reference to the library. This CL has a negligible effect on the linker relocation benchmark (146.9ms -> 146.2ms). Bug: none Test: bionic unit tests Change-Id: I385f312b8acf8d35aa0af9722131fe367b5edd9b
2019-12-27Do not add duplicate soinfos to g_default_namespaceNIEJuhu
The soinfo instances of linker and vdso have been added to g_default_namespace before init_default_namespace() is called. So init_default_namespace() don't have to add them a second time. Test: manual Change-Id: I29b3da782b1e9445509f45a7698561fc3e19e9a1
2019-12-20Stop using the __ANDROID_API_x__ constants.Elliott Hughes
Historically we've made a few mistakes where they haven't matched the right number. And most non-Googlers are much more familiar with the numbers, so it seems to make sense to rely more on them. Especially in header files, which we actually expect real people to have to read from time to time. Test: treehugger Change-Id: I0d4a97454ee108de1d32f21df285315c5488d886
2019-12-17Do not DL_WARN when failed to find generated linker configKiyoung Kim
DL_WARN message when failed to find generated linker config makes some of the ART tests fail. Lowering log level as ART test does not have linkerconfig generated for the test. Bug: 146386369 Test: Cuttlefish boot succeeded without any error Test: run_build_test_target.py art-linux-bionic-x64-zipapex passed Change-Id: I4f876c3ac5c30d32d51346d4cd16b5205da8f1bf
2019-12-16Prefer arch-specific linker config when availableEvgeny Eltsin
New linker configuration from /linkerconfig is not suitbale for emulated architectures. But as of now, native_bridge linkers pick it up as well and thus fail to find the libraries for emulated architectures. This is a (temporary) fix so native_bridge linker still picks up configuration from old location. Bug: 138920271 Test: native_bridge linker works Change-Id: I0abbd3e95f9e6830385b0f19db0688e6183030b9
2019-12-13Enable linker configuration from generator by defaultKiyoung Kim
Current linker configuration is only enabled from fully treblelized devices. This change will allow linker to first check generated linker configuration even for non-treblelized devices and recovery. Bug: 139638519 Test: Tested from cuttlefish Change-Id: I655b1ab807cd8db5696d07fd2bdd00ce0558901d
2019-12-05Move linker config under /linkerconfigKiyoung Kim
Due to some special environment, linker config should not be located under /dev partition. It would be better to relocate linker config under new root dir /linkerconfig. Bug: 144966380 Test: m -j && tested from cuttlefish Change-Id: Icda1d2ef34b42159c6ebce58b03211cc13f08121
2019-11-09Merge "linker: add more context to link failure error."Treehugger Robot
2019-11-05linker: add more context to link failure error.Josh Gao
This change makes it easier to diagnose mistakes in linker configuration that result in a library being accidentally loaded in multiple namespaces without its dependencies available everywhere. Test: manually tested the error message Test: bionic-unit-tests Change-Id: I03a20507f8fc902c2445a7fbbf59767ffffd5ebf
2019-11-05Use ifuncs in the linkerRyan Prichard
Using ifuncs allows the linker to select faster versions of libc functions like strcmp, making linking faster. The linker continues to first initialize TLS, then call the ifunc resolvers. There are small amounts of code in Bionic that need to avoid calling functions selected using ifuncs (generally string.h APIs). I've tried to compile those pieces with -ffreestanding. Maybe it's unnecessary, but maybe it could help avoid compiler-inserted memset calls, and maybe it will be useful later on. The ifuncs are called in a special early pass using special __rel[a]_iplt_start / __rel[a]_iplt_end symbols. The linker will encounter the ifuncs again as R_*_IRELATIVE dynamic relocations, so they're skipped on the second pass. Break linker_main.cpp into its own liblinker_main library so it can be compiled with -ffreestanding. On walleye, this change fixes a recent 2.3% linker64 start-up time regression (156.6ms -> 160.2ms), but it also helps the 32-bit time by about 1.9% on the same benchmark. I'm measuring the run-time using a synthetic benchmark based on loading libandroid_servers.so. Test: bionic unit tests, manual benchmarking Bug: none Merged-In: Ieb9446c2df13a66fc0d377596756becad0af6995 Change-Id: Ieb9446c2df13a66fc0d377596756becad0af6995 (cherry picked from commit 772bcbb0c2f7a87b18021849528240ef0c617d94)
2019-10-30Merge "linker: remove COUNT_PAGES"Ryan Prichard
2019-10-29Merge "Revert "Load /dev/linker/ld.config.txt by default""Treehugger Robot
2019-10-29Revert "Load /dev/linker/ld.config.txt by default"Roland Levillain
This reverts commit 61a97e95052a4ff22c7d2315f00cb3f0a5bce99e. Reason for revert: Breaks ART run-tests (b/143458513). Test: Run ART tests on device in a chroot environment Bug: 143458513 Bug: 139638519 Change-Id: Ib047a24d6e82e38ebdaafeab294b8be44b74bd9c
2019-10-28Adopt GNU calling convention for ifunc resolvers.Peter Collingbourne
In order for an ifunc resolver to detect the presence of certain CPU features, access to getauxval(AT_HWCAP) or getauxval(AT_HWCAP2) may be required. In order for getauxval() to work, it needs to access the pointer to the auxiliary vector stored by the linker in the libc shared globals data structure. Accessing the shared globals requires libc to call the __libc_shared_globals() function exported by the linker. However, in order to call this function, libc must be fully relocated, which is not guaranteed to be the case at the point when ifunc resolvers are called. glibc solves this problem by passing the values of getauxval(AT_HWCAP) (and getauxval(AT_HWCAP2) on aarch64) as arguments to the ifunc resolver. Since this seems to be not only the most straightforward way to solve the problem but also improves our compatibility with glibc, we adopt their calling convention. This change is ABI compatible with old resolvers because the arguments are passed in registers, so the old resolvers will simply ignore the new arguments. Bug: 135772972 Change-Id: Ie65bd6e7067f0c878df3d348c815fda61dc12de2
2019-10-25linker: remove COUNT_PAGESRyan Prichard
COUNT_PAGES tries to count the pages dirtied by relocations, but this implementation is broken because it's merging rel->r_offset values from multiple DSOs. The functionality is hard to use, because it requires rebuilding the linker, and it's not obvious to me that it should belong in the linker. If we do want it, we should make it work without rebuilding the linker. Similar information can currently be collected by parsing the result of `readelf -r` on a binary (or a set of binaries). Bug: none Test: m linker libc com.android.runtime ; adb sync ; run something Change-Id: I760fb6ea4ea3d1927eb5145cdf4ca133851d69b4