diff options
author | simonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 17:20:56 +0000 |
---|---|---|
committer | simonb@chromium.org <simonb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 17:20:56 +0000 |
commit | c635e28a3c098183e603a29b34da04aee90076bd (patch) | |
tree | 3650ad6ef20029568bd3caeb669188835e03fb34 | |
parent | 24641700af8733b212ac1b8f55d2982227c6158a (diff) | |
download | chromium_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.gyp | 1 | ||||
-rwxr-xr-x | build/android/gyp/pack_arm_relocations.py | 108 | ||||
-rw-r--r-- | build/android/pack_arm_relocations.gypi | 76 | ||||
-rw-r--r-- | build/common.gypi | 3 | ||||
-rw-r--r-- | build/java_apk.gypi | 39 |
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', { |