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 #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 #include <algorithm> |
11 #include <utility> | 11 #include <map> |
| 12 #include <set> |
| 13 #include <sstream> |
12 #include <vector> | 14 #include <vector> |
13 | 15 |
14 #include "base/logging.h" | 16 #include "base/logging.h" |
15 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/memory/scoped_ptr.h" |
| 19 |
16 #include "courgette/courgette.h" | 20 #include "courgette/courgette.h" |
17 #include "courgette/encoded_program.h" | 21 #include "courgette/encoded_program.h" |
18 | 22 |
19 namespace courgette { | 23 namespace courgette { |
20 | 24 |
21 namespace { | 25 namespace { |
22 | 26 |
23 // Sets the current address for the emitting instructions. | 27 // Sets the current address for the emitting instructions. |
24 class OriginInstruction : public Instruction { | 28 class OriginInstruction : public Instruction { |
25 public: | 29 public: |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 ++index; | 358 ++index; |
355 ++fill_infill_count; | 359 ++fill_infill_count; |
356 } | 360 } |
357 } | 361 } |
358 | 362 |
359 VLOG(1) << " fill forward " << fill_forward_count | 363 VLOG(1) << " fill forward " << fill_forward_count |
360 << " backward " << fill_backward_count | 364 << " backward " << fill_backward_count |
361 << " infill " << fill_infill_count; | 365 << " infill " << fill_infill_count; |
362 } | 366 } |
363 | 367 |
364 scoped_ptr<EncodedProgram> AssemblyProgram::Encode() const { | 368 EncodedProgram* AssemblyProgram::Encode() const { |
365 scoped_ptr<EncodedProgram> encoded(new EncodedProgram()); | 369 scoped_ptr<EncodedProgram> encoded(new EncodedProgram()); |
366 | 370 |
367 encoded->set_image_base(image_base_); | 371 encoded->set_image_base(image_base_); |
368 | 372 |
369 if (!encoded->DefineLabels(abs32_labels_, rel32_labels_)) | 373 if (!encoded->DefineLabels(abs32_labels_, rel32_labels_)) |
370 return nullptr; | 374 return NULL; |
371 | 375 |
372 for (size_t i = 0; i < instructions_.size(); ++i) { | 376 for (size_t i = 0; i < instructions_.size(); ++i) { |
373 Instruction* instruction = instructions_[i]; | 377 Instruction* instruction = instructions_[i]; |
374 | 378 |
375 switch (instruction->op()) { | 379 switch (instruction->op()) { |
376 case ORIGIN: { | 380 case ORIGIN: { |
377 OriginInstruction* org = static_cast<OriginInstruction*>(instruction); | 381 OriginInstruction* org = static_cast<OriginInstruction*>(instruction); |
378 if (!encoded->AddOrigin(org->origin_rva())) | 382 if (!encoded->AddOrigin(org->origin_rva())) |
379 return nullptr; | 383 return NULL; |
380 break; | 384 break; |
381 } | 385 } |
382 case DEFBYTE: { | 386 case DEFBYTE: { |
383 uint8_t b = static_cast<ByteInstruction*>(instruction)->byte_value(); | 387 uint8_t b = static_cast<ByteInstruction*>(instruction)->byte_value(); |
384 if (!encoded->AddCopy(1, &b)) | 388 if (!encoded->AddCopy(1, &b)) |
385 return nullptr; | 389 return NULL; |
386 break; | 390 break; |
387 } | 391 } |
388 case DEFBYTES: { | 392 case DEFBYTES: { |
389 const uint8_t* byte_values = | 393 const uint8_t* byte_values = |
390 static_cast<BytesInstruction*>(instruction)->byte_values(); | 394 static_cast<BytesInstruction*>(instruction)->byte_values(); |
391 size_t len = static_cast<BytesInstruction*>(instruction)->len(); | 395 size_t len = static_cast<BytesInstruction*>(instruction)->len(); |
392 | 396 |
393 if (!encoded->AddCopy(len, byte_values)) | 397 if (!encoded->AddCopy(len, byte_values)) |
394 return nullptr; | 398 return NULL; |
395 break; | 399 break; |
396 } | 400 } |
397 case REL32: { | 401 case REL32: { |
398 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); | 402 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); |
399 if (!encoded->AddRel32(label->index_)) | 403 if (!encoded->AddRel32(label->index_)) |
400 return nullptr; | 404 return NULL; |
401 break; | 405 break; |
402 } | 406 } |
403 case REL32ARM: { | 407 case REL32ARM: { |
404 Label* label = | 408 Label* label = |
405 static_cast<InstructionWithLabelARM*>(instruction)->label(); | 409 static_cast<InstructionWithLabelARM*>(instruction)->label(); |
406 uint16_t compressed_op = | 410 uint16_t compressed_op = |
407 static_cast<InstructionWithLabelARM*>(instruction)->compressed_op(); | 411 static_cast<InstructionWithLabelARM*>(instruction)->compressed_op(); |
408 if (!encoded->AddRel32ARM(compressed_op, label->index_)) | 412 if (!encoded->AddRel32ARM(compressed_op, label->index_)) |
409 return nullptr; | 413 return NULL; |
410 break; | 414 break; |
411 } | 415 } |
412 case ABS32: { | 416 case ABS32: { |
413 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); | 417 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); |
414 if (!encoded->AddAbs32(label->index_)) | 418 if (!encoded->AddAbs32(label->index_)) |
415 return nullptr; | 419 return NULL; |
416 break; | 420 break; |
417 } | 421 } |
418 case ABS64: { | 422 case ABS64: { |
419 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); | 423 Label* label = static_cast<InstructionWithLabel*>(instruction)->label(); |
420 if (!encoded->AddAbs64(label->index_)) | 424 if (!encoded->AddAbs64(label->index_)) |
421 return nullptr; | 425 return NULL; |
422 break; | 426 break; |
423 } | 427 } |
424 case MAKEPERELOCS: { | 428 case MAKEPERELOCS: { |
425 if (!encoded->AddPeMakeRelocs(kind_)) | 429 if (!encoded->AddPeMakeRelocs(kind_)) |
426 return nullptr; | 430 return NULL; |
427 break; | 431 break; |
428 } | 432 } |
429 case MAKEELFRELOCS: { | 433 case MAKEELFRELOCS: { |
430 if (!encoded->AddElfMakeRelocs()) | 434 if (!encoded->AddElfMakeRelocs()) |
431 return nullptr; | 435 return NULL; |
432 break; | 436 break; |
433 } | 437 } |
434 case MAKEELFARMRELOCS: { | 438 case MAKEELFARMRELOCS: { |
435 if (!encoded->AddElfARMMakeRelocs()) | 439 if (!encoded->AddElfARMMakeRelocs()) |
436 return nullptr; | 440 return NULL; |
437 break; | 441 break; |
438 } | 442 } |
439 default: { | 443 default: { |
440 NOTREACHED() << "Unknown Insn OP kind"; | 444 NOTREACHED() << "Unknown Insn OP kind"; |
441 } | 445 } |
442 } | 446 } |
443 } | 447 } |
444 | 448 |
445 return encoded; | 449 return encoded.release(); |
446 } | 450 } |
447 | 451 |
448 Instruction* AssemblyProgram::GetByteInstruction(uint8_t byte) { | 452 Instruction* AssemblyProgram::GetByteInstruction(uint8_t byte) { |
449 if (!byte_instruction_cache_) { | 453 if (!byte_instruction_cache_) { |
450 Instruction** ram = nullptr; | 454 Instruction** ram = nullptr; |
451 if (!base::UncheckedMalloc(sizeof(Instruction*) * 256, | 455 if (!base::UncheckedMalloc(sizeof(Instruction*) * 256, |
452 reinterpret_cast<void**>(&ram))) { | 456 reinterpret_cast<void**>(&ram))) { |
453 return nullptr; | 457 return nullptr; |
454 } | 458 } |
455 byte_instruction_cache_.reset(ram); | 459 byte_instruction_cache_.reset(ram); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } else { | 523 } else { |
520 ++it; | 524 ++it; |
521 } | 525 } |
522 } | 526 } |
523 | 527 |
524 return true; | 528 return true; |
525 } | 529 } |
526 | 530 |
527 //////////////////////////////////////////////////////////////////////////////// | 531 //////////////////////////////////////////////////////////////////////////////// |
528 | 532 |
529 Status Encode(const AssemblyProgram& program, | 533 Status Encode(AssemblyProgram* program, EncodedProgram** output) { |
530 scoped_ptr<EncodedProgram>* output) { | 534 *output = NULL; |
531 // Explicitly release any memory associated with the output before encoding. | 535 EncodedProgram *encoded = program->Encode(); |
532 output->reset(); | 536 if (encoded) { |
533 | 537 *output = encoded; |
534 *output = program.Encode(); | 538 return C_OK; |
535 return (*output) ? C_OK : C_GENERAL_ERROR; | 539 } else { |
| 540 return C_GENERAL_ERROR; |
| 541 } |
536 } | 542 } |
537 | 543 |
538 } // namespace courgette | 544 } // namespace courgette |
OLD | NEW |