Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2619)

Unified Diff: courgette/assembly_program.h

Issue 2462993003: [Courgette] Refactor: Add and use Instruction*Receptor classes; call ParseFile() in 2 passes. (Closed)
Patch Set: Fix style and comments; lint; remove size param from InstructionStoreReceptor ctor. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
};

Powered by Google App Engine
This is Rietveld 408576698