| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/encoded_program.h" | 5 #include "courgette/encoded_program.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 const int kStreamBytes = 2; | 23 const int kStreamBytes = 2; |
| 24 const int kStreamAbs32Indexes = 3; | 24 const int kStreamAbs32Indexes = 3; |
| 25 const int kStreamRel32Indexes = 4; | 25 const int kStreamRel32Indexes = 4; |
| 26 const int kStreamAbs32Addresses = 5; | 26 const int kStreamAbs32Addresses = 5; |
| 27 const int kStreamRel32Addresses = 6; | 27 const int kStreamRel32Addresses = 6; |
| 28 const int kStreamCopyCounts = 7; | 28 const int kStreamCopyCounts = 7; |
| 29 const int kStreamOriginAddresses = kStreamMisc; | 29 const int kStreamOriginAddresses = kStreamMisc; |
| 30 | 30 |
| 31 const int kStreamLimit = 9; | 31 const int kStreamLimit = 9; |
| 32 | 32 |
| 33 // Binary assembly language operations. | |
| 34 enum EncodedProgram::OP { | |
| 35 ORIGIN, // ORIGIN <rva> - set address for subsequent assembly. | |
| 36 COPY, // COPY <count> <bytes> - copy bytes to output. | |
| 37 COPY1, // COPY1 <byte> - same as COPY 1 <byte>. | |
| 38 REL32, // REL32 <index> - emit rel32 encoded reference to address at | |
| 39 // address table offset <index> | |
| 40 ABS32, // ABS32 <index> - emit abs32 encoded reference to address at | |
| 41 // address table offset <index> | |
| 42 MAKE_BASE_RELOCATION_TABLE, // Emit base relocation table blocks. | |
| 43 OP_LAST | |
| 44 }; | |
| 45 | |
| 46 | |
| 47 // Constructor is here rather than in the header. Although the constructor | 33 // Constructor is here rather than in the header. Although the constructor |
| 48 // appears to do nothing it is fact quite large because of the implict calls to | 34 // appears to do nothing it is fact quite large because of the implict calls to |
| 49 // field constructors. Ditto for the destructor. | 35 // field constructors. Ditto for the destructor. |
| 50 EncodedProgram::EncodedProgram() {} | 36 EncodedProgram::EncodedProgram() {} |
| 51 EncodedProgram::~EncodedProgram() {} | 37 EncodedProgram::~EncodedProgram() {} |
| 52 | 38 |
| 53 // Serializes a vector of integral values using Varint32 coding. | 39 // Serializes a vector of integral values using Varint32 coding. |
| 54 template<typename T> | 40 template<typename T> |
| 55 void WriteVector(const std::vector<T>& items, SinkStream* buffer) { | 41 void WriteVector(const std::vector<T>& items, SinkStream* buffer) { |
| 56 size_t count = items.size(); | 42 size_t count = items.size(); |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 if (ix_rel32_ix != rel32_ix_.size()) | 478 if (ix_rel32_ix != rel32_ix_.size()) |
| 493 return false; | 479 return false; |
| 494 | 480 |
| 495 return true; | 481 return true; |
| 496 } | 482 } |
| 497 | 483 |
| 498 | 484 |
| 499 // RelocBlock has the layout of a block of relocations in the base relocation | 485 // RelocBlock has the layout of a block of relocations in the base relocation |
| 500 // table file format. | 486 // table file format. |
| 501 // | 487 // |
| 502 class RelocBlock { | 488 struct RelocBlockPOD { |
| 503 public: | |
| 504 uint32 page_rva; | 489 uint32 page_rva; |
| 505 uint32 block_size; | 490 uint32 block_size; |
| 506 uint16 relocs[4096]; // Allow up to one relocation per byte of a 4k page. | 491 uint16 relocs[4096]; // Allow up to one relocation per byte of a 4k page. |
| 492 }; |
| 507 | 493 |
| 508 RelocBlock() : page_rva(~0), block_size(8) {} | 494 COMPILE_ASSERT(offsetof(RelocBlockPOD, relocs) == 8, reloc_block_header_size); |
| 495 |
| 496 class RelocBlock { |
| 497 public: |
| 498 RelocBlock() { |
| 499 pod.page_rva = ~0; |
| 500 pod.block_size = 8; |
| 501 } |
| 509 | 502 |
| 510 void Add(uint16 item) { | 503 void Add(uint16 item) { |
| 511 relocs[(block_size-8)/2] = item; | 504 pod.relocs[(pod.block_size-8)/2] = item; |
| 512 block_size += 2; | 505 pod.block_size += 2; |
| 513 } | 506 } |
| 514 | 507 |
| 515 void Flush(SinkStream* buffer) { | 508 void Flush(SinkStream* buffer) { |
| 516 if (block_size != 8) { | 509 if (pod.block_size != 8) { |
| 517 if (block_size % 4 != 0) { // Pad to make size multiple of 4 bytes. | 510 if (pod.block_size % 4 != 0) { // Pad to make size multiple of 4 bytes. |
| 518 Add(0); | 511 Add(0); |
| 519 } | 512 } |
| 520 buffer->Write(this, block_size); | 513 buffer->Write(&pod, pod.block_size); |
| 521 block_size = 8; | 514 pod.block_size = 8; |
| 522 } | 515 } |
| 523 } | 516 } |
| 517 RelocBlockPOD pod; |
| 524 }; | 518 }; |
| 525 | 519 |
| 526 COMPILE_ASSERT(offsetof(RelocBlock, relocs) == 8, reloc_block_header_size); | |
| 527 | |
| 528 void EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) { | 520 void EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) { |
| 529 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); | 521 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); |
| 530 | 522 |
| 531 RelocBlock block; | 523 RelocBlock block; |
| 532 | 524 |
| 533 for (size_t i = 0; i < abs32_relocs_.size(); ++i) { | 525 for (size_t i = 0; i < abs32_relocs_.size(); ++i) { |
| 534 uint32 rva = abs32_relocs_[i]; | 526 uint32 rva = abs32_relocs_[i]; |
| 535 uint32 page_rva = rva & ~0xFFF; | 527 uint32 page_rva = rva & ~0xFFF; |
| 536 if (page_rva != block.page_rva) { | 528 if (page_rva != block.pod.page_rva) { |
| 537 block.Flush(buffer); | 529 block.Flush(buffer); |
| 538 block.page_rva = page_rva; | 530 block.pod.page_rva = page_rva; |
| 539 } | 531 } |
| 540 block.Add(0x3000 | (rva & 0xFFF)); | 532 block.Add(0x3000 | (rva & 0xFFF)); |
| 541 } | 533 } |
| 542 block.Flush(buffer); | 534 block.Flush(buffer); |
| 543 } | 535 } |
| 544 | 536 |
| 545 //////////////////////////////////////////////////////////////////////////////// | 537 //////////////////////////////////////////////////////////////////////////////// |
| 546 | 538 |
| 547 Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink) { | 539 Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink) { |
| 548 encoded->WriteTo(sink); | 540 encoded->WriteTo(sink); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 564 if (assembled) | 556 if (assembled) |
| 565 return C_OK; | 557 return C_OK; |
| 566 return C_ASSEMBLY_FAILED; | 558 return C_ASSEMBLY_FAILED; |
| 567 } | 559 } |
| 568 | 560 |
| 569 void DeleteEncodedProgram(EncodedProgram* encoded) { | 561 void DeleteEncodedProgram(EncodedProgram* encoded) { |
| 570 delete encoded; | 562 delete encoded; |
| 571 } | 563 } |
| 572 | 564 |
| 573 } // end namespace | 565 } // end namespace |
| OLD | NEW |