summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsimonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-03 17:20:56 +0000
committersimonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-03 17:20:56 +0000
commitc635e28a3c098183e603a29b34da04aee90076bd (patch)
tree3650ad6ef20029568bd3caeb669188835e03fb34
parent24641700af8733b212ac1b8f55d2982227c6158a (diff)
downloadchromium_src-c635e28a3c098183e603a29b34da04aee90076bd.zip
chromium_src-c635e28a3c098183e603a29b34da04aee90076bd.tar.gz
chromium_src-c635e28a3c098183e603a29b34da04aee90076bd.tar.bz2
Add gyp machinery to build with packed ARM relative relocations.
Add gypi and python files to support packing ARM relative relocations during the build process. Define a use_relocation_packer gyp variable to turn ARM relocation packing on and off (currently set to 0). BUG=385553 Review URL: https://codereview.chromium.org/358863002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281286 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/all.gyp1
-rwxr-xr-xbuild/android/gyp/pack_arm_relocations.py108
-rw-r--r--build/android/pack_arm_relocations.gypi76
-rw-r--r--build/common.gypi3
-rw-r--r--build/java_apk.gypi39
5 files changed, 224 insertions, 3 deletions
diff --git a/build/all.gyp b/build/all.gyp
index f2b3f5a..4f7b7cc 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -54,6 +54,7 @@
'../chrome/chrome.gyp:chrome_shell_apk',
'../remoting/remoting.gyp:remoting_apk',
'../tools/telemetry/telemetry.gyp:*#host',
+ '../tools/relocation_packer/relocation_packer.gyp:relocation_packer_unittests#host',
# TODO(nyquist) This should instead by a target for sync when all of
# the sync-related code for Android has been upstreamed.
# See http://crbug.com/159203
diff --git a/build/android/gyp/pack_arm_relocations.py b/build/android/gyp/pack_arm_relocations.py
new file mode 100755
index 0000000..9fbd977
--- /dev/null
+++ b/build/android/gyp/pack_arm_relocations.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Pack ARM relative relocations in a library (or copy unchanged).
+
+If --enable-packing, invoke the relocation_packer tool to pack the .rel.dyn
+section in the given library files. This step is inserted after the libraries
+are stripped. Packing adds a new .android.rel.dyn section to the file and
+reduces the size of .rel.dyn accordingly.
+
+Currently packing only understands ARM32 shared libraries. For all other
+architectures --enable-packing should be set to zero. In this case the
+script copies files verbatim, with no attempt to pack relative relocations.
+
+Any library listed in --exclude-packing-list is also copied verbatim,
+irrespective of any --enable-packing setting. Typically this would be
+'libchromium_android_linker.so'.
+"""
+
+import json
+import optparse
+import os
+import shlex
+import shutil
+import sys
+import tempfile
+
+from util import build_utils
+
+def PackArmLibraryRelocations(android_pack_relocations,
+ android_objcopy,
+ library_path,
+ output_path):
+ if not build_utils.IsTimeStale(output_path, [library_path]):
+ return
+
+ # Copy and add a 'NULL' .android.rel.dyn section for the packing tool.
+ with tempfile.NamedTemporaryFile() as stream:
+ stream.write('NULL')
+ stream.flush()
+ objcopy_command = [android_objcopy,
+ '--add-section', '.android.rel.dyn=%s' % stream.name,
+ library_path, output_path]
+ build_utils.CheckOutput(objcopy_command)
+
+ # Pack R_ARM_RELATIVE relocations.
+ pack_command = [android_pack_relocations, output_path]
+ build_utils.CheckOutput(pack_command)
+
+
+def CopyArmLibraryUnchanged(library_path, output_path):
+ if not build_utils.IsTimeStale(output_path, [library_path]):
+ return
+
+ shutil.copy(library_path, output_path)
+
+
+def main():
+ parser = optparse.OptionParser()
+
+ parser.add_option('--enable-packing',
+ choices=['0', '1'],
+ help='Pack relocations if 1, otherwise plain file copy')
+ parser.add_option('--exclude-packing-list',
+ default='',
+ help='Names of any libraries explicitly not packed')
+ parser.add_option('--android-pack-relocations',
+ help='Path to the ARM relocations packer binary')
+ parser.add_option('--android-objcopy',
+ help='Path to the toolchain\'s objcopy binary')
+ parser.add_option('--stripped-libraries-dir',
+ help='Directory for stripped libraries')
+ parser.add_option('--packed-libraries-dir',
+ help='Directory for packed libraries')
+ parser.add_option('--libraries-file',
+ help='Path to json file containing list of libraries')
+ parser.add_option('--stamp', help='Path to touch on success')
+
+ options, _ = parser.parse_args()
+ enable_packing = options.enable_packing == '1'
+ exclude_packing_set = set(shlex.split(options.exclude_packing_list))
+
+ with open(options.libraries_file, 'r') as libfile:
+ libraries = json.load(libfile)
+
+ for library in libraries:
+ library_path = os.path.join(options.stripped_libraries_dir, library)
+ output_path = os.path.join(options.packed_libraries_dir, library)
+
+ if enable_packing and library not in exclude_packing_set:
+ PackArmLibraryRelocations(options.android_pack_relocations,
+ options.android_objcopy,
+ library_path,
+ output_path)
+ else:
+ CopyArmLibraryUnchanged(library_path, output_path)
+
+ if options.stamp:
+ build_utils.Touch(options.stamp)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/build/android/pack_arm_relocations.gypi b/build/android/pack_arm_relocations.gypi
new file mode 100644
index 0000000..5a6589b
--- /dev/null
+++ b/build/android/pack_arm_relocations.gypi
@@ -0,0 +1,76 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This file is meant to be included into an action to provide a rule that
+# packs ARM relative relocations in native libraries.
+#
+# To use this, create a gyp target with the following form:
+# {
+# 'action_name': 'pack_arm_relocations',
+# 'actions': [
+# 'variables': {
+# 'enable_packing': 'pack relocations if 1, plain file copy if 0'
+# 'exclude_packing_list': 'names of libraries explicitly not packed',
+# 'ordered_libraries_file': 'file generated by write_ordered_libraries'
+# 'input_paths': 'files to be added to the list of inputs'
+# 'stamp': 'file to touch when the action is complete'
+# 'stripped_libraries_dir': 'directory holding stripped libraries',
+# 'packed_libraries_dir': 'directory holding packed libraries',
+# 'includes': [ '../../build/android/pack_arm_relocations.gypi' ],
+# ],
+# },
+#
+
+{
+ 'variables': {
+ 'input_paths': [],
+ },
+ 'inputs': [
+ '<(DEPTH)/build/android/gyp/util/build_utils.py',
+ '<(DEPTH)/build/android/gyp/pack_arm_relocations.py',
+ '<(ordered_libraries_file)',
+ '>@(input_paths)',
+ ],
+ 'outputs': [
+ '<(stamp)',
+ ],
+ 'conditions': [
+ ['enable_packing == 1', {
+ 'message': 'Packing ARM relative relocations for <(_target_name)',
+ 'dependencies': [
+ '<(DEPTH)/tools/relocation_packer/relocation_packer.gyp:relocation_packer#host',
+ ],
+ 'inputs': [
+ '<(PRODUCT_DIR)/relocation_packer',
+ ],
+ 'action': [
+ 'python', '<(DEPTH)/build/android/gyp/pack_arm_relocations.py',
+ '--enable-packing=1',
+ '--exclude-packing-list=<@(exclude_packing_list)',
+ '--android-pack-relocations=<(PRODUCT_DIR)/relocation_packer',
+ '--android-objcopy=<(android_objcopy)',
+ '--stripped-libraries-dir=<(stripped_libraries_dir)',
+ '--packed-libraries-dir=<(packed_libraries_dir)',
+ '--libraries-file=<(ordered_libraries_file)',
+ '--stamp=<(stamp)',
+ ],
+ }, {
+ 'message': 'Copying libraries (no relocation packing) for <(_target_name)',
+ 'action': [
+ 'python', '<(DEPTH)/build/android/gyp/pack_arm_relocations.py',
+ '--enable-packing=0',
+ '--stripped-libraries-dir=<(stripped_libraries_dir)',
+ '--packed-libraries-dir=<(packed_libraries_dir)',
+ '--libraries-file=<(ordered_libraries_file)',
+ '--stamp=<(stamp)',
+ ],
+ }],
+ ['component == "shared_library"', {
+ # Add a fake output to force the build to always re-run this step. This
+ # is required because the real inputs are not known at gyp-time and
+ # changing base.so may not trigger changes to dependent libraries.
+ 'outputs': [ '<(stamp).fake' ]
+ }],
+ ],
+}
diff --git a/build/common.gypi b/build/common.gypi
index f5ab488..37c7fc8 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -1703,6 +1703,9 @@
'android_stlport_libs_dir': '<(android_stlport_root)/libs/<(android_app_abi)',
'host_os%': '<(host_os)',
+ # Location of the "objcopy" binary, used by both gyp and scripts.
+ 'android_objcopy%' : '<!(/bin/echo -n <(android_toolchain)/*-objcopy)',
+
# Location of the "strip" binary, used by both gyp and scripts.
'android_strip%' : '<!(/bin/echo -n <(android_toolchain)/*-strip)',
diff --git a/build/java_apk.gypi b/build/java_apk.gypi
index 4b0046b1..c860946 100644
--- a/build/java_apk.gypi
+++ b/build/java_apk.gypi
@@ -48,6 +48,8 @@
# RELRO section of the native libraries between the different processes.
# load_library_from_zip_file - When using the dynamic linker, load the library
# directly out of the zip file.
+# use_relocation_packer - Enable relocation packing. Relies on the chromium
+# linker, so use_chromium_linker must also be enabled.
# enable_chromium_linker_tests - Enable the content dynamic linker test support
# code. This allows a test APK to inject a Linker.TestRunner instance at
# runtime. Should only be used by the chromium_linker_test_apk target!!
@@ -95,7 +97,9 @@
'instr_stamp': '<(intermediate_dir)/instr.stamp',
'jar_stamp': '<(intermediate_dir)/jar.stamp',
'obfuscate_stamp': '<(intermediate_dir)/obfuscate.stamp',
+ 'pack_arm_relocations_stamp': '<(intermediate_dir)/pack_arm_relocations.stamp',
'strip_stamp': '<(intermediate_dir)/strip.stamp',
+ 'stripped_libraries_dir': '<(SHARED_INTERMEDIATE_DIR)/stripped_libraries',
'classes_dir': '<(intermediate_dir)/classes/2',
'javac_includes': [],
'jar_excluded_classes': [],
@@ -127,6 +131,7 @@
'native_lib_version_name%': '',
'use_chromium_linker%' : 0,
'load_library_from_zip_file%' : 0,
+ 'use_relocation_packer%' : 0,
'enable_chromium_linker_tests%': 0,
'is_test_apk%': 0,
},
@@ -151,11 +156,13 @@
'native_lib_target%': '',
'native_lib_version_name%': '',
'use_chromium_linker%' : 0,
- 'enable_chromium_linker_tests%': 0,
'load_library_from_zip_file%' : 0,
+ 'use_relocation_packer%' : 0,
+ 'enable_chromium_linker_tests%': 0,
'emma_instrument%': '<(emma_instrument)',
'apk_package_native_libs_dir': '<(apk_package_native_libs_dir)',
'unsigned_standalone_apk_path': '<(unsigned_standalone_apk_path)',
+ 'libchromium_android_linker': 'libchromium_android_linker.>(android_product_extension)',
'extra_native_libs': [],
},
# Pass the jar path to the apk's "fake" jar target. This would be better as
@@ -227,7 +234,7 @@
['use_chromium_linker == 1', {
'variables': {
'linker_input_libraries': [
- '<(SHARED_LIB_DIR)/libchromium_android_linker.>(android_product_extension)',
+ '<(SHARED_LIB_DIR)/<(libchromium_android_linker)',
],
}
}, {
@@ -332,7 +339,7 @@
'action_name': 'strip_native_libraries',
'variables': {
'ordered_libraries_file%': '<(ordered_libraries_file)',
- 'stripped_libraries_dir': '<(libraries_source_dir)',
+ 'stripped_libraries_dir%': '<(stripped_libraries_dir)',
'input_paths': [
'<@(native_libs_paths)',
'<@(extra_native_libs)',
@@ -341,6 +348,32 @@
},
'includes': ['../build/android/strip_native_libraries.gypi'],
},
+ {
+ 'action_name': 'pack_arm_relocations',
+ 'variables': {
+ 'conditions': [
+ ['use_chromium_linker == 1 and use_relocation_packer == 1', {
+ 'enable_packing': 1,
+ }, {
+ 'enable_packing': 0,
+ }],
+ ],
+ 'exclude_packing_list': [
+ '<(libchromium_android_linker)',
+ ],
+ 'ordered_libraries_file%': '<(ordered_libraries_file)',
+ 'stripped_libraries_dir%': '<(stripped_libraries_dir)',
+ 'packed_libraries_dir': '<(libraries_source_dir)',
+ 'input_paths': [
+ '<(strip_stamp)',
+ ],
+ 'stamp': '<(pack_arm_relocations_stamp)',
+ },
+ 'dependencies': [
+ 'strip_native_libraries',
+ ],
+ 'includes': ['../build/android/pack_arm_relocations.gypi'],
+ },
],
'conditions': [
['gyp_managed_install == 1', {