Skip to content

Commit

Permalink
Add Elf 32 Support to Courgette.
Browse files Browse the repository at this point in the history
This change takes advantage of recent refactoring and adds support for
Elf X86 32 executables to courgette. It should have no effect on handling
of Windows PE executables.

We have planned ahead to be able to restrict the code size of the courgette
library in different cases to reduce patcher sizes, but this change does
not yet take advantage of that (all platforms are supported everywhere).

Also, the patcher class currently contains a very small amount of Elf/PE
specific code for recreating relocation tables that cannot (currently) be
compiled out.

BUG=chromium-os:22149
TEST=Please verify that Chrome/Chromium patches can still be generated and
     work.
     Also, please see how much the updater executable which is downloaded to
     users has changed in size since R16.


Review URL: http://codereview.chromium.org/8428009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108929 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
dgarrett@chromium.org committed Nov 7, 2011
1 parent 2ca5986 commit 88da507
Show file tree
Hide file tree
Showing 19 changed files with 1,111 additions and 51 deletions.
32 changes: 24 additions & 8 deletions courgette/assembly_program.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ namespace courgette {
// Opcodes of simple assembly language
enum OP {
ORIGIN, // ORIGIN <rva> - set current address for assembly.
MAKERELOCS, // Generates a base relocation table.
MAKEPERELOCS, // Generates a base relocation table.
MAKEELFRELOCS, // 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'.
Expand Down Expand Up @@ -58,10 +59,16 @@ class OriginInstruction : public Instruction {
RVA rva_;
};

// Emits an entire base relocation table.
class MakeRelocsInstruction : public Instruction {
// Emits an entire PE base relocation table.
class PeRelocsInstruction : public Instruction {
public:
MakeRelocsInstruction() : Instruction(MAKERELOCS) {}
PeRelocsInstruction() : Instruction(MAKEPERELOCS) {}
};

// Emits an ELF relocation table.
class ElfRelocsInstruction : public Instruction {
public:
ElfRelocsInstruction() : Instruction(MAKEELFRELOCS) {}
};

// Emits a single byte.
Expand Down Expand Up @@ -108,8 +115,12 @@ AssemblyProgram::~AssemblyProgram() {
DeleteContainedLabels(abs32_labels_);
}

CheckBool AssemblyProgram::EmitMakeRelocsInstruction() {
return Emit(new(std::nothrow) MakeRelocsInstruction());
CheckBool AssemblyProgram::EmitPeRelocsInstruction() {
return Emit(new(std::nothrow) PeRelocsInstruction());
}

CheckBool AssemblyProgram::EmitElfRelocationInstruction() {
return Emit(new(std::nothrow) ElfRelocsInstruction());
}

CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) {
Expand Down Expand Up @@ -357,8 +368,13 @@ EncodedProgram* AssemblyProgram::Encode() const {
return NULL;
break;
}
case MAKERELOCS: {
if (!encoded->AddMakeRelocs())
case MAKEPERELOCS: {
if (!encoded->AddPeMakeRelocs())
return NULL;
break;
}
case MAKEELFRELOCS: {
if (!encoded->AddElfMakeRelocs())
return NULL;
break;
}
Expand Down
5 changes: 4 additions & 1 deletion courgette/assembly_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ class AssemblyProgram {
// Instructions will be assembled in the order they are emitted.

// Generates an entire base relocation table.
CheckBool EmitMakeRelocsInstruction() WARN_UNUSED_RESULT;
CheckBool EmitPeRelocsInstruction() WARN_UNUSED_RESULT;

// Generates an ELF style relocation table.
CheckBool EmitElfRelocationInstruction() WARN_UNUSED_RESULT;

// Following instruction will be assembled at address 'rva'.
CheckBool EmitOriginInstruction(RVA rva) WARN_UNUSED_RESULT;
Expand Down
6 changes: 6 additions & 0 deletions courgette/bsdiff_memory_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,9 @@ 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);
}
5 changes: 5 additions & 0 deletions courgette/courgette.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
'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',
Expand All @@ -37,6 +39,8 @@
'simple_delta.h',
'streams.cc',
'streams.h',
'types_elf.h',
'types_win_pe.h',
'patch_generator_x86_32.h',
'patcher_x86_32.h',
],
Expand Down Expand Up @@ -89,6 +93,7 @@
'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',
Expand Down
1 change: 1 addition & 0 deletions courgette/courgette.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ enum Status {
enum ExecutableType {
EXE_UNKNOWN = 0,
EXE_WIN_32_X86 = 1,
EXE_ELF_32_X86 = 2,
};

class SinkStream;
Expand Down
9 changes: 8 additions & 1 deletion courgette/disassembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#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"

Expand All @@ -30,8 +31,14 @@ Disassembler* DetectDisassembler(const void* buffer, size_t length) {
disassembler = new DisassemblerWin32X86(buffer, length);
if (disassembler->ParseHeader())
return disassembler;
else
delete disassembler;

delete disassembler;
disassembler = new DisassemblerElf32X86(buffer, length);
if (disassembler->ParseHeader())
return disassembler;
else
delete disassembler;

return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion courgette/disassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Disassembler {
}

// Reduce the length of the image in memory. Does not actually free
// (or realloc) any memory. Unusally only called via ParseHeader()
// (or realloc) any memory. Usually only called via ParseHeader()
void ReduceLength(size_t reduced_length);

private:
Expand Down
Loading

0 comments on commit 88da507

Please sign in to comment.