Index: courgette/assembly_program.h |
diff --git a/courgette/assembly_program.h b/courgette/assembly_program.h |
index 50ab30a6f6cac90685c496cbb96a8244bf30aae1..38477cc1a301a44a8c31fbf1505b3f8add918b51 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(); |
grt (UTC plus 2)
2016/11/04 09:38:53
remove this so that the compiler-generated ctor is
huangs
2016/11/04 18:20:40
Won't compile if I remove line. Changing to
Instr
|
+ virtual ~InstructionReceptor(); |
grt (UTC plus 2)
2016/11/04 09:38:53
= default; here and remove the definition from the
huangs
2016/11/04 18:20:39
Done.
|
+ |
+ // 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* value, |
grt (UTC plus 2)
2016/11/04 09:38:53
nit: value -> bytes here and elsewhere
huangs
2016/11/04 18:20:39
Done.
|
+ size_t len) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates 4-byte relative reference to address of 'label'. |
grt (UTC plus 2)
2016/11/04 09:38:53
nit: "Generates a..." (here and elsewhere)
huangs
2016/11/04 18:20:40
Done.
|
+ virtual CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates 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 4-byte absolute reference to address of 'label'. |
+ virtual CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT = 0; |
+ |
+ // Generates 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(); |
grt (UTC plus 2)
2016/11/04 09:38:53
remove
huangs
2016/11/04 18:20:39
Won't compile if I remove line. Changing to
Inst
|
+ ~InstructionCountReceptor() override; |
grt (UTC plus 2)
2016/11/04 09:38:53
remove
huangs
2016/11/04 18:20:39
Done.
|
+ |
+ // InstructionReceptor interfaces. |
grt (UTC plus 2)
2016/11/04 09:38:53
nit: just " // InstructionReceptor:"
huangs
2016/11/04 18:20:39
Done.
|
+ 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* value, |
+ 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; |
+ |
+ size_t size() const { return size_; } |
+ |
+ private: |
+ size_t size_; |
grt (UTC plus 2)
2016/11/04 09:38:53
= 0;
huangs
2016/11/04 18:20:39
Done.
|
+ |
+ DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor); |
+}; |
+ |
+class InstructionStoreReceptor : public InstructionReceptor { |
+ public: |
+ InstructionStoreReceptor(size_t init_size, AssemblyProgram* program); |
+ ~InstructionStoreReceptor() override; |
+ |
+ // InstructionReceptor interfaces. |
grt (UTC plus 2)
2016/11/04 09:38:53
// InstructionReceptor:
huangs
2016/11/04 18:20:39
Done.
|
+ 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* value, |
+ 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|. |
+ // Should only be called once. Returns true on success. |
grt (UTC plus 2)
2016/11/04 09:38:53
should or must?
huangs
2016/11/04 18:20:39
Must. Updated.
|
+ CheckBool CreateInstructionCountReceptor(InstructionCountReceptor** ret); |
+ |
+ // Returns via |ret| the InstructionStoreReceptor instance owned by |this|. |
+ // Should 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* 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; |
+ |
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); |
}; |