1#!/usr/bin/env python3 2# 3# Copyright 2018 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Creates a compressed archive of unstripped binaries cataloged by 8"ids.txt".""" 9 10import argparse 11import os 12import subprocess 13import sys 14import tarfile 15 16 17def main(args): 18 parser = argparse.ArgumentParser() 19 parser.add_argument('ids_txt', type=str, nargs=1, 20 help='Path to ids.txt files.') 21 parser.add_argument('-o', '--output_tarball', nargs=1, type=str, 22 help='Path which the tarball will be written to.') 23 parser.add_argument('--fuchsia-build-id-dir', type=str, required=True, 24 help='Directory containing symbols for SDK prebuilts.') 25 args = parser.parse_args(args) 26 27 ids_txt = args.ids_txt[0] 28 build_ids_archive = tarfile.open(args.output_tarball[0], 'w:bz2') 29 for line in open(ids_txt, 'r'): 30 build_id, binary_path = line.strip().split(' ') 31 32 # Look for prebuilt symbols in the SDK first. 33 symbol_source_path = os.path.join(args.fuchsia_build_id_dir, 34 build_id[:2], 35 build_id[2:] + '.debug') 36 if not os.path.exists(symbol_source_path): 37 symbol_source_path = os.path.abspath( 38 os.path.join(os.path.dirname(ids_txt), binary_path)) 39 40 if os.path.getsize(symbol_source_path) == 0: 41 # This is a prebuilt which wasn't accompanied by SDK symbols. 42 continue 43 44 # Exclude stripped binaries (indicated by their lack of symbol tables). 45 readelf_output = subprocess.check_output( 46 ['readelf', '-S', symbol_source_path], universal_newlines=True) 47 if not '.symtab' in readelf_output: 48 continue 49 50 # Archive the unstripped ELF binary, placing it in a hierarchy keyed to the 51 # GNU build ID. The binary resides in a directory whose name is the first 52 # two characters of the build ID, with the binary file itself named after 53 # the remaining characters of the build ID. So, a binary file with the build 54 # ID "deadbeef" would be located at the path 'de/adbeef.debug'. 55 build_ids_archive.add(symbol_source_path, 56 '%s/%s.debug' % (build_id[:2], build_id[2:])) 57 58 return 0 59 60 61if __name__ == '__main__': 62 sys.exit(main(sys.argv[1:])) 63