| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_ | 5 #ifndef COURGETTE_ASSEMBLY_PROGRAM_H_ |
| 6 #define COURGETTE_ASSEMBLY_PROGRAM_H_ | 6 #define COURGETTE_ASSEMBLY_PROGRAM_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| 11 #include <map> | 11 #include <map> |
| 12 #include <memory> | 12 #include <memory> |
| 13 | 13 |
| 14 #include "base/callback_forward.h" | 14 #include "base/callback_forward.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/free_deleter.h" | 16 #include "base/memory/free_deleter.h" |
| 17 #include "courgette/courgette.h" | 17 #include "courgette/courgette.h" |
| 18 #include "courgette/image_utils.h" | 18 #include "courgette/image_utils.h" |
| 19 #include "courgette/instruction_utils.h" |
| 19 #include "courgette/label_manager.h" | 20 #include "courgette/label_manager.h" |
| 20 #include "courgette/memory_allocator.h" | 21 #include "courgette/memory_allocator.h" |
| 21 | 22 |
| 22 namespace courgette { | 23 namespace courgette { |
| 23 | 24 |
| 24 class EncodedProgram; | 25 class EncodedProgram; |
| 25 | 26 |
| 26 // Opcodes of simple assembly language | 27 // Opcodes of simple assembly language |
| 27 enum OP { | 28 enum OP { |
| 28 ORIGIN, // ORIGIN <rva> - set current address for assembly. | 29 ORIGIN, // ORIGIN <rva> - set current address for assembly. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 48 explicit Instruction(OP op) : op_(op), info_(0) {} | 49 explicit Instruction(OP op) : op_(op), info_(0) {} |
| 49 Instruction(OP op, unsigned int info) : op_(op), info_(info) {} | 50 Instruction(OP op, unsigned int info) : op_(op), info_(info) {} |
| 50 | 51 |
| 51 uint32_t op_ : 4; // A few bits to store the OP code. | 52 uint32_t op_ : 4; // A few bits to store the OP code. |
| 52 uint32_t info_ : 28; // Remaining bits in first word available to subclass. | 53 uint32_t info_ : 28; // Remaining bits in first word available to subclass. |
| 53 | 54 |
| 54 private: | 55 private: |
| 55 DISALLOW_COPY_AND_ASSIGN(Instruction); | 56 DISALLOW_COPY_AND_ASSIGN(Instruction); |
| 56 }; | 57 }; |
| 57 | 58 |
| 58 // An interface to receive emitted instructions parsed from an executable. | |
| 59 class InstructionReceptor { | |
| 60 public: | |
| 61 InstructionReceptor() = default; | |
| 62 virtual ~InstructionReceptor() = default; | |
| 63 | |
| 64 // Generates an entire base relocation table. | |
| 65 virtual CheckBool EmitPeRelocs() = 0; | |
| 66 | |
| 67 // Generates an ELF style relocation table for X86. | |
| 68 virtual CheckBool EmitElfRelocation() = 0; | |
| 69 | |
| 70 // Generates an ELF style relocation table for ARM. | |
| 71 virtual CheckBool EmitElfARMRelocation() = 0; | |
| 72 | |
| 73 // Following instruction will be assembled at address 'rva'. | |
| 74 virtual CheckBool EmitOrigin(RVA rva) = 0; | |
| 75 | |
| 76 // Generates a single byte of data or machine instruction. | |
| 77 virtual CheckBool EmitSingleByte(uint8_t byte) = 0; | |
| 78 | |
| 79 // Generates multiple bytes of data or machine instructions. | |
| 80 virtual CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) = 0; | |
| 81 | |
| 82 // Generates a 4-byte relative reference to address of 'label'. | |
| 83 virtual CheckBool EmitRel32(Label* label) = 0; | |
| 84 | |
| 85 // Generates a 4-byte relative reference to address of 'label' for ARM. | |
| 86 virtual CheckBool EmitRel32ARM(uint16_t op, | |
| 87 Label* label, | |
| 88 const uint8_t* arm_op, | |
| 89 uint16_t op_size) = 0; | |
| 90 | |
| 91 // Generates a 4-byte absolute reference to address of 'label'. | |
| 92 virtual CheckBool EmitAbs32(Label* label) = 0; | |
| 93 | |
| 94 // Generates an 8-byte absolute reference to address of 'label'. | |
| 95 virtual CheckBool EmitAbs64(Label* label) = 0; | |
| 96 | |
| 97 private: | |
| 98 DISALLOW_COPY_AND_ASSIGN(InstructionReceptor); | |
| 99 }; | |
| 100 | |
| 101 // An AssemblyProgram is the result of disassembling an executable file. | 59 // An AssemblyProgram is the result of disassembling an executable file. |
| 102 // | 60 // |
| 103 // * The disassembler creates labels in the AssemblyProgram and emits | 61 // * The disassembler creates labels in the AssemblyProgram and emits |
| 104 // 'Instructions'. | 62 // 'Instructions'. |
| 105 // * The disassembler then calls DefaultAssignIndexes to assign | 63 // * The disassembler then calls DefaultAssignIndexes to assign |
| 106 // addresses to positions in the address tables. | 64 // addresses to positions in the address tables. |
| 107 // * [Optional step] | 65 // * [Optional step] |
| 108 // * At this point the AssemblyProgram can be converted into an | 66 // * At this point the AssemblyProgram can be converted into an |
| 109 // EncodedProgram and serialized to an output stream. | 67 // EncodedProgram and serialized to an output stream. |
| 110 // * Later, the EncodedProgram can be deserialized and assembled into | 68 // * Later, the EncodedProgram can be deserialized and assembled into |
| 111 // the original file. | 69 // the original file. |
| 112 // | 70 // |
| 113 // The optional step is to modify the AssemblyProgram. One form of modification | 71 // The optional step is to modify the AssemblyProgram. One form of modification |
| 114 // is to assign indexes in such a way as to make the EncodedProgram for this | 72 // is to assign indexes in such a way as to make the EncodedProgram for this |
| 115 // AssemblyProgram look more like the EncodedProgram for some other | 73 // AssemblyProgram look more like the EncodedProgram for some other |
| 116 // AssemblyProgram. The modification process should call UnassignIndexes, do | 74 // AssemblyProgram. The modification process should call UnassignIndexes, do |
| 117 // its own assignment, and then call AssignRemainingIndexes to ensure all | 75 // its own assignment, and then call AssignRemainingIndexes to ensure all |
| 118 // indexes are assigned. | 76 // indexes are assigned. |
| 119 | 77 |
| 120 class AssemblyProgram { | 78 class AssemblyProgram { |
| 121 public: | 79 public: |
| 122 using LabelHandler = base::Callback<void(Label*)>; | 80 using LabelHandler = base::Callback<void(Label*)>; |
| 123 using LabelHandlerMap = std::map<OP, LabelHandler>; | 81 using LabelHandlerMap = std::map<OP, LabelHandler>; |
| 124 | 82 |
| 125 // A callback for GenerateInstructions() to emit instructions. The first | |
| 126 // argument (AssemblyProgram*) is provided for Label-related feature access. | |
| 127 // The second argument (InstructionReceptor*) is a receptor for instructions. | |
| 128 // The callback (which gets called in 2 passes) should return true on success, | |
| 129 // and false otherwise. | |
| 130 using InstructionGenerator = | |
| 131 base::Callback<CheckBool(AssemblyProgram*, InstructionReceptor*)>; | |
| 132 | |
| 133 AssemblyProgram(ExecutableType kind, uint64_t image_base); | 83 AssemblyProgram(ExecutableType kind, uint64_t image_base); |
| 134 ~AssemblyProgram(); | 84 ~AssemblyProgram(); |
| 135 | 85 |
| 136 ExecutableType kind() const { return kind_; } | 86 ExecutableType kind() const { return kind_; } |
| 137 | 87 |
| 138 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. | 88 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. |
| 139 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); | 89 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); |
| 140 | 90 |
| 141 // Removes underused Labels. Thresholds used (0 = no trimming) is | 91 // Removes underused Labels. Thresholds used (0 = no trimming) is |
| 142 // architecture-dependent. | 92 // architecture-dependent. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 186 |
| 237 // Converts |program| into encoded form, returning it as |*output|. | 187 // Converts |program| into encoded form, returning it as |*output|. |
| 238 // Returns C_OK if succeeded, otherwise returns an error status and sets | 188 // Returns C_OK if succeeded, otherwise returns an error status and sets |
| 239 // |*output| to null. | 189 // |*output| to null. |
| 240 Status Encode(const AssemblyProgram& program, | 190 Status Encode(const AssemblyProgram& program, |
| 241 std::unique_ptr<EncodedProgram>* output); | 191 std::unique_ptr<EncodedProgram>* output); |
| 242 | 192 |
| 243 } // namespace courgette | 193 } // namespace courgette |
| 244 | 194 |
| 245 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_ | 195 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_ |
| OLD | NEW |