| Index: courgette/assembly_program.h
|
| diff --git a/courgette/assembly_program.h b/courgette/assembly_program.h
|
| index 86bd0449e670acb95e0a8316f026a316ea2677dc..ddc3e7471a83a29c83c1fd0331e83cd1ef9a28ed 100644
|
| --- a/courgette/assembly_program.h
|
| +++ b/courgette/assembly_program.h
|
| @@ -25,36 +25,28 @@ namespace courgette {
|
|
|
| class EncodedProgram;
|
|
|
| -// Opcodes of simple assembly language
|
| -enum OP {
|
| - ORIGIN, // ORIGIN <rva> - set current address for assembly.
|
| - MAKEPERELOCS, // Generates a base relocation table.
|
| - MAKEELFRELOCS, // Generates a base relocation table.
|
| - DEFBYTE, // DEFBYTE <value> - emit a byte literal.
|
| - REL32, // REL32 <label> - emit a rel32 encoded reference to 'label'.
|
| - ABS32, // ABS32 <label> - emit an abs32 encoded reference to 'label'.
|
| - REL32ARM, // REL32ARM <c_op> <label> - arm-specific rel32 reference
|
| - MAKEELFARMRELOCS, // Generates a base relocation table.
|
| - DEFBYTES, // Emits any number of byte literals
|
| - ABS64, // ABS64 <label> - emit an abs64 encoded reference to 'label'.
|
| - LAST_OP
|
| -};
|
| -
|
| -// Base class for instructions. Because we have so many instructions we want to
|
| -// keep them as small as possible. For this reason we avoid virtual functions.
|
| -class Instruction {
|
| - public:
|
| - OP op() const { return static_cast<OP>(op_); }
|
| -
|
| - protected:
|
| - explicit Instruction(OP op) : op_(op), info_(0) {}
|
| - Instruction(OP op, unsigned int info) : op_(op), info_(info) {}
|
| +using serialized_size_t = uint32_t;
|
|
|
| - uint32_t op_ : 4; // A few bits to store the OP code.
|
| - uint32_t info_ : 28; // Remaining bits in first word available to subclass.
|
| +// Raw data array for AssemblyData seralization.
|
| +using AssemblyRawDataVector = NoThrowBuffer<uint8_t>;
|
|
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(Instruction);
|
| +// Opcodes of simple assembly language
|
| +class AssemblyOp {
|
| + public:
|
| + // Any change in this Update |kOpSize|
|
| + enum OP : uint8_t {
|
| + ORIGIN, // ORIGIN <rva>: Sets current address for assembly.
|
| + MAKEPERELOCS, // Generates a base relocation table.
|
| + MAKEELFRELOCS, // Generates a base relocation table.
|
| + SINGLEBYTE, // SINGLEBYTE <value>: Emits a byte literal.
|
| + REL32, // REL32 <label>: Emits a rel32 encoded reference to Label.
|
| + ABS32, // ABS32 <label>: Emits an abs32 encoded reference to Label.
|
| + REL32ARM, // REL32ARM <c_op> <label>: ARM-specific rel32 reference.
|
| + MAKEELFARMRELOCS, // Generates a base relocation table.
|
| + MULTIPLEBYTES, // Emits any number of byte literals.
|
| + ABS64, // ABS64 <label>: Emits an abs64 encoded reference to Label.
|
| + NUM_OP
|
| + };
|
| };
|
|
|
| // An interface to receive emitted instructions parsed from an executable.
|
| @@ -122,7 +114,7 @@ class InstructionReceptor {
|
| class AssemblyProgram {
|
| public:
|
| using LabelHandler = base::Callback<void(Label*)>;
|
| - using LabelHandlerMap = std::map<OP, LabelHandler>;
|
| + using LabelHandlerMap = std::map<AssemblyOp::OP, LabelHandler>;
|
|
|
| // A callback for GenerateInstructions() to emit instructions. The first
|
| // argument (AssemblyProgram*) is provided for Label-related feature access.
|
| @@ -133,7 +125,7 @@ class AssemblyProgram {
|
| base::Callback<CheckBool(AssemblyProgram*, InstructionReceptor*)>;
|
|
|
| explicit AssemblyProgram(ExecutableType kind);
|
| - ~AssemblyProgram();
|
| + ~AssemblyProgram() = default;
|
|
|
| ExecutableType kind() const { return kind_; }
|
|
|
| @@ -158,65 +150,20 @@ class AssemblyProgram {
|
|
|
| std::unique_ptr<EncodedProgram> Encode() const;
|
|
|
| - // For each |instruction| in |instructions_|, looks up its opcode from
|
| - // |handler_map| for a handler. If a handler exists, invoke it by passing the
|
| - // |instruction|'s label. We assume that |handler_map| has correct keys, i.e.,
|
| - // opcodes for an instruction that have label.
|
| + // For each instruction in |raw_data_|, looks up its opcode from |handler_map|
|
| + // for a handler. If a handler exists, invoke it by passing the instruction's
|
| + // label. We assume that |handler_map| has correct keys, i.e., 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.
|
| + // store instructions. This function can only be called once per instance.
|
| 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>>;
|
| -
|
| ExecutableType kind_;
|
|
|
| - CheckBool Emit(ScopedInstruction instruction) WARN_UNUSED_RESULT;
|
| - CheckBool EmitShared(Instruction* instruction) WARN_UNUSED_RESULT;
|
| -
|
| static const int kLabelLowerLimit;
|
|
|
| // Looks up a label or creates a new one. Might return NULL.
|
| @@ -227,19 +174,16 @@ class AssemblyProgram {
|
| static void DefaultAssignIndexes(RVAToLabel* labels);
|
| static void AssignRemainingIndexes(RVAToLabel* labels);
|
|
|
| - // Sharing instructions that emit a single byte saves a lot of space.
|
| - Instruction* GetByteInstruction(uint8_t byte);
|
| - std::unique_ptr<Instruction* [], base::FreeDeleter> byte_instruction_cache_;
|
| -
|
| - uint64_t image_base_; // Desired or mandated base address of image.
|
| -
|
| - InstructionVector instructions_; // All the instructions in program.
|
| + uint64_t image_base_ = 0; // Desired or mandated base address of image.
|
|
|
| // Storage and lookup of Labels associated with target addresses. We use
|
| // separate abs32 and rel32 labels.
|
| LabelManager abs32_label_manager_;
|
| LabelManager rel32_label_manager_;
|
|
|
| + // Container of serialized instruction data.
|
| + AssemblyRawDataVector instruction_raw_data_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(AssemblyProgram);
|
| };
|
|
|
|
|