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 |