058eb8fa4e
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
23 lines
586 B
C++
23 lines
586 B
C++
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
|
|
// Mark foo and bar weak so that Clang allows the run-time linker to decide which DSO's symbol to
|
|
// use.
|
|
|
|
__attribute__((weak)) extern "C" void foo() {
|
|
printf("foo lib3\n");
|
|
void (*next)(void) = reinterpret_cast<void (*)()>(dlsym(RTLD_NEXT, "foo"));
|
|
if (next != nullptr) next();
|
|
}
|
|
|
|
__attribute__((weak)) extern "C" void bar() {
|
|
printf("bar lib3\n");
|
|
void (*next)(void) = reinterpret_cast<void (*)()>(dlsym(RTLD_NEXT, "bar"));
|
|
if (next != nullptr) next();
|
|
}
|
|
|
|
void lib3_call_funcs() {
|
|
printf("lib3_call_funcs\n");
|
|
foo();
|
|
bar();
|
|
}
|