summaryrefslogtreecommitdiffstats
path: root/third_party/android_platform
diff options
context:
space:
mode:
authorsimonb <simonb@chromium.org>2015-05-28 10:35:27 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-28 17:35:55 +0000
commit9cb10e88d01e71c5786a463f7c39409e7a41ddcd (patch)
tree42f3fd48377efff161d8abc8f64513f172a62192 /third_party/android_platform
parent9bacad65abe3631048c1e5d0467e1cea414e5700 (diff)
downloadchromium_src-9cb10e88d01e71c5786a463f7c39409e7a41ddcd.zip
chromium_src-9cb10e88d01e71c5786a463f7c39409e7a41ddcd.tar.gz
chromium_src-9cb10e88d01e71c5786a463f7c39409e7a41ddcd.tar.bz2
Refresh android relocation packer from AOSP bionic.
Imports: Fix unit tests, and extend for other architectures https://android-review.googlesource.com/#/c/151901/ Do not adjust PT_GNU_STACK segment https://android-review.googlesource.com/#/c/149300/ Adjust DT_MIPS_RLD_MAP2 value https://android-review.googlesource.com/#/c/148822/ Reduce p_align for program header to page size. https://android-review.googlesource.com/#/c/148492/ Exit normally when relocations are already packed. https://android-review.googlesource.com/#/c/148175/ NOPRESUBMIT=true BUG=385553 Review URL: https://codereview.chromium.org/1164453002 Cr-Commit-Position: refs/heads/master@{#331808}
Diffstat (limited to 'third_party/android_platform')
-rw-r--r--third_party/android_platform/README.chromium14
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/Android.mk11
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc120
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/src/elf_file_unittest.cc28
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/src/elf_traits.h4
-rwxr-xr-xthird_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.sobin93210 -> 92788 bytes
-rwxr-xr-xthird_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.sobin89114 -> 88692 bytes
-rwxr-xr-xthird_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.sobin134131 -> 134144 bytes
-rwxr-xr-xthird_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.sobin113651 -> 113664 bytes
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.sobin0 -> 76736 bytes
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.sobin0 -> 72640 bytes
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.sobin0 -> 134545 bytes
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.sobin0 -> 130449 bytes
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.sobin0 -> 108688 bytes
-rw-r--r--third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.sobin0 -> 88208 bytes
-rw-r--r--third_party/android_platform/relocation_packer.gyp6
16 files changed, 163 insertions, 20 deletions
diff --git a/third_party/android_platform/README.chromium b/third_party/android_platform/README.chromium
index 1dea3b60..192b9d6 100644
--- a/third_party/android_platform/README.chromium
+++ b/third_party/android_platform/README.chromium
@@ -40,7 +40,13 @@ Android relocation packing tool details:
Create a nativehelper/ScopedFd.h to satisfy inclusion from main.cc
Create gyp build
Create gn build (currently packer only; no unit tests)
- Apply https://android-review.googlesource.com/#/c/143878/
- Apply https://android-review.googlesource.com/#/c/147620/
- https://android-review.googlesource.com/#/c/147745/
- https://android-review.googlesource.com/#/c/148073/
+ List of bionic changes currently included:
+ Refresh: https://android-review.googlesource.com/#/c/143878/
+ Refresh: https://android-review.googlesource.com/#/c/147620/
+ https://android-review.googlesource.com/#/c/147745/
+ https://android-review.googlesource.com/#/c/148073/
+ Refresh: https://android-review.googlesource.com/#/c/151901/
+ https://android-review.googlesource.com/#/c/149300/
+ https://android-review.googlesource.com/#/c/148822/
+ https://android-review.googlesource.com/#/c/148492/
+ https://android-review.googlesource.com/#/c/148175/
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/Android.mk b/third_party/android_platform/bionic/tools/relocation_packer/Android.mk
index 99a39c0..94c946c 100644
--- a/third_party/android_platform/bionic/tools/relocation_packer/Android.mk
+++ b/third_party/android_platform/bionic/tools/relocation_packer/Android.mk
@@ -26,7 +26,6 @@ LOCAL_SRC_FILES := \
src/debug.cc \
src/delta_encoder.cc \
src/elf_file.cc \
- src/leb128.cc \
src/packer.cc \
src/sleb128.cc \
@@ -46,6 +45,9 @@ LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := src/main.cc
LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf
+
+# Statically linking libc++ to make it work from prebuilts
+LOCAL_CXX_STL := libc++_static
LOCAL_C_INCLUDES := external/elfutils/src/libelf libnativehelper/include
LOCAL_MODULE := relocation_packer
@@ -64,7 +66,6 @@ LOCAL_SRC_FILES := \
src/debug_unittest.cc \
src/delta_encoder_unittest.cc \
src/elf_file_unittest.cc \
- src/leb128_unittest.cc \
src/sleb128_unittest.cc \
src/packer_unittest.cc \
@@ -94,3 +95,9 @@ $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32_packed.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_x64.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_x64_packed.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32_packed.so))
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
index fb74233..4004239 100644
--- a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
+++ b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
@@ -37,11 +37,13 @@ static constexpr int32_t DT_ANDROID_RELASZ = DT_LOOS + 5;
static constexpr uint32_t SHT_ANDROID_REL = SHT_LOOS + 1;
static constexpr uint32_t SHT_ANDROID_RELA = SHT_LOOS + 2;
+static const size_t kPageSize = 4096;
+
// Alignment to preserve, in bytes. This must be at least as large as the
// largest d_align and sh_addralign values found in the loaded file.
// Out of caution for RELRO page alignment, we preserve to a complete target
// page. See http://www.airs.com/blog/archives/189.
-static constexpr size_t kPreserveAlignment = 4096;
+static const size_t kPreserveAlignment = kPageSize;
// Get section data. Checks that the section has exactly one data entry,
// so that the section size and the data size are the same. True in
@@ -300,16 +302,85 @@ static void AdjustSectionHeadersForHole(Elf* elf,
}
}
-// Helper for ResizeSection(). Adjust the offsets of any program headers
-// that have offsets currently beyond the hole start.
+// Helpers for ResizeSection(). On packing, reduce p_align for LOAD segments
+// to 4kb if larger. On unpacking, restore p_align for LOAD segments if
+// packing reduced it to 4kb. Return true if p_align was changed.
+template <typename ELF>
+static bool ClampLoadSegmentAlignment(typename ELF::Phdr* program_header) {
+ CHECK(program_header->p_type == PT_LOAD);
+
+ // If large, reduce p_align for a LOAD segment to page size on packing.
+ if (program_header->p_align > kPageSize) {
+ program_header->p_align = kPageSize;
+ return true;
+ }
+ return false;
+}
+
template <typename ELF>
-static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
+static bool RestoreLoadSegmentAlignment(typename ELF::Phdr* program_headers,
+ size_t count,
+ typename ELF::Phdr* program_header) {
+ CHECK(program_header->p_type == PT_LOAD);
+
+ // If p_align was reduced on packing, restore it to its previous value
+ // on unpacking. We do this by searching for a different LOAD segment
+ // and setting p_align to that of the other LOAD segment found.
+ //
+ // Relies on the following observations:
+ // - a packable ELF executable has more than one LOAD segment;
+ // - before packing all LOAD segments have the same p_align;
+ // - on packing we reduce only one LOAD segment's p_align.
+ if (program_header->p_align == kPageSize) {
+ for (size_t i = 0; i < count; ++i) {
+ typename ELF::Phdr* other_header = &program_headers[i];
+ if (other_header->p_type == PT_LOAD && other_header != program_header) {
+ program_header->p_align = other_header->p_align;
+ return true;
+ }
+ }
+ LOG(WARNING) << "Cannot find a LOAD segment from which to restore p_align";
+ }
+ return false;
+}
+
+template <typename ELF>
+static bool AdjustLoadSegmentAlignment(typename ELF::Phdr* program_headers,
size_t count,
- typename ELF::Off hole_start,
+ typename ELF::Phdr* program_header,
ssize_t hole_size) {
+ CHECK(program_header->p_type == PT_LOAD);
+
+ bool status = false;
+ if (hole_size < 0) {
+ status = ClampLoadSegmentAlignment<ELF>(program_header);
+ } else if (hole_size > 0) {
+ status = RestoreLoadSegmentAlignment<ELF>(program_headers,
+ count,
+ program_header);
+ }
+ return status;
+}
+
+// Helper for ResizeSection(). Adjust the offsets of any program headers
+// that have offsets currently beyond the hole start, and adjust the
+// virtual and physical addrs (and perhaps alignment) of the others.
+template <typename ELF>
+static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers,
+ size_t count,
+ typename ELF::Off hole_start,
+ ssize_t hole_size) {
+ int alignment_changes = 0;
for (size_t i = 0; i < count; ++i) {
typename ELF::Phdr* program_header = &program_headers[i];
+ // Do not adjust PT_GNU_STACK - it confuses gdb and results
+ // in incorrect unwinding if the executable is stripped after
+ // packing.
+ if (program_header->p_type == PT_GNU_STACK) {
+ continue;
+ }
+
if (program_header->p_offset > hole_start) {
// The hole start is past this segment, so adjust offset.
program_header->p_offset += hole_size;
@@ -318,9 +389,24 @@ static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
} else {
program_header->p_vaddr -= hole_size;
program_header->p_paddr -= hole_size;
+
+ // If packing, clamp LOAD segment alignment to 4kb to prevent strip
+ // from adjusting it unnecessarily if run on a packed file. If
+ // unpacking, attempt to restore a reduced alignment to its previous
+ // value. Ensure that we do this on at most one LOAD segment.
+ if (program_header->p_type == PT_LOAD) {
+ alignment_changes += AdjustLoadSegmentAlignment<ELF>(program_headers,
+ count,
+ program_header,
+ hole_size);
+ LOG_IF(FATAL, alignment_changes > 1)
+ << "Changed p_align on more than one LOAD segment";
+ }
+
VLOG(1) << "phdr[" << i
<< "] p_vaddr adjusted to "<< program_header->p_vaddr
- << "; p_paddr adjusted to "<< program_header->p_paddr;
+ << "; p_paddr adjusted to "<< program_header->p_paddr
+ << "; p_align adjusted to "<< program_header->p_align;
}
}
}
@@ -370,10 +456,10 @@ static void RewriteProgramHeadersForHole(Elf* elf,
target_load_header->p_memsz += hole_size;
// Adjust the offsets and p_vaddrs
- AdjustProgramHeaderOffsets<ELF>(elf_program_header,
- program_header_count,
- hole_start,
- hole_size);
+ AdjustProgramHeaderFields<ELF>(elf_program_header,
+ program_header_count,
+ hole_start,
+ hole_size);
}
// Helper for ResizeSection(). Locate and return the dynamic section.
@@ -466,6 +552,16 @@ void ElfFile<ELF>::AdjustDynamicSectionForHole(Elf_Scn* dynamic_section,
<< " d_val adjusted to " << dynamic->d_un.d_val;
}
+ // Special case: DT_MIPS_RLD_MAP2 stores the difference between dynamic
+ // entry address and the address of the _r_debug (used by GDB)
+ // since the dynamic section and target address are on the
+ // different sides of the hole it needs to be adjusted accordingly
+ if (tag == DT_MIPS_RLD_MAP2) {
+ dynamic->d_un.d_val += hole_size;
+ VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
+ << " d_val adjusted to " << dynamic->d_un.d_val;
+ }
+
// Ignore DT_RELCOUNT and DT_RELACOUNT: (1) nobody uses them and
// technically (2) the relative relocation count is not changed.
@@ -618,8 +714,8 @@ bool ElfFile<ELF>::PackTypedRelocations(std::vector<typename ELF::Rela>* relocat
typedef typename ELF::Rela Rela;
if (has_android_relocations_) {
- LOG(ERROR) << "Relocation table is already packed";
- return false;
+ LOG(INFO) << "Relocation table is already packed";
+ return true;
}
// If no relocations then we have nothing packable. Perhaps
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file_unittest.cc b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file_unittest.cc
index 5271eef..d5c8918 100644
--- a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file_unittest.cc
+++ b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file_unittest.cc
@@ -103,8 +103,8 @@ template <typename ELF>
static void ProcessUnpack(FILE* relocs_so, FILE* packed_relocs_so) {
relocation_packer::ElfFile<ELF> elf_file(fileno(packed_relocs_so));
- // Ensure packing fails (already packed).
- EXPECT_FALSE(elf_file.PackRelocations());
+ // Ensure packing already packed elf-file does not fail the build.
+ EXPECT_TRUE(elf_file.PackRelocations());
// Unpack golden relocations, and check files are now identical.
EXPECT_TRUE(elf_file.UnpackRelocations());
@@ -183,6 +183,18 @@ TEST(ElfFile, PackRelocationsArm64) {
RunPackRelocationsTestFor("arm64");
}
+TEST(ElfFile, PackRelocationsMips32) {
+ RunPackRelocationsTestFor("mips32");
+}
+
+TEST(ElfFile, PackRelocationsIa32) {
+ RunPackRelocationsTestFor("ia32");
+}
+
+TEST(ElfFile, PackRelocationsX64) {
+ RunPackRelocationsTestFor("x64");
+}
+
TEST(ElfFile, UnpackRelocationsArm32) {
RunUnpackRelocationsTestFor("arm32");
}
@@ -191,4 +203,16 @@ TEST(ElfFile, UnpackRelocationsArm64) {
RunUnpackRelocationsTestFor("arm64");
}
+TEST(ElfFile, UnpackRelocationsMips32) {
+ RunUnpackRelocationsTestFor("mips32");
+}
+
+TEST(ElfFile, UnpackRelocationsIa32) {
+ RunUnpackRelocationsTestFor("ia32");
+}
+
+TEST(ElfFile, UnpackRelocationsX64) {
+ RunUnpackRelocationsTestFor("x64");
+}
+
} // namespace relocation_packer
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_traits.h b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_traits.h
index 41b06c8..1c938fa 100644
--- a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_traits.h
+++ b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_traits.h
@@ -10,6 +10,10 @@
#include "elf.h"
#include "libelf.h"
+#if !defined(DT_MIPS_RLD_MAP2)
+#define DT_MIPS_RLD_MAP2 0x70000035
+#endif
+
// ELF is a traits structure used to provide convenient aliases for
// 32/64 bit Elf types and functions, depending on the target file.
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so
index 6ce6d0c..5e339ae 100755
--- a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so
index 6ac2eef..253dd97 100755
--- a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so
index 945b450..d3d0194 100755
--- a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
index a2b0039..269b975 100755
--- a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so
new file mode 100644
index 0000000..42db62c
--- /dev/null
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so
new file mode 100644
index 0000000..27817cc
--- /dev/null
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so
new file mode 100644
index 0000000..6da324b
--- /dev/null
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so
new file mode 100644
index 0000000..b11ca48
--- /dev/null
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so
new file mode 100644
index 0000000..6cb689e
--- /dev/null
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so
Binary files differ
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so
new file mode 100644
index 0000000..60b9ad1
--- /dev/null
+++ b/third_party/android_platform/bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so
Binary files differ
diff --git a/third_party/android_platform/relocation_packer.gyp b/third_party/android_platform/relocation_packer.gyp
index a41253f..cb09841 100644
--- a/third_party/android_platform/relocation_packer.gyp
+++ b/third_party/android_platform/relocation_packer.gyp
@@ -73,6 +73,12 @@
'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so',
'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so',
'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so',
+ 'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so',
+ 'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so',
+ 'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so',
+ 'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so',
+ 'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so',
+ 'bionic/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so',
],
},
],