summaryrefslogtreecommitdiffstats
path: root/courgette
diff options
context:
space:
mode:
authorhuangs <huangs@chromium.org>2016-02-04 14:26:43 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-04 22:27:34 +0000
commit7ec152caaf55f64431dcb2c63cc052890c4a93f1 (patch)
tree3adafe7ee167fc3ae5d91aaab6ee92fb85b3f34b /courgette
parent3dfbb081c34eb485535b7f2cc1ea21a4d6b1ed76 (diff)
downloadchromium_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.cc31
-rw-r--r--courgette/disassembler_elf_32.h24
-rw-r--r--courgette/encode_decode_unittest.cc5
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);
+}