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); |
}; |