Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: courgette/encoded_program.cc

Issue 1543643002: Switch to standard integer types in courgette/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/encoded_program.h ('k') | courgette/encoded_program_fuzz_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <stddef.h>
8 #include <stdint.h>
9
7 #include <algorithm> 10 #include <algorithm>
8 #include <map> 11 #include <map>
9 #include <string> 12 #include <string>
10 #include <vector> 13 #include <vector>
11 14
12 #include "base/environment.h" 15 #include "base/environment.h"
13 #include "base/logging.h" 16 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
15 #include "base/numerics/safe_conversions.h" 18 #include "base/numerics/safe_conversions.h"
16 #include "base/numerics/safe_math.h" 19 #include "base/numerics/safe_math.h"
(...skipping 18 matching lines...) Expand all
35 size_t count = items.size(); 38 size_t count = items.size();
36 bool ok = buffer->WriteSizeVarint32(count); 39 bool ok = buffer->WriteSizeVarint32(count);
37 for (size_t i = 0; ok && i < count; ++i) { 40 for (size_t i = 0; ok && i < count; ++i) {
38 ok = buffer->WriteSizeVarint32(items[i]); 41 ok = buffer->WriteSizeVarint32(items[i]);
39 } 42 }
40 return ok; 43 return ok;
41 } 44 }
42 45
43 template<typename V> 46 template<typename V>
44 bool ReadVector(V* items, SourceStream* buffer) { 47 bool ReadVector(V* items, SourceStream* buffer) {
45 uint32 count; 48 uint32_t count;
46 if (!buffer->ReadVarint32(&count)) 49 if (!buffer->ReadVarint32(&count))
47 return false; 50 return false;
48 51
49 items->clear(); 52 items->clear();
50 53
51 bool ok = items->reserve(count); 54 bool ok = items->reserve(count);
52 for (size_t i = 0; ok && i < count; ++i) { 55 for (size_t i = 0; ok && i < count; ++i) {
53 uint32 item; 56 uint32_t item;
54 ok = buffer->ReadVarint32(&item); 57 ok = buffer->ReadVarint32(&item);
55 if (ok) 58 if (ok)
56 ok = items->push_back(static_cast<typename V::value_type>(item)); 59 ok = items->push_back(static_cast<typename V::value_type>(item));
57 } 60 }
58 61
59 return ok; 62 return ok;
60 } 63 }
61 64
62 // Serializes a vector, using delta coding followed by Varint32Signed coding. 65 // Serializes a vector, using delta coding followed by Varint32Signed coding.
63 template<typename V> 66 template<typename V>
64 CheckBool WriteSigned32Delta(const V& set, SinkStream* buffer) { 67 CheckBool WriteSigned32Delta(const V& set, SinkStream* buffer) {
65 size_t count = set.size(); 68 size_t count = set.size();
66 bool ok = buffer->WriteSizeVarint32(count); 69 bool ok = buffer->WriteSizeVarint32(count);
67 uint32 prev = 0; 70 uint32_t prev = 0;
68 for (size_t i = 0; ok && i < count; ++i) { 71 for (size_t i = 0; ok && i < count; ++i) {
69 uint32 current = set[i]; 72 uint32_t current = set[i];
70 int32 delta = current - prev; 73 int32_t delta = current - prev;
71 ok = buffer->WriteVarint32Signed(delta); 74 ok = buffer->WriteVarint32Signed(delta);
72 prev = current; 75 prev = current;
73 } 76 }
74 return ok; 77 return ok;
75 } 78 }
76 79
77 template <typename V> 80 template <typename V>
78 static CheckBool ReadSigned32Delta(V* set, SourceStream* buffer) { 81 static CheckBool ReadSigned32Delta(V* set, SourceStream* buffer) {
79 uint32 count; 82 uint32_t count;
80 83
81 if (!buffer->ReadVarint32(&count)) 84 if (!buffer->ReadVarint32(&count))
82 return false; 85 return false;
83 86
84 set->clear(); 87 set->clear();
85 bool ok = set->reserve(count); 88 bool ok = set->reserve(count);
86 uint32 prev = 0; 89 uint32_t prev = 0;
87 for (size_t i = 0; ok && i < count; ++i) { 90 for (size_t i = 0; ok && i < count; ++i) {
88 int32 delta; 91 int32_t delta;
89 ok = buffer->ReadVarint32Signed(&delta); 92 ok = buffer->ReadVarint32Signed(&delta);
90 if (ok) { 93 if (ok) {
91 uint32 current = static_cast<uint32>(prev + delta); 94 uint32_t current = static_cast<uint32_t>(prev + delta);
92 ok = set->push_back(current); 95 ok = set->push_back(current);
93 prev = current; 96 prev = current;
94 } 97 }
95 } 98 }
96 return ok; 99 return ok;
97 } 100 }
98 101
99 // Write a vector as the byte representation of the contents. 102 // Write a vector as the byte representation of the contents.
100 // 103 //
101 // (This only really makes sense for a type T that has sizeof(T)==1, otherwise 104 // (This only really makes sense for a type T that has sizeof(T)==1, otherwise
102 // serialized representation is not endian-agnostic. But it is useful to keep 105 // serialized representation is not endian-agnostic. But it is useful to keep
103 // the possibility of a greater size for experiments comparing Varint32 encoding 106 // the possibility of a greater size for experiments comparing Varint32 encoding
104 // of a vector of larger integrals vs a plain form.) 107 // of a vector of larger integrals vs a plain form.)
105 // 108 //
106 template<typename V> 109 template<typename V>
107 CheckBool WriteVectorU8(const V& items, SinkStream* buffer) { 110 CheckBool WriteVectorU8(const V& items, SinkStream* buffer) {
108 size_t count = items.size(); 111 size_t count = items.size();
109 bool ok = buffer->WriteSizeVarint32(count); 112 bool ok = buffer->WriteSizeVarint32(count);
110 if (count != 0 && ok) { 113 if (count != 0 && ok) {
111 size_t byte_count = count * sizeof(typename V::value_type); 114 size_t byte_count = count * sizeof(typename V::value_type);
112 ok = buffer->Write(static_cast<const void*>(&items[0]), byte_count); 115 ok = buffer->Write(static_cast<const void*>(&items[0]), byte_count);
113 } 116 }
114 return ok; 117 return ok;
115 } 118 }
116 119
117 template<typename V> 120 template<typename V>
118 bool ReadVectorU8(V* items, SourceStream* buffer) { 121 bool ReadVectorU8(V* items, SourceStream* buffer) {
119 uint32 count; 122 uint32_t count;
120 if (!buffer->ReadVarint32(&count)) 123 if (!buffer->ReadVarint32(&count))
121 return false; 124 return false;
122 125
123 items->clear(); 126 items->clear();
124 bool ok = items->resize(count, 0); 127 bool ok = items->resize(count, 0);
125 if (ok && count != 0) { 128 if (ok && count != 0) {
126 size_t byte_count = count * sizeof(typename V::value_type); 129 size_t byte_count = count * sizeof(typename V::value_type);
127 return buffer->Read(static_cast<void*>(&((*items)[0])), byte_count); 130 return buffer->Read(static_cast<void*>(&((*items)[0])), byte_count);
128 } 131 }
129 return ok; 132 return ok;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 else 186 else
184 previous = (*rvas)[i]; 187 previous = (*rvas)[i];
185 } 188 }
186 } 189 }
187 190
188 CheckBool EncodedProgram::AddOrigin(RVA origin) { 191 CheckBool EncodedProgram::AddOrigin(RVA origin) {
189 return ops_.push_back(ORIGIN) && origins_.push_back(origin); 192 return ops_.push_back(ORIGIN) && origins_.push_back(origin);
190 } 193 }
191 194
192 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) { 195 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) {
193 const uint8* source = static_cast<const uint8*>(bytes); 196 const uint8_t* source = static_cast<const uint8_t*>(bytes);
194 197
195 bool ok = true; 198 bool ok = true;
196 199
197 // Fold adjacent COPY instructions into one. This nearly halves the size of 200 // Fold adjacent COPY instructions into one. This nearly halves the size of
198 // an EncodedProgram with only COPY1 instructions since there are approx plain 201 // an EncodedProgram with only COPY1 instructions since there are approx plain
199 // 16 bytes per reloc. This has a working-set benefit during decompression. 202 // 16 bytes per reloc. This has a working-set benefit during decompression.
200 // For compression of files with large differences this makes a small (4%) 203 // For compression of files with large differences this makes a small (4%)
201 // improvement in size. For files with small differences this degrades the 204 // improvement in size. For files with small differences this degrades the
202 // compressed size by 1.3% 205 // compressed size by 1.3%
203 if (!ops_.empty()) { 206 if (!ops_.empty()) {
(...skipping 29 matching lines...) Expand all
233 } 236 }
234 237
235 CheckBool EncodedProgram::AddAbs64(int label_index) { 238 CheckBool EncodedProgram::AddAbs64(int label_index) {
236 return ops_.push_back(ABS64) && abs32_ix_.push_back(label_index); 239 return ops_.push_back(ABS64) && abs32_ix_.push_back(label_index);
237 } 240 }
238 241
239 CheckBool EncodedProgram::AddRel32(int label_index) { 242 CheckBool EncodedProgram::AddRel32(int label_index) {
240 return ops_.push_back(REL32) && rel32_ix_.push_back(label_index); 243 return ops_.push_back(REL32) && rel32_ix_.push_back(label_index);
241 } 244 }
242 245
243 CheckBool EncodedProgram::AddRel32ARM(uint16 op, int label_index) { 246 CheckBool EncodedProgram::AddRel32ARM(uint16_t op, int label_index) {
244 return ops_.push_back(static_cast<OP>(op)) && 247 return ops_.push_back(static_cast<OP>(op)) &&
245 rel32_ix_.push_back(label_index); 248 rel32_ix_.push_back(label_index);
246 } 249 }
247 250
248 CheckBool EncodedProgram::AddPeMakeRelocs(ExecutableType kind) { 251 CheckBool EncodedProgram::AddPeMakeRelocs(ExecutableType kind) {
249 if (kind == EXE_WIN_32_X86) 252 if (kind == EXE_WIN_32_X86)
250 return ops_.push_back(MAKE_PE_RELOCATION_TABLE); 253 return ops_.push_back(MAKE_PE_RELOCATION_TABLE);
251 return ops_.push_back(MAKE_PE64_RELOCATION_TABLE); 254 return ops_.push_back(MAKE_PE64_RELOCATION_TABLE);
252 } 255 }
253 256
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 INCLUDE_BYTES = 0x0200, 291 INCLUDE_BYTES = 0x0200,
289 INCLUDE_COPY_COUNTS = 0x0400, 292 INCLUDE_COPY_COUNTS = 0x0400,
290 INCLUDE_MISC = 0x1000 293 INCLUDE_MISC = 0x1000
291 }; 294 };
292 295
293 static FieldSelect GetFieldSelect() { 296 static FieldSelect GetFieldSelect() {
294 // TODO(sra): Use better configuration. 297 // TODO(sra): Use better configuration.
295 scoped_ptr<base::Environment> env(base::Environment::Create()); 298 scoped_ptr<base::Environment> env(base::Environment::Create());
296 std::string s; 299 std::string s;
297 env->GetVar("A_FIELDS", &s); 300 env->GetVar("A_FIELDS", &s);
298 uint64 fields; 301 uint64_t fields;
299 if (!base::StringToUint64(s, &fields)) 302 if (!base::StringToUint64(s, &fields))
300 return static_cast<FieldSelect>(~0); 303 return static_cast<FieldSelect>(~0);
301 return static_cast<FieldSelect>(fields); 304 return static_cast<FieldSelect>(fields);
302 } 305 }
303 306
304 CheckBool EncodedProgram::WriteTo(SinkStreamSet* streams) { 307 CheckBool EncodedProgram::WriteTo(SinkStreamSet* streams) {
305 FieldSelect select = GetFieldSelect(); 308 FieldSelect select = GetFieldSelect();
306 309
307 // The order of fields must be consistent in WriteTo and ReadFrom, regardless 310 // The order of fields must be consistent in WriteTo and ReadFrom, regardless
308 // of the streams used. The code can be configured with all kStreamXXX 311 // of the streams used. The code can be configured with all kStreamXXX
309 // constants the same. 312 // constants the same.
310 // 313 //
311 // If we change the code to pipeline reading with assembly (to avoid temporary 314 // If we change the code to pipeline reading with assembly (to avoid temporary
312 // storage vectors by consuming operands directly from the stream) then we 315 // storage vectors by consuming operands directly from the stream) then we
313 // need to read the base address and the random access address tables first, 316 // need to read the base address and the random access address tables first,
314 // the rest can be interleaved. 317 // the rest can be interleaved.
315 318
316 if (select & INCLUDE_MISC) { 319 if (select & INCLUDE_MISC) {
317 uint32 high = static_cast<uint32>(image_base_ >> 32); 320 uint32_t high = static_cast<uint32_t>(image_base_ >> 32);
318 uint32 low = static_cast<uint32>(image_base_ & 0xffffffffU); 321 uint32_t low = static_cast<uint32_t>(image_base_ & 0xffffffffU);
319 322
320 if (!streams->stream(kStreamMisc)->WriteVarint32(high) || 323 if (!streams->stream(kStreamMisc)->WriteVarint32(high) ||
321 !streams->stream(kStreamMisc)->WriteVarint32(low)) { 324 !streams->stream(kStreamMisc)->WriteVarint32(low)) {
322 return false; 325 return false;
323 } 326 }
324 } 327 }
325 328
326 bool success = true; 329 bool success = true;
327 330
328 if (select & INCLUDE_ABS32_ADDRESSES) { 331 if (select & INCLUDE_ABS32_ADDRESSES) {
(...skipping 24 matching lines...) Expand all
353 if (select & INCLUDE_ABS32_INDEXES) 356 if (select & INCLUDE_ABS32_INDEXES)
354 success &= WriteVector(abs32_ix_, streams->stream(kStreamAbs32Indexes)); 357 success &= WriteVector(abs32_ix_, streams->stream(kStreamAbs32Indexes));
355 358
356 if (select & INCLUDE_REL32_INDEXES) 359 if (select & INCLUDE_REL32_INDEXES)
357 success &= WriteVector(rel32_ix_, streams->stream(kStreamRel32Indexes)); 360 success &= WriteVector(rel32_ix_, streams->stream(kStreamRel32Indexes));
358 361
359 return success; 362 return success;
360 } 363 }
361 364
362 bool EncodedProgram::ReadFrom(SourceStreamSet* streams) { 365 bool EncodedProgram::ReadFrom(SourceStreamSet* streams) {
363 uint32 high; 366 uint32_t high;
364 uint32 low; 367 uint32_t low;
365 368
366 if (!streams->stream(kStreamMisc)->ReadVarint32(&high) || 369 if (!streams->stream(kStreamMisc)->ReadVarint32(&high) ||
367 !streams->stream(kStreamMisc)->ReadVarint32(&low)) { 370 !streams->stream(kStreamMisc)->ReadVarint32(&low)) {
368 return false; 371 return false;
369 } 372 }
370 image_base_ = (static_cast<uint64>(high) << 32) | low; 373 image_base_ = (static_cast<uint64_t>(high) << 32) | low;
371 374
372 if (!ReadSigned32Delta(&abs32_rva_, streams->stream(kStreamAbs32Addresses))) 375 if (!ReadSigned32Delta(&abs32_rva_, streams->stream(kStreamAbs32Addresses)))
373 return false; 376 return false;
374 if (!ReadSigned32Delta(&rel32_rva_, streams->stream(kStreamRel32Addresses))) 377 if (!ReadSigned32Delta(&rel32_rva_, streams->stream(kStreamRel32Addresses)))
375 return false; 378 return false;
376 if (!ReadVector(&origins_, streams->stream(kStreamOriginAddresses))) 379 if (!ReadVector(&origins_, streams->stream(kStreamOriginAddresses)))
377 return false; 380 return false;
378 if (!ReadVector(&ops_, streams->stream(kStreamOps))) 381 if (!ReadVector(&ops_, streams->stream(kStreamOps)))
379 return false; 382 return false;
380 if (!ReadVector(&copy_counts_, streams->stream(kStreamCopyCounts))) 383 if (!ReadVector(&copy_counts_, streams->stream(kStreamCopyCounts)))
(...skipping 23 matching lines...) Expand all
404 *output = v[index]; 407 *output = v[index];
405 return true; 408 return true;
406 } 409 }
407 410
408 CheckBool EncodedProgram::EvaluateRel32ARM(OP op, 411 CheckBool EncodedProgram::EvaluateRel32ARM(OP op,
409 size_t& ix_rel32_ix, 412 size_t& ix_rel32_ix,
410 RVA& current_rva, 413 RVA& current_rva,
411 SinkStream* output) { 414 SinkStream* output) {
412 switch (op & 0x0000F000) { 415 switch (op & 0x0000F000) {
413 case REL32ARM8: { 416 case REL32ARM8: {
414 uint32 index; 417 uint32_t index;
415 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) 418 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index))
416 return false; 419 return false;
417 ++ix_rel32_ix; 420 ++ix_rel32_ix;
418 RVA rva; 421 RVA rva;
419 if (!VectorAt(rel32_rva_, index, &rva)) 422 if (!VectorAt(rel32_rva_, index, &rva))
420 return false; 423 return false;
421 uint32 decompressed_op; 424 uint32_t decompressed_op;
422 if (!DisassemblerElf32ARM::Decompress(ARM_OFF8, 425 if (!DisassemblerElf32ARM::Decompress(
423 static_cast<uint16>(op), 426 ARM_OFF8, static_cast<uint16_t>(op),
424 static_cast<uint32>(rva - 427 static_cast<uint32_t>(rva - current_rva), &decompressed_op)) {
425 current_rva),
426 &decompressed_op)) {
427 return false; 428 return false;
428 } 429 }
429 uint16 op16 = static_cast<uint16>(decompressed_op); 430 uint16_t op16 = static_cast<uint16_t>(decompressed_op);
430 if (!output->Write(&op16, 2)) 431 if (!output->Write(&op16, 2))
431 return false; 432 return false;
432 current_rva += 2; 433 current_rva += 2;
433 break; 434 break;
434 } 435 }
435 case REL32ARM11: { 436 case REL32ARM11: {
436 uint32 index; 437 uint32_t index;
437 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) 438 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index))
438 return false; 439 return false;
439 ++ix_rel32_ix; 440 ++ix_rel32_ix;
440 RVA rva; 441 RVA rva;
441 if (!VectorAt(rel32_rva_, index, &rva)) 442 if (!VectorAt(rel32_rva_, index, &rva))
442 return false; 443 return false;
443 uint32 decompressed_op; 444 uint32_t decompressed_op;
444 if (!DisassemblerElf32ARM::Decompress(ARM_OFF11, (uint16) op, 445 if (!DisassemblerElf32ARM::Decompress(ARM_OFF11, (uint16_t)op,
445 (uint32) (rva - current_rva), 446 (uint32_t)(rva - current_rva),
446 &decompressed_op)) { 447 &decompressed_op)) {
447 return false; 448 return false;
448 } 449 }
449 uint16 op16 = static_cast<uint16>(decompressed_op); 450 uint16_t op16 = static_cast<uint16_t>(decompressed_op);
450 if (!output->Write(&op16, 2)) 451 if (!output->Write(&op16, 2))
451 return false; 452 return false;
452 current_rva += 2; 453 current_rva += 2;
453 break; 454 break;
454 } 455 }
455 case REL32ARM24: { 456 case REL32ARM24: {
456 uint32 index; 457 uint32_t index;
457 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) 458 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index))
458 return false; 459 return false;
459 ++ix_rel32_ix; 460 ++ix_rel32_ix;
460 RVA rva; 461 RVA rva;
461 if (!VectorAt(rel32_rva_, index, &rva)) 462 if (!VectorAt(rel32_rva_, index, &rva))
462 return false; 463 return false;
463 uint32 decompressed_op; 464 uint32_t decompressed_op;
464 if (!DisassemblerElf32ARM::Decompress(ARM_OFF24, (uint16) op, 465 if (!DisassemblerElf32ARM::Decompress(ARM_OFF24, (uint16_t)op,
465 (uint32) (rva - current_rva), 466 (uint32_t)(rva - current_rva),
466 &decompressed_op)) { 467 &decompressed_op)) {
467 return false; 468 return false;
468 } 469 }
469 if (!output->Write(&decompressed_op, 4)) 470 if (!output->Write(&decompressed_op, 4))
470 return false; 471 return false;
471 current_rva += 4; 472 current_rva += 4;
472 break; 473 break;
473 } 474 }
474 case REL32ARM25: { 475 case REL32ARM25: {
475 uint32 index; 476 uint32_t index;
476 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) 477 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index))
477 return false; 478 return false;
478 ++ix_rel32_ix; 479 ++ix_rel32_ix;
479 RVA rva; 480 RVA rva;
480 if (!VectorAt(rel32_rva_, index, &rva)) 481 if (!VectorAt(rel32_rva_, index, &rva))
481 return false; 482 return false;
482 uint32 decompressed_op; 483 uint32_t decompressed_op;
483 if (!DisassemblerElf32ARM::Decompress(ARM_OFF25, (uint16) op, 484 if (!DisassemblerElf32ARM::Decompress(ARM_OFF25, (uint16_t)op,
484 (uint32) (rva - current_rva), 485 (uint32_t)(rva - current_rva),
485 &decompressed_op)) { 486 &decompressed_op)) {
486 return false; 487 return false;
487 } 488 }
488 uint32 words = (decompressed_op << 16) | (decompressed_op >> 16); 489 uint32_t words = (decompressed_op << 16) | (decompressed_op >> 16);
489 if (!output->Write(&words, 4)) 490 if (!output->Write(&words, 4))
490 return false; 491 return false;
491 current_rva += 4; 492 current_rva += 4;
492 break; 493 break;
493 } 494 }
494 case REL32ARM21: { 495 case REL32ARM21: {
495 uint32 index; 496 uint32_t index;
496 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) 497 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index))
497 return false; 498 return false;
498 ++ix_rel32_ix; 499 ++ix_rel32_ix;
499 RVA rva; 500 RVA rva;
500 if (!VectorAt(rel32_rva_, index, &rva)) 501 if (!VectorAt(rel32_rva_, index, &rva))
501 return false; 502 return false;
502 uint32 decompressed_op; 503 uint32_t decompressed_op;
503 if (!DisassemblerElf32ARM::Decompress(ARM_OFF21, (uint16) op, 504 if (!DisassemblerElf32ARM::Decompress(ARM_OFF21, (uint16_t)op,
504 (uint32) (rva - current_rva), 505 (uint32_t)(rva - current_rva),
505 &decompressed_op)) { 506 &decompressed_op)) {
506 return false; 507 return false;
507 } 508 }
508 uint32 words = (decompressed_op << 16) | (decompressed_op >> 16); 509 uint32_t words = (decompressed_op << 16) | (decompressed_op >> 16);
509 if (!output->Write(&words, 4)) 510 if (!output->Write(&words, 4))
510 return false; 511 return false;
511 current_rva += 4; 512 current_rva += 4;
512 break; 513 break;
513 } 514 }
514 default: 515 default:
515 return false; 516 return false;
516 } 517 }
517 518
518 return true; 519 return true;
519 } 520 }
520 521
521 CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) { 522 CheckBool EncodedProgram::AssembleTo(SinkStream* final_buffer) {
522 // For the most part, the assembly process walks the various tables. 523 // For the most part, the assembly process walks the various tables.
523 // ix_mumble is the index into the mumble table. 524 // ix_mumble is the index into the mumble table.
524 size_t ix_origins = 0; 525 size_t ix_origins = 0;
525 size_t ix_copy_counts = 0; 526 size_t ix_copy_counts = 0;
526 size_t ix_copy_bytes = 0; 527 size_t ix_copy_bytes = 0;
527 size_t ix_abs32_ix = 0; 528 size_t ix_abs32_ix = 0;
528 size_t ix_rel32_ix = 0; 529 size_t ix_rel32_ix = 0;
529 530
530 RVA current_rva = 0; 531 RVA current_rva = 0;
531 532
532 bool pending_pe_relocation_table = false; 533 bool pending_pe_relocation_table = false;
533 uint8 pending_pe_relocation_table_type = 0x03; // IMAGE_REL_BASED_HIGHLOW 534 uint8_t pending_pe_relocation_table_type = 0x03; // IMAGE_REL_BASED_HIGHLOW
534 Elf32_Word pending_elf_relocation_table_type = 0; 535 Elf32_Word pending_elf_relocation_table_type = 0;
535 SinkStream bytes_following_relocation_table; 536 SinkStream bytes_following_relocation_table;
536 537
537 SinkStream* output = final_buffer; 538 SinkStream* output = final_buffer;
538 539
539 for (size_t ix_ops = 0; ix_ops < ops_.size(); ++ix_ops) { 540 for (size_t ix_ops = 0; ix_ops < ops_.size(); ++ix_ops) {
540 OP op = ops_[ix_ops]; 541 OP op = ops_[ix_ops];
541 542
542 switch (op) { 543 switch (op) {
543 default: 544 default:
544 if (!EvaluateRel32ARM(op, ix_rel32_ix, current_rva, output)) 545 if (!EvaluateRel32ARM(op, ix_rel32_ix, current_rva, output))
545 return false; 546 return false;
546 break; 547 break;
547 548
548 case ORIGIN: { 549 case ORIGIN: {
549 RVA section_rva; 550 RVA section_rva;
550 if (!VectorAt(origins_, ix_origins, &section_rva)) 551 if (!VectorAt(origins_, ix_origins, &section_rva))
551 return false; 552 return false;
552 ++ix_origins; 553 ++ix_origins;
553 current_rva = section_rva; 554 current_rva = section_rva;
554 break; 555 break;
555 } 556 }
556 557
557 case COPY: { 558 case COPY: {
558 size_t count; 559 size_t count;
559 if (!VectorAt(copy_counts_, ix_copy_counts, &count)) 560 if (!VectorAt(copy_counts_, ix_copy_counts, &count))
560 return false; 561 return false;
561 ++ix_copy_counts; 562 ++ix_copy_counts;
562 for (size_t i = 0; i < count; ++i) { 563 for (size_t i = 0; i < count; ++i) {
563 uint8 b; 564 uint8_t b;
564 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) 565 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b))
565 return false; 566 return false;
566 ++ix_copy_bytes; 567 ++ix_copy_bytes;
567 if (!output->Write(&b, 1)) 568 if (!output->Write(&b, 1))
568 return false; 569 return false;
569 } 570 }
570 current_rva += static_cast<RVA>(count); 571 current_rva += static_cast<RVA>(count);
571 break; 572 break;
572 } 573 }
573 574
574 case COPY1: { 575 case COPY1: {
575 uint8 b; 576 uint8_t b;
576 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) 577 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b))
577 return false; 578 return false;
578 ++ix_copy_bytes; 579 ++ix_copy_bytes;
579 if (!output->Write(&b, 1)) 580 if (!output->Write(&b, 1))
580 return false; 581 return false;
581 current_rva += 1; 582 current_rva += 1;
582 break; 583 break;
583 } 584 }
584 585
585 case REL32: { 586 case REL32: {
586 uint32 index; 587 uint32_t index;
587 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index)) 588 if (!VectorAt(rel32_ix_, ix_rel32_ix, &index))
588 return false; 589 return false;
589 ++ix_rel32_ix; 590 ++ix_rel32_ix;
590 RVA rva; 591 RVA rva;
591 if (!VectorAt(rel32_rva_, index, &rva)) 592 if (!VectorAt(rel32_rva_, index, &rva))
592 return false; 593 return false;
593 uint32 offset = (rva - (current_rva + 4)); 594 uint32_t offset = (rva - (current_rva + 4));
594 if (!output->Write(&offset, 4)) 595 if (!output->Write(&offset, 4))
595 return false; 596 return false;
596 current_rva += 4; 597 current_rva += 4;
597 break; 598 break;
598 } 599 }
599 600
600 case ABS32: 601 case ABS32:
601 case ABS64: { 602 case ABS64: {
602 uint32 index; 603 uint32_t index;
603 if (!VectorAt(abs32_ix_, ix_abs32_ix, &index)) 604 if (!VectorAt(abs32_ix_, ix_abs32_ix, &index))
604 return false; 605 return false;
605 ++ix_abs32_ix; 606 ++ix_abs32_ix;
606 RVA rva; 607 RVA rva;
607 if (!VectorAt(abs32_rva_, index, &rva)) 608 if (!VectorAt(abs32_rva_, index, &rva))
608 return false; 609 return false;
609 if (op == ABS32) { 610 if (op == ABS32) {
610 base::CheckedNumeric<uint32> abs32 = image_base_; 611 base::CheckedNumeric<uint32_t> abs32 = image_base_;
611 abs32 += rva; 612 abs32 += rva;
612 uint32 safe_abs32 = abs32.ValueOrDie(); 613 uint32_t safe_abs32 = abs32.ValueOrDie();
613 if (!abs32_relocs_.push_back(current_rva) || 614 if (!abs32_relocs_.push_back(current_rva) ||
614 !output->Write(&safe_abs32, 4)) { 615 !output->Write(&safe_abs32, 4)) {
615 return false; 616 return false;
616 } 617 }
617 current_rva += 4; 618 current_rva += 4;
618 } else { 619 } else {
619 base::CheckedNumeric<uint64> abs64 = image_base_; 620 base::CheckedNumeric<uint64_t> abs64 = image_base_;
620 abs64 += rva; 621 abs64 += rva;
621 uint64 safe_abs64 = abs64.ValueOrDie(); 622 uint64_t safe_abs64 = abs64.ValueOrDie();
622 if (!abs32_relocs_.push_back(current_rva) || 623 if (!abs32_relocs_.push_back(current_rva) ||
623 !output->Write(&safe_abs64, 8)) { 624 !output->Write(&safe_abs64, 8)) {
624 return false; 625 return false;
625 } 626 }
626 current_rva += 8; 627 current_rva += 8;
627 } 628 }
628 break; 629 break;
629 } 630 }
630 631
631 case MAKE_PE_RELOCATION_TABLE: { 632 case MAKE_PE_RELOCATION_TABLE: {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 if (ix_rel32_ix != rel32_ix_.size()) 709 if (ix_rel32_ix != rel32_ix_.size())
709 return false; 710 return false;
710 711
711 return true; 712 return true;
712 } 713 }
713 714
714 // RelocBlock has the layout of a block of relocations in the base relocation 715 // RelocBlock has the layout of a block of relocations in the base relocation
715 // table file format. 716 // table file format.
716 // 717 //
717 struct RelocBlockPOD { 718 struct RelocBlockPOD {
718 uint32 page_rva; 719 uint32_t page_rva;
719 uint32 block_size; 720 uint32_t block_size;
720 uint16 relocs[4096]; // Allow up to one relocation per byte of a 4k page. 721 uint16_t relocs[4096]; // Allow up to one relocation per byte of a 4k page.
721 }; 722 };
722 723
723 static_assert(offsetof(RelocBlockPOD, relocs) == 8, "reloc block header size"); 724 static_assert(offsetof(RelocBlockPOD, relocs) == 8, "reloc block header size");
724 725
725 class RelocBlock { 726 class RelocBlock {
726 public: 727 public:
727 RelocBlock() { 728 RelocBlock() {
728 pod.page_rva = 0xFFFFFFFF; 729 pod.page_rva = 0xFFFFFFFF;
729 pod.block_size = 8; 730 pod.block_size = 8;
730 } 731 }
731 732
732 void Add(uint16 item) { 733 void Add(uint16_t item) {
733 pod.relocs[(pod.block_size-8)/2] = item; 734 pod.relocs[(pod.block_size-8)/2] = item;
734 pod.block_size += 2; 735 pod.block_size += 2;
735 } 736 }
736 737
737 CheckBool Flush(SinkStream* buffer) WARN_UNUSED_RESULT { 738 CheckBool Flush(SinkStream* buffer) WARN_UNUSED_RESULT {
738 bool ok = true; 739 bool ok = true;
739 if (pod.block_size != 8) { 740 if (pod.block_size != 8) {
740 if (pod.block_size % 4 != 0) { // Pad to make size multiple of 4 bytes. 741 if (pod.block_size % 4 != 0) { // Pad to make size multiple of 4 bytes.
741 Add(0); 742 Add(0);
742 } 743 }
743 ok = buffer->Write(&pod, pod.block_size); 744 ok = buffer->Write(&pod, pod.block_size);
744 pod.block_size = 8; 745 pod.block_size = 8;
745 } 746 }
746 return ok; 747 return ok;
747 } 748 }
748 RelocBlockPOD pod; 749 RelocBlockPOD pod;
749 }; 750 };
750 751
751 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer, 752 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer,
752 uint8 type) { 753 uint8_t type) {
753 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); 754 std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
754 755
755 RelocBlock block; 756 RelocBlock block;
756 757
757 bool ok = true; 758 bool ok = true;
758 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) { 759 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) {
759 uint32 rva = abs32_relocs_[i]; 760 uint32_t rva = abs32_relocs_[i];
760 uint32 page_rva = rva & ~0xFFF; 761 uint32_t page_rva = rva & ~0xFFF;
761 if (page_rva != block.pod.page_rva) { 762 if (page_rva != block.pod.page_rva) {
762 ok &= block.Flush(buffer); 763 ok &= block.Flush(buffer);
763 block.pod.page_rva = page_rva; 764 block.pod.page_rva = page_rva;
764 } 765 }
765 if (ok) 766 if (ok)
766 block.Add(((static_cast<uint16>(type)) << 12) | (rva & 0xFFF)); 767 block.Add(((static_cast<uint16_t>(type)) << 12) | (rva & 0xFFF));
767 } 768 }
768 ok &= block.Flush(buffer); 769 ok &= block.Flush(buffer);
769 return ok; 770 return ok;
770 } 771 }
771 772
772 CheckBool EncodedProgram::GenerateElfRelocations(Elf32_Word r_info, 773 CheckBool EncodedProgram::GenerateElfRelocations(Elf32_Word r_info,
773 SinkStream* buffer) { 774 SinkStream* buffer) {
774 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); 775 std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
775 776
776 Elf32_Rel relocation_block; 777 Elf32_Rel relocation_block;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 if (assembled) 809 if (assembled)
809 return C_OK; 810 return C_OK;
810 return C_ASSEMBLY_FAILED; 811 return C_ASSEMBLY_FAILED;
811 } 812 }
812 813
813 void DeleteEncodedProgram(EncodedProgram* encoded) { 814 void DeleteEncodedProgram(EncodedProgram* encoded) {
814 delete encoded; 815 delete encoded;
815 } 816 }
816 817
817 } // namespace courgette 818 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/encoded_program.h ('k') | courgette/encoded_program_fuzz_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698