15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#!/usr/bin/env python
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# found in the LICENSE file.
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)"""Build relocation packer unit test data.
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)Uses a built relocation packer to generate 'golden' reference test data
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)files for elf_file_unittests.cc.
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)"""
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import optparse
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import os
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import shutil
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import subprocess
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import sys
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import tempfile
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def PackArmLibraryRelocations(android_pack_relocations,
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              android_objcopy,
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              added_section,
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              input_path,
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              output_path):
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  # Copy and add a 'NULL' .android.rel.dyn section for the packing tool.
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  with tempfile.NamedTemporaryFile() as stream:
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stream.write('NULL')
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stream.flush()
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    objcopy_command = [android_objcopy,
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       '--add-section', '%s=%s' % (added_section, stream.name),
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       input_path, output_path]
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    subprocess.check_call(objcopy_command)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  # Pack relocations.
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pack_command = [android_pack_relocations, output_path]
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  subprocess.check_call(pack_command)
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def UnpackArmLibraryRelocations(android_pack_relocations,
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                input_path,
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                output_path):
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  shutil.copy(input_path, output_path)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  # Unpack relocations.  We leave the .android.rel.dyn or .android.rela.dyn
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  # in place.
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  unpack_command = [android_pack_relocations, '-u', output_path]
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  subprocess.check_call(unpack_command)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def main():
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser = optparse.OptionParser()
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.add_option('--android-pack-relocations',
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      help='Path to the ARM relocations packer binary')
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.add_option('--android-objcopy',
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      help='Path to the toolchain\'s objcopy binary')
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.add_option('--added-section',
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      choices=['.android.rel.dyn', '.android.rela.dyn'],
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      help='Section to add, one of ".android.rel.dyn" or ".android.rela.dyn"')
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.add_option('--test-file',
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      help='Path to the input test file, an unpacked ARM .so')
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.add_option('--unpacked-output',
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      help='Path to the output file for reference unpacked data')
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.add_option('--packed-output',
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      help='Path to the output file for reference packed data')
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  options, _ = parser.parse_args()
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for output in [options.unpacked_output, options.packed_output]:
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    directory = os.path.dirname(output)
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if not os.path.exists(directory):
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      os.makedirs(directory)
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PackArmLibraryRelocations(options.android_pack_relocations,
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            options.android_objcopy,
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            options.added_section,
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            options.test_file,
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            options.packed_output)
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UnpackArmLibraryRelocations(options.android_pack_relocations,
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              options.packed_output,
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              options.unpacked_output)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return 0
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)if __name__ == '__main__':
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sys.exit(main())
89