Index: courgette/encoded_program.cc |
diff --git a/courgette/encoded_program.cc b/courgette/encoded_program.cc |
index a675dc25dd5f52e77fa1bc5a296d375e2191468c..3da94147671890b9b80bb53ea2e71a2b63cf403c 100644 |
--- a/courgette/encoded_program.cc |
+++ b/courgette/encoded_program.cc |
@@ -16,6 +16,7 @@ |
#include "base/utf_string_conversions.h" |
#include "courgette/courgette.h" |
#include "courgette/streams.h" |
+#include "courgette/types_elf.h" |
namespace courgette { |
@@ -241,8 +242,12 @@ CheckBool EncodedProgram::AddRel32(int label_index) { |
return ops_.push_back(REL32) && rel32_ix_.push_back(label_index); |
} |
-CheckBool EncodedProgram::AddMakeRelocs() { |
- return ops_.push_back(MAKE_BASE_RELOCATION_TABLE); |
+CheckBool EncodedProgram::AddPeMakeRelocs() { |
+ return ops_.push_back(MAKE_PE_RELOCATION_TABLE); |
+} |
+ |
+CheckBool EncodedProgram::AddElfMakeRelocs() { |
+ return ops_.push_back(MAKE_ELF_RELOCATION_TABLE); |
} |
void EncodedProgram::DebuggingSummary() { |
@@ -399,8 +404,9 @@ CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) { |
RVA current_rva = 0; |
- bool pending_base_relocation_table = false; |
- SinkStream bytes_following_base_relocation_table; |
+ bool pending_pe_relocation_table = false; |
+ bool pending_elf_relocation_table = false; |
+ SinkStream bytes_following_relocation_table; |
SinkStream* output = final_buffer; |
@@ -478,16 +484,16 @@ CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) { |
break; |
} |
- case MAKE_BASE_RELOCATION_TABLE: { |
+ case MAKE_PE_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_base_relocation_table) // Can't have two base relocation |
+ if (pending_pe_relocation_table) // Can't have two base relocation |
// tables. |
return false; |
- pending_base_relocation_table = true; |
- output = &bytes_following_base_relocation_table; |
+ pending_pe_relocation_table = true; |
+ output = &bytes_following_relocation_table; |
break; |
// There is a potential problem *if* the instruction stream contains |
// some REL32 relocations following the base relocation and in the same |
@@ -498,12 +504,31 @@ 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_base_relocation_table) { |
- if (!GenerateBaseRelocations(final_buffer) || |
- !final_buffer->Append(&bytes_following_base_relocation_table)) |
+ 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)) |
return false; |
} |
@@ -557,7 +582,7 @@ class RelocBlock { |
RelocBlockPOD pod; |
}; |
-CheckBool EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) { |
+CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer) { |
std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); |
RelocBlock block; |
@@ -577,6 +602,22 @@ CheckBool EncodedProgram::GenerateBaseRelocations(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)); |
+ } |
+ |
+ return ok; |
+} |
//////////////////////////////////////////////////////////////////////////////// |
Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink) { |