| 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 |