Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: courgette/assembly_program.h

Issue 2476863004: [Courgette] AssemblyProgram: Serialize data to single raw buffer, instead of storing pointer of obj… (Closed)
Patch Set: Sync and merge. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/adjustment_method_2.cc ('k') | courgette/assembly_program.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <set> 13 #include <set>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/free_deleter.h" 18 #include "base/memory/free_deleter.h"
19 #include "courgette/courgette.h" 19 #include "courgette/courgette.h"
20 #include "courgette/image_utils.h" 20 #include "courgette/image_utils.h"
21 #include "courgette/label_manager.h" 21 #include "courgette/label_manager.h"
22 #include "courgette/memory_allocator.h" 22 #include "courgette/memory_allocator.h"
23 23
24 namespace courgette { 24 namespace courgette {
25 25
26 class EncodedProgram; 26 class EncodedProgram;
27 27
28 using serialized_size_t = uint32_t;
29
30 // Raw data array for AssemblyData seralization.
31 using AssemblyRawDataVector = NoThrowBuffer<uint8_t>;
32
28 // Opcodes of simple assembly language 33 // Opcodes of simple assembly language
29 enum OP { 34 class AssemblyOp {
30 ORIGIN, // ORIGIN <rva> - set current address for assembly.
31 MAKEPERELOCS, // Generates a base relocation table.
32 MAKEELFRELOCS, // Generates a base relocation table.
33 DEFBYTE, // DEFBYTE <value> - emit a byte literal.
34 REL32, // REL32 <label> - emit a rel32 encoded reference to 'label'.
35 ABS32, // ABS32 <label> - emit an abs32 encoded reference to 'label'.
36 REL32ARM, // REL32ARM <c_op> <label> - arm-specific rel32 reference
37 MAKEELFARMRELOCS, // Generates a base relocation table.
38 DEFBYTES, // Emits any number of byte literals
39 ABS64, // ABS64 <label> - emit an abs64 encoded reference to 'label'.
40 LAST_OP
41 };
42
43 // Base class for instructions. Because we have so many instructions we want to
44 // keep them as small as possible. For this reason we avoid virtual functions.
45 class Instruction {
46 public: 35 public:
47 OP op() const { return static_cast<OP>(op_); } 36 // Any change in this Update |kOpSize|
48 37 enum OP : uint8_t {
49 protected: 38 ORIGIN, // ORIGIN <rva>: Sets current address for assembly.
50 explicit Instruction(OP op) : op_(op), info_(0) {} 39 MAKEPERELOCS, // Generates a base relocation table.
51 Instruction(OP op, unsigned int info) : op_(op), info_(info) {} 40 MAKEELFRELOCS, // Generates a base relocation table.
52 41 SINGLEBYTE, // SINGLEBYTE <value>: Emits a byte literal.
53 uint32_t op_ : 4; // A few bits to store the OP code. 42 REL32, // REL32 <label>: Emits a rel32 encoded reference to Label.
54 uint32_t info_ : 28; // Remaining bits in first word available to subclass. 43 ABS32, // ABS32 <label>: Emits an abs32 encoded reference to Label.
55 44 REL32ARM, // REL32ARM <c_op> <label>: ARM-specific rel32 reference.
56 private: 45 MAKEELFARMRELOCS, // Generates a base relocation table.
57 DISALLOW_COPY_AND_ASSIGN(Instruction); 46 MULTIPLEBYTES, // Emits any number of byte literals.
47 ABS64, // ABS64 <label>: Emits an abs64 encoded reference to Label.
48 NUM_OP
49 };
58 }; 50 };
59 51
60 // An interface to receive emitted instructions parsed from an executable. 52 // An interface to receive emitted instructions parsed from an executable.
61 class InstructionReceptor { 53 class InstructionReceptor {
62 public: 54 public:
63 InstructionReceptor() = default; 55 InstructionReceptor() = default;
64 virtual ~InstructionReceptor() = default; 56 virtual ~InstructionReceptor() = default;
65 57
66 // Generates an entire base relocation table. 58 // Generates an entire base relocation table.
67 virtual CheckBool EmitPeRelocs() = 0; 59 virtual CheckBool EmitPeRelocs() = 0;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // The optional step is to modify the AssemblyProgram. One form of modification 107 // The optional step is to modify the AssemblyProgram. One form of modification
116 // is to assign indexes in such a way as to make the EncodedProgram for this 108 // is to assign indexes in such a way as to make the EncodedProgram for this
117 // AssemblyProgram look more like the EncodedProgram for some other 109 // AssemblyProgram look more like the EncodedProgram for some other
118 // AssemblyProgram. The modification process should call UnassignIndexes, do 110 // AssemblyProgram. The modification process should call UnassignIndexes, do
119 // its own assignment, and then call AssignRemainingIndexes to ensure all 111 // its own assignment, and then call AssignRemainingIndexes to ensure all
120 // indexes are assigned. 112 // indexes are assigned.
121 113
122 class AssemblyProgram { 114 class AssemblyProgram {
123 public: 115 public:
124 using LabelHandler = base::Callback<void(Label*)>; 116 using LabelHandler = base::Callback<void(Label*)>;
125 using LabelHandlerMap = std::map<OP, LabelHandler>; 117 using LabelHandlerMap = std::map<AssemblyOp::OP, LabelHandler>;
126 118
127 // A callback for GenerateInstructions() to emit instructions. The first 119 // A callback for GenerateInstructions() to emit instructions. The first
128 // argument (AssemblyProgram*) is provided for Label-related feature access. 120 // argument (AssemblyProgram*) is provided for Label-related feature access.
129 // The second argument (InstructionReceptor*) is a receptor for instructions. 121 // The second argument (InstructionReceptor*) is a receptor for instructions.
130 // The callback (which gets called in 2 passes) should return true on success, 122 // The callback (which gets called in 2 passes) should return true on success,
131 // and false otherwise. 123 // and false otherwise.
132 using InstructionGenerator = 124 using InstructionGenerator =
133 base::Callback<CheckBool(AssemblyProgram*, InstructionReceptor*)>; 125 base::Callback<CheckBool(AssemblyProgram*, InstructionReceptor*)>;
134 126
135 explicit AssemblyProgram(ExecutableType kind); 127 explicit AssemblyProgram(ExecutableType kind);
136 ~AssemblyProgram(); 128 ~AssemblyProgram() = default;
137 129
138 ExecutableType kind() const { return kind_; } 130 ExecutableType kind() const { return kind_; }
139 131
140 void set_image_base(uint64_t image_base) { image_base_ = image_base; } 132 void set_image_base(uint64_t image_base) { image_base_ = image_base; }
141 133
142 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels. 134 // Traverses RVAs in |abs32_visitor| and |rel32_visitor| to precompute Labels.
143 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor); 135 void PrecomputeLabels(RvaVisitor* abs32_visitor, RvaVisitor* rel32_visitor);
144 136
145 // Removes underused Labels. Thresholds used (0 = no trimming) is 137 // Removes underused Labels. Thresholds used (0 = no trimming) is
146 // architecture-dependent. 138 // architecture-dependent.
147 void TrimLabels(); 139 void TrimLabels();
148 140
149 void UnassignIndexes(); 141 void UnassignIndexes();
150 void DefaultAssignIndexes(); 142 void DefaultAssignIndexes();
151 void AssignRemainingIndexes(); 143 void AssignRemainingIndexes();
152 144
153 // Looks up abs32 label. Returns null if none found. 145 // Looks up abs32 label. Returns null if none found.
154 Label* FindAbs32Label(RVA rva); 146 Label* FindAbs32Label(RVA rva);
155 147
156 // Looks up rel32 label. Returns null if none found. 148 // Looks up rel32 label. Returns null if none found.
157 Label* FindRel32Label(RVA rva); 149 Label* FindRel32Label(RVA rva);
158 150
159 std::unique_ptr<EncodedProgram> Encode() const; 151 std::unique_ptr<EncodedProgram> Encode() const;
160 152
161 // For each |instruction| in |instructions_|, looks up its opcode from 153 // For each instruction in |raw_data_|, looks up its opcode from |handler_map|
162 // |handler_map| for a handler. If a handler exists, invoke it by passing the 154 // for a handler. If a handler exists, invoke it by passing the instruction's
163 // |instruction|'s label. We assume that |handler_map| has correct keys, i.e., 155 // label. We assume that |handler_map| has correct keys, i.e., opcodes for an
164 // opcodes for an instruction that have label. 156 // instruction that have label.
165 void HandleInstructionLabels(const LabelHandlerMap& handler_map) const; 157 void HandleInstructionLabels(const LabelHandlerMap& handler_map) const;
166 158
167 // Calls |gen| in 2 passes to emit instructions. In pass 1 we provide a 159 // Calls |gen| in 2 passes to emit instructions. In pass 1 we provide a
168 // receptor to count space requirement. In pass 2 we provide a receptor to 160 // receptor to count space requirement. In pass 2 we provide a receptor to
169 // store instructions. 161 // store instructions. This function can only be called once per instance.
170 CheckBool GenerateInstructions(const InstructionGenerator& gen); 162 CheckBool GenerateInstructions(const InstructionGenerator& gen);
171 163
172 // TODO(huangs): Implement these in InstructionStoreReceptor.
173 // Instructions will be assembled in the order they are emitted.
174
175 // Generates an entire base relocation table.
176 CheckBool EmitPeRelocs() WARN_UNUSED_RESULT;
177
178 // Generates an ELF style relocation table for X86.
179 CheckBool EmitElfRelocation() WARN_UNUSED_RESULT;
180
181 // Generates an ELF style relocation table for ARM.
182 CheckBool EmitElfARMRelocation() WARN_UNUSED_RESULT;
183
184 // Following instruction will be assembled at address 'rva'.
185 CheckBool EmitOrigin(RVA rva) WARN_UNUSED_RESULT;
186
187 // Generates a single byte of data or machine instruction.
188 CheckBool EmitSingleByte(uint8_t byte) WARN_UNUSED_RESULT;
189
190 // Generates multiple bytes of data or machine instructions.
191 CheckBool EmitMultipleBytes(const uint8_t* bytes,
192 size_t len) WARN_UNUSED_RESULT;
193
194 // Generates a 4-byte relative reference to address of 'label'.
195 CheckBool EmitRel32(Label* label) WARN_UNUSED_RESULT;
196
197 // Generates a 4-byte relative reference to address of 'label' for ARM.
198 CheckBool EmitRel32ARM(uint16_t op,
199 Label* label,
200 const uint8_t* arm_op,
201 uint16_t op_size) WARN_UNUSED_RESULT;
202
203 // Generates a 4-byte absolute reference to address of 'label'.
204 CheckBool EmitAbs32(Label* label) WARN_UNUSED_RESULT;
205
206 // Generates an 8-byte absolute reference to address of 'label'.
207 CheckBool EmitAbs64(Label* label) WARN_UNUSED_RESULT;
208
209 private: 164 private:
210 using InstructionVector = NoThrowBuffer<Instruction*>;
211
212 using ScopedInstruction =
213 std::unique_ptr<Instruction, UncheckedDeleter<Instruction>>;
214
215 ExecutableType kind_; 165 ExecutableType kind_;
216 166
217 CheckBool Emit(ScopedInstruction instruction) WARN_UNUSED_RESULT;
218 CheckBool EmitShared(Instruction* instruction) WARN_UNUSED_RESULT;
219
220 static const int kLabelLowerLimit; 167 static const int kLabelLowerLimit;
221 168
222 // Looks up a label or creates a new one. Might return NULL. 169 // Looks up a label or creates a new one. Might return NULL.
223 Label* FindLabel(RVA rva, RVAToLabel* labels); 170 Label* FindLabel(RVA rva, RVAToLabel* labels);
224 171
225 // Helper methods for the public versions. 172 // Helper methods for the public versions.
226 static void UnassignIndexes(RVAToLabel* labels); 173 static void UnassignIndexes(RVAToLabel* labels);
227 static void DefaultAssignIndexes(RVAToLabel* labels); 174 static void DefaultAssignIndexes(RVAToLabel* labels);
228 static void AssignRemainingIndexes(RVAToLabel* labels); 175 static void AssignRemainingIndexes(RVAToLabel* labels);
229 176
230 // Sharing instructions that emit a single byte saves a lot of space. 177 uint64_t image_base_ = 0; // Desired or mandated base address of image.
231 Instruction* GetByteInstruction(uint8_t byte);
232 std::unique_ptr<Instruction* [], base::FreeDeleter> byte_instruction_cache_;
233
234 uint64_t image_base_; // Desired or mandated base address of image.
235
236 InstructionVector instructions_; // All the instructions in program.
237 178
238 // Storage and lookup of Labels associated with target addresses. We use 179 // Storage and lookup of Labels associated with target addresses. We use
239 // separate abs32 and rel32 labels. 180 // separate abs32 and rel32 labels.
240 LabelManager abs32_label_manager_; 181 LabelManager abs32_label_manager_;
241 LabelManager rel32_label_manager_; 182 LabelManager rel32_label_manager_;
242 183
184 // Container of serialized instruction data.
185 AssemblyRawDataVector instruction_raw_data_;
186
243 DISALLOW_COPY_AND_ASSIGN(AssemblyProgram); 187 DISALLOW_COPY_AND_ASSIGN(AssemblyProgram);
244 }; 188 };
245 189
246 // Converts |program| into encoded form, returning it as |*output|. 190 // Converts |program| into encoded form, returning it as |*output|.
247 // Returns C_OK if succeeded, otherwise returns an error status and sets 191 // Returns C_OK if succeeded, otherwise returns an error status and sets
248 // |*output| to null. 192 // |*output| to null.
249 Status Encode(const AssemblyProgram& program, 193 Status Encode(const AssemblyProgram& program,
250 std::unique_ptr<EncodedProgram>* output); 194 std::unique_ptr<EncodedProgram>* output);
251 195
252 } // namespace courgette 196 } // namespace courgette
253 197
254 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_ 198 #endif // COURGETTE_ASSEMBLY_PROGRAM_H_
OLDNEW
« no previous file with comments | « courgette/adjustment_method_2.cc ('k') | courgette/assembly_program.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698