summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--courgette/assembly_program.cc32
-rw-r--r--courgette/assembly_program.h5
-rw-r--r--courgette/bsdiff_memory_unittest.cc6
-rw-r--r--courgette/courgette.gyp5
-rw-r--r--courgette/courgette.h1
-rw-r--r--courgette/disassembler.cc9
-rw-r--r--courgette/disassembler.h2
-rw-r--r--courgette/disassembler_elf_32_x86.cc602
-rw-r--r--courgette/disassembler_elf_32_x86.h143
-rw-r--r--courgette/disassembler_elf_32_x86_unittest.cc71
-rw-r--r--courgette/disassembler_win32_x86.cc2
-rw-r--r--courgette/encode_decode_unittest.cc29
-rw-r--r--courgette/encoded_program.cc67
-rw-r--r--courgette/encoded_program.h26
-rw-r--r--courgette/encoded_program_fuzz_unittest.cc3
-rw-r--r--courgette/ensemble_apply.cc3
-rw-r--r--courgette/ensemble_create.cc9
-rw-r--r--courgette/patch_generator_x86_32.h6
-rw-r--r--courgette/types_elf.h141
19 files changed, 51 insertions, 1111 deletions
diff --git a/courgette/assembly_program.cc b/courgette/assembly_program.cc
index 9225578..f759e16 100644
--- a/courgette/assembly_program.cc
+++ b/courgette/assembly_program.cc
@@ -22,8 +22,7 @@ namespace courgette {
// Opcodes of simple assembly language
enum OP {
ORIGIN, // ORIGIN <rva> - set current address for assembly.
- MAKEPERELOCS, // Generates a base relocation table.
- MAKEELFRELOCS, // Generates a base relocation table.
+ MAKERELOCS, // Generates a base relocation table.
DEFBYTE, // DEFBYTE <value> - emit a byte literal.
REL32, // REL32 <label> - emit a rel32 encoded reference to 'label'.
ABS32, // REL32 <label> - emit am abs32 encoded reference to 'label'.
@@ -59,16 +58,10 @@ class OriginInstruction : public Instruction {
RVA rva_;
};
-// Emits an entire PE base relocation table.
-class PeRelocsInstruction : public Instruction {
+// Emits an entire base relocation table.
+class MakeRelocsInstruction : public Instruction {
public:
- PeRelocsInstruction() : Instruction(MAKEPERELOCS) {}
-};
-
-// Emits an ELF relocation table.
-class ElfRelocsInstruction : public Instruction {
- public:
- ElfRelocsInstruction() : Instruction(MAKEELFRELOCS) {}
+ MakeRelocsInstruction() : Instruction(MAKERELOCS) {}
};
// Emits a single byte.
@@ -115,12 +108,8 @@ AssemblyProgram::~AssemblyProgram() {
DeleteContainedLabels(abs32_labels_);
}
-CheckBool AssemblyProgram::EmitPeRelocsInstruction() {
- return Emit(new(std::nothrow) PeRelocsInstruction());
-}
-
-CheckBool AssemblyProgram::EmitElfRelocationInstruction() {
- return Emit(new(std::nothrow) ElfRelocsInstruction());
+CheckBool AssemblyProgram::EmitMakeRelocsInstruction() {
+ return Emit(new(std::nothrow) MakeRelocsInstruction());
}
CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) {
@@ -368,13 +357,8 @@ EncodedProgram* AssemblyProgram::Encode() const {
return NULL;
break;
}
- case MAKEPERELOCS: {
- if (!encoded->AddPeMakeRelocs())
- return NULL;
- break;
- }
- case MAKEELFRELOCS: {
- if (!encoded->AddElfMakeRelocs())
+ case MAKERELOCS: {
+ if (!encoded->AddMakeRelocs())
return NULL;
break;
}
diff --git a/courgette/assembly_program.h b/courgette/assembly_program.h
index 3d231c2..5c6b1b1 100644
--- a/courgette/assembly_program.h
+++ b/courgette/assembly_program.h
@@ -69,10 +69,7 @@ class AssemblyProgram {
// Instructions will be assembled in the order they are emitted.
// Generates an entire base relocation table.
- CheckBool EmitPeRelocsInstruction() WARN_UNUSED_RESULT;
-
- // Generates an ELF style relocation table.
- CheckBool EmitElfRelocationInstruction() WARN_UNUSED_RESULT;
+ CheckBool EmitMakeRelocsInstruction() WARN_UNUSED_RESULT;
// Following instruction will be assembled at address 'rva'.
CheckBool EmitOriginInstruction(RVA rva) WARN_UNUSED_RESULT;
diff --git a/courgette/bsdiff_memory_unittest.cc b/courgette/bsdiff_memory_unittest.cc
index f1718e2..ce80eb7 100644
--- a/courgette/bsdiff_memory_unittest.cc
+++ b/courgette/bsdiff_memory_unittest.cc
@@ -117,9 +117,3 @@ TEST_F(BSDiffMemoryTest, TestDifferentExes) {
std::string file2 = FileContents("setup2.exe");
GenerateAndTestPatch(file1, file2);
}
-
-TEST_F(BSDiffMemoryTest, TestDifferentElfs) {
- std::string file1 = FileContents("elf-32-1");
- std::string file2 = FileContents("elf-32-2");
- GenerateAndTestPatch(file1, file2);
-}
diff --git a/courgette/courgette.gyp b/courgette/courgette.gyp
index 31276ae..6233d77 100644
--- a/courgette/courgette.gyp
+++ b/courgette/courgette.gyp
@@ -22,8 +22,6 @@
'difference_estimator.h',
'disassembler.cc',
'disassembler.h',
- 'disassembler_elf_32_x86.cc',
- 'disassembler_elf_32_x86.h',
'disassembler_win32_x86.cc',
'disassembler_win32_x86.h',
'encoded_program.cc',
@@ -39,8 +37,6 @@
'simple_delta.h',
'streams.cc',
'streams.h',
- 'types_elf.h',
- 'types_win_pe.h',
'patch_generator_x86_32.h',
'patcher_x86_32.h',
],
@@ -93,7 +89,6 @@
'base_test_unittest.cc',
'base_test_unittest.h',
'difference_estimator_unittest.cc',
- 'disassembler_elf_32_x86_unittest.cc',
'disassembler_win32_x86_unittest.cc',
'encoded_program_unittest.cc',
'encode_decode_unittest.cc',
diff --git a/courgette/courgette.h b/courgette/courgette.h
index a58f16d..20a25ea 100644
--- a/courgette/courgette.h
+++ b/courgette/courgette.h
@@ -55,7 +55,6 @@ enum Status {
enum ExecutableType {
EXE_UNKNOWN = 0,
EXE_WIN_32_X86 = 1,
- EXE_ELF_32_X86 = 2,
};
class SinkStream;
diff --git a/courgette/disassembler.cc b/courgette/disassembler.cc
index 103bbe0..5514be9 100644
--- a/courgette/disassembler.cc
+++ b/courgette/disassembler.cc
@@ -13,7 +13,6 @@
#include "courgette/assembly_program.h"
#include "courgette/courgette.h"
-#include "courgette/disassembler_elf_32_x86.h"
#include "courgette/disassembler_win32_x86.h"
#include "courgette/encoded_program.h"
@@ -31,14 +30,8 @@ Disassembler* DetectDisassembler(const void* buffer, size_t length) {
disassembler = new DisassemblerWin32X86(buffer, length);
if (disassembler->ParseHeader())
return disassembler;
- else
- delete disassembler;
- disassembler = new DisassemblerElf32X86(buffer, length);
- if (disassembler->ParseHeader())
- return disassembler;
- else
- delete disassembler;
+ delete disassembler;
return NULL;
}
diff --git a/courgette/disassembler.h b/courgette/disassembler.h
index 2de67fd..85c0c3d 100644
--- a/courgette/disassembler.h
+++ b/courgette/disassembler.h
@@ -68,7 +68,7 @@ class Disassembler {
}
// Reduce the length of the image in memory. Does not actually free
- // (or realloc) any memory. Usually only called via ParseHeader()
+ // (or realloc) any memory. Unusally only called via ParseHeader()
void ReduceLength(size_t reduced_length);
private:
diff --git a/courgette/disassembler_elf_32_x86.cc b/courgette/disassembler_elf_32_x86.cc
deleted file mode 100644
index 5f3ba95..0000000
--- a/courgette/disassembler_elf_32_x86.cc
+++ /dev/null
@@ -1,602 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "courgette/disassembler_elf_32_x86.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-
-#include "courgette/assembly_program.h"
-#include "courgette/courgette.h"
-#include "courgette/encoded_program.h"
-
-namespace courgette {
-
-DisassemblerElf32X86::DisassemblerElf32X86(const void* start, size_t length)
- : Disassembler(start, length) {
-}
-
-bool DisassemblerElf32X86::ParseHeader() {
- if (length() < sizeof(Elf32_Ehdr))
- return Bad("Too small");
-
- header_ = (Elf32_Ehdr *)start();
-
- // Have magic for elf header?
- if (header_->e_ident[0] != 0x7f ||
- header_->e_ident[1] != 'E' ||
- header_->e_ident[2] != 'L' ||
- header_->e_ident[3] != 'F')
- return Bad("No Magic Number");
-
- if (header_->e_type != ET_EXEC &&
- header_->e_type != ET_DYN)
- return Bad("Not an executable file or shared library");
-
- if (header_->e_machine != EM_386)
- return Bad("Not a supported architecture");
-
- if (header_->e_version != 1)
- return Bad("Unknown file version");
-
- if (header_->e_shentsize != sizeof(Elf32_Shdr))
- return Bad("Unexpected section header size");
-
- if (header_->e_shoff >= length())
- return Bad("Out of bounds section header table offset");
-
- section_header_table_ = (Elf32_Shdr *)OffsetToPointer(header_->e_shoff);
- section_header_table_size_ = header_->e_shnum;
-
- if ((header_->e_shoff + header_->e_shnum ) >= length())
- return Bad("Out of bounds section header table");
-
- if (header_->e_phoff >= length())
- return Bad("Out of bounds program header table offset");
-
- program_header_table_ = (Elf32_Phdr *)OffsetToPointer(header_->e_phoff);
- program_header_table_size_ = header_->e_phnum;
-
- if ((header_->e_phoff + header_->e_phnum) >= length())
- return Bad("Out of bounds program header table");
-
- default_string_section_ = (const char *)SectionBody((int)header_->e_shstrndx);
-
- ReduceLength(DiscoverLength());
-
- return Good();
-}
-
-bool DisassemblerElf32X86::Disassemble(AssemblyProgram* target) {
- if (!ok())
- return false;
-
- // The Image Base is always 0 for ELF Executables
- target->set_image_base(0);
-
- if (!ParseAbs32Relocs())
- return false;
-
- if (!ParseRel32RelocsFromSections())
- return false;
-
- if (!ParseFile(target))
- return false;
-
- target->DefaultAssignIndexes();
-
- return true;
-}
-
-uint32 DisassemblerElf32X86::DiscoverLength() {
- uint32 result = 0;
-
- // Find the end of the last section
- for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) {
- const Elf32_Shdr *section_header = SectionHeader(section_id);
-
- if (section_header->sh_type == SHT_NOBITS)
- continue;
-
- uint32 section_end = section_header->sh_offset + section_header->sh_size;
-
- if (section_end > result)
- result = section_end;
- }
-
- // Find the end of the last segment
- for (int i = 0; i < ProgramSegmentHeaderCount(); i++) {
- const Elf32_Phdr *segment_header = ProgramSegmentHeader(i);
-
- uint32 segment_end = segment_header->p_offset + segment_header->p_filesz;
-
- if (segment_end > result)
- result = segment_end;
- }
-
- uint32 section_table_end = header_->e_shoff +
- (header_->e_shnum * sizeof(Elf32_Shdr));
- if (section_table_end > result)
- result = section_table_end;
-
- uint32 segment_table_end = header_->e_phoff +
- (header_->e_phnum * sizeof(Elf32_Phdr));
- if (segment_table_end > result)
- result = segment_table_end;
-
- return result;
-}
-
-CheckBool DisassemblerElf32X86::IsValidRVA(RVA rva) const {
-
- // It's valid if it's contained in any program segment
- for (int i = 0; i < ProgramSegmentHeaderCount(); i++) {
- const Elf32_Phdr *segment_header = ProgramSegmentHeader(i);
-
- if (segment_header->p_type != PT_LOAD)
- continue;
-
- Elf32_Addr begin = segment_header->p_vaddr;
- Elf32_Addr end = segment_header->p_vaddr + segment_header->p_memsz;
-
- if (rva >= begin && rva < end)
- return true;
- }
-
- return false;
-}
-
-// Convert an ELF relocation struction into an RVA
-CheckBool DisassemblerElf32X86::RelToRVA(Elf32_Rel rel, RVA* result) const {
-
- // The rightmost byte of r_info is the type...
- elf32_rel_386_type_values type =
- (elf32_rel_386_type_values)(unsigned char)rel.r_info;
-
- // The other 3 bytes of r_info are the symbol
- uint32 symbol = rel.r_info >> 8;
-
- switch(type)
- {
- case R_386_NONE:
- case R_386_32:
- case R_386_PC32:
- case R_386_GOT32:
- case R_386_PLT32:
- case R_386_COPY:
- case R_386_GLOB_DAT:
- case R_386_JMP_SLOT:
- return false;
-
- case R_386_RELATIVE:
- if (symbol != 0)
- return false;
-
- // This is a basic ABS32 relocation address
- *result = rel.r_offset;
- return true;
-
- case R_386_GOTOFF:
- case R_386_GOTPC:
- case R_386_TLS_TPOFF:
- return false;
- }
-
- return false;
-}
-
-// Returns RVA for an in memory address, or NULL.
-CheckBool DisassemblerElf32X86::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;
-
- if (offset < ProgramSegmentFileSize(i)) {
- *result = ProgramSegmentFileOffset(i) + offset;
- return true;
- }
- }
- }
-
- return false;
-}
-
-RVA DisassemblerElf32X86::FileOffsetToRVA(size_t offset) const {
- // File offsets can be 64 bit values, but we are dealing with 32
- // bit executables and so only need to support 32bit file sizes.
- uint32 offset32 = (uint32)offset;
-
- 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_Off section_begin = section_header->sh_offset;
- Elf32_Off section_end = section_begin + section_header->sh_size;
-
- if (offset32 >= section_begin && offset32 < section_end) {
- return section_header->sh_addr + (offset32 - section_begin);
- }
- }
-
- return 0;
-}
-
-CheckBool DisassemblerElf32X86::RVAsToOffsets(std::vector<RVA>* rvas,
- std::vector<size_t>* offsets) {
- offsets->clear();
-
- for (std::vector<RVA>::iterator rva = rvas->begin();
- rva != rvas->end();
- rva++) {
-
- size_t offset;
-
- if (!RVAToFileOffset(*rva, &offset))
- return false;
-
- offsets->push_back(offset);
- }
-
- return true;
-}
-
-CheckBool DisassemblerElf32X86::ParseFile(AssemblyProgram* program) {
- bool ok = true;
-
- // Walk all the bytes in the file, whether or not in a section.
- uint32 file_offset = 0;
-
- std::vector<size_t> abs_offsets;
- std::vector<size_t> rel_offsets;
-
- if (ok)
- ok = RVAsToOffsets(&abs32_locations_, &abs_offsets);
-
- if (ok)
- ok = RVAsToOffsets(&rel32_locations_, &rel_offsets);
-
- std::vector<size_t>::iterator current_abs_offset = abs_offsets.begin();
- std::vector<size_t>::iterator current_rel_offset = rel_offsets.begin();
-
- std::vector<size_t>::iterator end_abs_offset = abs_offsets.end();
- std::vector<size_t>::iterator end_rel_offset = rel_offsets.end();
-
- for (int section_id = 0;
- ok && (section_id < SectionHeaderCount());
- section_id++) {
-
- const Elf32_Shdr *section_header = SectionHeader(section_id);
-
- if (ok) {
- ok = ParseSimpleRegion(file_offset,
- section_header->sh_offset,
- program);
- file_offset = section_header->sh_offset;
- }
-
- switch (section_header->sh_type) {
- case SHT_REL:
- if (ok) {
- ok = ParseRelocationSection(section_header, program);
- file_offset = section_header->sh_offset + section_header->sh_size;
- }
- break;
- case SHT_PROGBITS:
- if (ok) {
- ok = ParseProgbitsSection(section_header,
- &current_abs_offset, end_abs_offset,
- &current_rel_offset, end_rel_offset,
- program);
- file_offset = section_header->sh_offset + section_header->sh_size;
- }
-
- break;
- default:
- break;
- }
- }
-
- // Rest of the file past the last section
- if (ok) {
- ok = ParseSimpleRegion(file_offset,
- length(),
- program);
- }
-
- // Make certain we consume all of the relocations as expected
- ok = ok && (current_abs_offset == end_abs_offset);
-
- return ok;
-}
-
-CheckBool DisassemblerElf32X86::ParseRelocationSection(
- const Elf32_Shdr *section_header,
- AssemblyProgram* program) {
- // We can reproduce the R_386_RELATIVE entries in one of the relocation
- // table based on other information in the patch, given these
- // conditions....
- //
- // All R_386_RELATIVE entries are:
- // 1) In the same relocation table
- // 2) Are consecutive
- // 3) Are sorted in memory address order
- //
- // Happily, this is normally the case, but it's not required by spec
- // so we check, and just don't do it if we don't match up.
-
- // The expectation is that one relocation section will contain
- // all of our R_386_RELATIVE entries in the expected order followed
- // by assorted other entries we can't use special handling for.
-
- bool ok = true;
- bool match = true;
-
- // Walk all the bytes in the section, matching relocation table or not
- size_t file_offset = section_header->sh_offset;
- size_t section_end = section_header->sh_offset + section_header->sh_size;
-
- Elf32_Rel *section_relocs_iter =
- (Elf32_Rel *)OffsetToPointer(section_header->sh_offset);
-
- uint32 section_relocs_count = section_header->sh_size /
- section_header->sh_entsize;
-
- if (abs32_locations_.size() > section_relocs_count)
- match = false;
-
- std::vector<RVA>::iterator reloc_iter = abs32_locations_.begin();
-
- while (match && (reloc_iter != abs32_locations_.end())) {
- if (section_relocs_iter->r_info != R_386_RELATIVE ||
- section_relocs_iter->r_offset != *reloc_iter)
- match = false;
- section_relocs_iter++;
- reloc_iter++;
- }
-
- if (match) {
- // Skip over relocation tables
- ok = program->EmitElfRelocationInstruction();
- file_offset += sizeof(Elf32_Rel) * abs32_locations_.size();
- }
-
- if (ok) {
- ok = ParseSimpleRegion(file_offset, section_end, program);
- }
-
- return ok;
-}
-
-CheckBool DisassemblerElf32X86::ParseProgbitsSection(
- const Elf32_Shdr *section_header,
- std::vector<size_t>::iterator* current_abs_offset,
- std::vector<size_t>::iterator end_abs_offset,
- std::vector<size_t>::iterator* current_rel_offset,
- std::vector<size_t>::iterator end_rel_offset,
- AssemblyProgram* program) {
-
- bool ok = true;
-
- // Walk all the bytes in the file, whether or not in a section.
- size_t file_offset = section_header->sh_offset;
- size_t section_end = section_header->sh_offset + section_header->sh_size;
-
- Elf32_Addr origin = section_header->sh_addr;
- size_t origin_offset = section_header->sh_offset;
- ok = program->EmitOriginInstruction(origin);
-
- while (ok && file_offset < section_end) {
-
- if (*current_abs_offset != end_abs_offset &&
- file_offset > **current_abs_offset) {
- ok = false;
- }
-
- while (*current_rel_offset != end_rel_offset &&
- file_offset > **current_rel_offset) {
- (*current_rel_offset)++;
- }
-
- size_t next_relocation = section_end;
-
- if (*current_abs_offset != end_abs_offset &&
- next_relocation > **current_abs_offset)
- next_relocation = **current_abs_offset;
-
- // Rel offsets are heuristically derived, and might (incorrectly) overlap
- // an Abs value, or the end of the section, so +3 to make sure there is
- // room for the full 4 byte value.
- if (*current_rel_offset != end_rel_offset &&
- next_relocation > (**current_rel_offset + 3))
- next_relocation = **current_rel_offset;
-
- if (ok && (next_relocation > file_offset)) {
- ok = ParseSimpleRegion(file_offset, next_relocation, program);
-
- file_offset = next_relocation;
- continue;
- }
-
- if (ok &&
- *current_abs_offset != end_abs_offset &&
- file_offset == **current_abs_offset) {
-
- const uint8* p = OffsetToPointer(file_offset);
- RVA target_rva = Read32LittleEndian(p);
-
- ok = program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva));
- file_offset += sizeof(RVA);
- (*current_abs_offset)++;
- continue;
- }
-
- if (ok &&
- *current_rel_offset != end_rel_offset &&
- file_offset == **current_rel_offset) {
-
- const uint8* p = OffsetToPointer(file_offset);
- uint32 relative_target = Read32LittleEndian(p);
- // This cast is for 64 bit systems, and is only safe because we
- // are working on 32 bit executables.
- RVA target_rva = (RVA)(origin + (file_offset - origin_offset) +
- 4 + relative_target);
-
- ok = program->EmitRel32(program->FindOrMakeRel32Label(target_rva));
- file_offset += sizeof(RVA);
- (*current_rel_offset)++;
- continue;
- }
- }
-
- // Rest of the section (if any)
- if (ok) {
- ok = ParseSimpleRegion(file_offset, section_end, program);
- }
-
- return ok;
-}
-
-CheckBool DisassemblerElf32X86::ParseSimpleRegion(
- size_t start_file_offset,
- size_t end_file_offset,
- AssemblyProgram* program) {
-
- const uint8* start = OffsetToPointer(start_file_offset);
- const uint8* end = OffsetToPointer(end_file_offset);
-
- const uint8* p = start;
-
- bool ok = true;
- while (p < end && ok) {
- ok = program->EmitByteInstruction(*p);
- ++p;
- }
-
- return ok;
-}
-
-CheckBool DisassemblerElf32X86::ParseAbs32Relocs() {
- abs32_locations_.clear();
-
- // Loop through sections for relocation sections
- for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) {
- const Elf32_Shdr *section_header = SectionHeader(section_id);
-
- if (section_header->sh_type == SHT_REL) {
-
- Elf32_Rel *relocs_table = (Elf32_Rel *)SectionBody(section_id);
-
- int relocs_table_count = section_header->sh_size /
- section_header->sh_entsize;
-
- // Elf32_Word relocation_section_id = section_header->sh_info;
-
- // Loop through relocation objects in the relocation section
- for (int rel_id = 0; rel_id < relocs_table_count; rel_id++) {
- RVA rva;
-
- // Quite a few of these conversions fail, and we simply skip
- // them, that's okay.
- if (RelToRVA(relocs_table[rel_id], &rva))
- abs32_locations_.push_back(rva);
- }
- }
- }
-
- std::sort(abs32_locations_.begin(), abs32_locations_.end());
- return true;
-}
-
-CheckBool DisassemblerElf32X86::ParseRel32RelocsFromSections() {
-
- rel32_locations_.clear();
-
- // Loop through sections for relocation sections
- for (int section_id = 0;
- section_id < SectionHeaderCount();
- section_id++) {
-
- const Elf32_Shdr *section_header = SectionHeader(section_id);
-
- if (section_header->sh_type != SHT_PROGBITS)
- continue;
-
- if (!ParseRel32RelocsFromSection(section_header))
- return false;
- }
-
- std::sort(rel32_locations_.begin(), rel32_locations_.end());
- return true;
-}
-
-CheckBool DisassemblerElf32X86::ParseRel32RelocsFromSection(
- const Elf32_Shdr* section_header) {
-
- uint32 start_file_offset = section_header->sh_offset;
- uint32 end_file_offset = start_file_offset + section_header->sh_size;
-
- const uint8* start_pointer = OffsetToPointer(start_file_offset);
- const uint8* end_pointer = OffsetToPointer(end_file_offset);
-
- // Quick way to convert from Pointer to RVA within a single Section is to
- // subtract 'pointer_to_rva'.
- const uint8* const adjust_pointer_to_rva = start_pointer -
- section_header->sh_addr;
-
- // Find the rel32 relocations.
- const uint8* p = start_pointer;
- while (p < end_pointer) {
- //RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva);
-
- // Heuristic discovery of rel32 locations in instruction stream: are the
- // next few bytes the start of an instruction containing a rel32
- // addressing mode?
- const uint8* rel32 = NULL;
-
- if (p + 5 < end_pointer) {
- if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32
- rel32 = p + 1;
- }
- }
- if (p + 6 < end_pointer) {
- if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form
- if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely
- rel32 = p + 2;
- }
- }
- if (rel32) {
- RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva);
-
- RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32);
- // To be valid, rel32 target must be within image, and within this
- // section.
- if (IsValidRVA(target_rva)) {
- rel32_locations_.push_back(rel32_rva);
-#if COURGETTE_HISTOGRAM_TARGETS
- ++rel32_target_rvas_[target_rva];
-#endif
- p += 4;
- continue;
- }
- }
- p += 1;
- }
-
- return true;
-}
-
-} // namespace courgette
diff --git a/courgette/disassembler_elf_32_x86.h b/courgette/disassembler_elf_32_x86.h
deleted file mode 100644
index c797a8b..0000000
--- a/courgette/disassembler_elf_32_x86.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COURGETTE_DISASSEMBLER_ELF_32_X86_H_
-#define COURGETTE_DISASSEMBLER_ELF_32_X86_H_
-
-#include "base/basictypes.h"
-#include "courgette/disassembler.h"
-#include "courgette/memory_allocator.h"
-#include "courgette/types_elf.h"
-
-namespace courgette {
-
-class AssemblyProgram;
-
-class DisassemblerElf32X86 : public Disassembler {
- public:
- explicit DisassemblerElf32X86(const void* start, size_t length);
-
- virtual ExecutableType kind() { return EXE_ELF_32_X86; }
-
- // Returns 'true' if the buffer appears to point to a valid ELF executable
- // for X86 32 bitWindows 32 bit. If ParseHeader() succeeds, other member
- // functions may be called.
- virtual bool ParseHeader();
-
- virtual bool Disassemble(AssemblyProgram* target);
-
- // Public for unittests only
- std::vector<RVA> &Abs32Locations() { return abs32_locations_; }
- std::vector<RVA> &Rel32Locations() { return rel32_locations_; }
-
- protected:
-
- uint32 DiscoverLength();
-
- // Misc Section Helpers
-
- const Elf32_Half SectionHeaderCount() const {
- return section_header_table_size_;
- }
-
- const Elf32_Shdr *SectionHeader(int id) const {
- assert(id >= 0 && id < SectionHeaderCount());
- return section_header_table_ + id;
- }
-
- const uint8 *SectionBody(int id) const {
- return OffsetToPointer(SectionHeader(id)->sh_offset);
- }
-
- const Elf32_Word SectionBodySize(int id) const {
- return SectionHeader(id)->sh_size;
- }
-
- // Misc Segment Helpers
-
- const Elf32_Half ProgramSegmentHeaderCount() const {
- return program_header_table_size_;
- }
-
- const Elf32_Phdr *ProgramSegmentHeader(int id) const {
- assert(id >= 0 && id < ProgramSegmentHeaderCount());
- return program_header_table_ + id;
- }
-
- // The virtual memory address at which this program segment will be loaded
- const Elf32_Addr ProgramSegmentMemoryBegin(int id) const {
- return ProgramSegmentHeader(id)->p_vaddr;
- }
-
- // The number of virtual memory bytes for this program segment
- const Elf32_Word ProgramSegmentMemorySize(int id) const {
- return ProgramSegmentHeader(id)->p_memsz;
- }
-
- // Pointer into the source file for this program segment
- const Elf32_Addr ProgramSegmentFileOffset(int id) const {
- return ProgramSegmentHeader(id)->p_offset;
- }
-
- // Number of file bytes for this program segment. Is <= ProgramMemorySize.
- const Elf32_Word ProgramSegmentFileSize(int id) const {
- return ProgramSegmentHeader(id)->p_filesz;
- }
-
- // Misc address space helpers
-
- CheckBool IsValidRVA(RVA rva) const WARN_UNUSED_RESULT;
-
- // Convert an ELF relocation struction into an RVA
- CheckBool RelToRVA(Elf32_Rel rel, RVA* result) const WARN_UNUSED_RESULT;
-
- // Returns kNoOffset if there is no file offset corresponding to 'rva'.
- CheckBool RVAToFileOffset(RVA rva, size_t* result) const WARN_UNUSED_RESULT;
-
- RVA FileOffsetToRVA(size_t offset) const WARN_UNUSED_RESULT;
-
- CheckBool RVAsToOffsets(std::vector<RVA>* rvas /*in*/,
- std::vector<size_t>* offsets /*out*/);
-
- // Parsing Code used to really implement Disassemble
-
- CheckBool ParseFile(AssemblyProgram* target) WARN_UNUSED_RESULT;
- CheckBool ParseRelocationSection(
- const Elf32_Shdr *section_header,
- AssemblyProgram* program) WARN_UNUSED_RESULT;
- CheckBool ParseProgbitsSection(
- const Elf32_Shdr *section_header,
- std::vector<size_t>::iterator* current_abs_offset,
- std::vector<size_t>::iterator end_abs_offset,
- std::vector<size_t>::iterator* current_rel_offset,
- std::vector<size_t>::iterator end_rel_offset,
- AssemblyProgram* program) WARN_UNUSED_RESULT;
- CheckBool ParseSimpleRegion(size_t start_file_offset,
- size_t end_file_offset,
- AssemblyProgram* program) WARN_UNUSED_RESULT;
-
- CheckBool ParseAbs32Relocs() WARN_UNUSED_RESULT;
- CheckBool ParseRel32RelocsFromSections() WARN_UNUSED_RESULT;
- CheckBool ParseRel32RelocsFromSection(
- const Elf32_Shdr* section) WARN_UNUSED_RESULT;
-
- Elf32_Ehdr *header_;
- Elf32_Shdr *section_header_table_;
- Elf32_Half section_header_table_size_;
-
- Elf32_Phdr *program_header_table_;
- Elf32_Half program_header_table_size_;
-
- // Section header for default
- const char *default_string_section_;
-
- std::vector<RVA> abs32_locations_;
- std::vector<RVA> rel32_locations_;
-
- DISALLOW_COPY_AND_ASSIGN(DisassemblerElf32X86);
-};
-
-} // namespace courgette
-
-#endif // COURGETTE_DISASSEMBLER_ELF_32_X86_H_
diff --git a/courgette/disassembler_elf_32_x86_unittest.cc b/courgette/disassembler_elf_32_x86_unittest.cc
deleted file mode 100644
index 85c8e26..0000000
--- a/courgette/disassembler_elf_32_x86_unittest.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "courgette/assembly_program.h"
-#include "courgette/base_test_unittest.h"
-#include "courgette/disassembler_elf_32_x86.h"
-
-class DisassemblerElf32X86Test : public BaseTest {
- public:
-
- void TestExe(const char* file_name,
- size_t expected_abs_count,
- size_t expected_rel_count) const;
-};
-
-void DisassemblerElf32X86Test::TestExe(const char* file_name,
- size_t expected_abs_count,
- size_t expected_rel_count) const {
- std::string file1 = FileContents(file_name);
-
- scoped_ptr<courgette::DisassemblerElf32X86> disassembler(
- new courgette::DisassemblerElf32X86(file1.c_str(), file1.length()));
-
- bool can_parse_header = disassembler->ParseHeader();
- EXPECT_TRUE(can_parse_header);
- EXPECT_TRUE(disassembler->ok());
-
- // The length of the disassembled value will be slightly smaller than the
- // real file, since trailing debug info is not included
- EXPECT_EQ(file1.length(), disassembler->length());
-
- const uint8* offset_p = disassembler->OffsetToPointer(0);
- EXPECT_EQ(reinterpret_cast<const void*>(file1.c_str()),
- reinterpret_cast<const void*>(offset_p));
- EXPECT_EQ(0x7F, offset_p[0]);
- EXPECT_EQ('E', offset_p[1]);
- EXPECT_EQ('L', offset_p[2]);
- EXPECT_EQ('F', offset_p[3]);
-
- courgette::AssemblyProgram* program = new courgette::AssemblyProgram();
-
- EXPECT_TRUE(disassembler->Disassemble(program));
-
- EXPECT_EQ(disassembler->Abs32Locations().size(), expected_abs_count);
- EXPECT_EQ(disassembler->Rel32Locations().size(), expected_rel_count);
-
- // Prove that none of the rel32 RVAs overlap with abs32 RVAs
- std::set<courgette::RVA> abs(disassembler->Abs32Locations().begin(),
- disassembler->Abs32Locations().end());
- std::set<courgette::RVA> rel(disassembler->Rel32Locations().begin(),
- disassembler->Rel32Locations().end());
- for (std::vector<courgette::RVA>::iterator rel32 =
- disassembler->Rel32Locations().begin();
- rel32 != disassembler->Rel32Locations().end();
- rel32++) {
- EXPECT_TRUE(abs.find(*rel32) == abs.end());
- }
-
- for (std::vector<courgette::RVA>::iterator abs32 =
- disassembler->Abs32Locations().begin();
- abs32 != disassembler->Abs32Locations().end();
- abs32++) {
- EXPECT_TRUE(rel.find(*abs32) == rel.end());
- }
- delete program;
-}
-
-TEST_F(DisassemblerElf32X86Test, All) {
- TestExe("elf-32-1", 200, 3441);
-}
diff --git a/courgette/disassembler_win32_x86.cc b/courgette/disassembler_win32_x86.cc
index 39cb695..d09d67d 100644
--- a/courgette/disassembler_win32_x86.cc
+++ b/courgette/disassembler_win32_x86.cc
@@ -562,7 +562,7 @@ CheckBool DisassemblerWin32X86::ParseFileRegion(
// actually be anywhere. Make sure we skip it because we will regenerate it
// during assembly.
if (current_rva == relocs_start_rva) {
- ok = program->EmitPeRelocsInstruction();
+ ok = program->EmitMakeRelocsInstruction();
if (!ok)
break;
uint32 relocs_size = base_relocation_table().size_;
diff --git a/courgette/encode_decode_unittest.cc b/courgette/encode_decode_unittest.cc
index 20f0e16..90f5cd6 100644
--- a/courgette/encode_decode_unittest.cc
+++ b/courgette/encode_decode_unittest.cc
@@ -8,20 +8,20 @@
class EncodeDecodeTest : public BaseTest {
public:
- void TestAssembleToStreamDisassemble(std::string file,
- size_t expected_encoded_lenth) const;
+ void TestExe(const char *) const;
};
-void EncodeDecodeTest::TestAssembleToStreamDisassemble(
- std::string file,
- size_t expected_encoded_lenth) const {
- const void* original_buffer = file.c_str();
- size_t original_length = file.length();
+void EncodeDecodeTest::TestExe(const char* file_name) const {
+ // Test top-level Courgette API for converting an a file to a binary
+ // assembly representation and back.
+ std::string file1 = FileContents(file_name);
+
+ const void* original_buffer = file1.c_str();
+ size_t original_length = file1.size();
courgette::AssemblyProgram* program = NULL;
const courgette::Status parse_status =
- courgette::ParseDetectedExecutable(original_buffer,
- original_length,
+ courgette::ParseDetectedExecutable(original_buffer, original_length,
&program);
EXPECT_EQ(courgette::C_OK, parse_status);
@@ -45,7 +45,7 @@ void EncodeDecodeTest::TestAssembleToStreamDisassemble(
const void* buffer = sink.Buffer();
size_t length = sink.Length();
- EXPECT_EQ(expected_encoded_lenth, length);
+ EXPECT_EQ(971850U, length);
courgette::SourceStreamSet sources;
bool can_get_source_streams = sources.Init(buffer, length);
@@ -68,12 +68,7 @@ void EncodeDecodeTest::TestAssembleToStreamDisassemble(
DeleteEncodedProgram(encoded2);
}
-TEST_F(EncodeDecodeTest, PE) {
- std::string file = FileContents("setup1.exe");
- TestAssembleToStreamDisassemble(file, 971850);
-}
-TEST_F(EncodeDecodeTest, Elf_Small) {
- std::string file = FileContents("elf-32-1");
- TestAssembleToStreamDisassemble(file, 135988);
+TEST_F(EncodeDecodeTest, All) {
+ TestExe("setup1.exe");
}
diff --git a/courgette/encoded_program.cc b/courgette/encoded_program.cc
index b5e7310..a675dc2 100644
--- a/courgette/encoded_program.cc
+++ b/courgette/encoded_program.cc
@@ -16,7 +16,6 @@
#include "base/utf_string_conversions.h"
#include "courgette/courgette.h"
#include "courgette/streams.h"
-#include "courgette/types_elf.h"
namespace courgette {
@@ -242,12 +241,8 @@ CheckBool EncodedProgram::AddRel32(int label_index) {
return ops_.push_back(REL32) && rel32_ix_.push_back(label_index);
}
-CheckBool EncodedProgram::AddPeMakeRelocs() {
- return ops_.push_back(MAKE_PE_RELOCATION_TABLE);
-}
-
-CheckBool EncodedProgram::AddElfMakeRelocs() {
- return ops_.push_back(MAKE_ELF_RELOCATION_TABLE);
+CheckBool EncodedProgram::AddMakeRelocs() {
+ return ops_.push_back(MAKE_BASE_RELOCATION_TABLE);
}
void EncodedProgram::DebuggingSummary() {
@@ -404,9 +399,8 @@ CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) {
RVA current_rva = 0;
- bool pending_pe_relocation_table = false;
- bool pending_elf_relocation_table = false;
- SinkStream bytes_following_relocation_table;
+ bool pending_base_relocation_table = false;
+ SinkStream bytes_following_base_relocation_table;
SinkStream* output = final_buffer;
@@ -484,16 +478,16 @@ CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) {
break;
}
- case MAKE_PE_RELOCATION_TABLE: {
+ case MAKE_BASE_RELOCATION_TABLE: {
// We can see the base relocation anywhere, but we only have the
// information to generate it at the very end. So we divert the bytes
// we are generating to a temporary stream.
- if (pending_pe_relocation_table) // Can't have two base relocation
+ if (pending_base_relocation_table) // Can't have two base relocation
// tables.
return false;
- pending_pe_relocation_table = true;
- output = &bytes_following_relocation_table;
+ pending_base_relocation_table = true;
+ output = &bytes_following_base_relocation_table;
break;
// There is a potential problem *if* the instruction stream contains
// some REL32 relocations following the base relocation and in the same
@@ -504,31 +498,12 @@ CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) {
// executable except some padding zero bytes. We could fix this by
// emitting an ORIGIN after the MAKE_BASE_RELOCATION_TABLE.
}
-
- case MAKE_ELF_RELOCATION_TABLE: {
- // We can see the base relocation anywhere, but we only have the
- // information to generate it at the very end. So we divert the bytes
- // we are generating to a temporary stream.
- if (pending_elf_relocation_table) // Can't have two relocation
- // tables.
- return false;
-
- pending_elf_relocation_table = true;
- output = &bytes_following_relocation_table;
- break;
- }
}
}
- if (pending_pe_relocation_table) {
- if (!GeneratePeRelocations(final_buffer) ||
- !final_buffer->Append(&bytes_following_relocation_table))
- return false;
- }
-
- if (pending_elf_relocation_table) {
- if (!GenerateElfRelocations(final_buffer) ||
- !final_buffer->Append(&bytes_following_relocation_table))
+ if (pending_base_relocation_table) {
+ if (!GenerateBaseRelocations(final_buffer) ||
+ !final_buffer->Append(&bytes_following_base_relocation_table))
return false;
}
@@ -582,7 +557,7 @@ class RelocBlock {
RelocBlockPOD pod;
};
-CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer) {
+CheckBool EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) {
std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
RelocBlock block;
@@ -602,24 +577,6 @@ CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer) {
return ok;
}
-CheckBool EncodedProgram::GenerateElfRelocations(SinkStream* buffer) {
- std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
-
- Elf32_Rel relocation_block;
-
- // We only handle this specific type of relocation, so far.
- relocation_block.r_info = R_386_RELATIVE;
-
- bool ok = true;
- for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) {
- relocation_block.r_offset = abs32_relocs_[i];
- ok = buffer->Write(&relocation_block, sizeof(Elf32_Rel));
- }
-
- printf("Emitting size %ld\n", sizeof(Elf32_Rel) * abs32_relocs_.size());
-
- return ok;
-}
////////////////////////////////////////////////////////////////////////////////
Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink) {
diff --git a/courgette/encoded_program.h b/courgette/encoded_program.h
index 62f1439..b120353 100644
--- a/courgette/encoded_program.h
+++ b/courgette/encoded_program.h
@@ -43,8 +43,7 @@ class EncodedProgram {
CheckBool AddCopy(uint32 count, const void* bytes) WARN_UNUSED_RESULT;
CheckBool AddRel32(int label_index) WARN_UNUSED_RESULT;
CheckBool AddAbs32(int label_index) WARN_UNUSED_RESULT;
- CheckBool AddPeMakeRelocs() WARN_UNUSED_RESULT;
- CheckBool AddElfMakeRelocs() WARN_UNUSED_RESULT;
+ CheckBool AddMakeRelocs() WARN_UNUSED_RESULT;
// (3) Serialize binary assembly language tables to a set of streams.
CheckBool WriteTo(SinkStreamSet* streams) WARN_UNUSED_RESULT;
@@ -59,18 +58,16 @@ class EncodedProgram {
private:
// Binary assembly language operations.
- // These are part of the patch format. Reusing an existing value will
- // break backwards compatibility.
enum OP {
- ORIGIN = 0, // ORIGIN <rva> - set address for subsequent assembly.
- COPY = 1, // COPY <count> <bytes> - copy bytes to output.
- COPY1 = 2, // COPY1 <byte> - same as COPY 1 <byte>.
- REL32 = 3, // REL32 <index> - emit rel32 encoded reference to address at
- // address table offset <index>
- ABS32 = 4, // ABS32 <index> - emit abs32 encoded reference to address at
- // address table offset <index>
- MAKE_PE_RELOCATION_TABLE = 5, // Emit PE base relocation table blocks.
- MAKE_ELF_RELOCATION_TABLE = 6, // Emit Elf relocation table.
+ ORIGIN, // ORIGIN <rva> - set address for subsequent assembly.
+ COPY, // COPY <count> <bytes> - copy bytes to output.
+ COPY1, // COPY1 <byte> - same as COPY 1 <byte>.
+ REL32, // REL32 <index> - emit rel32 encoded reference to address at
+ // address table offset <index>
+ ABS32, // ABS32 <index> - emit abs32 encoded reference to address at
+ // address table offset <index>
+ MAKE_BASE_RELOCATION_TABLE, // Emit base relocation table blocks.
+ OP_LAST
};
typedef NoThrowBuffer<RVA> RvaVector;
@@ -79,8 +76,7 @@ class EncodedProgram {
typedef NoThrowBuffer<OP> OPVector;
void DebuggingSummary();
- CheckBool GeneratePeRelocations(SinkStream *buffer) WARN_UNUSED_RESULT;
- CheckBool GenerateElfRelocations(SinkStream *buffer) WARN_UNUSED_RESULT;
+ CheckBool GenerateBaseRelocations(SinkStream *buffer) WARN_UNUSED_RESULT;
CheckBool DefineLabelCommon(RvaVector*, int, RVA) WARN_UNUSED_RESULT;
void FinishLabelsCommon(RvaVector* addresses);
diff --git a/courgette/encoded_program_fuzz_unittest.cc b/courgette/encoded_program_fuzz_unittest.cc
index 9801fc8..fbf8df7 100644
--- a/courgette/encoded_program_fuzz_unittest.cc
+++ b/courgette/encoded_program_fuzz_unittest.cc
@@ -36,7 +36,7 @@ void DecodeFuzzTest::FuzzExe(const char* file_name) const {
std::string file1 = FileContents(file_name);
const void* original_buffer = file1.c_str();
- size_t original_length = file1.length();
+ size_t original_length = file1.size();
courgette::AssemblyProgram* program = NULL;
const courgette::Status parse_status =
@@ -199,7 +199,6 @@ bool DecodeFuzzTest::TryAssemble(const std::string& buffer,
TEST_F(DecodeFuzzTest, All) {
FuzzExe("setup1.exe");
- FuzzExe("elf-32-1.exe");
}
int main(int argc, char** argv) {
diff --git a/courgette/ensemble_apply.cc b/courgette/ensemble_apply.cc
index 475cdf2..d814264 100644
--- a/courgette/ensemble_apply.cc
+++ b/courgette/ensemble_apply.cc
@@ -142,9 +142,6 @@ Status EnsemblePatchApplication::ReadInitialParameters(
case EXE_WIN_32_X86:
patcher = new PatcherX86_32(base_region_);
break;
- case EXE_ELF_32_X86:
- patcher = new PatcherX86_32(base_region_);
- break;
}
if (patcher)
diff --git a/courgette/ensemble_create.cc b/courgette/ensemble_create.cc
index c098710..a5674ca9 100644
--- a/courgette/ensemble_create.cc
+++ b/courgette/ensemble_create.cc
@@ -76,15 +76,6 @@ TransformationPatchGenerator* MakeGenerator(Element* old_element,
EXE_WIN_32_X86);
return generator;
}
- case EXE_ELF_32_X86: {
- TransformationPatchGenerator* generator =
- new PatchGeneratorX86_32(
- old_element,
- new_element,
- new PatcherX86_32(old_element->region()),
- EXE_ELF_32_X86);
- return generator;
- }
}
LOG(WARNING) << "Unexpected Element::Kind " << old_element->kind();
diff --git a/courgette/patch_generator_x86_32.h b/courgette/patch_generator_x86_32.h
index 5ac017b..0e3b0a8 100644
--- a/courgette/patch_generator_x86_32.h
+++ b/courgette/patch_generator_x86_32.h
@@ -17,9 +17,9 @@ namespace courgette {
class PatchGeneratorX86_32 : public TransformationPatchGenerator {
public:
PatchGeneratorX86_32(Element* old_element,
- Element* new_element,
- PatcherX86_32* patcher,
- ExecutableType kind)
+ Element* new_element,
+ PatcherX86_32* patcher,
+ ExecutableType kind)
: TransformationPatchGenerator(old_element, new_element, patcher),
kind_(kind) {
}
diff --git a/courgette/types_elf.h b/courgette/types_elf.h
deleted file mode 100644
index 707f481..0000000
--- a/courgette/types_elf.h
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COURGETTE_ELF_TYPES_H_
-#define COURGETTE_ELF_TYPES_H_
-
-//
-// This header defines various types from the ELF file spec, but no code
-// related to using them.
-//
-
-typedef uint32 Elf32_Addr; // Unsigned program address
-typedef uint16 Elf32_Half; // Unsigned medium integer
-typedef uint32 Elf32_Off; // Unsigned file offset
-typedef int32 Elf32_Sword; // Signed large integer
-typedef uint32 Elf32_Word; // Unsigned large integer
-
-
-// The header at the top of the file
-struct Elf32_Ehdr {
- unsigned char e_ident[16];
- Elf32_Half e_type;
- Elf32_Half e_machine;
- Elf32_Word e_version;
- Elf32_Addr e_entry;
- Elf32_Off e_phoff;
- Elf32_Off e_shoff;
- Elf32_Word e_flags;
- Elf32_Half e_ehsize;
- Elf32_Half e_phentsize;
- Elf32_Half e_phnum;
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
-};
-
-// values for header->e_type
-enum e_type_values {
- ET_NONE = 0, // No file type
- ET_REL = 1, // Relocatable file
- ET_EXEC = 2, // Executable file
- ET_DYN = 3, // Shared object file
- ET_CORE = 4, // Core file
- ET_LOPROC = 0xff00, // Processor-specific
- ET_HIPROC = 0xfff // Processor-specific
-};
-
-// values for header->e_machine
-enum e_machine_values {
- EM_NONE = 0, // No machine
- EM_386 = 3, // Intel Architecture
- EM_x86_64 = 62, // Intel x86-64 Architecture
- // Other values skipped
-};
-
-// A section header in the section header table
-struct Elf32_Shdr {
- Elf32_Word sh_name;
- Elf32_Word sh_type;
- Elf32_Word sh_flags;
- Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
- Elf32_Word sh_size;
- Elf32_Word sh_link;
- Elf32_Word sh_info;
- Elf32_Word sh_addralign;
- Elf32_Word sh_entsize;
-};
-
-// Values for the section type field in a section header
-enum sh_type_values {
- SHT_NULL = 0,
- SHT_PROGBITS = 1,
- SHT_SYMTAB = 2,
- SHT_STRTAB = 3,
- SHT_RELA = 4,
- SHT_HASH = 5,
- SHT_DYNAMIC = 6,
- SHT_NOTE = 7,
- SHT_NOBITS = 8,
- SHT_REL = 9,
- SHT_SHLIB = 10,
- SHT_DYNSYM = 11,
- SHT_LOPROC = 0x70000000,
- SHT_HIPROC = 0x7fffffff,
- SHT_LOUSER = 0x80000000,
- SHT_HIUSER = 0xffffffff,
-};
-
-struct Elf32_Phdr {
- Elf32_Word p_type;
- Elf32_Off p_offset;
- Elf32_Addr p_vaddr;
- Elf32_Addr p_paddr;
- Elf32_Word p_filesz;
- Elf32_Word p_memsz;
- Elf32_Word p_flags;
- Elf32_Word p_align;
-};
-
-// Values for the segment type field in a program segment header
-enum ph_type_values {
- PT_NULL = 0,
- PT_LOAD = 1,
- PT_DYNAMIC = 2,
- PT_INTERP = 3,
- PT_NOTE = 4,
- PT_SHLIB = 5,
- PT_PHDR = 6,
- PT_LOPROC = 0x70000000,
- PT_HIPROC = 0x7fffffff
-};
-
-struct Elf32_Rel {
- Elf32_Addr r_offset;
- Elf32_Word r_info;
-};
-
-struct Elf32_Rela {
- Elf32_Addr r_offset;
- Elf32_Word r_info;
- Elf32_Sword r_addend;
-};
-
-enum elf32_rel_386_type_values {
- R_386_NONE = 0,
- R_386_32 = 1,
- R_386_PC32 = 2,
- R_386_GOT32 = 3,
- R_386_PLT32 = 4,
- R_386_COPY = 5,
- R_386_GLOB_DAT = 6,
- R_386_JMP_SLOT = 7,
- R_386_RELATIVE = 8,
- R_386_GOTOFF = 9,
- R_386_GOTPC = 10,
- R_386_TLS_TPOFF = 14,
-};
-
-#endif // COURGETTE_ELF_TYPES_H_