Index: courgette/assembly_program.h |
diff --git a/courgette/assembly_program.h b/courgette/assembly_program.h |
index 50ab30a6f6cac90685c496cbb96a8244bf30aae1..547d1489e08fe1b5b061974895c25b2764f05ed1 100644 |
--- a/courgette/assembly_program.h |
+++ b/courgette/assembly_program.h |
@@ -23,6 +23,7 @@ |
namespace courgette { |
+class AssemblyProgram; |
class EncodedProgram; |
// Opcodes of simple assembly language |
@@ -57,7 +58,104 @@ class Instruction { |
DISALLOW_COPY_AND_ASSIGN(Instruction); |
}; |
-typedef NoThrowBuffer<Instruction*> InstructionVector; |
+class InstructionReceptor { |
+ public: |
+ InstructionReceptor() = default; |
+ virtual ~InstructionReceptor() = default; |
+ |
+ // Generates an entire base relocation table. |
+ virtual CheckBool EmitPeRelocs() WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates an ELF style relocation table for X86. |
+ virtual CheckBool EmitElfRelocation() WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates an ELF style relocation table for ARM. |
+ virtual CheckBool EmitElfARMRelocation() WARN_UNUSED_RESULT = 0; |
+ |
+ // Following instruction will be assembled at address 'rva'. |
+ virtual CheckBool EmitOrigin(RVA rva) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates a single byte of data or machine instruction. |
+ virtual CheckBool EmitSingleByte(uint8_t byte) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates multiple bytes of data or machine instructions. |
+ virtual CheckBool EmitMultipleBytes(const uint8_t* bytes, |
+ size_t len) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates a 4-byte relative reference to address of 'label'. |
+ virtual CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates a 4-byte relative reference to address of 'label' for ARM. |
+ virtual CheckBool EmitRel32ARM(uint16_t op, |
+ Label* label, |
+ const uint8_t* arm_op, |
+ uint16_t op_size) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates a 4-byte absolute reference to address of 'label'. |
+ virtual CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates an 8-byte absolute reference to address of 'label'. |
+ virtual CheckBool EmitAbs64(Label* label) WARN_UNUSED_RESULT = 0; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(InstructionReceptor); |
+}; |
+ |
+class InstructionCountReceptor : public InstructionReceptor { |
+ public: |
+ InstructionCountReceptor() = default; |
+ |
+ size_t size() const { return size_; } |
+ |
+ // InstructionReceptor: |
+ CheckBool EmitPeRelocs() override WARN_UNUSED_RESULT; |
+ CheckBool EmitElfRelocation() override WARN_UNUSED_RESULT; |
+ CheckBool EmitElfARMRelocation() override WARN_UNUSED_RESULT; |
+ CheckBool EmitOrigin(RVA rva) override WARN_UNUSED_RESULT; |
+ CheckBool EmitSingleByte(uint8_t byte) override WARN_UNUSED_RESULT; |
+ CheckBool EmitMultipleBytes(const uint8_t* bytes, |
+ size_t len) override WARN_UNUSED_RESULT; |
+ CheckBool EmitRel32(Label* label) override WARN_UNUSED_RESULT; |
+ CheckBool EmitRel32ARM(uint16_t op, |
+ Label* label, |
+ const uint8_t* arm_op, |
+ uint16_t op_size) override WARN_UNUSED_RESULT; |
+ CheckBool EmitAbs32(Label* label) override WARN_UNUSED_RESULT; |
+ CheckBool EmitAbs64(Label* label) override WARN_UNUSED_RESULT; |
+ |
+ private: |
+ size_t size_ = 0; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor); |
+}; |
+ |
+class InstructionStoreReceptor : public InstructionReceptor { |
+ public: |
+ explicit InstructionStoreReceptor(AssemblyProgram* program); |
+ |
+ // TODO(huangs): 2016/11: Add Reserve(). |
+ |
+ // InstructionReceptor: |
+ CheckBool EmitPeRelocs() override WARN_UNUSED_RESULT; |
+ CheckBool EmitElfRelocation() override WARN_UNUSED_RESULT; |
+ CheckBool EmitElfARMRelocation() override WARN_UNUSED_RESULT; |
+ CheckBool EmitOrigin(RVA rva) override WARN_UNUSED_RESULT; |
+ CheckBool EmitSingleByte(uint8_t byte) override WARN_UNUSED_RESULT; |
+ CheckBool EmitMultipleBytes(const uint8_t* bytes, |
+ size_t len) override WARN_UNUSED_RESULT; |
+ CheckBool EmitRel32(Label* label) override WARN_UNUSED_RESULT; |
+ CheckBool EmitRel32ARM(uint16_t op, |
+ Label* label, |
+ const uint8_t* arm_op, |
+ uint16_t op_size) override WARN_UNUSED_RESULT; |
+ CheckBool EmitAbs32(Label* label) override WARN_UNUSED_RESULT; |
+ CheckBool EmitAbs64(Label* label) override WARN_UNUSED_RESULT; |
+ |
+ private: |
+ AssemblyProgram* program_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); |
+}; |
// An AssemblyProgram is the result of disassembling an executable file. |
// |
@@ -77,7 +175,7 @@ typedef NoThrowBuffer<Instruction*> InstructionVector; |
// AssemblyProgram. The modification process should call UnassignIndexes, do |
// its own assignment, and then call AssignRemainingIndexes to ensure all |
// indexes are assigned. |
-// |
+ |
class AssemblyProgram { |
public: |
using LabelHandler = base::Callback<void(Label*)>; |
@@ -90,43 +188,6 @@ class AssemblyProgram { |
void set_image_base(uint64_t image_base) { image_base_ = image_base; } |
- // 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 for X86. |
- CheckBool EmitElfRelocationInstruction() WARN_UNUSED_RESULT; |
- |
- // Generates an ELF style relocation table for ARM. |
- CheckBool EmitElfARMRelocationInstruction() WARN_UNUSED_RESULT; |
- |
- // Following instruction will be assembled at address 'rva'. |
- CheckBool EmitOriginInstruction(RVA rva) WARN_UNUSED_RESULT; |
- |
- // Generates a single byte of data or machine instruction. |
- CheckBool EmitByteInstruction(uint8_t byte) WARN_UNUSED_RESULT; |
- |
- // Generates multiple bytes of data or machine instructions. |
- CheckBool EmitBytesInstruction(const uint8_t* value, |
- size_t len) WARN_UNUSED_RESULT; |
- |
- // Generates 4-byte relative reference to address of 'label'. |
- CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT; |
- |
- // Generates 4-byte relative reference to address of 'label' for |
- // ARM. |
- CheckBool EmitRel32ARM(uint16_t op, |
- Label* label, |
- const uint8_t* arm_op, |
- uint16_t op_size) WARN_UNUSED_RESULT; |
- |
- // Generates 4-byte absolute reference to address of 'label'. |
- CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT; |
- |
- // Generates 8-byte absolute reference to address of 'label'. |
- CheckBool EmitAbs64(Label* label) WARN_UNUSED_RESULT; |
- |
// Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. |
void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); |
@@ -152,10 +213,61 @@ class AssemblyProgram { |
// opcodes for an instruction that have label. |
void HandleInstructionLabels(const LabelHandlerMap& handler_map) const; |
+ // Returns via |ret| the InstructionCountReceptor instance owned by |this|. |
+ // Must only be called once. Returns true on success. |
+ CheckBool CreateInstructionCountReceptor(InstructionCountReceptor** ret); |
grt (UTC plus 2)
2016/11/07 09:36:17
consumers of these methods don't need to know the
huangs
2016/11/07 19:46:52
Move implementations entirely into .cc file.
|
+ |
+ // Returns via |ret| the InstructionStoreReceptor instance owned by |this|. |
+ // Must only be called once, and only after CreateInstructionCountReceptor() |
+ // has been called. Returns true on success. |
+ CheckBool CreateInstructionStoreReceptor(InstructionStoreReceptor** ret); |
+ |
private: |
+ using InstructionVector = NoThrowBuffer<Instruction*>; |
+ |
using ScopedInstruction = |
std::unique_ptr<Instruction, UncheckedDeleter<Instruction>>; |
+ friend InstructionStoreReceptor; |
+ |
+ // Instructions will be assembled in the order they are emitted. |
+ |
+ // TODO(huangs): Implement these in InstructionStoreReceptor. |
+ |
+ // Generates an entire base relocation table. |
+ CheckBool EmitPeRelocs() WARN_UNUSED_RESULT; |
+ |
+ // Generates an ELF style relocation table for X86. |
+ CheckBool EmitElfRelocation() WARN_UNUSED_RESULT; |
+ |
+ // Generates an ELF style relocation table for ARM. |
+ CheckBool EmitElfARMRelocation() WARN_UNUSED_RESULT; |
+ |
+ // Following instruction will be assembled at address 'rva'. |
+ CheckBool EmitOrigin(RVA rva) WARN_UNUSED_RESULT; |
+ |
+ // Generates a single byte of data or machine instruction. |
+ CheckBool EmitSingleByte(uint8_t byte) WARN_UNUSED_RESULT; |
+ |
+ // Generates multiple bytes of data or machine instructions. |
+ CheckBool EmitMultipleBytes(const uint8_t* bytes, |
+ size_t len) WARN_UNUSED_RESULT; |
+ |
+ // Generates a 4-byte relative reference to address of 'label'. |
+ CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT; |
+ |
+ // Generates a 4-byte relative reference to address of 'label' for ARM. |
+ CheckBool EmitRel32ARM(uint16_t op, |
+ Label* label, |
+ const uint8_t* arm_op, |
+ uint16_t op_size) WARN_UNUSED_RESULT; |
+ |
+ // Generates a 4-byte absolute reference to address of 'label'. |
+ CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT; |
+ |
+ // Generates an 8-byte absolute reference to address of 'label'. |
+ CheckBool EmitAbs64(Label* label) WARN_UNUSED_RESULT; |
+ |
ExecutableType kind_; |
CheckBool Emit(ScopedInstruction instruction) WARN_UNUSED_RESULT; |
@@ -184,6 +296,9 @@ class AssemblyProgram { |
LabelManager abs32_label_manager_; |
LabelManager rel32_label_manager_; |
+ std::unique_ptr<InstructionCountReceptor> count_receptor_; |
+ std::unique_ptr<InstructionStoreReceptor> store_receptor_; |
+ |
DISALLOW_COPY_AND_ASSIGN(AssemblyProgram); |
}; |