diff options
| author | Christopher Ferris <cferris@google.com> | 2017-12-20 18:49:01 -0800 |
|---|---|---|
| committer | Christopher Ferris <cferris@google.com> | 2018-01-12 11:18:42 -0800 |
| commit | 150db124f3f3c0f8e1c341fd33c6c64310e0ac39 (patch) | |
| tree | 87fb701a6895bf8f273997edb1d98bf9aea2a3cd /libunwindstack/tests/ElfInterfaceTest.cpp | |
| parent | 55feb241b159a946ad3a24286baec3b8bf43a9e6 (diff) | |
| download | system_core-150db124f3f3c0f8e1c341fd33c6c64310e0ac39.tar.gz system_core-150db124f3f3c0f8e1c341fd33c6c64310e0ac39.tar.bz2 system_core-150db124f3f3c0f8e1c341fd33c6c64310e0ac39.zip | |
Add ability to read jit gdb data.
Changes:
- New JitDebug class to handle all of the jit gdb interface.
- Add unit tests for all, along with new offline test using debug data.
- Add new Memory type called MemoryOfflineParts that has multiple
MemoryOffline objects to support the offline test.
- Update the tools to use the JitDebug object.
- Modify libbacktrace to use the JitDebug, but only looking in libart.so
and libartd.so.
- Change the Format32Bits to Is32Bit since it's more accurate and I use
it in a different context where original name didn't make sense.
- Add a new function to find global variables in an elf file
(GetGlobalVariable).
- Add a new function to determine if a pc is valid for this elf (IsValidPc).
Bug: 68396769
Test: Ran new unit tests. Added new offline test that uses jit debug data.
Test: Ran art test that generates jit data and verified a crash unwinds
Test: through the jit data.
Change-Id: I6e7ee2f5bab2242028a06feece156dff21c0a974
Diffstat (limited to 'libunwindstack/tests/ElfInterfaceTest.cpp')
| -rw-r--r-- | libunwindstack/tests/ElfInterfaceTest.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp index e138c3acf..042c5fb3b 100644 --- a/libunwindstack/tests/ElfInterfaceTest.cpp +++ b/libunwindstack/tests/ElfInterfaceTest.cpp @@ -958,4 +958,189 @@ TEST_F(ElfInterfaceTest, init_section_headers_offsets64) { InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(); } +TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) { + std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_)); + + Elf32_Ehdr ehdr; + memset(&ehdr, 0, sizeof(ehdr)); + ehdr.e_phoff = 0x100; + ehdr.e_phnum = 1; + ehdr.e_phentsize = sizeof(Elf32_Phdr); + memory_.SetMemory(0, &ehdr, sizeof(ehdr)); + + Elf32_Phdr phdr; + memset(&phdr, 0, sizeof(phdr)); + phdr.p_type = PT_LOAD; + phdr.p_vaddr = 0; + phdr.p_memsz = 0x10000; + phdr.p_flags = PF_R | PF_X; + phdr.p_align = 0x1000; + memory_.SetMemory(0x100, &phdr, sizeof(phdr)); + + uint64_t load_bias = 0; + ASSERT_TRUE(elf->Init(&load_bias)); + EXPECT_EQ(0U, load_bias); + EXPECT_TRUE(elf->IsValidPc(0)); + EXPECT_TRUE(elf->IsValidPc(0x5000)); + EXPECT_TRUE(elf->IsValidPc(0xffff)); + EXPECT_FALSE(elf->IsValidPc(0x10000)); +} + +TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) { + std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_)); + + Elf32_Ehdr ehdr; + memset(&ehdr, 0, sizeof(ehdr)); + ehdr.e_phoff = 0x100; + ehdr.e_phnum = 1; + ehdr.e_phentsize = sizeof(Elf32_Phdr); + memory_.SetMemory(0, &ehdr, sizeof(ehdr)); + + Elf32_Phdr phdr; + memset(&phdr, 0, sizeof(phdr)); + phdr.p_type = PT_LOAD; + phdr.p_vaddr = 0x2000; + phdr.p_memsz = 0x10000; + phdr.p_flags = PF_R | PF_X; + phdr.p_align = 0x1000; + memory_.SetMemory(0x100, &phdr, sizeof(phdr)); + + uint64_t load_bias = 0; + ASSERT_TRUE(elf->Init(&load_bias)); + EXPECT_EQ(0x2000U, load_bias); + EXPECT_FALSE(elf->IsValidPc(0)); + EXPECT_FALSE(elf->IsValidPc(0x1000)); + EXPECT_FALSE(elf->IsValidPc(0x1fff)); + EXPECT_TRUE(elf->IsValidPc(0x2000)); + EXPECT_TRUE(elf->IsValidPc(0x5000)); + EXPECT_TRUE(elf->IsValidPc(0x11fff)); + EXPECT_FALSE(elf->IsValidPc(0x12000)); +} + +TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) { + std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_)); + + uint64_t sh_offset = 0x100; + + Elf32_Ehdr ehdr; + memset(&ehdr, 0, sizeof(ehdr)); + ehdr.e_shstrndx = 1; + ehdr.e_shoff = sh_offset; + ehdr.e_shentsize = sizeof(Elf32_Shdr); + ehdr.e_shnum = 3; + memory_.SetMemory(0, &ehdr, sizeof(ehdr)); + + Elf32_Shdr shdr; + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_NULL; + memory_.SetMemory(sh_offset, &shdr, sizeof(shdr)); + + sh_offset += sizeof(shdr); + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_STRTAB; + shdr.sh_name = 1; + shdr.sh_offset = 0x500; + shdr.sh_size = 0x100; + memory_.SetMemory(sh_offset, &shdr, sizeof(shdr)); + memory_.SetMemory(0x500, ".debug_frame"); + + sh_offset += sizeof(shdr); + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_PROGBITS; + shdr.sh_name = 0; + shdr.sh_addr = 0x600; + shdr.sh_offset = 0x600; + shdr.sh_size = 0x200; + memory_.SetMemory(sh_offset, &shdr, sizeof(shdr)); + + // CIE 32. + memory_.SetData32(0x600, 0xfc); + memory_.SetData32(0x604, 0xffffffff); + memory_.SetData8(0x608, 1); + memory_.SetData8(0x609, '\0'); + memory_.SetData8(0x60a, 0x4); + memory_.SetData8(0x60b, 0x4); + memory_.SetData8(0x60c, 0x1); + + // FDE 32. + memory_.SetData32(0x700, 0xfc); + memory_.SetData32(0x704, 0); + memory_.SetData32(0x708, 0x2100); + memory_.SetData32(0x70c, 0x200); + + uint64_t load_bias = 0; + ASSERT_TRUE(elf->Init(&load_bias)); + elf->InitHeaders(); + EXPECT_EQ(0U, load_bias); + EXPECT_FALSE(elf->IsValidPc(0)); + EXPECT_FALSE(elf->IsValidPc(0x20ff)); + EXPECT_TRUE(elf->IsValidPc(0x2100)); + EXPECT_TRUE(elf->IsValidPc(0x2200)); + EXPECT_TRUE(elf->IsValidPc(0x22ff)); + EXPECT_FALSE(elf->IsValidPc(0x2300)); +} + +TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) { + std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_)); + + uint64_t sh_offset = 0x100; + + Elf32_Ehdr ehdr; + memset(&ehdr, 0, sizeof(ehdr)); + ehdr.e_shstrndx = 1; + ehdr.e_shoff = sh_offset; + ehdr.e_shentsize = sizeof(Elf32_Shdr); + ehdr.e_shnum = 3; + memory_.SetMemory(0, &ehdr, sizeof(ehdr)); + + Elf32_Shdr shdr; + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_NULL; + memory_.SetMemory(sh_offset, &shdr, sizeof(shdr)); + + sh_offset += sizeof(shdr); + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_STRTAB; + shdr.sh_name = 1; + shdr.sh_offset = 0x500; + shdr.sh_size = 0x100; + memory_.SetMemory(sh_offset, &shdr, sizeof(shdr)); + memory_.SetMemory(0x500, ".eh_frame"); + + sh_offset += sizeof(shdr); + memset(&shdr, 0, sizeof(shdr)); + shdr.sh_type = SHT_PROGBITS; + shdr.sh_name = 0; + shdr.sh_addr = 0x600; + shdr.sh_offset = 0x600; + shdr.sh_size = 0x200; + memory_.SetMemory(sh_offset, &shdr, sizeof(shdr)); + + // CIE 32. + memory_.SetData32(0x600, 0xfc); + memory_.SetData32(0x604, 0); + memory_.SetData8(0x608, 1); + memory_.SetData8(0x609, '\0'); + memory_.SetData8(0x60a, 0x4); + memory_.SetData8(0x60b, 0x4); + memory_.SetData8(0x60c, 0x1); + + // FDE 32. + memory_.SetData32(0x700, 0xfc); + memory_.SetData32(0x704, 0x104); + memory_.SetData32(0x708, 0x20f8); + memory_.SetData32(0x70c, 0x200); + + uint64_t load_bias = 0; + ASSERT_TRUE(elf->Init(&load_bias)); + elf->InitHeaders(); + EXPECT_EQ(0U, load_bias); + EXPECT_FALSE(elf->IsValidPc(0)); + EXPECT_FALSE(elf->IsValidPc(0x27ff)); + EXPECT_TRUE(elf->IsValidPc(0x2800)); + EXPECT_TRUE(elf->IsValidPc(0x2900)); + EXPECT_TRUE(elf->IsValidPc(0x29ff)); + EXPECT_FALSE(elf->IsValidPc(0x2a00)); +} + } // namespace unwindstack |
