platform_bionic/tests/libs/ld_config_test_helper.cpp
Ryan Prichard 058eb8fa4e Ensure same order of global group members in all NS's
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-22 03:27:43 -08:00

55 lines
1.4 KiB
C++

/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#if __has_include(<sys/auxv.h>)
#include <sys/auxv.h>
#endif
#include <unistd.h>
extern "C" void foo();
void lib1_call_funcs();
__attribute__((weak)) void lib3_call_funcs();
int main() {
bool skip_vdso_check = false;
#if __has_include(<sys/auxv.h>)
if (getauxval(AT_SYSINFO_EHDR) == 0) {
skip_vdso_check = true;
}
#endif
if (!skip_vdso_check) {
const char* vdso_name = "linux-vdso.so.1";
#if defined(__i386__)
vdso_name = "linux-gate.so.1";
#endif
void* handle = dlopen(vdso_name, RTLD_NOW);
if (handle == nullptr) {
printf("%s", dlerror());
return 1;
}
dlclose(handle);
}
foo();
lib1_call_funcs();
if (lib3_call_funcs) lib3_call_funcs();
return 0;
}