Merge "Always process TLS relocs using general code path"
This commit is contained in:
commit
df41909cf6
|
@ -229,6 +229,12 @@ static bool process_relocation_impl(Relocator& relocator, const rel_t& reloc) {
|
|||
auto get_addend_norel = [&]() -> ElfW(Addr) { return 0; };
|
||||
#endif
|
||||
|
||||
if (!IsGeneral && __predict_false(is_tls_reloc(r_type))) {
|
||||
// Always process TLS relocations using the slow code path, so that STB_LOCAL symbols are
|
||||
// diagnosed, and ifunc processing is skipped.
|
||||
return process_relocation_general(relocator, reloc);
|
||||
}
|
||||
|
||||
if (IsGeneral && is_tls_reloc(r_type)) {
|
||||
if (r_sym == 0) {
|
||||
// By convention in ld.bfd and lld, an omitted symbol on a TLS relocation
|
||||
|
@ -242,8 +248,15 @@ static bool process_relocation_impl(Relocator& relocator, const rel_t& reloc) {
|
|||
// - https://groups.google.com/d/topic/generic-abi/dJ4_Y78aQ2M/discussion
|
||||
// - https://sourceware.org/bugzilla/show_bug.cgi?id=17699
|
||||
sym = &relocator.si_symtab[r_sym];
|
||||
DL_ERR("unexpected TLS reference to local symbol \"%s\" in \"%s\": sym type %d, rel type %u",
|
||||
sym_name, relocator.si->get_realpath(), ELF_ST_TYPE(sym->st_info), r_type);
|
||||
auto sym_type = ELF_ST_TYPE(sym->st_info);
|
||||
if (sym_type == STT_SECTION) {
|
||||
DL_ERR("unexpected TLS reference to local section in \"%s\": sym type %d, rel type %u",
|
||||
relocator.si->get_realpath(), sym_type, r_type);
|
||||
} else {
|
||||
DL_ERR(
|
||||
"unexpected TLS reference to local symbol \"%s\" in \"%s\": sym type %d, rel type %u",
|
||||
sym_name, relocator.si->get_realpath(), sym_type, r_type);
|
||||
}
|
||||
return false;
|
||||
} else if (!lookup_symbol<IsGeneral>(relocator, r_sym, sym_name, &found_in, &sym)) {
|
||||
return false;
|
||||
|
|
|
@ -295,6 +295,29 @@ cc_prebuilt_test_library_shared {
|
|||
},
|
||||
}
|
||||
|
||||
cc_prebuilt_test_library_shared {
|
||||
name: "libtest_invalid-local-tls",
|
||||
strip: {
|
||||
none: true,
|
||||
},
|
||||
check_elf_files: false,
|
||||
relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
|
||||
arch: {
|
||||
arm: {
|
||||
srcs: ["prebuilt-elf-files/arm/libtest_invalid-local-tls.so"],
|
||||
},
|
||||
arm64: {
|
||||
srcs: ["prebuilt-elf-files/arm64/libtest_invalid-local-tls.so"],
|
||||
},
|
||||
x86: {
|
||||
srcs: ["prebuilt-elf-files/x86/libtest_invalid-local-tls.so"],
|
||||
},
|
||||
x86_64: {
|
||||
srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// All standard tests.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -994,6 +1017,7 @@ cc_defaults {
|
|||
"libtest_init_fini_order_root",
|
||||
"libtest_init_fini_order_root2",
|
||||
"libtest_invalid-empty_shdr_table",
|
||||
"libtest_invalid-local-tls",
|
||||
"libtest_invalid-rw_load_segment",
|
||||
"libtest_invalid-textrels",
|
||||
"libtest_invalid-textrels2",
|
||||
|
|
|
@ -1654,6 +1654,21 @@ TEST(dlfcn, dlopen_invalid_textrels2) {
|
|||
ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
|
||||
}
|
||||
|
||||
TEST(dlfcn, dlopen_invalid_local_tls) {
|
||||
const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-local-tls.so";
|
||||
|
||||
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
|
||||
ASSERT_TRUE(handle == nullptr);
|
||||
#if defined(__arm__)
|
||||
const char* referent = "local section";
|
||||
#else
|
||||
const char* referent = "local symbol \"tls_var_2\"";
|
||||
#endif
|
||||
std::string expected_dlerror = std::string("dlopen failed: unexpected TLS reference to ") +
|
||||
referent + " in \"" + libpath + "\"";
|
||||
ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
|
||||
}
|
||||
|
||||
TEST(dlfcn, dlopen_df_1_global) {
|
||||
void* handle = dlopen("libtest_dlopen_df_1_global.so", RTLD_NOW);
|
||||
ASSERT_TRUE(handle != nullptr) << dlerror();
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Bionic doesn't support the references to STB_LOCAL symbols of type STT_TLS
|
||||
# and STT_SECTION that ld.gold generates. Set NDK21E to the path to a copy of
|
||||
# NDK r21e, which still has ld.gold (unlike the platform build or newer NDKs).
|
||||
|
||||
set -e
|
||||
|
||||
cat >test.c <<EOF
|
||||
static __thread int tls_var_1;
|
||||
extern __thread int tls_var_2;
|
||||
int* getaddr1() { return &tls_var_1; }
|
||||
int* getaddr2() { return &tls_var_2; }
|
||||
EOF
|
||||
cat >test2.c <<EOF
|
||||
__attribute__((visibility("hidden"))) __thread int tls_var_2;
|
||||
EOF
|
||||
|
||||
build() {
|
||||
arch=$1
|
||||
target=$2
|
||||
$NDK21E/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -O2 --target=$target \
|
||||
-fpic -shared -o $arch/libtest_invalid-local-tls.so -fno-emulated-tls \
|
||||
-fuse-ld=gold test.c test2.c
|
||||
}
|
||||
|
||||
build arm armv7a-linux-androideabi29
|
||||
build arm64 aarch64-linux-android29
|
||||
build x86 i686-linux-android29
|
||||
build x86_64 x86_64-linux-android29
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue