| Index: courgette/disassembler_elf_32.cc
|
| diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc
|
| index a6cb16fab8a5a6a558a47d9c663c23a4329749fe..a668401ba06287fbf2788fcd799da104eb70755d 100644
|
| --- a/courgette/disassembler_elf_32.cc
|
| +++ b/courgette/disassembler_elf_32.cc
|
| @@ -8,6 +8,7 @@
|
| #include <iterator>
|
| #include <utility>
|
|
|
| +#include "base/bind.h"
|
| #include "base/logging.h"
|
| #include "courgette/assembly_program.h"
|
| #include "courgette/courgette.h"
|
| @@ -179,8 +180,10 @@ bool DisassemblerElf32::Disassemble(AssemblyProgram* target) {
|
| PrecomputeLabels(target);
|
| RemoveUnusedRel32Locations(target);
|
|
|
| - if (!ParseFile(target))
|
| + if (!target->GenerateInstructions(
|
| + base::Bind(&DisassemblerElf32::ParseFile, base::Unretained(this)))) {
|
| return false;
|
| + }
|
|
|
| // Finally sort rel32 locations.
|
| std::sort(rel32_locations_.begin(),
|
| @@ -301,7 +304,7 @@ CheckBool DisassemblerElf32::SectionName(const Elf32_Shdr& shdr,
|
|
|
| CheckBool DisassemblerElf32::RVAsToFileOffsets(
|
| const std::vector<RVA>& rvas,
|
| - std::vector<FileOffset>* file_offsets) {
|
| + std::vector<FileOffset>* file_offsets) const {
|
| file_offsets->clear();
|
| file_offsets->reserve(rvas.size());
|
| for (RVA rva : rvas) {
|
| @@ -314,7 +317,7 @@ CheckBool DisassemblerElf32::RVAsToFileOffsets(
|
| }
|
|
|
| CheckBool DisassemblerElf32::RVAsToFileOffsets(
|
| - std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) {
|
| + std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) const {
|
| for (auto& typed_rva : *typed_rvas) {
|
| FileOffset file_offset = RVAToFileOffset(typed_rva->rva());
|
| if (file_offset == kNoFileOffset)
|
| @@ -350,7 +353,8 @@ void DisassemblerElf32::RemoveUnusedRel32Locations(AssemblyProgram* program) {
|
| rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it));
|
| }
|
|
|
| -CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) {
|
| +CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program,
|
| + InstructionReceptor* receptor) const {
|
| // Walk all the bytes in the file, whether or not in a section.
|
| FileOffset file_offset = 0;
|
|
|
| @@ -384,24 +388,21 @@ CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) {
|
| if (section_header->sh_type == SHT_NOBITS)
|
| continue;
|
|
|
| - if (!ParseSimpleRegion(file_offset, section_header->sh_offset, program))
|
| + if (!ParseSimpleRegion(file_offset, section_header->sh_offset, receptor))
|
| return false;
|
|
|
| file_offset = section_header->sh_offset;
|
|
|
| switch (section_header->sh_type) {
|
| case SHT_REL:
|
| - if (!ParseRelocationSection(section_header, program))
|
| + if (!ParseRelocationSection(section_header, receptor))
|
| return false;
|
| file_offset = section_header->sh_offset + section_header->sh_size;
|
| break;
|
| case SHT_PROGBITS:
|
| - if (!ParseProgbitsSection(section_header,
|
| - ¤t_abs_offset,
|
| - end_abs_offset,
|
| - ¤t_rel,
|
| - end_rel,
|
| - program)) {
|
| + if (!ParseProgbitsSection(section_header, ¤t_abs_offset,
|
| + end_abs_offset, ¤t_rel, end_rel,
|
| + program, receptor)) {
|
| return false;
|
| }
|
| file_offset = section_header->sh_offset + section_header->sh_size;
|
| @@ -432,7 +433,7 @@ CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) {
|
| }
|
|
|
| // Rest of the file past the last section
|
| - if (!ParseSimpleRegion(file_offset, length(), program))
|
| + if (!ParseSimpleRegion(file_offset, length(), receptor))
|
| return false;
|
|
|
| // Make certain we consume all of the relocations as expected
|
| @@ -445,14 +446,15 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
|
| std::vector<FileOffset>::iterator end_abs_offset,
|
| std::vector<std::unique_ptr<TypedRVA>>::iterator* current_rel,
|
| std::vector<std::unique_ptr<TypedRVA>>::iterator end_rel,
|
| - AssemblyProgram* program) {
|
| + AssemblyProgram* program,
|
| + InstructionReceptor* receptor) const {
|
| // Walk all the bytes in the file, whether or not in a section.
|
| FileOffset file_offset = section_header->sh_offset;
|
| FileOffset section_end = section_header->sh_offset + section_header->sh_size;
|
|
|
| Elf32_Addr origin = section_header->sh_addr;
|
| FileOffset origin_offset = section_header->sh_offset;
|
| - if (!program->EmitOriginInstruction(origin))
|
| + if (!receptor->EmitOrigin(origin))
|
| return false;
|
|
|
| while (file_offset < section_end) {
|
| @@ -479,7 +481,7 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
|
| next_relocation = (**current_rel)->file_offset();
|
|
|
| if (next_relocation > file_offset) {
|
| - if (!ParseSimpleRegion(file_offset, next_relocation, program))
|
| + if (!ParseSimpleRegion(file_offset, next_relocation, receptor))
|
| return false;
|
|
|
| file_offset = next_relocation;
|
| @@ -493,7 +495,7 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
|
|
|
| Label* label = program->FindAbs32Label(target_rva);
|
| CHECK(label);
|
| - if (!program->EmitAbs32(label))
|
| + if (!receptor->EmitAbs32(label))
|
| return false;
|
| file_offset += sizeof(RVA);
|
| ++(*current_abs_offset);
|
| @@ -513,7 +515,7 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
|
| Label* label = program->FindRel32Label(target_rva);
|
| CHECK(label);
|
|
|
| - if (!(**current_rel)->EmitInstruction(program, label))
|
| + if (!(**current_rel)->EmitInstruction(label, receptor))
|
| return false;
|
| file_offset += (**current_rel)->op_size();
|
| ++(*current_rel);
|
| @@ -522,20 +524,21 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
|
| }
|
|
|
| // Rest of the section (if any)
|
| - return ParseSimpleRegion(file_offset, section_end, program);
|
| + return ParseSimpleRegion(file_offset, section_end, receptor);
|
| }
|
|
|
| -CheckBool DisassemblerElf32::ParseSimpleRegion(FileOffset start_file_offset,
|
| - FileOffset end_file_offset,
|
| - AssemblyProgram* program) {
|
| +CheckBool DisassemblerElf32::ParseSimpleRegion(
|
| + FileOffset start_file_offset,
|
| + FileOffset end_file_offset,
|
| + InstructionReceptor* receptor) const {
|
| // Callers don't guarantee start < end
|
| if (start_file_offset >= end_file_offset)
|
| return true;
|
|
|
| const size_t len = end_file_offset - start_file_offset;
|
|
|
| - if (!program->EmitBytesInstruction(FileOffsetToPointer(start_file_offset),
|
| - len)) {
|
| + if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset),
|
| + len)) {
|
| return false;
|
| }
|
|
|
|
|