Merge "Always process TLS relocs using general code path"

This commit is contained in:
Ryan Prichard 2022-03-28 19:19:12 +00:00 committed by Gerrit Code Review
commit df41909cf6
8 changed files with 84 additions and 2 deletions

View File

@ -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;

View File

@ -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",

View File

@ -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.

View File

@ -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.