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

Side by Side Diff: tools/relocation_packer/src/elf_file.cc

Issue 571333003: Set spliced LOAD segment's memsz equal to filesz. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months 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 | « no previous file | tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so » ('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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // Implementation notes: 5 // Implementation notes:
6 // 6 //
7 // We need to remove a piece from the ELF shared library. However, we also 7 // We need to remove a piece from the ELF shared library. However, we also
8 // want to ensure that code and data loads at the same addresses as before 8 // want to ensure that code and data loads at the same addresses as before
9 // packing, so that tools like breakpad can still match up addresses found 9 // packing, so that tools like breakpad can still match up addresses found
10 // in any crash dumps with data extracted from the pre-packed version of 10 // in any crash dumps with data extracted from the pre-packed version of
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 // GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0 526 // GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0
527 // 527 //
528 // The hole in the file is in the first of these. In order to preserve all 528 // The hole in the file is in the first of these. In order to preserve all
529 // load addresses, what we do is to turn the GNU_STACK into a new LOAD entry 529 // load addresses, what we do is to turn the GNU_STACK into a new LOAD entry
530 // that maps segments up to where we created the hole, adjust the first LOAD 530 // that maps segments up to where we created the hole, adjust the first LOAD
531 // entry so that it maps segments after that, adjust any other program 531 // entry so that it maps segments after that, adjust any other program
532 // headers whose offset is after the hole start, and finally order the LOAD 532 // headers whose offset is after the hole start, and finally order the LOAD
533 // segments by offset, to give: 533 // segments by offset, to give:
534 // 534 //
535 // Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 535 // Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
536 // LOAD 0x000000 0x00000000 0x00000000 0x14ea4 0x212ea4 R E 0x1000 536 // LOAD 0x000000 0x00000000 0x00000000 0x14ea4 0x14ea4 R E 0x1000
537 // LOAD 0x014ea4 0x00212ea4 0x00212ea4 0x1cea164 0x1cea164 R E 0x1000 537 // LOAD 0x014ea4 0x00212ea4 0x00212ea4 0x1cea164 0x1cea164 R E 0x1000
538 // DYNAMIC 0x1e60c50 0x0205fc50 0x0205fc50 0x00108 0x00108 RW 0x4 538 // DYNAMIC 0x1e60c50 0x0205fc50 0x0205fc50 0x00108 0x00108 RW 0x4
539 // LOAD 0x1cff008 0x01efe008 0x01efe008 0x17ec3c 0x1a0324 RW 0x1000 539 // LOAD 0x1cff008 0x01efe008 0x01efe008 0x17ec3c 0x1a0324 RW 0x1000
540 // 540 //
541 // We work out the split points by finding the .rel.dyn or .rela.dyn section 541 // We work out the split points by finding the .rel.dyn or .rela.dyn section
542 // that contains the hole, and by finding the last section in a given segment. 542 // that contains the hole, and by finding the last section in a given segment.
543 // 543 //
544 // To unpack, we reverse the above to leave the file as it was originally. 544 // To unpack, we reverse the above to leave the file as it was originally.
545 void SplitProgramHeadersForHole(Elf* elf, 545 void SplitProgramHeadersForHole(Elf* elf,
546 ELF::Off hole_start, 546 ELF::Off hole_start,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 586
587 // Split on the section following the holed one, and up to (but not 587 // Split on the section following the holed one, and up to (but not
588 // including) the section following the last one in the split segment. 588 // including) the section following the last one in the split segment.
589 Elf_Scn* split_section = elf_nextscn(elf, holed_section); 589 Elf_Scn* split_section = elf_nextscn(elf, holed_section);
590 LOG_IF(FATAL, !split_section) 590 LOG_IF(FATAL, !split_section)
591 << "No section follows the section that contains the hole"; 591 << "No section follows the section that contains the hole";
592 Elf_Scn* end_section = elf_nextscn(elf, last_section); 592 Elf_Scn* end_section = elf_nextscn(elf, last_section);
593 LOG_IF(FATAL, !end_section) 593 LOG_IF(FATAL, !end_section)
594 << "No section follows the last section in the segment being split"; 594 << "No section follows the last section in the segment being split";
595 595
596 // Split the first portion of split_header into spliced_header. Done 596 // Split the first portion of split_header into spliced_header.
597 // by copying the entire split_header into spliced_header, then changing
598 // only the fields that set the segment sizes.
599 *spliced_header = *split_header;
600 const ELF::Shdr* split_section_header = ELF::getshdr(split_section); 597 const ELF::Shdr* split_section_header = ELF::getshdr(split_section);
598 spliced_header->p_type = split_header->p_type;
599 spliced_header->p_offset = split_header->p_offset;
600 spliced_header->p_vaddr = split_header->p_vaddr;
601 spliced_header->p_paddr = split_header->p_paddr;
602 CHECK(split_header->p_filesz == split_header->p_memsz);
601 spliced_header->p_filesz = split_section_header->sh_offset; 603 spliced_header->p_filesz = split_section_header->sh_offset;
602 spliced_header->p_memsz = split_section_header->sh_addr; 604 spliced_header->p_memsz = split_section_header->sh_offset;
605 spliced_header->p_flags = split_header->p_flags;
606 spliced_header->p_align = split_header->p_align;
603 607
604 // Now rewrite split_header to remove the part we spliced from it. 608 // Now rewrite split_header to remove the part we spliced from it.
605 const ELF::Shdr* end_section_header = ELF::getshdr(end_section); 609 const ELF::Shdr* end_section_header = ELF::getshdr(end_section);
606 split_header->p_offset = spliced_header->p_filesz; 610 split_header->p_offset = spliced_header->p_filesz;
607
608 CHECK(split_header->p_vaddr == split_header->p_paddr); 611 CHECK(split_header->p_vaddr == split_header->p_paddr);
609 split_header->p_vaddr = spliced_header->p_memsz; 612 split_header->p_vaddr = split_section_header->sh_addr;
610 split_header->p_paddr = split_header->p_vaddr; 613 split_header->p_paddr = split_section_header->sh_addr;
611
612 CHECK(split_header->p_filesz == split_header->p_memsz); 614 CHECK(split_header->p_filesz == split_header->p_memsz);
613 split_header->p_filesz = 615 split_header->p_filesz =
614 end_section_header->sh_offset - spliced_header->p_filesz; 616 end_section_header->sh_offset - spliced_header->p_filesz;
615 split_header->p_memsz = split_header->p_filesz; 617 split_header->p_memsz =
618 end_section_header->sh_offset - spliced_header->p_filesz;
616 619
617 // Adjust the offsets of all program headers that are not one of the pair 620 // Adjust the offsets of all program headers that are not one of the pair
618 // we just created by splitting. 621 // we just created by splitting.
619 AdjustProgramHeaderOffsets(elf_program_header, 622 AdjustProgramHeaderOffsets(elf_program_header,
620 program_header_count, 623 program_header_count,
621 spliced_header, 624 spliced_header,
622 split_header, 625 split_header,
623 hole_start, 626 hole_start,
624 hole_size); 627 hole_size);
625 628
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 size_t string_index; 662 size_t string_index;
660 elf_getshdrstrndx(elf, &string_index); 663 elf_getshdrstrndx(elf, &string_index);
661 664
662 const ELF::Shdr* section_header = ELF::getshdr(last_section); 665 const ELF::Shdr* section_header = ELF::getshdr(last_section);
663 std::string name = elf_strptr(elf, string_index, section_header->sh_name); 666 std::string name = elf_strptr(elf, string_index, section_header->sh_name);
664 VLOG(1) << "section " << name << " coalesced"; 667 VLOG(1) << "section " << name << " coalesced";
665 668
666 // Rewrite the coalesced segment into split_header. 669 // Rewrite the coalesced segment into split_header.
667 const ELF::Shdr* last_section_header = ELF::getshdr(last_section); 670 const ELF::Shdr* last_section_header = ELF::getshdr(last_section);
668 split_header->p_offset = spliced_header->p_offset; 671 split_header->p_offset = spliced_header->p_offset;
672 CHECK(split_header->p_vaddr == split_header->p_paddr);
669 split_header->p_vaddr = spliced_header->p_vaddr; 673 split_header->p_vaddr = spliced_header->p_vaddr;
670 split_header->p_paddr = split_header->p_vaddr; 674 split_header->p_paddr = spliced_header->p_vaddr;
675 CHECK(split_header->p_filesz == split_header->p_memsz);
671 split_header->p_filesz = 676 split_header->p_filesz =
672 last_section_header->sh_offset + last_section_header->sh_size; 677 last_section_header->sh_offset + last_section_header->sh_size;
673 split_header->p_memsz = split_header->p_filesz; 678 split_header->p_memsz =
679 last_section_header->sh_offset + last_section_header->sh_size;
674 680
675 // Reconstruct the original GNU_STACK segment into spliced_header. 681 // Reconstruct the original GNU_STACK segment into spliced_header.
676 spliced_header->p_type = PT_GNU_STACK; 682 spliced_header->p_type = PT_GNU_STACK;
677 spliced_header->p_offset = 0; 683 spliced_header->p_offset = 0;
678 spliced_header->p_vaddr = 0; 684 spliced_header->p_vaddr = 0;
679 spliced_header->p_paddr = 0; 685 spliced_header->p_paddr = 0;
680 spliced_header->p_filesz = 0; 686 spliced_header->p_filesz = 0;
681 spliced_header->p_memsz = 0; 687 spliced_header->p_memsz = 0;
682 spliced_header->p_flags = PF_R | PF_W; 688 spliced_header->p_flags = PF_R | PF_W;
683 spliced_header->p_align = ELF::kGnuStackSegmentAlignment; 689 spliced_header->p_align = ELF::kGnuStackSegmentAlignment;
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 1283
1278 // Clean up libelf, and truncate the output file to the number of bytes 1284 // Clean up libelf, and truncate the output file to the number of bytes
1279 // written by elf_update(). 1285 // written by elf_update().
1280 elf_end(elf_); 1286 elf_end(elf_);
1281 elf_ = NULL; 1287 elf_ = NULL;
1282 const int truncate = ftruncate(fd_, file_bytes); 1288 const int truncate = ftruncate(fd_, file_bytes);
1283 CHECK(truncate == 0); 1289 CHECK(truncate == 0);
1284 } 1290 }
1285 1291
1286 } // namespace relocation_packer 1292 } // namespace relocation_packer
OLDNEW
« no previous file with comments | « no previous file | tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698