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

Side by Side Diff: courgette/assembly_program.cc

Issue 2462993003: [Courgette] Refactor: Add and use Instruction*Receptor classes; call ParseFile() in 2 passes. (Closed)
Patch Set: Fix comments. 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/assembly_program.h ('k') | courgette/disassembler_elf_32.h » ('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 #include "courgette/assembly_program.h" 5 #include "courgette/assembly_program.h"
6 6
7 #include <memory.h> 7 #include <memory.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 uint16_t compressed_op() const { return compressed_op_; } 98 uint16_t compressed_op() const { return compressed_op_; }
99 const uint8_t* arm_op() const { return arm_op_; } 99 const uint8_t* arm_op() const { return arm_op_; }
100 uint16_t op_size() const { return op_size_; } 100 uint16_t op_size() const { return op_size_; }
101 101
102 private: 102 private:
103 uint16_t compressed_op_; 103 uint16_t compressed_op_;
104 const uint8_t* arm_op_; 104 const uint8_t* arm_op_;
105 uint16_t op_size_; 105 uint16_t op_size_;
106 }; 106 };
107 107
108 /******** InstructionCountReceptor ********/
109
110 // An InstructionReceptor that counts space occupied by emitted instructions.
111 class InstructionCountReceptor : public InstructionReceptor {
112 public:
113 InstructionCountReceptor() = default;
114
115 size_t size() const { return size_; }
116
117 // InstructionReceptor:
118 // TODO(huangs): 2016/11: Populate these with size_ += ...
119 CheckBool EmitPeRelocs() override { return true; }
120 CheckBool EmitElfRelocation() override { return true; }
121 CheckBool EmitElfARMRelocation() override { return true; }
122 CheckBool EmitOrigin(RVA rva) override { return true; }
123 CheckBool EmitSingleByte(uint8_t byte) override { return true; }
124 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override {
125 return true;
126 }
127 CheckBool EmitRel32(Label* label) override { return true; }
128 CheckBool EmitRel32ARM(uint16_t op,
129 Label* label,
130 const uint8_t* arm_op,
131 uint16_t op_size) override {
132 return true;
133 }
134 CheckBool EmitAbs32(Label* label) override { return true; }
135 CheckBool EmitAbs64(Label* label) override { return true; }
136
137 private:
138 size_t size_ = 0;
139
140 DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor);
141 };
142
143 /******** InstructionStoreReceptor ********/
144
145 // An InstructionReceptor that stores emitted instructions.
146 class InstructionStoreReceptor : public InstructionReceptor {
147 public:
148 explicit InstructionStoreReceptor(AssemblyProgram* program)
149 : program_(program) {
150 CHECK(program_);
151 }
152
153 // TODO(huangs): 2016/11: Add Reserve().
154
155 // InstructionReceptor:
156 // TODO(huangs): 2016/11: Replace stub with implementation.
157 CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); }
158 CheckBool EmitElfRelocation() override {
159 return program_->EmitElfRelocation();
160 }
161 CheckBool EmitElfARMRelocation() override {
162 return program_->EmitElfARMRelocation();
163 }
164 CheckBool EmitOrigin(RVA rva) override { return program_->EmitOrigin(rva); }
165 CheckBool EmitSingleByte(uint8_t byte) override {
166 return program_->EmitSingleByte(byte);
167 }
168 CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override {
169 return program_->EmitMultipleBytes(bytes, len);
170 }
171 CheckBool EmitRel32(Label* label) override {
172 return program_->EmitRel32(label);
173 }
174 CheckBool EmitRel32ARM(uint16_t op,
175 Label* label,
176 const uint8_t* arm_op,
177 uint16_t op_size) override {
178 return program_->EmitRel32ARM(op, label, arm_op, op_size);
179 }
180 CheckBool EmitAbs32(Label* label) override {
181 return program_->EmitAbs32(label);
182 }
183 CheckBool EmitAbs64(Label* label) override {
184 return program_->EmitAbs64(label);
185 }
186
187 private:
188 AssemblyProgram* program_;
189
190 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor);
191 };
192
108 } // namespace 193 } // namespace
109 194
195 /******** AssemblyProgram ********/
196
110 AssemblyProgram::AssemblyProgram(ExecutableType kind) 197 AssemblyProgram::AssemblyProgram(ExecutableType kind)
111 : kind_(kind), image_base_(0) { 198 : kind_(kind), image_base_(0) {
112 } 199 }
113 200
114 AssemblyProgram::~AssemblyProgram() { 201 AssemblyProgram::~AssemblyProgram() {
115 for (size_t i = 0; i < instructions_.size(); ++i) { 202 for (size_t i = 0; i < instructions_.size(); ++i) {
116 Instruction* instruction = instructions_[i]; 203 Instruction* instruction = instructions_[i];
117 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_. 204 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_.
118 UncheckedDelete(instruction); 205 UncheckedDelete(instruction);
119 } 206 }
120 if (byte_instruction_cache_.get()) { 207 if (byte_instruction_cache_.get()) {
121 for (size_t i = 0; i < 256; ++i) 208 for (size_t i = 0; i < 256; ++i)
122 UncheckedDelete(byte_instruction_cache_[i]); 209 UncheckedDelete(byte_instruction_cache_[i]);
123 } 210 }
124 } 211 }
125 212
126 CheckBool AssemblyProgram::EmitPeRelocsInstruction() { 213 CheckBool AssemblyProgram::EmitPeRelocs() {
127 return Emit(ScopedInstruction(UncheckedNew<PeRelocsInstruction>())); 214 return Emit(ScopedInstruction(UncheckedNew<PeRelocsInstruction>()));
128 } 215 }
129 216
130 CheckBool AssemblyProgram::EmitElfRelocationInstruction() { 217 CheckBool AssemblyProgram::EmitElfRelocation() {
131 return Emit(ScopedInstruction(UncheckedNew<ElfRelocsInstruction>())); 218 return Emit(ScopedInstruction(UncheckedNew<ElfRelocsInstruction>()));
132 } 219 }
133 220
134 CheckBool AssemblyProgram::EmitElfARMRelocationInstruction() { 221 CheckBool AssemblyProgram::EmitElfARMRelocation() {
135 return Emit(ScopedInstruction(UncheckedNew<ElfARMRelocsInstruction>())); 222 return Emit(ScopedInstruction(UncheckedNew<ElfARMRelocsInstruction>()));
136 } 223 }
137 224
138 CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) { 225 CheckBool AssemblyProgram::EmitOrigin(RVA rva) {
139 return Emit(ScopedInstruction(UncheckedNew<OriginInstruction>(rva))); 226 return Emit(ScopedInstruction(UncheckedNew<OriginInstruction>(rva)));
140 } 227 }
141 228
142 CheckBool AssemblyProgram::EmitByteInstruction(uint8_t byte) { 229 CheckBool AssemblyProgram::EmitSingleByte(uint8_t byte) {
143 return EmitShared(GetByteInstruction(byte)); 230 return EmitShared(GetByteInstruction(byte));
144 } 231 }
145 232
146 CheckBool AssemblyProgram::EmitBytesInstruction(const uint8_t* values, 233 CheckBool AssemblyProgram::EmitMultipleBytes(const uint8_t* bytes, size_t len) {
147 size_t len) { 234 return Emit(ScopedInstruction(UncheckedNew<BytesInstruction>(bytes, len)));
148 return Emit(ScopedInstruction(UncheckedNew<BytesInstruction>(values, len)));
149 } 235 }
150 236
151 CheckBool AssemblyProgram::EmitRel32(Label* label) { 237 CheckBool AssemblyProgram::EmitRel32(Label* label) {
152 return Emit( 238 return Emit(
153 ScopedInstruction(UncheckedNew<InstructionWithLabel>(REL32, label))); 239 ScopedInstruction(UncheckedNew<InstructionWithLabel>(REL32, label)));
154 } 240 }
155 241
156 CheckBool AssemblyProgram::EmitRel32ARM(uint16_t op, 242 CheckBool AssemblyProgram::EmitRel32ARM(uint16_t op,
157 Label* label, 243 Label* label,
158 const uint8_t* arm_op, 244 const uint8_t* arm_op,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 const AssemblyProgram::LabelHandlerMap& handler_map) const { 307 const AssemblyProgram::LabelHandlerMap& handler_map) const {
222 for (const Instruction* instruction : instructions_) { 308 for (const Instruction* instruction : instructions_) {
223 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op()); 309 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op());
224 if (it != handler_map.end()) { 310 if (it != handler_map.end()) {
225 it->second.Run( 311 it->second.Run(
226 static_cast<const InstructionWithLabel*>(instruction)->label()); 312 static_cast<const InstructionWithLabel*>(instruction)->label());
227 } 313 }
228 } 314 }
229 } 315 }
230 316
317 CheckBool AssemblyProgram::GenerateInstructions(
318 const InstructionGenerator& gen) {
319 // Pass 1: Count the space needed to store instructions.
320 InstructionCountReceptor count_receptor;
321 if (!gen.Run(this, &count_receptor))
322 return false;
323
324 // Pass 2: Emit all instructions to preallocated buffer (uses Phase 1 count).
325 InstructionStoreReceptor store_receptor(this);
326 // TODO(huangs): 2016/11: Pass |count_receptor_->size()| to |store_receptor_|
327 // to reserve space for raw data.
328 return gen.Run(this, &store_receptor);
329 }
330
231 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { 331 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) {
232 if (!instruction || !instructions_.push_back(instruction.get())) 332 if (!instruction || !instructions_.push_back(instruction.get()))
233 return false; 333 return false;
234 // Ownership successfully passed to instructions_. 334 // Ownership successfully passed to instructions_.
235 ignore_result(instruction.release()); 335 ignore_result(instruction.release());
236 return true; 336 return true;
237 } 337 }
238 338
239 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { 339 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) {
240 DCHECK(!instruction || instruction->op() == DEFBYTE); 340 DCHECK(!instruction || instruction->op() == DEFBYTE);
241 return instruction && instructions_.push_back(instruction); 341 return instruction && instructions_.push_back(instruction);
242 } 342 }
243 343
244 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { 344 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) {
245 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 345 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
246 Label* current = p->second; 346 Label* current = p->second;
247 current->index_ = Label::kNoIndex; 347 current->index_ = Label::kNoIndex;
248 } 348 }
249 } 349 }
250 350
251 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing 351 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing
252 // address order. 352 // address order.
253 //
254 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) { 353 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) {
255 int index = 0; 354 int index = 0;
256 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 355 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
257 Label* current = p->second; 356 Label* current = p->second;
258 if (current->index_ != Label::kNoIndex) 357 if (current->index_ != Label::kNoIndex)
259 NOTREACHED(); 358 NOTREACHED();
260 current->index_ = index; 359 current->index_ = index;
261 ++index; 360 ++index;
262 } 361 }
263 } 362 }
264 363
265 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not 364 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not
266 // yet assigned an index. 365 // yet assigned an index.
267 //
268 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) { 366 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) {
269 // An address table compresses best when each index is associated with an 367 // An address table compresses best when each index is associated with an
270 // address that is slight larger than the previous index. 368 // address that is slight larger than the previous index.
271 369
272 // First see which indexes have not been used. The 'available' vector could 370 // First see which indexes have not been used. The 'available' vector could
273 // grow even bigger, but the number of addresses is a better starting size 371 // grow even bigger, but the number of addresses is a better starting size
274 // than empty. 372 // than empty.
275 std::vector<bool> available(labels->size(), true); 373 std::vector<bool> available(labels->size(), true);
276 int used = 0; 374 int used = 0;
277 375
278 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 376 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
279 int index = p->second->index_; 377 int index = p->second->index_;
280 if (index != Label::kNoIndex) { 378 if (index != Label::kNoIndex) {
281 while (static_cast<size_t>(index) >= available.size()) 379 while (static_cast<size_t>(index) >= available.size())
282 available.push_back(true); 380 available.push_back(true);
283 available.at(index) = false; 381 available.at(index) = false;
284 ++used; 382 ++used;
285 } 383 }
286 } 384 }
287 385
288 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned"; 386 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned";
289 387
290 // Are there any unused labels that happen to be adjacent following a used 388 // Are there any unused labels that happen to be adjacent following a used
291 // label? 389 // label?
292 //
293 int fill_forward_count = 0; 390 int fill_forward_count = 0;
294 Label* prev = 0; 391 Label* prev = 0;
295 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 392 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
296 Label* current = p->second; 393 Label* current = p->second;
297 if (current->index_ == Label::kNoIndex) { 394 if (current->index_ == Label::kNoIndex) {
298 int index = 0; 395 int index = 0;
299 if (prev && prev->index_ != Label::kNoIndex) 396 if (prev && prev->index_ != Label::kNoIndex)
300 index = prev->index_ + 1; 397 index = prev->index_ + 1;
301 if (index < static_cast<int>(available.size()) && available.at(index)) { 398 if (index < static_cast<int>(available.size()) && available.at(index)) {
302 current->index_ = index; 399 current->index_ = index;
303 available.at(index) = false; 400 available.at(index) = false;
304 ++fill_forward_count; 401 ++fill_forward_count;
305 } 402 }
306 } 403 }
307 prev = current; 404 prev = current;
308 } 405 }
309 406
310 // Are there any unused labels that happen to be adjacent preceeding a used 407 // Are there any unused labels that happen to be adjacent preceeding a used
311 // label? 408 // label?
312 //
313 int fill_backward_count = 0; 409 int fill_backward_count = 0;
314 prev = 0; 410 prev = 0;
315 for (RVAToLabel::reverse_iterator p = labels->rbegin(); 411 for (RVAToLabel::reverse_iterator p = labels->rbegin();
316 p != labels->rend(); 412 p != labels->rend();
317 ++p) { 413 ++p) {
318 Label* current = p->second; 414 Label* current = p->second;
319 if (current->index_ == Label::kNoIndex) { 415 if (current->index_ == Label::kNoIndex) {
320 int prev_index; 416 int prev_index;
321 if (prev) 417 if (prev)
322 prev_index = prev->index_; 418 prev_index = prev->index_;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 Status Encode(const AssemblyProgram& program, 563 Status Encode(const AssemblyProgram& program,
468 std::unique_ptr<EncodedProgram>* output) { 564 std::unique_ptr<EncodedProgram>* output) {
469 // Explicitly release any memory associated with the output before encoding. 565 // Explicitly release any memory associated with the output before encoding.
470 output->reset(); 566 output->reset();
471 567
472 *output = program.Encode(); 568 *output = program.Encode();
473 return (*output) ? C_OK : C_GENERAL_ERROR; 569 return (*output) ? C_OK : C_GENERAL_ERROR;
474 } 570 }
475 571
476 } // namespace courgette 572 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/assembly_program.h ('k') | courgette/disassembler_elf_32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698