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

Side by Side Diff: courgette/encoded_program.cc

Issue 8477045: Add Elf 32 Support to Courgette. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Remove debug printf present by mistake. Created 9 years, 1 month 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 | Annotate | Revision Log
« 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 <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/environment.h" 12 #include "base/environment.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
17 #include "courgette/courgette.h" 17 #include "courgette/courgette.h"
18 #include "courgette/streams.h" 18 #include "courgette/streams.h"
19 #include "courgette/types_elf.h"
19 20
20 namespace courgette { 21 namespace courgette {
21 22
22 // Stream indexes. 23 // Stream indexes.
23 const int kStreamMisc = 0; 24 const int kStreamMisc = 0;
24 const int kStreamOps = 1; 25 const int kStreamOps = 1;
25 const int kStreamBytes = 2; 26 const int kStreamBytes = 2;
26 const int kStreamAbs32Indexes = 3; 27 const int kStreamAbs32Indexes = 3;
27 const int kStreamRel32Indexes = 4; 28 const int kStreamRel32Indexes = 4;
28 const int kStreamAbs32Addresses = 5; 29 const int kStreamAbs32Addresses = 5;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 235 }
235 236
236 CheckBool EncodedProgram::AddAbs32(int label_index) { 237 CheckBool EncodedProgram::AddAbs32(int label_index) {
237 return ops_.push_back(ABS32) && abs32_ix_.push_back(label_index); 238 return ops_.push_back(ABS32) && abs32_ix_.push_back(label_index);
238 } 239 }
239 240
240 CheckBool EncodedProgram::AddRel32(int label_index) { 241 CheckBool EncodedProgram::AddRel32(int label_index) {
241 return ops_.push_back(REL32) && rel32_ix_.push_back(label_index); 242 return ops_.push_back(REL32) && rel32_ix_.push_back(label_index);
242 } 243 }
243 244
244 CheckBool EncodedProgram::AddMakeRelocs() { 245 CheckBool EncodedProgram::AddPeMakeRelocs() {
245 return ops_.push_back(MAKE_BASE_RELOCATION_TABLE); 246 return ops_.push_back(MAKE_PE_RELOCATION_TABLE);
247 }
248
249 CheckBool EncodedProgram::AddElfMakeRelocs() {
250 return ops_.push_back(MAKE_ELF_RELOCATION_TABLE);
246 } 251 }
247 252
248 void EncodedProgram::DebuggingSummary() { 253 void EncodedProgram::DebuggingSummary() {
249 VLOG(1) << "EncodedProgram Summary" 254 VLOG(1) << "EncodedProgram Summary"
250 << "\n image base " << image_base_ 255 << "\n image base " << image_base_
251 << "\n abs32 rvas " << abs32_rva_.size() 256 << "\n abs32 rvas " << abs32_rva_.size()
252 << "\n rel32 rvas " << rel32_rva_.size() 257 << "\n rel32 rvas " << rel32_rva_.size()
253 << "\n ops " << ops_.size() 258 << "\n ops " << ops_.size()
254 << "\n origins " << origins_.size() 259 << "\n origins " << origins_.size()
255 << "\n copy_counts " << copy_counts_.size() 260 << "\n copy_counts " << copy_counts_.size()
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 // For the most part, the assembly process walks the various tables. 397 // For the most part, the assembly process walks the various tables.
393 // ix_mumble is the index into the mumble table. 398 // ix_mumble is the index into the mumble table.
394 size_t ix_origins = 0; 399 size_t ix_origins = 0;
395 size_t ix_copy_counts = 0; 400 size_t ix_copy_counts = 0;
396 size_t ix_copy_bytes = 0; 401 size_t ix_copy_bytes = 0;
397 size_t ix_abs32_ix = 0; 402 size_t ix_abs32_ix = 0;
398 size_t ix_rel32_ix = 0; 403 size_t ix_rel32_ix = 0;
399 404
400 RVA current_rva = 0; 405 RVA current_rva = 0;
401 406
402 bool pending_base_relocation_table = false; 407 bool pending_pe_relocation_table = false;
403 SinkStream bytes_following_base_relocation_table; 408 bool pending_elf_relocation_table = false;
409 SinkStream bytes_following_relocation_table;
404 410
405 SinkStream* output = final_buffer; 411 SinkStream* output = final_buffer;
406 412
407 for (size_t ix_ops = 0; ix_ops < ops_.size(); ++ix_ops) { 413 for (size_t ix_ops = 0; ix_ops < ops_.size(); ++ix_ops) {
408 OP op = ops_[ix_ops]; 414 OP op = ops_[ix_ops];
409 415
410 switch (op) { 416 switch (op) {
411 default: 417 default:
412 return false; 418 return false;
413 419
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 RVA rva; 477 RVA rva;
472 if (!VectorAt(abs32_rva_, index, &rva)) 478 if (!VectorAt(abs32_rva_, index, &rva))
473 return false; 479 return false;
474 uint32 abs32 = static_cast<uint32>(rva + image_base_); 480 uint32 abs32 = static_cast<uint32>(rva + image_base_);
475 if (!abs32_relocs_.push_back(current_rva) || !output->Write(&abs32, 4)) 481 if (!abs32_relocs_.push_back(current_rva) || !output->Write(&abs32, 4))
476 return false; 482 return false;
477 current_rva += 4; 483 current_rva += 4;
478 break; 484 break;
479 } 485 }
480 486
481 case MAKE_BASE_RELOCATION_TABLE: { 487 case MAKE_PE_RELOCATION_TABLE: {
482 // We can see the base relocation anywhere, but we only have the 488 // We can see the base relocation anywhere, but we only have the
483 // information to generate it at the very end. So we divert the bytes 489 // information to generate it at the very end. So we divert the bytes
484 // we are generating to a temporary stream. 490 // we are generating to a temporary stream.
485 if (pending_base_relocation_table) // Can't have two base relocation 491 if (pending_pe_relocation_table) // Can't have two base relocation
486 // tables. 492 // tables.
487 return false; 493 return false;
488 494
489 pending_base_relocation_table = true; 495 pending_pe_relocation_table = true;
490 output = &bytes_following_base_relocation_table; 496 output = &bytes_following_relocation_table;
491 break; 497 break;
492 // There is a potential problem *if* the instruction stream contains 498 // There is a potential problem *if* the instruction stream contains
493 // some REL32 relocations following the base relocation and in the same 499 // some REL32 relocations following the base relocation and in the same
494 // section. We don't know the size of the table, so 'current_rva' will 500 // section. We don't know the size of the table, so 'current_rva' will
495 // be wrong, causing REL32 offsets to be miscalculated. This never 501 // be wrong, causing REL32 offsets to be miscalculated. This never
496 // happens; the base relocation table is usually in a section of its 502 // happens; the base relocation table is usually in a section of its
497 // own, a data-only section, and following everything else in the 503 // own, a data-only section, and following everything else in the
498 // executable except some padding zero bytes. We could fix this by 504 // executable except some padding zero bytes. We could fix this by
499 // emitting an ORIGIN after the MAKE_BASE_RELOCATION_TABLE. 505 // emitting an ORIGIN after the MAKE_BASE_RELOCATION_TABLE.
500 } 506 }
507
508 case MAKE_ELF_RELOCATION_TABLE: {
509 // We can see the base relocation anywhere, but we only have the
510 // information to generate it at the very end. So we divert the bytes
511 // we are generating to a temporary stream.
512 if (pending_elf_relocation_table) // Can't have two relocation
513 // tables.
514 return false;
515
516 pending_elf_relocation_table = true;
517 output = &bytes_following_relocation_table;
518 break;
519 }
501 } 520 }
502 } 521 }
503 522
504 if (pending_base_relocation_table) { 523 if (pending_pe_relocation_table) {
505 if (!GenerateBaseRelocations(final_buffer) || 524 if (!GeneratePeRelocations(final_buffer) ||
506 !final_buffer->Append(&bytes_following_base_relocation_table)) 525 !final_buffer->Append(&bytes_following_relocation_table))
507 return false; 526 return false;
508 } 527 }
509 528
529 if (pending_elf_relocation_table) {
530 if (!GenerateElfRelocations(final_buffer) ||
531 !final_buffer->Append(&bytes_following_relocation_table))
532 return false;
533 }
534
510 // Final verification check: did we consume all lists? 535 // Final verification check: did we consume all lists?
511 if (ix_copy_counts != copy_counts_.size()) 536 if (ix_copy_counts != copy_counts_.size())
512 return false; 537 return false;
513 if (ix_copy_bytes != copy_bytes_.size()) 538 if (ix_copy_bytes != copy_bytes_.size())
514 return false; 539 return false;
515 if (ix_abs32_ix != abs32_ix_.size()) 540 if (ix_abs32_ix != abs32_ix_.size())
516 return false; 541 return false;
517 if (ix_rel32_ix != rel32_ix_.size()) 542 if (ix_rel32_ix != rel32_ix_.size())
518 return false; 543 return false;
519 544
(...skipping 30 matching lines...) Expand all
550 Add(0); 575 Add(0);
551 } 576 }
552 ok = buffer->Write(&pod, pod.block_size); 577 ok = buffer->Write(&pod, pod.block_size);
553 pod.block_size = 8; 578 pod.block_size = 8;
554 } 579 }
555 return ok; 580 return ok;
556 } 581 }
557 RelocBlockPOD pod; 582 RelocBlockPOD pod;
558 }; 583 };
559 584
560 CheckBool EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) { 585 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer) {
561 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); 586 std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
562 587
563 RelocBlock block; 588 RelocBlock block;
564 589
565 bool ok = true; 590 bool ok = true;
566 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) { 591 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) {
567 uint32 rva = abs32_relocs_[i]; 592 uint32 rva = abs32_relocs_[i];
568 uint32 page_rva = rva & ~0xFFF; 593 uint32 page_rva = rva & ~0xFFF;
569 if (page_rva != block.pod.page_rva) { 594 if (page_rva != block.pod.page_rva) {
570 ok &= block.Flush(buffer); 595 ok &= block.Flush(buffer);
571 block.pod.page_rva = page_rva; 596 block.pod.page_rva = page_rva;
572 } 597 }
573 if (ok) 598 if (ok)
574 block.Add(0x3000 | (rva & 0xFFF)); 599 block.Add(0x3000 | (rva & 0xFFF));
575 } 600 }
576 ok &= block.Flush(buffer); 601 ok &= block.Flush(buffer);
577 return ok; 602 return ok;
578 } 603 }
579 604
605 CheckBool EncodedProgram::GenerateElfRelocations(SinkStream* buffer) {
606 std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
607
608 Elf32_Rel relocation_block;
609
610 // We only handle this specific type of relocation, so far.
611 relocation_block.r_info = R_386_RELATIVE;
612
613 bool ok = true;
614 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) {
615 relocation_block.r_offset = abs32_relocs_[i];
616 ok = buffer->Write(&relocation_block, sizeof(Elf32_Rel));
617 }
618
619 return ok;
620 }
580 //////////////////////////////////////////////////////////////////////////////// 621 ////////////////////////////////////////////////////////////////////////////////
581 622
582 Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink) { 623 Status WriteEncodedProgram(EncodedProgram* encoded, SinkStreamSet* sink) {
583 if (!encoded->WriteTo(sink)) 624 if (!encoded->WriteTo(sink))
584 return C_STREAM_ERROR; 625 return C_STREAM_ERROR;
585 return C_OK; 626 return C_OK;
586 } 627 }
587 628
588 Status ReadEncodedProgram(SourceStreamSet* streams, EncodedProgram** output) { 629 Status ReadEncodedProgram(SourceStreamSet* streams, EncodedProgram** output) {
589 EncodedProgram* encoded = new EncodedProgram(); 630 EncodedProgram* encoded = new EncodedProgram();
(...skipping 10 matching lines...) Expand all
600 if (assembled) 641 if (assembled)
601 return C_OK; 642 return C_OK;
602 return C_ASSEMBLY_FAILED; 643 return C_ASSEMBLY_FAILED;
603 } 644 }
604 645
605 void DeleteEncodedProgram(EncodedProgram* encoded) { 646 void DeleteEncodedProgram(EncodedProgram* encoded) {
606 delete encoded; 647 delete encoded;
607 } 648 }
608 649
609 } // end namespace 650 } // end namespace
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