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