| Index: courgette/assembly_program.h
|
| diff --git a/courgette/assembly_program.h b/courgette/assembly_program.h
|
| index 50ab30a6f6cac90685c496cbb96a8244bf30aae1..86bd0449e670acb95e0a8316f026a316ea2677dc 100644
|
| --- a/courgette/assembly_program.h
|
| +++ b/courgette/assembly_program.h
|
| @@ -57,7 +57,48 @@ class Instruction {
|
| DISALLOW_COPY_AND_ASSIGN(Instruction);
|
| };
|
|
|
| -typedef NoThrowBuffer<Instruction*> InstructionVector;
|
| +// An interface to receive emitted instructions parsed from an executable.
|
| +class InstructionReceptor {
|
| + public:
|
| + InstructionReceptor() = default;
|
| + virtual ~InstructionReceptor() = default;
|
| +
|
| + // Generates an entire base relocation table.
|
| + virtual CheckBool EmitPeRelocs() = 0;
|
| +
|
| + // Generates an ELF style relocation table for X86.
|
| + virtual CheckBool EmitElfRelocation() = 0;
|
| +
|
| + // Generates an ELF style relocation table for ARM.
|
| + virtual CheckBool EmitElfARMRelocation() = 0;
|
| +
|
| + // Following instruction will be assembled at address 'rva'.
|
| + virtual CheckBool EmitOrigin(RVA rva) = 0;
|
| +
|
| + // Generates a single byte of data or machine instruction.
|
| + virtual CheckBool EmitSingleByte(uint8_t byte) = 0;
|
| +
|
| + // Generates multiple bytes of data or machine instructions.
|
| + virtual CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) = 0;
|
| +
|
| + // Generates a 4-byte relative reference to address of 'label'.
|
| + virtual CheckBool EmitRel32(Label* label) = 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) = 0;
|
| +
|
| + // Generates a 4-byte absolute reference to address of 'label'.
|
| + virtual CheckBool EmitAbs32(Label* label) = 0;
|
| +
|
| + // Generates an 8-byte absolute reference to address of 'label'.
|
| + virtual CheckBool EmitAbs64(Label* label) = 0;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(InstructionReceptor);
|
| +};
|
|
|
| // An AssemblyProgram is the result of disassembling an executable file.
|
| //
|
| @@ -77,12 +118,20 @@ 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*)>;
|
| using LabelHandlerMap = std::map<OP, LabelHandler>;
|
|
|
| + // A callback for GenerateInstructions() to emit instructions. The first
|
| + // argument (AssemblyProgram*) is provided for Label-related feature access.
|
| + // The second argument (InstructionReceptor*) is a receptor for instructions.
|
| + // The callback (which gets called in 2 passes) should return true on success,
|
| + // and false otherwise.
|
| + using InstructionGenerator =
|
| + base::Callback<CheckBool(AssemblyProgram*, InstructionReceptor*)>;
|
| +
|
| explicit AssemblyProgram(ExecutableType kind);
|
| ~AssemblyProgram();
|
|
|
| @@ -90,43 +139,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,7 +164,51 @@ class AssemblyProgram {
|
| // opcodes for an instruction that have label.
|
| void HandleInstructionLabels(const LabelHandlerMap& handler_map) const;
|
|
|
| + // Calls |gen| in 2 passes to emit instructions. In pass 1 we provide a
|
| + // receptor to count space requirement. In pass 2 we provide a receptor to
|
| + // store instructions.
|
| + CheckBool GenerateInstructions(const InstructionGenerator& gen);
|
| +
|
| + // TODO(huangs): Implement these in InstructionStoreReceptor.
|
| + // Instructions will be assembled in the order they are emitted.
|
| +
|
| + // 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;
|
| +
|
| private:
|
| + using InstructionVector = NoThrowBuffer<Instruction*>;
|
| +
|
| using ScopedInstruction =
|
| std::unique_ptr<Instruction, UncheckedDeleter<Instruction>>;
|
|
|
|
|