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

Unified Diff: tools/relocation_packer/src/elf_file.cc

Issue 935333002: Update from https://crrev.com/316786 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/relocation_packer/src/debug.h ('k') | tools/relocation_packer/src/elf_traits.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/relocation_packer/src/elf_file.cc
diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc
index 3ffccecd7c4bc4d87a34194f7416b04b141524ee..5853c9d7d5547de5108bb3b99ce79f533d00446c 100644
--- a/tools/relocation_packer/src/elf_file.cc
+++ b/tools/relocation_packer/src/elf_file.cc
@@ -56,6 +56,14 @@ static const ELF::Sword DT_ANDROID_REL_SIZE = DT_LOOS + 1;
// page. See http://www.airs.com/blog/archives/189.
static const size_t kPreserveAlignment = 4096;
+// Alignment values used by ld and gold for the GNU_STACK segment. Different
+// linkers write different values; the actual value is immaterial on Android
+// because it ignores GNU_STACK segments. However, it is useful for binary
+// comparison and unit test purposes if packing and unpacking can preserve
+// them through a round-trip.
+static const size_t kLdGnuStackSegmentAlignment = 16;
+static const size_t kGoldGnuStackSegmentAlignment = 0;
+
namespace {
// Get section data. Checks that the section has exactly one data entry,
@@ -363,11 +371,36 @@ ELF::Phdr* FindFirstLoadSegment(ELF::Phdr* program_headers,
return first_loadable_segment;
}
+// Helper for ResizeSection(). Deduce the alignment that the PT_GNU_STACK
+// segment will use. Determined by sensing the linker that was used to
+// create the shared library.
+size_t DeduceGnuStackSegmentAlignment(Elf* elf) {
+ size_t string_index;
+ elf_getshdrstrndx(elf, &string_index);
+
+ Elf_Scn* section = NULL;
+ size_t gnu_stack_segment_alignment = kLdGnuStackSegmentAlignment;
+
+ while ((section = elf_nextscn(elf, section)) != NULL) {
+ const ELF::Shdr* section_header = ELF::getshdr(section);
+ std::string name = elf_strptr(elf, string_index, section_header->sh_name);
+
+ if (name == ".note.gnu.gold-version") {
+ gnu_stack_segment_alignment = kGoldGnuStackSegmentAlignment;
+ break;
+ }
+ }
+
+ return gnu_stack_segment_alignment;
+}
+
// Helper for ResizeSection(). Find the PT_GNU_STACK segment, and check
// that it contains what we expect so we can restore it on unpack if needed.
-ELF::Phdr* FindUnusedGnuStackSegment(ELF::Phdr* program_headers,
+ELF::Phdr* FindUnusedGnuStackSegment(Elf* elf,
+ ELF::Phdr* program_headers,
size_t count) {
ELF::Phdr* unused_segment = NULL;
+ const size_t stack_alignment = DeduceGnuStackSegmentAlignment(elf);
for (size_t i = 0; i < count; ++i) {
ELF::Phdr* program_header = &program_headers[i];
@@ -379,7 +412,7 @@ ELF::Phdr* FindUnusedGnuStackSegment(ELF::Phdr* program_headers,
program_header->p_filesz == 0 &&
program_header->p_memsz == 0 &&
program_header->p_flags == (PF_R | PF_W) &&
- program_header->p_align == ELF::kGnuStackSegmentAlignment) {
+ program_header->p_align == stack_alignment) {
unused_segment = program_header;
}
}
@@ -558,7 +591,7 @@ void SplitProgramHeadersForHole(Elf* elf,
// Locate the segment that we can overwrite to form the new LOAD entry,
// and the segment that we are going to split into two parts.
ELF::Phdr* spliced_header =
- FindUnusedGnuStackSegment(elf_program_header, program_header_count);
+ FindUnusedGnuStackSegment(elf, elf_program_header, program_header_count);
ELF::Phdr* split_header =
FindFirstLoadSegment(elf_program_header, program_header_count);
@@ -680,6 +713,7 @@ void CoalesceProgramHeadersForHole(Elf* elf,
last_section_header->sh_offset + last_section_header->sh_size;
// Reconstruct the original GNU_STACK segment into spliced_header.
+ const size_t stack_alignment = DeduceGnuStackSegmentAlignment(elf);
spliced_header->p_type = PT_GNU_STACK;
spliced_header->p_offset = 0;
spliced_header->p_vaddr = 0;
@@ -687,7 +721,7 @@ void CoalesceProgramHeadersForHole(Elf* elf,
spliced_header->p_filesz = 0;
spliced_header->p_memsz = 0;
spliced_header->p_flags = PF_R | PF_W;
- spliced_header->p_align = ELF::kGnuStackSegmentAlignment;
+ spliced_header->p_align = stack_alignment;
// Adjust the offsets of all program headers that are not one of the pair
// we just coalesced.
« no previous file with comments | « tools/relocation_packer/src/debug.h ('k') | tools/relocation_packer/src/elf_traits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698