diff options
author | huangs <huangs@chromium.org> | 2016-02-04 14:26:43 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-04 22:27:34 +0000 |
commit | 7ec152caaf55f64431dcb2c63cc052890c4a93f1 (patch) | |
tree | 3adafe7ee167fc3ae5d91aaab6ee92fb85b3f34b /courgette | |
parent | 3dfbb081c34eb485535b7f2cc1ea21a4d6b1ed76 (diff) | |
download | chromium_src-7ec152caaf55f64431dcb2c63cc052890c4a93f1.zip chromium_src-7ec152caaf55f64431dcb2c63cc052890c4a93f1.tar.gz chromium_src-7ec152caaf55f64431dcb2c63cc052890c4a93f1.tar.bz2 |
[Courgette] Fix AssemblyProgram parsing for ELF-ARM.
This fixes two problems:
(A) In DisassemblerElf32, RVAToFileOffset() used Program Segment Header,
but FileOffsetToRVA() used Section Header. For consistency, both
should use the same one. We choose the latter (for now).
(B) Even if a section has sh_type=SHT_PROGBITS, it can still have
sh_addr=0. Extracting Rel32 address from these sections would add
overlapping RVA chaos, and so should be avoided.
Also using elf-arm7 in a unit test. The test fails before the fix and
passes after.
BUG= 579206
Review URL: https://codereview.chromium.org/1658463002
Cr-Commit-Position: refs/heads/master@{#373639}
Diffstat (limited to 'courgette')
-rw-r--r-- | courgette/disassembler_elf_32.cc | 31 | ||||
-rw-r--r-- | courgette/disassembler_elf_32.h | 24 | ||||
-rw-r--r-- | courgette/encode_decode_unittest.cc | 5 |
3 files changed, 20 insertions, 40 deletions
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc index c0f42e6..84aa971 100644 --- a/courgette/disassembler_elf_32.cc +++ b/courgette/disassembler_elf_32.cc @@ -162,24 +162,21 @@ CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const { return false; } -// Returns RVA for an in memory address, or NULL. -CheckBool DisassemblerElf32::RVAToFileOffset(Elf32_Addr addr, - size_t* result) const { - - for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { - Elf32_Addr begin = ProgramSegmentMemoryBegin(i); - Elf32_Addr end = begin + ProgramSegmentMemorySize(i); - - if (addr >= begin && addr < end) { - Elf32_Addr offset = addr - begin; +CheckBool DisassemblerElf32::RVAToFileOffset(RVA rva, + size_t* result) const { + for (int i = 0; i < SectionHeaderCount(); i++) { + const Elf32_Shdr *section_header = SectionHeader(i); + // These can appear to have a size in the file, but don't. + if (section_header->sh_type == SHT_NOBITS) + continue; + Elf32_Addr begin = section_header->sh_addr; + Elf32_Addr end = begin + section_header->sh_size; - if (offset < ProgramSegmentFileSize(i)) { - *result = ProgramSegmentFileOffset(i) + offset; - return true; - } + if (rva >= begin && rva < end) { + *result = section_header->sh_offset + (rva - begin); + return true; } } - return false; } @@ -491,7 +488,9 @@ CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { const Elf32_Shdr *section_header = SectionHeader(section_id); - if (section_header->sh_type != SHT_PROGBITS) + // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. + if (section_header->sh_type != SHT_PROGBITS || + section_header->sh_addr == 0) continue; if (!ParseRel32RelocsFromSection(section_header)) diff --git a/courgette/disassembler_elf_32.h b/courgette/disassembler_elf_32.h index 110dd71..8483ce3 100644 --- a/courgette/disassembler_elf_32.h +++ b/courgette/disassembler_elf_32.h @@ -116,10 +116,6 @@ class DisassemblerElf32 : public Disassembler { return OffsetToPointer(SectionHeader(id)->sh_offset); } - Elf32_Word SectionBodySize(int id) const { - return SectionHeader(id)->sh_size; - } - // Misc Segment Helpers Elf32_Half ProgramSegmentHeaderCount() const { @@ -131,26 +127,6 @@ class DisassemblerElf32 : public Disassembler { return program_header_table_ + id; } - // The virtual memory address at which this program segment will be loaded - Elf32_Addr ProgramSegmentMemoryBegin(int id) const { - return ProgramSegmentHeader(id)->p_vaddr; - } - - // The number of virtual memory bytes for this program segment - Elf32_Word ProgramSegmentMemorySize(int id) const { - return ProgramSegmentHeader(id)->p_memsz; - } - - // Pointer into the source file for this program segment - Elf32_Addr ProgramSegmentFileOffset(int id) const { - return ProgramSegmentHeader(id)->p_offset; - } - - // Number of file bytes for this program segment. Is <= ProgramMemorySize. - Elf32_Word ProgramSegmentFileSize(int id) const { - return ProgramSegmentHeader(id)->p_filesz; - } - // Misc address space helpers CheckBool IsValidRVA(RVA rva) const WARN_UNUSED_RESULT; diff --git a/courgette/encode_decode_unittest.cc b/courgette/encode_decode_unittest.cc index 7494785..8c972a6 100644 --- a/courgette/encode_decode_unittest.cc +++ b/courgette/encode_decode_unittest.cc @@ -94,3 +94,8 @@ TEST_F(EncodeDecodeTest, Elf_HighBSS) { std::string file = FileContents("elf-32-high-bss"); TestAssembleToStreamDisassemble(file, 7312); } + +TEST_F(EncodeDecodeTest, Elf_Arm) { + std::string file = FileContents("elf-armv7"); + TestAssembleToStreamDisassemble(file, 8531); +} |