1#!/usr/bin/env python
2#
3# Copyright 2014 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Build relocation packer unit test data.
8
9Uses a built relocation packer to generate 'golden' reference test data
10files for elf_file_unittests.cc.
11"""
12
13import optparse
14import os
15import shutil
16import subprocess
17import sys
18import tempfile
19
20def PackArmLibraryRelocations(android_pack_relocations,
21                              android_objcopy,
22                              added_section,
23                              input_path,
24                              output_path):
25  # Copy and add a 'NULL' .android.rel.dyn section for the packing tool.
26  with tempfile.NamedTemporaryFile() as stream:
27    stream.write('NULL')
28    stream.flush()
29    objcopy_command = [android_objcopy,
30                       '--add-section', '%s=%s' % (added_section, stream.name),
31                       input_path, output_path]
32    subprocess.check_call(objcopy_command)
33
34  # Pack relocations.
35  pack_command = [android_pack_relocations, output_path]
36  subprocess.check_call(pack_command)
37
38
39def UnpackArmLibraryRelocations(android_pack_relocations,
40                                input_path,
41                                output_path):
42  shutil.copy(input_path, output_path)
43
44  # Unpack relocations.  We leave the .android.rel.dyn or .android.rela.dyn
45  # in place.
46  unpack_command = [android_pack_relocations, '-u', output_path]
47  subprocess.check_call(unpack_command)
48
49
50def main():
51  parser = optparse.OptionParser()
52
53  parser.add_option('--android-pack-relocations',
54      help='Path to the ARM relocations packer binary')
55  parser.add_option('--android-objcopy',
56      help='Path to the toolchain\'s objcopy binary')
57  parser.add_option('--added-section',
58      choices=['.android.rel.dyn', '.android.rela.dyn'],
59      help='Section to add, one of ".android.rel.dyn" or ".android.rela.dyn"')
60  parser.add_option('--test-file',
61      help='Path to the input test file, an unpacked ARM .so')
62  parser.add_option('--unpacked-output',
63      help='Path to the output file for reference unpacked data')
64  parser.add_option('--packed-output',
65      help='Path to the output file for reference packed data')
66
67  options, _ = parser.parse_args()
68
69  for output in [options.unpacked_output, options.packed_output]:
70    directory = os.path.dirname(output)
71    if not os.path.exists(directory):
72      os.makedirs(directory)
73
74  PackArmLibraryRelocations(options.android_pack_relocations,
75                            options.android_objcopy,
76                            options.added_section,
77                            options.test_file,
78                            options.packed_output)
79
80  UnpackArmLibraryRelocations(options.android_pack_relocations,
81                              options.packed_output,
82                              options.unpacked_output)
83
84  return 0
85
86
87if __name__ == '__main__':
88  sys.exit(main())
89