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/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 28 matching lines...) Expand all Loading... |
39 // field constructors. Ditto for the destructor. | 39 // field constructors. Ditto for the destructor. |
40 EncodedProgram::EncodedProgram() : image_base_(0) {} | 40 EncodedProgram::EncodedProgram() : image_base_(0) {} |
41 EncodedProgram::~EncodedProgram() {} | 41 EncodedProgram::~EncodedProgram() {} |
42 | 42 |
43 // Serializes a vector of integral values using Varint32 coding. | 43 // Serializes a vector of integral values using Varint32 coding. |
44 template<typename V> | 44 template<typename V> |
45 CheckBool WriteVector(const V& items, SinkStream* buffer) { | 45 CheckBool WriteVector(const V& items, SinkStream* buffer) { |
46 size_t count = items.size(); | 46 size_t count = items.size(); |
47 bool ok = buffer->WriteSizeVarint32(count); | 47 bool ok = buffer->WriteSizeVarint32(count); |
48 for (size_t i = 0; ok && i < count; ++i) { | 48 for (size_t i = 0; ok && i < count; ++i) { |
49 COMPILE_ASSERT(sizeof(items[0]) <= sizeof(uint32), // NOLINT | |
50 T_must_fit_in_uint32); | |
51 ok = buffer->WriteSizeVarint32(items[i]); | 49 ok = buffer->WriteSizeVarint32(items[i]); |
52 } | 50 } |
53 return ok; | 51 return ok; |
54 } | 52 } |
55 | 53 |
56 template<typename V> | 54 template<typename V> |
57 bool ReadVector(V* items, SourceStream* buffer) { | 55 bool ReadVector(V* items, SourceStream* buffer) { |
58 uint32 count; | 56 uint32 count; |
59 if (!buffer->ReadVarint32(&count)) | 57 if (!buffer->ReadVarint32(&count)) |
60 return false; | 58 return false; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 (*rvas)[i] = previous; | 187 (*rvas)[i] = previous; |
190 else | 188 else |
191 previous = (*rvas)[i]; | 189 previous = (*rvas)[i]; |
192 } | 190 } |
193 } | 191 } |
194 | 192 |
195 CheckBool EncodedProgram::AddOrigin(RVA origin) { | 193 CheckBool EncodedProgram::AddOrigin(RVA origin) { |
196 return ops_.push_back(ORIGIN) && origins_.push_back(origin); | 194 return ops_.push_back(ORIGIN) && origins_.push_back(origin); |
197 } | 195 } |
198 | 196 |
199 CheckBool EncodedProgram::AddCopy(uint32 count, const void* bytes) { | 197 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) { |
200 const uint8* source = static_cast<const uint8*>(bytes); | 198 const uint8* source = static_cast<const uint8*>(bytes); |
201 | 199 |
202 bool ok = true; | 200 bool ok = true; |
203 | 201 |
204 // Fold adjacent COPY instructions into one. This nearly halves the size of | 202 // Fold adjacent COPY instructions into one. This nearly halves the size of |
205 // an EncodedProgram with only COPY1 instructions since there are approx plain | 203 // an EncodedProgram with only COPY1 instructions since there are approx plain |
206 // 16 bytes per reloc. This has a working-set benefit during decompression. | 204 // 16 bytes per reloc. This has a working-set benefit during decompression. |
207 // For compression of files with large differences this makes a small (4%) | 205 // For compression of files with large differences this makes a small (4%) |
208 // improvement in size. For files with small differences this degrades the | 206 // improvement in size. For files with small differences this degrades the |
209 // compressed size by 1.3% | 207 // compressed size by 1.3% |
210 if (!ops_.empty()) { | 208 if (!ops_.empty()) { |
211 if (ops_.back() == COPY1) { | 209 if (ops_.back() == COPY1) { |
212 ops_.back() = COPY; | 210 ops_.back() = COPY; |
213 ok = copy_counts_.push_back(1); | 211 ok = copy_counts_.push_back(1); |
214 } | 212 } |
215 if (ok && ops_.back() == COPY) { | 213 if (ok && ops_.back() == COPY) { |
216 copy_counts_.back() += count; | 214 copy_counts_.back() += count; |
217 for (uint32 i = 0; ok && i < count; ++i) { | 215 for (size_t i = 0; ok && i < count; ++i) { |
218 ok = copy_bytes_.push_back(source[i]); | 216 ok = copy_bytes_.push_back(source[i]); |
219 } | 217 } |
220 return ok; | 218 return ok; |
221 } | 219 } |
222 } | 220 } |
223 | 221 |
224 if (ok) { | 222 if (ok) { |
225 if (count == 1) { | 223 if (count == 1) { |
226 ok = ops_.push_back(COPY1) && copy_bytes_.push_back(source[0]); | 224 ok = ops_.push_back(COPY1) && copy_bytes_.push_back(source[0]); |
227 } else { | 225 } else { |
228 ok = ops_.push_back(COPY) && copy_counts_.push_back(count); | 226 ok = ops_.push_back(COPY) && copy_counts_.push_back(count); |
229 for (uint32 i = 0; ok && i < count; ++i) { | 227 for (size_t i = 0; ok && i < count; ++i) { |
230 ok = copy_bytes_.push_back(source[i]); | 228 ok = copy_bytes_.push_back(source[i]); |
231 } | 229 } |
232 } | 230 } |
233 } | 231 } |
234 | 232 |
235 return ok; | 233 return ok; |
236 } | 234 } |
237 | 235 |
238 CheckBool EncodedProgram::AddAbs32(int label_index) { | 236 CheckBool EncodedProgram::AddAbs32(int label_index) { |
239 return ops_.push_back(ABS32) && abs32_ix_.push_back(label_index); | 237 return ops_.push_back(ABS32) && abs32_ix_.push_back(label_index); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 if (!VectorAt(rel32_rva_, index, &rva)) | 418 if (!VectorAt(rel32_rva_, index, &rva)) |
421 return false; | 419 return false; |
422 uint32 decompressed_op; | 420 uint32 decompressed_op; |
423 if (!DisassemblerElf32ARM::Decompress(ARM_OFF8, | 421 if (!DisassemblerElf32ARM::Decompress(ARM_OFF8, |
424 static_cast<uint16>(op), | 422 static_cast<uint16>(op), |
425 static_cast<uint32>(rva - | 423 static_cast<uint32>(rva - |
426 current_rva), | 424 current_rva), |
427 &decompressed_op)) { | 425 &decompressed_op)) { |
428 return false; | 426 return false; |
429 } | 427 } |
430 uint16 op16 = decompressed_op; | 428 uint16 op16 = static_cast<uint16>(decompressed_op); |
431 if (!output->Write(&op16, 2)) | 429 if (!output->Write(&op16, 2)) |
432 return false; | 430 return false; |
433 current_rva += 2; | 431 current_rva += 2; |
434 break; | 432 break; |
435 } | 433 } |
436 case REL32ARM11: { | 434 case REL32ARM11: { |
437 uint32 index; | 435 uint32 index; |
438 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) | 436 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) |
439 return false; | 437 return false; |
440 ++ix_rel32_ix; | 438 ++ix_rel32_ix; |
441 RVA rva; | 439 RVA rva; |
442 if (!VectorAt(rel32_rva_, index, &rva)) | 440 if (!VectorAt(rel32_rva_, index, &rva)) |
443 return false; | 441 return false; |
444 uint32 decompressed_op; | 442 uint32 decompressed_op; |
445 if (!DisassemblerElf32ARM::Decompress(ARM_OFF11, (uint16) op, | 443 if (!DisassemblerElf32ARM::Decompress(ARM_OFF11, (uint16) op, |
446 (uint32) (rva - current_rva), | 444 (uint32) (rva - current_rva), |
447 &decompressed_op)) { | 445 &decompressed_op)) { |
448 return false; | 446 return false; |
449 } | 447 } |
450 uint16 op16 = decompressed_op; | 448 uint16 op16 = static_cast<uint16>(decompressed_op); |
451 if (!output->Write(&op16, 2)) | 449 if (!output->Write(&op16, 2)) |
452 return false; | 450 return false; |
453 current_rva += 2; | 451 current_rva += 2; |
454 break; | 452 break; |
455 } | 453 } |
456 case REL32ARM24: { | 454 case REL32ARM24: { |
457 uint32 index; | 455 uint32 index; |
458 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) | 456 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) |
459 return false; | 457 return false; |
460 ++ix_rel32_ix; | 458 ++ix_rel32_ix; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 case ORIGIN: { | 547 case ORIGIN: { |
550 RVA section_rva; | 548 RVA section_rva; |
551 if (!VectorAt(origins_, ix_origins, §ion_rva)) | 549 if (!VectorAt(origins_, ix_origins, §ion_rva)) |
552 return false; | 550 return false; |
553 ++ix_origins; | 551 ++ix_origins; |
554 current_rva = section_rva; | 552 current_rva = section_rva; |
555 break; | 553 break; |
556 } | 554 } |
557 | 555 |
558 case COPY: { | 556 case COPY: { |
559 uint32 count; | 557 size_t count; |
560 if (!VectorAt(copy_counts_, ix_copy_counts, &count)) | 558 if (!VectorAt(copy_counts_, ix_copy_counts, &count)) |
561 return false; | 559 return false; |
562 ++ix_copy_counts; | 560 ++ix_copy_counts; |
563 for (uint32 i = 0; i < count; ++i) { | 561 for (size_t i = 0; i < count; ++i) { |
564 uint8 b; | 562 uint8 b; |
565 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) | 563 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) |
566 return false; | 564 return false; |
567 ++ix_copy_bytes; | 565 ++ix_copy_bytes; |
568 if (!output->Write(&b, 1)) | 566 if (!output->Write(&b, 1)) |
569 return false; | 567 return false; |
570 } | 568 } |
571 current_rva += count; | 569 current_rva += static_cast<RVA>(count); |
572 break; | 570 break; |
573 } | 571 } |
574 | 572 |
575 case COPY1: { | 573 case COPY1: { |
576 uint8 b; | 574 uint8 b; |
577 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) | 575 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) |
578 return false; | 576 return false; |
579 ++ix_copy_bytes; | 577 ++ix_copy_bytes; |
580 if (!output->Write(&b, 1)) | 578 if (!output->Write(&b, 1)) |
581 return false; | 579 return false; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 if (assembled) | 791 if (assembled) |
794 return C_OK; | 792 return C_OK; |
795 return C_ASSEMBLY_FAILED; | 793 return C_ASSEMBLY_FAILED; |
796 } | 794 } |
797 | 795 |
798 void DeleteEncodedProgram(EncodedProgram* encoded) { | 796 void DeleteEncodedProgram(EncodedProgram* encoded) { |
799 delete encoded; | 797 delete encoded; |
800 } | 798 } |
801 | 799 |
802 } // end namespace | 800 } // end namespace |
OLD | NEW |