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