diff options
Diffstat (limited to 'libunwindstack/tests/ElfInterfaceTest.cpp')
-rw-r--r-- | libunwindstack/tests/ElfInterfaceTest.cpp | 615 |
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(¬e_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(¬e_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(¬e_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(¬e_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(¬e_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 |