summaryrefslogtreecommitdiff
path: root/libunwindstack/tests/ElfInterfaceTest.cpp
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2019-10-03 13:35:48 -0700
committerChristopher Ferris <cferris@google.com>2019-10-08 17:36:06 +0000
commit819f13116e25c2724a7daeed9afb3adb2d027f5b (patch)
tree85e5d2e80bb63bf0bdaef49823079b9323268572 /libunwindstack/tests/ElfInterfaceTest.cpp
parent6c1668d6600da00aefabd245430d68c395e4b207 (diff)
Handle when bias is different in elf headers.
The original code assumed that the load bias in the program headers would be exactly the same as in eh_frame/eh_frame_hdr/debug_frame. This isn't guaranteed, so add a section bias for use when creating a DwarfSection. In addtion, make the load bias and section bias a signed value. There is no reason that this value needs to be positive, so don't force it to be. Add a new offline test that has a different load bias in eh_frame than in the executable load. Add additional unit tests to verify the load bias values are set properly. Clean up the tests in ElfInterfaceTest, making all tests names follow the same convention. Bug: 141888859 Bug: 142094469 Test: New units and old unit tests pass on host and taimen. Change-Id: Ib878123ab5545f0f315c749cfe0d27b012d873ee
Diffstat (limited to 'libunwindstack/tests/ElfInterfaceTest.cpp')
-rw-r--r--libunwindstack/tests/ElfInterfaceTest.cpp615
1 files changed, 470 insertions, 145 deletions
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp
index 5b2036bdb..b048b178f 100644
--- a/libunwindstack/tests/ElfInterfaceTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceTest.cpp
@@ -112,6 +112,21 @@ class ElfInterfaceTest : public ::testing::Test {
template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
void InitSectionHeadersOffsets();
+ template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
+ void InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
+ int64_t expected_bias);
+
+ template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
+ void InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr, uint64_t offset,
+ int64_t expected_bias);
+
+ template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
+ void InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr, uint64_t offset,
+ int64_t expected_bias);
+
+ template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
+ void CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias);
+
template <typename Sym>
void InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
uint64_t sym_offset, const char* name);
@@ -132,10 +147,10 @@ class ElfInterfaceTest : public ::testing::Test {
void BuildIDSectionTooSmallForHeader();
template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
- void CheckLoadBiasInFirstPhdr(uint64_t load_bias);
+ void CheckLoadBiasInFirstPhdr(int64_t load_bias);
template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
- void CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr, uint64_t load_bias);
+ void CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr, int64_t load_bias);
MemoryFake memory_;
};
@@ -172,9 +187,9 @@ void ElfInterfaceTest::SinglePtLoad() {
phdr.p_align = 0x1000;
memory_.SetMemory(0x100, &phdr, sizeof(phdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0x2000U, load_bias);
+ EXPECT_EQ(0x2000, load_bias);
const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
ASSERT_EQ(1U, pt_loads.size());
@@ -184,11 +199,11 @@ void ElfInterfaceTest::SinglePtLoad() {
ASSERT_EQ(0x10000U, load_data.table_size);
}
-TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
+TEST_F(ElfInterfaceTest, single_pt_load_32) {
SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
+TEST_F(ElfInterfaceTest, single_pt_load_64) {
SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
}
@@ -228,9 +243,9 @@ void ElfInterfaceTest::MultipleExecutablePtLoads() {
phdr.p_align = 0x1002;
memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0x2000U, load_bias);
+ EXPECT_EQ(0x2000, load_bias);
const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
ASSERT_EQ(3U, pt_loads.size());
@@ -251,11 +266,11 @@ void ElfInterfaceTest::MultipleExecutablePtLoads() {
ASSERT_EQ(0x10002U, load_data.table_size);
}
-TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
+TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_32) {
MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
+TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_64) {
MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
}
@@ -295,9 +310,9 @@ void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
phdr.p_align = 0x1002;
memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0x2000U, load_bias);
+ EXPECT_EQ(0x2000, load_bias);
const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
ASSERT_EQ(3U, pt_loads.size());
@@ -318,12 +333,12 @@ void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
ASSERT_EQ(0x10002U, load_data.table_size);
}
-TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
+TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_32) {
MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
+TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_64) {
MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
ElfInterface64>();
}
@@ -364,9 +379,9 @@ void ElfInterfaceTest::NonExecutablePtLoads() {
phdr.p_align = 0x1002;
memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0x1001U, load_bias);
+ EXPECT_EQ(0x1001, load_bias);
const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
ASSERT_EQ(1U, pt_loads.size());
@@ -377,11 +392,11 @@ void ElfInterfaceTest::NonExecutablePtLoads() {
ASSERT_EQ(0x10001U, load_data.table_size);
}
-TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
+TEST_F(ElfInterfaceTest, non_executable_pt_loads_32) {
NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
+TEST_F(ElfInterfaceTest, non_executable_pt_loads_64) {
NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
}
@@ -434,11 +449,10 @@ void ElfInterfaceTest::ManyPhdrs() {
memset(&phdr, 0, sizeof(phdr));
phdr.p_type = PT_GNU_EH_FRAME;
memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
- phdr_offset += sizeof(phdr);
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0x2000U, load_bias);
+ EXPECT_EQ(0x2000, load_bias);
const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
ASSERT_EQ(1U, pt_loads.size());
@@ -449,15 +463,15 @@ void ElfInterfaceTest::ManyPhdrs() {
ASSERT_EQ(0x10000U, load_data.table_size);
}
-TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
+TEST_F(ElfInterfaceTest, many_phdrs_32) {
ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
+TEST_F(ElfInterfaceTest, many_phdrs_64) {
ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
}
-TEST_F(ElfInterfaceTest, elf32_arm) {
+TEST_F(ElfInterfaceTest, arm32) {
ElfInterfaceArm elf_arm(&memory_);
Elf32_Ehdr ehdr = {};
@@ -476,9 +490,9 @@ TEST_F(ElfInterfaceTest, elf32_arm) {
memory_.SetData32(0x2000, 0x1000);
memory_.SetData32(0x2008, 0x1000);
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf_arm.Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
std::vector<uint32_t> entries;
for (auto addr : elf_arm) {
@@ -557,19 +571,19 @@ template <typename ElfInterfaceType>
void ElfInterfaceTest::Soname() {
std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
ASSERT_EQ("fake_soname.so", elf->GetSoname());
}
-TEST_F(ElfInterfaceTest, elf32_soname) {
+TEST_F(ElfInterfaceTest, soname_32) {
SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
Soname<ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_soname) {
+TEST_F(ElfInterfaceTest, soname_64) {
SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
Soname<ElfInterface64>();
}
@@ -578,19 +592,19 @@ template <typename ElfInterfaceType>
void ElfInterfaceTest::SonameAfterDtNull() {
std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
ASSERT_EQ("", elf->GetSoname());
}
-TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
+TEST_F(ElfInterfaceTest, soname_after_dt_null_32) {
SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
SonameAfterDtNull<ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
+TEST_F(ElfInterfaceTest, soname_after_dt_null_64) {
SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
SonameAfterDtNull<ElfInterface64>();
}
@@ -599,19 +613,19 @@ template <typename ElfInterfaceType>
void ElfInterfaceTest::SonameSize() {
std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
ASSERT_EQ("", elf->GetSoname());
}
-TEST_F(ElfInterfaceTest, elf32_soname_size) {
+TEST_F(ElfInterfaceTest, soname_size_32) {
SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
SonameSize<ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_soname_size) {
+TEST_F(ElfInterfaceTest, soname_size_64) {
SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
SonameSize<ElfInterface64>();
}
@@ -622,19 +636,19 @@ template <typename ElfInterfaceType>
void ElfInterfaceTest::SonameMissingMap() {
std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
ASSERT_EQ("", elf->GetSoname());
}
-TEST_F(ElfInterfaceTest, elf32_soname_missing_map) {
+TEST_F(ElfInterfaceTest, soname_missing_map_32) {
SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
SonameMissingMap<ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, elf64_soname_missing_map) {
+TEST_F(ElfInterfaceTest, soname_missing_map_64) {
SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
SonameMissingMap<ElfInterface64>();
}
@@ -653,17 +667,17 @@ void ElfInterfaceTest::InitHeadersEhFrameTest() {
memory_.SetData32(0x10004, 0x500);
memory_.SetData32(0x10008, 250);
- elf.InitHeaders(0);
+ elf.InitHeaders();
EXPECT_FALSE(elf.eh_frame() == nullptr);
EXPECT_TRUE(elf.debug_frame() == nullptr);
}
-TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
+TEST_F(ElfInterfaceTest, init_headers_eh_frame_32) {
InitHeadersEhFrameTest<ElfInterface32Fake>();
}
-TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
+TEST_F(ElfInterfaceTest, init_headers_eh_frame_64) {
InitHeadersEhFrameTest<ElfInterface64Fake>();
}
@@ -685,17 +699,17 @@ void ElfInterfaceTest::InitHeadersDebugFrame() {
memory_.SetData32(0x5108, 0x1500);
memory_.SetData32(0x510c, 0x200);
- elf.InitHeaders(0);
+ elf.InitHeaders();
EXPECT_TRUE(elf.eh_frame() == nullptr);
EXPECT_FALSE(elf.debug_frame() == nullptr);
}
-TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
+TEST_F(ElfInterfaceTest, init_headers_debug_frame_32) {
InitHeadersDebugFrame<ElfInterface32Fake>();
}
-TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
+TEST_F(ElfInterfaceTest, init_headers_debug_frame_64) {
InitHeadersDebugFrame<ElfInterface64Fake>();
}
@@ -709,16 +723,16 @@ void ElfInterfaceTest::InitProgramHeadersMalformed() {
ehdr.e_phentsize = sizeof(Phdr);
memory_.SetMemory(0, &ehdr, sizeof(ehdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
}
-TEST_F(ElfInterfaceTest, init_program_headers_malformed32) {
+TEST_F(ElfInterfaceTest, init_program_headers_malformed_32) {
InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, init_program_headers_malformed64) {
+TEST_F(ElfInterfaceTest, init_program_headers_malformed_64) {
InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
}
@@ -732,16 +746,16 @@ void ElfInterfaceTest::InitSectionHeadersMalformed() {
ehdr.e_shentsize = sizeof(Shdr);
memory_.SetMemory(0, &ehdr, sizeof(ehdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
}
-TEST_F(ElfInterfaceTest, init_section_headers_malformed32) {
+TEST_F(ElfInterfaceTest, init_section_headers_malformed_32) {
InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, init_section_headers_malformed64) {
+TEST_F(ElfInterfaceTest, init_section_headers_malformed_64) {
InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
}
@@ -796,11 +810,10 @@ void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
EXPECT_EQ(0U, elf->debug_frame_offset());
EXPECT_EQ(0U, elf->debug_frame_size());
EXPECT_EQ(0U, elf->gnu_debugdata_offset());
@@ -811,11 +824,11 @@ void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
}
-TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata32) {
+TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_32) {
InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata64) {
+TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_64) {
InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
}
@@ -866,14 +879,13 @@ void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
EXPECT_EQ(0U, elf->debug_frame_offset());
EXPECT_EQ(0U, elf->debug_frame_size());
EXPECT_EQ(0U, elf->gnu_debugdata_offset());
@@ -890,19 +902,19 @@ void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
EXPECT_EQ(32U, name_offset);
}
-TEST_F(ElfInterfaceTest, init_section_headers32) {
+TEST_F(ElfInterfaceTest, init_section_headers_32) {
InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
}
-TEST_F(ElfInterfaceTest, init_section_headers64) {
+TEST_F(ElfInterfaceTest, init_section_headers_64) {
InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
}
-TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size32) {
+TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_32) {
InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
}
-TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size64) {
+TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_64) {
InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
}
@@ -967,7 +979,7 @@ void ElfInterfaceTest::InitSectionHeadersOffsets() {
shdr.sh_type = SHT_PROGBITS;
shdr.sh_link = 2;
shdr.sh_name = 0x400;
- shdr.sh_addr = 0x6000;
+ shdr.sh_addr = 0xa000;
shdr.sh_offset = 0xa000;
shdr.sh_entsize = 0x100;
shdr.sh_size = 0xf00;
@@ -977,10 +989,10 @@ void ElfInterfaceTest::InitSectionHeadersOffsets() {
memset(&shdr, 0, sizeof(shdr));
shdr.sh_type = SHT_NOTE;
shdr.sh_name = 0x500;
+ shdr.sh_addr = 0xb000;
shdr.sh_offset = 0xb000;
shdr.sh_size = 0xf00;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
@@ -988,29 +1000,352 @@ void ElfInterfaceTest::InitSectionHeadersOffsets() {
memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
EXPECT_EQ(0x6000U, elf->debug_frame_offset());
+ EXPECT_EQ(0, elf->debug_frame_section_bias());
EXPECT_EQ(0x500U, elf->debug_frame_size());
+
EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
+
EXPECT_EQ(0x7000U, elf->eh_frame_offset());
+ EXPECT_EQ(0, elf->eh_frame_section_bias());
EXPECT_EQ(0x800U, elf->eh_frame_size());
+
EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
+ EXPECT_EQ(0, elf->eh_frame_hdr_section_bias());
EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
+
EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
}
-TEST_F(ElfInterfaceTest, init_section_headers_offsets32) {
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_32) {
InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, init_section_headers_offsets64) {
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_64) {
InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
}
+template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
+void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
+ int64_t expected_bias) {
+ std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
+
+ uint64_t elf_offset = 0x2000;
+
+ Ehdr ehdr = {};
+ ehdr.e_shoff = elf_offset;
+ ehdr.e_shnum = 4;
+ ehdr.e_shentsize = sizeof(Shdr);
+ ehdr.e_shstrndx = 2;
+ memory_.SetMemory(0, &ehdr, sizeof(ehdr));
+
+ elf_offset += ehdr.e_shentsize;
+
+ Shdr shdr = {};
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_link = 2;
+ shdr.sh_name = 0x200;
+ shdr.sh_addr = 0x8000;
+ shdr.sh_offset = 0x8000;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x800;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+ elf_offset += ehdr.e_shentsize;
+
+ // The string data for section header names.
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_name = 0x20000;
+ shdr.sh_offset = 0xf000;
+ shdr.sh_size = 0x1000;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+ elf_offset += ehdr.e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_link = 2;
+ shdr.sh_name = 0x100;
+ shdr.sh_addr = addr;
+ shdr.sh_offset = offset;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x500;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+
+ memory_.SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
+ memory_.SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
+
+ int64_t load_bias = 0;
+ ASSERT_TRUE(elf->Init(&load_bias));
+ EXPECT_EQ(0, load_bias);
+ EXPECT_EQ(offset, elf->eh_frame_offset());
+ EXPECT_EQ(expected_bias, elf->eh_frame_section_bias());
+ EXPECT_EQ(0x500U, elf->eh_frame_size());
+
+ EXPECT_EQ(0x8000U, elf->eh_frame_hdr_offset());
+ EXPECT_EQ(0, elf->eh_frame_hdr_section_bias());
+ EXPECT_EQ(0x800U, elf->eh_frame_hdr_size());
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_32) {
+ InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x4000,
+ 0x4000, 0);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_64) {
+ InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0x6000,
+ 0x6000, 0);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_32) {
+ InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
+ 0x5000, 0x4000, 0x1000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_64) {
+ InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
+ 0x6000, 0x4000, 0x2000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_32) {
+ InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
+ 0x3000, 0x4000, -0x1000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_64) {
+ InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
+ 0x6000, 0x9000, -0x3000);
+}
+
+template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
+void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr,
+ uint64_t offset,
+ int64_t expected_bias) {
+ std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
+
+ uint64_t elf_offset = 0x2000;
+
+ Ehdr ehdr = {};
+ ehdr.e_shoff = elf_offset;
+ ehdr.e_shnum = 4;
+ ehdr.e_shentsize = sizeof(Shdr);
+ ehdr.e_shstrndx = 2;
+ memory_.SetMemory(0, &ehdr, sizeof(ehdr));
+
+ elf_offset += ehdr.e_shentsize;
+
+ Shdr shdr = {};
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_link = 2;
+ shdr.sh_name = 0x200;
+ shdr.sh_addr = addr;
+ shdr.sh_offset = offset;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x800;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+ elf_offset += ehdr.e_shentsize;
+
+ // The string data for section header names.
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_name = 0x20000;
+ shdr.sh_offset = 0xf000;
+ shdr.sh_size = 0x1000;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+ elf_offset += ehdr.e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_link = 2;
+ shdr.sh_name = 0x100;
+ shdr.sh_addr = 0x5000;
+ shdr.sh_offset = 0x5000;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x500;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+
+ memory_.SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
+ memory_.SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
+
+ int64_t load_bias = 0;
+ ASSERT_TRUE(elf->Init(&load_bias));
+ EXPECT_EQ(0, load_bias);
+ EXPECT_EQ(0x5000U, elf->eh_frame_offset());
+ EXPECT_EQ(0, elf->eh_frame_section_bias());
+ EXPECT_EQ(0x500U, elf->eh_frame_size());
+ EXPECT_EQ(offset, elf->eh_frame_hdr_offset());
+ EXPECT_EQ(expected_bias, elf->eh_frame_hdr_section_bias());
+ EXPECT_EQ(0x800U, elf->eh_frame_hdr_size());
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_32) {
+ InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x9000,
+ 0x9000, 0);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_64) {
+ InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
+ 0xa000, 0);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_32) {
+ InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
+ 0x9000, 0x4000, 0x5000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_64) {
+ InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
+ 0x6000, 0x1000, 0x5000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_32) {
+ InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
+ 0x3000, 0x5000, -0x2000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_64) {
+ InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
+ 0x5000, 0x9000, -0x4000);
+}
+
+template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
+void ElfInterfaceTest::InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr,
+ uint64_t offset,
+ int64_t expected_bias) {
+ std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
+
+ uint64_t elf_offset = 0x2000;
+
+ Ehdr ehdr = {};
+ ehdr.e_shoff = elf_offset;
+ ehdr.e_shnum = 3;
+ ehdr.e_shentsize = sizeof(Shdr);
+ ehdr.e_shstrndx = 2;
+ memory_.SetMemory(0, &ehdr, sizeof(ehdr));
+
+ elf_offset += ehdr.e_shentsize;
+
+ Shdr shdr = {};
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_link = 2;
+ shdr.sh_name = 0x100;
+ shdr.sh_addr = addr;
+ shdr.sh_offset = offset;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x800;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+ elf_offset += ehdr.e_shentsize;
+
+ // The string data for section header names.
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_name = 0x20000;
+ shdr.sh_offset = 0xf000;
+ shdr.sh_size = 0x1000;
+ memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
+
+ memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
+
+ int64_t load_bias = 0;
+ ASSERT_TRUE(elf->Init(&load_bias));
+ EXPECT_EQ(0, load_bias);
+ EXPECT_EQ(offset, elf->debug_frame_offset());
+ EXPECT_EQ(expected_bias, elf->debug_frame_section_bias());
+ EXPECT_EQ(0x800U, elf->debug_frame_size());
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_32) {
+ InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x5000,
+ 0x5000, 0);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_64) {
+ InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
+ 0xa000, 0);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_32) {
+ InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
+ 0x5000, 0x2000, 0x3000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_64) {
+ InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
+ 0x7000, 0x1000, 0x6000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_32) {
+ InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
+ 0x6000, 0x7000, -0x1000);
+}
+
+TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_64) {
+ InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
+ 0x3000, 0x5000, -0x2000);
+}
+
+template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
+void ElfInterfaceTest::CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias) {
+ std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
+
+ Ehdr ehdr = {};
+ ehdr.e_phoff = 0x100;
+ ehdr.e_phnum = 2;
+ ehdr.e_phentsize = sizeof(Phdr);
+ memory_.SetMemory(0, &ehdr, sizeof(ehdr));
+
+ uint64_t phdr_offset = 0x100;
+
+ Phdr phdr = {};
+ phdr.p_type = PT_LOAD;
+ phdr.p_memsz = 0x10000;
+ phdr.p_flags = PF_R | PF_X;
+ phdr.p_align = 0x1000;
+ memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
+ phdr_offset += sizeof(phdr);
+
+ memset(&phdr, 0, sizeof(phdr));
+ phdr.p_type = PT_GNU_EH_FRAME;
+ phdr.p_paddr = addr;
+ phdr.p_offset = offset;
+ memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
+
+ int64_t load_bias = 0;
+ ASSERT_TRUE(elf->Init(&load_bias));
+ EXPECT_EQ(0, load_bias);
+ EXPECT_EQ(expected_bias, elf->eh_frame_hdr_section_bias());
+}
+
+TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_32) {
+ ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x4000, 0);
+}
+
+TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_64) {
+ ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x4000, 0);
+}
+
+TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_32) {
+ ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x1000, 0x3000);
+}
+
+TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_64) {
+ ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x1000, 0x3000);
+}
+
+TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_32) {
+ ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x5000,
+ -0x1000);
+}
+
+TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_64) {
+ ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x5000,
+ -0x1000);
+}
+
TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
@@ -1028,9 +1363,9 @@ TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
phdr.p_align = 0x1000;
memory_.SetMemory(0x100, &phdr, sizeof(phdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0U, load_bias);
+ EXPECT_EQ(0, load_bias);
EXPECT_TRUE(elf->IsValidPc(0));
EXPECT_TRUE(elf->IsValidPc(0x5000));
EXPECT_TRUE(elf->IsValidPc(0xffff));
@@ -1054,9 +1389,9 @@ TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
phdr.p_align = 0x1000;
memory_.SetMemory(0x100, &phdr, sizeof(phdr));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- EXPECT_EQ(0x2000U, load_bias);
+ EXPECT_EQ(0x2000, load_bias);
EXPECT_FALSE(elf->IsValidPc(0));
EXPECT_FALSE(elf->IsValidPc(0x1000));
EXPECT_FALSE(elf->IsValidPc(0x1fff));
@@ -1111,10 +1446,10 @@ TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
memory_.SetData32(0x708, 0x2100);
memory_.SetData32(0x70c, 0x200);
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- elf->InitHeaders(0);
- EXPECT_EQ(0U, load_bias);
+ elf->InitHeaders();
+ EXPECT_EQ(0, load_bias);
EXPECT_FALSE(elf->IsValidPc(0));
EXPECT_FALSE(elf->IsValidPc(0x20ff));
EXPECT_TRUE(elf->IsValidPc(0x2100));
@@ -1168,10 +1503,10 @@ TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
memory_.SetData32(0x708, 0x20f8);
memory_.SetData32(0x70c, 0x200);
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
- elf->InitHeaders(0);
- EXPECT_EQ(0U, load_bias);
+ elf->InitHeaders();
+ EXPECT_EQ(0, load_bias);
EXPECT_FALSE(elf->IsValidPc(0));
EXPECT_FALSE(elf->IsValidPc(0x27ff));
EXPECT_TRUE(elf->IsValidPc(0x2800));
@@ -1207,7 +1542,6 @@ void ElfInterfaceTest::BuildID() {
note_offset += sizeof("GNU");
// This part of the note does not contain any trailing '\0'.
memcpy(&note_section[note_offset], "BUILDID", 7);
- note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1224,16 +1558,23 @@ void ElfInterfaceTest::BuildID() {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
memory_.SetMemory(0xb000, note_section, sizeof(note_section));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
ASSERT_EQ("BUILDID", elf->GetBuildID());
}
+TEST_F(ElfInterfaceTest, build_id_32) {
+ BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
+}
+
+TEST_F(ElfInterfaceTest, build_id_64) {
+ BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
+}
+
template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
void ElfInterfaceTest::BuildIDTwoNotes() {
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
@@ -1272,7 +1613,6 @@ void ElfInterfaceTest::BuildIDTwoNotes() {
note_offset += sizeof("GNU");
// This part of the note does not contain any trailing '\0'.
memcpy(&note_section[note_offset], "BUILDID", 7);
- note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1289,16 +1629,23 @@ void ElfInterfaceTest::BuildIDTwoNotes() {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
memory_.SetMemory(0xb000, note_section, sizeof(note_section));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
ASSERT_EQ("BUILDID", elf->GetBuildID());
}
+TEST_F(ElfInterfaceTest, build_id_two_notes_32) {
+ BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
+}
+
+TEST_F(ElfInterfaceTest, build_id_two_notes_64) {
+ BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
+}
+
template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
@@ -1326,7 +1673,6 @@ void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
note_offset += sizeof("GNU");
// This part of the note does not contain any trailing '\0'.
memcpy(&note_section[note_offset], "BUILDID", 7);
- note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1343,16 +1689,23 @@ void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
memory_.SetMemory(0xb000, note_section, sizeof(note_section));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
ASSERT_EQ("", elf->GetBuildID());
}
+TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_32) {
+ BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
+}
+
+TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_64) {
+ BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
+}
+
template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
@@ -1380,7 +1733,6 @@ void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
note_offset += sizeof("GNU");
// This part of the note does not contain any trailing '\0'.
memcpy(&note_section[note_offset], "BUILDID", 7);
- note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1397,16 +1749,23 @@ void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
memory_.SetMemory(0xb000, note_section, sizeof(note_section));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
ASSERT_EQ("", elf->GetBuildID());
}
+TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_32) {
+ BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
+}
+
+TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_64) {
+ BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
+}
+
template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
@@ -1434,7 +1793,6 @@ void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
note_offset += sizeof("GNU");
// This part of the note does not contain any trailing '\0'.
memcpy(&note_section[note_offset], "BUILDID", 7);
- note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1451,58 +1809,25 @@ void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
shdr.sh_offset = 0xf000;
shdr.sh_size = 0x1000;
memory_.SetMemory(offset, &shdr, sizeof(shdr));
- offset += ehdr.e_shentsize;
memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
memory_.SetMemory(0xb000, note_section, sizeof(note_section));
- uint64_t load_bias = 0;
+ int64_t load_bias = 0;
ASSERT_TRUE(elf->Init(&load_bias));
ASSERT_EQ("", elf->GetBuildID());
}
-TEST_F(ElfInterfaceTest, build_id32) {
- BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
-}
-
-TEST_F(ElfInterfaceTest, build_id64) {
- BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_two_notes32) {
- BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_two_notes64) {
- BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name32) {
- BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name64) {
- BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc32) {
- BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc64) {
- BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
-}
-
-TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header32) {
+TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_32) {
BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
}
-TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header64) {
+TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_64) {
BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
}
template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
-void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(uint64_t load_bias) {
+void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(int64_t load_bias) {
Ehdr ehdr = {};
ehdr.e_phoff = 0x100;
ehdr.e_phnum = 2;
@@ -1526,11 +1851,11 @@ void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(uint64_t load_bias) {
phdr.p_align = 0x1000;
memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
- uint64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
+ int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
ASSERT_EQ(load_bias, static_load_bias);
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
- uint64_t init_load_bias = 0;
+ int64_t init_load_bias = 0;
ASSERT_TRUE(elf->Init(&init_load_bias));
ASSERT_EQ(init_load_bias, static_load_bias);
}
@@ -1553,7 +1878,7 @@ TEST_F(ElfInterfaceTest, get_load_bias_non_zero_64) {
template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
void ElfInterfaceTest::CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr,
- uint64_t load_bias) {
+ int64_t load_bias) {
Ehdr ehdr = {};
ehdr.e_phoff = 0x100;
ehdr.e_phnum = 3;
@@ -1586,11 +1911,11 @@ void ElfInterfaceTest::CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t va
phdr.p_align = 0x1000;
memory_.SetMemory(0x200 + sizeof(phdr), &phdr, sizeof(phdr));
- uint64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
+ int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
ASSERT_EQ(load_bias, static_load_bias);
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
- uint64_t init_load_bias = 0;
+ int64_t init_load_bias = 0;
ASSERT_TRUE(elf->Init(&init_load_bias));
ASSERT_EQ(init_load_bias, static_load_bias);
}
@@ -1603,20 +1928,20 @@ TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_64) {
CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x1000, 0);
}
-TEST_F(ElfInterfaceTest, get_load_bias_exec_non_zero_32) {
+TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_32) {
CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x4000, 0x3000);
}
-TEST_F(ElfInterfaceTest, get_load_bias_exec_non_zero_64) {
+TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_64) {
CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x4000, 0x3000);
}
-TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_from_error_32) {
- CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x5000, 0x1000, 0);
+TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_32) {
+ CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x5000, 0x1000, -0x4000);
}
-TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_from_error_64) {
- CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, 0);
+TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_64) {
+ CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, -0x4000);
}
} // namespace unwindstack