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 |