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

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

Issue 341483002: Preserve section and data alignment in libchrome.<ver>.so. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review feedback changes Created 6 years, 6 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.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 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 // TODO(simonb): Extend for 64-bit target libraries. 5 // TODO(simonb): Extend for 64-bit target libraries.
6 6
7 #include "elf_file.h" 7 #include "elf_file.h"
8 8
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <unistd.h> 11 #include <unistd.h>
12 #include <string> 12 #include <string>
13 #include <vector> 13 #include <vector>
14 14
15 #include "debug.h" 15 #include "debug.h"
16 #include "libelf.h" 16 #include "libelf.h"
17 #include "packer.h" 17 #include "packer.h"
18 18
19 namespace relocation_packer { 19 namespace relocation_packer {
20 20
21 // Stub identifier written to 'null out' packed data, "NULL". 21 // Stub identifier written to 'null out' packed data, "NULL".
22 static const Elf32_Word kStubIdentifier = 0x4c4c554eu; 22 static const Elf32_Word kStubIdentifier = 0x4c4c554eu;
23 23
24 // Out-of-band dynamic tags used to indicate the offset and size of the 24 // Out-of-band dynamic tags used to indicate the offset and size of the
25 // .android.rel.dyn section. 25 // .android.rel.dyn section.
26 static const Elf32_Sword DT_ANDROID_ARM_REL_OFFSET = DT_LOPROC; 26 static const Elf32_Sword DT_ANDROID_ARM_REL_OFFSET = DT_LOPROC;
27 static const Elf32_Sword DT_ANDROID_ARM_REL_SIZE = DT_LOPROC + 1; 27 static const Elf32_Sword DT_ANDROID_ARM_REL_SIZE = DT_LOPROC + 1;
28 28
29 // Alignment to preserve, in bytes. This must be at least as large as the
30 // largest d_align and sh_addralign values found in the loaded file.
31 static const size_t kPreserveAlignment = 256;
32
29 namespace { 33 namespace {
30 34
31 // Get section data. Checks that the section has exactly one data entry, 35 // Get section data. Checks that the section has exactly one data entry,
32 // so that the section size and the data size are the same. True in 36 // so that the section size and the data size are the same. True in
33 // practice for all sections we resize when packing or unpacking. Done 37 // practice for all sections we resize when packing or unpacking. Done
34 // by ensuring that a call to elf_getdata(section, data) returns NULL as 38 // by ensuring that a call to elf_getdata(section, data) returns NULL as
35 // the next data entry. 39 // the next data entry.
36 Elf_Data* GetSectionData(Elf_Scn* section) { 40 Elf_Data* GetSectionData(Elf_Scn* section) {
37 Elf_Data* data = elf_getdata(section, NULL); 41 Elf_Data* data = elf_getdata(section, NULL);
38 CHECK(data && elf_getdata(section, data) == NULL); 42 CHECK(data && elf_getdata(section, data) == NULL);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 VLOG(" p_memsz = %u\n", program_header->p_memsz); 88 VLOG(" p_memsz = %u\n", program_header->p_memsz);
85 } 89 }
86 90
87 // Verbose ELF section header logging. 91 // Verbose ELF section header logging.
88 void VerboseLogSectionHeader(const std::string& section_name, 92 void VerboseLogSectionHeader(const std::string& section_name,
89 const Elf32_Shdr* section_header) { 93 const Elf32_Shdr* section_header) {
90 VLOG("section %s\n", section_name.c_str()); 94 VLOG("section %s\n", section_name.c_str());
91 VLOG(" sh_addr = %u\n", section_header->sh_addr); 95 VLOG(" sh_addr = %u\n", section_header->sh_addr);
92 VLOG(" sh_offset = %u\n", section_header->sh_offset); 96 VLOG(" sh_offset = %u\n", section_header->sh_offset);
93 VLOG(" sh_size = %u\n", section_header->sh_size); 97 VLOG(" sh_size = %u\n", section_header->sh_size);
98 VLOG(" sh_addralign = %u\n", section_header->sh_addralign);
94 } 99 }
95 100
96 // Verbose ELF section data logging. 101 // Verbose ELF section data logging.
97 void VerboseLogSectionData(const Elf_Data* data) { 102 void VerboseLogSectionData(const Elf_Data* data) {
98 VLOG(" data\n"); 103 VLOG(" data\n");
99 VLOG(" d_buf = %p\n", data->d_buf); 104 VLOG(" d_buf = %p\n", data->d_buf);
100 VLOG(" d_off = %lu\n", data->d_off); 105 VLOG(" d_off = %lu\n", data->d_off);
101 VLOG(" d_size = %lu\n", data->d_size); 106 VLOG(" d_size = %lu\n", data->d_size);
107 VLOG(" d_align = %lu\n", data->d_align);
102 } 108 }
103 109
104 } // namespace 110 } // namespace
105 111
106 // Load the complete ELF file into a memory image in libelf, and identify 112 // Load the complete ELF file into a memory image in libelf, and identify
107 // the .rel.dyn, .dynamic, and .android.rel.dyn sections. No-op if the 113 // the .rel.dyn, .dynamic, and .android.rel.dyn sections. No-op if the
108 // ELF file has already been loaded. 114 // ELF file has already been loaded.
109 bool ElfFile::Load() { 115 bool ElfFile::Load() {
110 if (elf_) 116 if (elf_)
111 return true; 117 return true;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 } 189 }
184 if (section_header->sh_offset == dynamic_program_header->p_offset) { 190 if (section_header->sh_offset == dynamic_program_header->p_offset) {
185 found_dynamic_section = section; 191 found_dynamic_section = section;
186 } 192 }
187 193
188 // If we find a section named .debug*, set the debug warning flag. 194 // If we find a section named .debug*, set the debug warning flag.
189 if (std::string(name).find(".debug") == 0) { 195 if (std::string(name).find(".debug") == 0) {
190 has_debug_section = true; 196 has_debug_section = true;
191 } 197 }
192 198
199 // Ensure we preserve alignment, repeated later for the data block(s).
200 CHECK(section_header->sh_addralign <= kPreserveAlignment);
201
193 Elf_Data* data = NULL; 202 Elf_Data* data = NULL;
194 while ((data = elf_getdata(section, data)) != NULL) { 203 while ((data = elf_getdata(section, data)) != NULL) {
204 CHECK(data->d_align <= kPreserveAlignment);
195 VerboseLogSectionData(data); 205 VerboseLogSectionData(data);
196 } 206 }
197 } 207 }
198 208
199 // Loading failed if we did not find the required special sections. 209 // Loading failed if we did not find the required special sections.
200 if (!found_rel_dyn_section) { 210 if (!found_rel_dyn_section) {
201 LOG("ERROR: Missing .rel.dyn section\n"); 211 LOG("ERROR: Missing .rel.dyn section\n");
202 return false; 212 return false;
203 } 213 }
204 if (!found_dynamic_section) { 214 if (!found_dynamic_section) {
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 CHECK(ELF32_R_TYPE(relocation->r_info) == R_ARM_RELATIVE); 657 CHECK(ELF32_R_TYPE(relocation->r_info) == R_ARM_RELATIVE);
648 658
649 // See if this relocation points into the current section. 659 // See if this relocation points into the current section.
650 if (relocation->r_offset >= section_start && 660 if (relocation->r_offset >= section_start &&
651 relocation->r_offset < section_end) { 661 relocation->r_offset < section_end) {
652 Elf32_Addr byte_offset = relocation->r_offset - section_start; 662 Elf32_Addr byte_offset = relocation->r_offset - section_start;
653 Elf32_Off* target = reinterpret_cast<Elf32_Off*>(area + byte_offset); 663 Elf32_Off* target = reinterpret_cast<Elf32_Off*>(area + byte_offset);
654 664
655 // Is the relocation's target after the hole's start? 665 // Is the relocation's target after the hole's start?
656 if (*target > hole_start) { 666 if (*target > hole_start) {
657
658 // Copy on first write. Recompute target to point into the newly 667 // Copy on first write. Recompute target to point into the newly
659 // allocated buffer. 668 // allocated buffer.
660 if (area == data->d_buf) { 669 if (area == data->d_buf) {
661 area = new uint8_t[data->d_size]; 670 area = new uint8_t[data->d_size];
662 memcpy(area, data->d_buf, data->d_size); 671 memcpy(area, data->d_buf, data->d_size);
663 target = reinterpret_cast<Elf32_Off*>(area + byte_offset); 672 target = reinterpret_cast<Elf32_Off*>(area + byte_offset);
664 } 673 }
665 674
666 *target += hole_size; 675 *target += hole_size;
667 VLOG("relocation[%lu] target adjusted to %u\n", i, *target); 676 VLOG("relocation[%lu] target adjusted to %u\n", i, *target);
668 } 677 }
669 } 678 }
670 } 679 }
671 680
672 // If we applied any relocation to this section, write it back. 681 // If we applied any relocation to this section, write it back.
673 if (area != data->d_buf) { 682 if (area != data->d_buf) {
674 RewriteSectionData(data, area, data->d_size); 683 RewriteSectionData(data, area, data->d_size);
675 delete [] area; 684 delete [] area;
676 } 685 }
677 } 686 }
678 } 687 }
679 688
689 // Pad relocations with a given number of R_ARM_NONE relocations.
690 void PadRelocations(size_t count,
691 std::vector<Elf32_Rel>* relocations) {
692 const Elf32_Rel r_arm_none = {R_ARM_NONE, 0};
693 std::vector<Elf32_Rel> padding(count, r_arm_none);
694 relocations->insert(relocations->end(), padding.begin(), padding.end());
695 }
696
680 // Adjust relocations so that the offset that they indicate will be correct 697 // Adjust relocations so that the offset that they indicate will be correct
681 // after the hole in .rel.dyn is added or removed (in effect, relocate the 698 // after the hole in .rel.dyn is added or removed (in effect, relocate the
682 // relocations). 699 // relocations).
683 void AdjustRelocations(Elf32_Off hole_start, 700 void AdjustRelocations(Elf32_Off hole_start,
684 size_t hole_size, 701 size_t hole_size,
685 std::vector<Elf32_Rel>* relocations) { 702 std::vector<Elf32_Rel>* relocations) {
686 for (size_t i = 0; i < relocations->size(); ++i) { 703 for (size_t i = 0; i < relocations->size(); ++i) {
687 Elf32_Rel* relocation = &relocations->at(i); 704 Elf32_Rel* relocation = &relocations->at(i);
688 if (relocation->r_offset > hole_start) { 705 if (relocation->r_offset > hole_start) {
689 relocation->r_offset += hole_size; 706 relocation->r_offset += hole_size;
(...skipping 28 matching lines...) Expand all
718 // Filter relocations into those that are R_ARM_RELATIVE and others. 735 // Filter relocations into those that are R_ARM_RELATIVE and others.
719 for (size_t i = 0; i < relocations.size(); ++i) { 736 for (size_t i = 0; i < relocations.size(); ++i) {
720 const Elf32_Rel& relocation = relocations[i]; 737 const Elf32_Rel& relocation = relocations[i];
721 if (ELF32_R_TYPE(relocation.r_info) == R_ARM_RELATIVE) { 738 if (ELF32_R_TYPE(relocation.r_info) == R_ARM_RELATIVE) {
722 CHECK(ELF32_R_SYM(relocation.r_info) == 0); 739 CHECK(ELF32_R_SYM(relocation.r_info) == 0);
723 relative_relocations.push_back(relocation); 740 relative_relocations.push_back(relocation);
724 } else { 741 } else {
725 other_relocations.push_back(relocation); 742 other_relocations.push_back(relocation);
726 } 743 }
727 } 744 }
728 VLOG("R_ARM_RELATIVE: %lu entries\n", relative_relocations.size()); 745 LOG("R_ARM_RELATIVE: %lu entries\n", relative_relocations.size());
729 VLOG("Other : %lu entries\n", other_relocations.size()); 746 LOG("Other : %lu entries\n", other_relocations.size());
730 VLOG("Total : %lu entries\n", relocations.size()); 747 LOG("Total : %lu entries\n", relocations.size());
731 748
732 // If no relative relocations then we have nothing packable. Perhaps 749 // If no relative relocations then we have nothing packable. Perhaps
733 // the shared object has already been packed? 750 // the shared object has already been packed?
734 if (relative_relocations.empty()) { 751 if (relative_relocations.empty()) {
735 LOG("ERROR: No R_ARM_RELATIVE relocations found (already packed?)\n"); 752 LOG("ERROR: No R_ARM_RELATIVE relocations found (already packed?)\n");
736 return false; 753 return false;
737 } 754 }
738 755
739 // Pre-calculate the size of the hole we will close up when we rewrite
740 // .reldyn. We have to adjust all relocation addresses to account for this.
741 Elf32_Shdr* section_header = elf32_getshdr(rel_dyn_section_);
742 const Elf32_Off hole_start = section_header->sh_offset;
743 const size_t hole_size =
744 relative_relocations.size() * sizeof(relative_relocations[0]);
745
746 // Unless padding, pre-apply R_ARM_RELATIVE relocations to account for the 756 // Unless padding, pre-apply R_ARM_RELATIVE relocations to account for the
747 // hole, and pre-adjust all relocation offsets accordingly. 757 // hole, and pre-adjust all relocation offsets accordingly.
748 if (!is_padding_rel_dyn_) { 758 if (!is_padding_rel_dyn_) {
759 // Pre-calculate the size of the hole we will close up when we rewrite
760 // .rel.dyn. We have to adjust relocation addresses to account for this.
761 Elf32_Shdr* section_header = elf32_getshdr(rel_dyn_section_);
762 const Elf32_Off hole_start = section_header->sh_offset;
763 size_t hole_size =
764 relative_relocations.size() * sizeof(relative_relocations[0]);
765 const size_t unaligned_hole_size = hole_size;
766
767 // Adjust the actual hole size to preserve alignment.
768 hole_size -= hole_size % kPreserveAlignment;
769 LOG("Compaction : %lu bytes\n", hole_size);
770
771 // Adjusting for alignment may have removed any packing benefit.
772 if (hole_size == 0) {
773 LOG("Too few R_ARM_RELATIVE relocations to pack after alignment\n");
774 return false;
775 }
776
777 // Add R_ARM_NONE relocations to other_relocations to preserve alignment.
778 const size_t padding_bytes = unaligned_hole_size - hole_size;
779 CHECK(padding_bytes % sizeof(other_relocations[0]) == 0);
780 const size_t required = padding_bytes / sizeof(other_relocations[0]);
781 PadRelocations(required, &other_relocations);
782 LOG("Alignment pad : %lu relocations\n", required);
783
749 // Apply relocations to all R_ARM_RELATIVE data to relocate it into the 784 // Apply relocations to all R_ARM_RELATIVE data to relocate it into the
750 // area it will occupy once the hole in .rel.dyn is removed. 785 // area it will occupy once the hole in .rel.dyn is removed.
751 AdjustRelocationTargets(elf_, hole_start, -hole_size, relative_relocations); 786 AdjustRelocationTargets(elf_, hole_start, -hole_size, relative_relocations);
752 // Relocate the relocations. 787 // Relocate the relocations.
753 AdjustRelocations(hole_start, -hole_size, &relative_relocations); 788 AdjustRelocations(hole_start, -hole_size, &relative_relocations);
754 AdjustRelocations(hole_start, -hole_size, &other_relocations); 789 AdjustRelocations(hole_start, -hole_size, &other_relocations);
790 } else {
791 // If padding, add R_ARM_NONE relocations to other_relocations to make it
792 // the same size as the the original relocations we read in. This makes
793 // the ResizeSection() below a no-op.
794 const size_t required = relocations.size() - other_relocations.size();
795 PadRelocations(required, &other_relocations);
755 } 796 }
756 797
798
757 // Pack R_ARM_RELATIVE relocations. 799 // Pack R_ARM_RELATIVE relocations.
758 const size_t initial_bytes = 800 const size_t initial_bytes =
759 relative_relocations.size() * sizeof(relative_relocations[0]); 801 relative_relocations.size() * sizeof(relative_relocations[0]);
760 LOG("Unpacked R_ARM_RELATIVE: %lu bytes\n", initial_bytes); 802 LOG("Unpacked R_ARM_RELATIVE: %lu bytes\n", initial_bytes);
761 std::vector<uint8_t> packed; 803 std::vector<uint8_t> packed;
762 RelocationPacker packer; 804 RelocationPacker packer;
763 packer.PackRelativeRelocations(relative_relocations, &packed); 805 packer.PackRelativeRelocations(relative_relocations, &packed);
764 const void* packed_data = &packed[0]; 806 const void* packed_data = &packed[0];
765 const size_t packed_bytes = packed.size() * sizeof(packed[0]); 807 const size_t packed_bytes = packed.size() * sizeof(packed[0]);
766 LOG("Packed R_ARM_RELATIVE: %lu bytes\n", packed_bytes); 808 LOG("Packed R_ARM_RELATIVE: %lu bytes\n", packed_bytes);
(...skipping 13 matching lines...) Expand all
780 CHECK(unpacked[i].r_offset == relative_relocations[i].r_offset); 822 CHECK(unpacked[i].r_offset == relative_relocations[i].r_offset);
781 CHECK(unpacked[i].r_info == relative_relocations[i].r_info); 823 CHECK(unpacked[i].r_info == relative_relocations[i].r_info);
782 } 824 }
783 825
784 // Make sure packing saved some space. 826 // Make sure packing saved some space.
785 if (packed_bytes >= initial_bytes) { 827 if (packed_bytes >= initial_bytes) {
786 LOG("Packing R_ARM_RELATIVE relocations saves no space\n"); 828 LOG("Packing R_ARM_RELATIVE relocations saves no space\n");
787 return false; 829 return false;
788 } 830 }
789 831
790 // If padding, add R_ARM_NONE relocations to other_relocations to make it
791 // the same size as the the original relocations we read in. This makes
792 // the ResizeSection() below a no-op.
793 if (is_padding_rel_dyn_) {
794 const Elf32_Rel r_arm_none = {R_ARM_NONE, 0};
795 const size_t required = relocations.size() - other_relocations.size();
796 std::vector<Elf32_Rel> padding(required, r_arm_none);
797 other_relocations.insert(
798 other_relocations.end(), padding.begin(), padding.end());
799 }
800
801 // Rewrite the current .rel.dyn section to be only the non-R_ARM_RELATIVE 832 // Rewrite the current .rel.dyn section to be only the non-R_ARM_RELATIVE
802 // relocations, then shrink it to size. 833 // relocations, then shrink it to size.
803 const void* section_data = &other_relocations[0]; 834 const void* section_data = &other_relocations[0];
804 const size_t bytes = other_relocations.size() * sizeof(other_relocations[0]); 835 const size_t bytes = other_relocations.size() * sizeof(other_relocations[0]);
805 ResizeSection(elf_, rel_dyn_section_, bytes); 836 ResizeSection(elf_, rel_dyn_section_, bytes);
806 RewriteSectionData(data, section_data, bytes); 837 RewriteSectionData(data, section_data, bytes);
807 838
808 // Rewrite the current .android.rel.dyn section to hold the packed 839 // Rewrite the current .android.rel.dyn section to hold the packed
809 // R_ARM_RELATIVE relocations. 840 // R_ARM_RELATIVE relocations.
810 data = GetSectionData(android_rel_dyn_section_); 841 data = GetSectionData(android_rel_dyn_section_);
811 ResizeSection(elf_, android_rel_dyn_section_, packed_bytes); 842 ResizeSection(elf_, android_rel_dyn_section_, packed_bytes);
812 RewriteSectionData(data, packed_data, packed_bytes); 843 RewriteSectionData(data, packed_data, packed_bytes);
813 844
814 // Rewrite .dynamic to include two new tags describing .android.rel.dyn. 845 // Rewrite .dynamic to include two new tags describing .android.rel.dyn.
815 data = GetSectionData(dynamic_section_); 846 data = GetSectionData(dynamic_section_);
816 const Elf32_Dyn* dynamic_base = reinterpret_cast<Elf32_Dyn*>(data->d_buf); 847 const Elf32_Dyn* dynamic_base = reinterpret_cast<Elf32_Dyn*>(data->d_buf);
817 std::vector<Elf32_Dyn> dynamics( 848 std::vector<Elf32_Dyn> dynamics(
818 dynamic_base, 849 dynamic_base,
819 dynamic_base + data->d_size / sizeof(dynamics[0])); 850 dynamic_base + data->d_size / sizeof(dynamics[0]));
820 section_header = elf32_getshdr(android_rel_dyn_section_); 851 Elf32_Shdr* section_header = elf32_getshdr(android_rel_dyn_section_);
821 // Use two of the spare slots to describe the .android.rel.dyn section. 852 // Use two of the spare slots to describe the .android.rel.dyn section.
822 const Elf32_Dyn offset_dyn 853 const Elf32_Dyn offset_dyn
823 = {DT_ANDROID_ARM_REL_OFFSET, {section_header->sh_offset}}; 854 = {DT_ANDROID_ARM_REL_OFFSET, {section_header->sh_offset}};
824 AddDynamicEntry(offset_dyn, &dynamics); 855 AddDynamicEntry(offset_dyn, &dynamics);
825 const Elf32_Dyn size_dyn 856 const Elf32_Dyn size_dyn
826 = {DT_ANDROID_ARM_REL_SIZE, {section_header->sh_size}}; 857 = {DT_ANDROID_ARM_REL_SIZE, {section_header->sh_size}};
827 AddDynamicEntry(size_dyn, &dynamics); 858 AddDynamicEntry(size_dyn, &dynamics);
828 const void* dynamics_data = &dynamics[0]; 859 const void* dynamics_data = &dynamics[0];
829 const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]); 860 const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
830 RewriteSectionData(data, dynamics_data, dynamics_bytes); 861 RewriteSectionData(data, dynamics_data, dynamics_bytes);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 ++padding; 922 ++padding;
892 } 923 }
893 } 924 }
894 LOG("R_ARM_RELATIVE: %lu entries\n", relative_relocations.size()); 925 LOG("R_ARM_RELATIVE: %lu entries\n", relative_relocations.size());
895 LOG("Other : %lu entries\n", other_relocations.size()); 926 LOG("Other : %lu entries\n", other_relocations.size());
896 927
897 // If we found the same number of R_ARM_NONE entries in .rel.dyn as we 928 // If we found the same number of R_ARM_NONE entries in .rel.dyn as we
898 // hold as unpacked relative relocations, then this is a padded file. 929 // hold as unpacked relative relocations, then this is a padded file.
899 const bool is_padded = padding == relative_relocations.size(); 930 const bool is_padded = padding == relative_relocations.size();
900 931
901 // Pre-calculate the size of the hole we will open up when we rewrite
902 // .reldyn. We have to adjust all relocation addresses to account for this.
903 Elf32_Shdr* section_header = elf32_getshdr(rel_dyn_section_);
904 const Elf32_Off hole_start = section_header->sh_offset;
905 const size_t hole_size =
906 relative_relocations.size() * sizeof(relative_relocations[0]);
907
908 // Unless padded, pre-apply R_ARM_RELATIVE relocations to account for the 932 // Unless padded, pre-apply R_ARM_RELATIVE relocations to account for the
909 // hole, and pre-adjust all relocation offsets accordingly. 933 // hole, and pre-adjust all relocation offsets accordingly.
910 if (!is_padded) { 934 if (!is_padded) {
935 // Pre-calculate the size of the hole we will open up when we rewrite
936 // .rel.dyn. We have to adjust relocation addresses to account for this.
937 Elf32_Shdr* section_header = elf32_getshdr(rel_dyn_section_);
938 const Elf32_Off hole_start = section_header->sh_offset;
939 size_t hole_size =
940 relative_relocations.size() * sizeof(relative_relocations[0]);
941
942 // Adjust the hole size for the padding added to preserve alignment.
943 hole_size -= padding * sizeof(other_relocations[0]);
944 LOG("Expansion : %lu bytes\n", hole_size);
945
911 // Apply relocations to all R_ARM_RELATIVE data to relocate it into the 946 // Apply relocations to all R_ARM_RELATIVE data to relocate it into the
912 // area it will occupy once the hole in .rel.dyn is opened. 947 // area it will occupy once the hole in .rel.dyn is opened.
913 AdjustRelocationTargets(elf_, hole_start, hole_size, relative_relocations); 948 AdjustRelocationTargets(elf_, hole_start, hole_size, relative_relocations);
914 // Relocate the relocations. 949 // Relocate the relocations.
915 AdjustRelocations(hole_start, hole_size, &relative_relocations); 950 AdjustRelocations(hole_start, hole_size, &relative_relocations);
916 AdjustRelocations(hole_start, hole_size, &other_relocations); 951 AdjustRelocations(hole_start, hole_size, &other_relocations);
917 } 952 }
918 953
919 // Rewrite the current .rel.dyn section to be the R_ARM_RELATIVE relocations 954 // Rewrite the current .rel.dyn section to be the R_ARM_RELATIVE relocations
920 // followed by other relocations. This is the usual order in which we find 955 // followed by other relocations. This is the usual order in which we find
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 1003
969 // Clean up libelf, and truncate the output file to the number of bytes 1004 // Clean up libelf, and truncate the output file to the number of bytes
970 // written by elf_update(). 1005 // written by elf_update().
971 elf_end(elf_); 1006 elf_end(elf_);
972 elf_ = NULL; 1007 elf_ = NULL;
973 const int truncate = ftruncate(fd_, file_bytes); 1008 const int truncate = ftruncate(fd_, file_bytes);
974 CHECK(truncate == 0); 1009 CHECK(truncate == 0);
975 } 1010 }
976 1011
977 } // namespace relocation_packer 1012 } // namespace relocation_packer
OLDNEW
« no previous file with comments | « no previous file | tools/relocation_packer/test_data/elf_file_unittest_relocs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698