From 27b15618496eb3d04a1fe7daf1554239b0d624f6 Mon Sep 17 00:00:00 2001 From: pasko Date: Tue, 10 Feb 2015 07:21:34 -0800 Subject: [PATCH] reloc_packer: Allow aarch64 DSO linked with gold Using the Gold linker is needed for -section-ordering-file. The new aarch64 Gold linker in android_tools produces PT_GNU_STACK header with alignment of 0. This breaks the relocation packer that expects alignment of 16 for aarch64 (i.e. what the GNU LD produces). Relaxing the relocation packer requirement for the alignment produces a successfully packed DSO: * only 32KiB bigger than packed DSO produced by GNU LD * this means, as usual, about ~5 MiB benefits of relocation packing (yay!) * loads OK on Nexus 9 BUG=448054 Review URL: https://codereview.chromium.org/906973006 Cr-Commit-Position: refs/heads/master@{#315565} --- tools/relocation_packer/src/elf_file.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc index 3ffccecd7c4b..099a02e80bf3 100644 --- a/tools/relocation_packer/src/elf_file.cc +++ b/tools/relocation_packer/src/elf_file.cc @@ -365,6 +365,14 @@ ELF::Phdr* FindFirstLoadSegment(ELF::Phdr* program_headers, // 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. +// +// Note: GNU LD and Gold on aarch64 differ in p_align of PT_GNU_STACK (16 vs. +// 0). This fact is ignored when unpacking, so a Gold-linked DSO would not +// remain bit-identical after packing-unpacking cycle. Modifying p_align is safe +// because the Android dynamic linker ignores PT_GNU_STACK segment. +// +// To produce bit-idential unpacked DSOs the linker could be detected by the +// presence of .note.gnu.gold-version section. It is not done for simplicity. ELF::Phdr* FindUnusedGnuStackSegment(ELF::Phdr* program_headers, size_t count) { ELF::Phdr* unused_segment = NULL; @@ -378,8 +386,7 @@ ELF::Phdr* FindUnusedGnuStackSegment(ELF::Phdr* program_headers, program_header->p_paddr == 0 && 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_flags == (PF_R | PF_W)) { unused_segment = program_header; } } -- 2.11.4.GIT