Merge "Add test for elf-hash and packed relocations"

This commit is contained in:
Dimitry Ivanov 2016-12-15 18:27:22 +00:00 committed by Gerrit Code Review
commit 59dd61573f
3 changed files with 102 additions and 2 deletions

View file

@ -21,6 +21,7 @@ cc_library {
arch: {
arm: {
version_script: "libdl.arm.map",
ldflags: ["-Wl,--hash-style=both"],
},
arm64: {
version_script: "libdl.arm64.map",
@ -32,7 +33,10 @@ cc_library {
version_script: "libdl.mips64.map",
},
x86: {
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
ldflags: [
"-Wl,--exclude-libs=libgcc_eh.a",
"-Wl,--hash-style=both",
],
version_script: "libdl.x86.map",
},
x86_64: {

View file

@ -273,7 +273,7 @@ cc_test_library {
cc_test_library {
name: "libBionicLoaderTests",
defaults: ["bionic_tests_defaults"],
defaults: ["bionic_tests_defaults", "llvm-defaults"],
srcs: [
"atexit_test.cpp",
"dl_test.cpp",
@ -298,6 +298,12 @@ cc_test_library {
],
static_libs: [
"libpagemap",
"libLLVMObject",
"libLLVMBitReader",
"libLLVMMC",
"libLLVMMCParser",
"libLLVMCore",
"libLLVMSupport",
],
}
}
@ -373,6 +379,12 @@ cc_defaults {
"libziparchive",
"libz",
"libutils",
"libLLVMObject",
"libLLVMBitReader",
"libLLVMMC",
"libLLVMMCParser",
"libLLVMCore",
"libLLVMSupport",
],
ldflags: [
"-Wl,--rpath,${ORIGIN}/../bionic-loader-test-libs",

View file

@ -31,6 +31,18 @@
#include "dlfcn_symlink_support.h"
#include "utils.h"
#if defined(__BIONIC__) && (defined(__arm__) || defined(__i386__))
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#include <llvm/ADT/StringRef.h>
#include <llvm/Object/Binary.h>
#include <llvm/Object/ELFObjectFile.h>
#include <llvm/Object/ObjectFile.h>
#pragma clang diagnostic pop
#endif // defined(__ANDROID__) && (defined(__arm__) || defined(__i386__))
#define ASSERT_SUBSTR(needle, haystack) \
ASSERT_PRED_FORMAT2(::testing::IsSubstring, needle, haystack)
@ -1184,6 +1196,78 @@ TEST(dlfcn, dt_runpath_smoke) {
// Bionic specific tests
#if defined(__BIONIC__)
#if defined(__arm__) || defined(__i386__)
const llvm::ELF::Elf32_Dyn* to_dynamic_table(const char* p) {
return reinterpret_cast<const llvm::ELF::Elf32_Dyn*>(p);
}
// Duplicate these definitions here because they are android specific
// note that we cannot include <elf.h> because #defines conflict with
// enum names provided by LLVM.
#define DT_ANDROID_REL (llvm::ELF::DT_LOOS + 2)
#define DT_ANDROID_RELA (llvm::ELF::DT_LOOS + 4)
template<typename ELFT>
void validate_compatibility_of_native_library(const std::string& path, ELFT* elf) {
bool has_elf_hash = false;
bool has_android_rel = false;
bool has_rel = false;
// Find dynamic section and check that DT_HASH and there is no DT_ANDROID_REL
for (auto it = elf->section_begin(); it != elf->section_end(); ++it) {
const llvm::object::ELFSectionRef& section_ref = *it;
if (section_ref.getType() == llvm::ELF::SHT_DYNAMIC) {
llvm::StringRef data;
ASSERT_TRUE(!it->getContents(data)) << "unable to get SHT_DYNAMIC section data";
for (auto d = to_dynamic_table(data.data()); d->d_tag != llvm::ELF::DT_NULL; ++d) {
if (d->d_tag == llvm::ELF::DT_HASH) {
has_elf_hash = true;
} else if (d->d_tag == DT_ANDROID_REL || d->d_tag == DT_ANDROID_RELA) {
has_android_rel = true;
} else if (d->d_tag == llvm::ELF::DT_REL || d->d_tag == llvm::ELF::DT_RELA) {
has_rel = true;
}
}
break;
}
}
ASSERT_TRUE(has_elf_hash) << path.c_str() << ": missing elf hash (DT_HASH)";
ASSERT_TRUE(!has_android_rel) << path.c_str() << ": has packed relocations";
ASSERT_TRUE(has_rel) << path.c_str() << ": missing DT_REL/DT_RELA";
}
void validate_compatibility_of_native_library(const char* soname) {
std::string path = std::string(PATH_TO_SYSTEM_LIB) + soname;
auto binary_or_error = llvm::object::createBinary(path);
ASSERT_FALSE(!binary_or_error);
llvm::object::Binary* binary = binary_or_error.get().getBinary();
auto obj = llvm::dyn_cast<llvm::object::ObjectFile>(binary);
ASSERT_TRUE(obj != nullptr);
auto elf = llvm::dyn_cast<llvm::object::ELF32LEObjectFile>(obj);
ASSERT_TRUE(elf != nullptr);
validate_compatibility_of_native_library(path, elf);
}
// This is a test for app compatibility workaround for arm and x86 apps
// affected by http://b/24465209
TEST(dlext, compat_elf_hash_and_relocation_tables) {
validate_compatibility_of_native_library("libc.so");
validate_compatibility_of_native_library("liblog.so");
validate_compatibility_of_native_library("libstdc++.so");
validate_compatibility_of_native_library("libdl.so");
validate_compatibility_of_native_library("libm.so");
validate_compatibility_of_native_library("libz.so");
validate_compatibility_of_native_library("libjnigraphics.so");
}
#endif // defined(__arm__) || defined(__i386__)
TEST(dlfcn, dt_runpath_absolute_path) {
std::string libpath = get_testlib_root() + "/libtest_dt_runpath_d.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);