1#!/usr/bin/env python 2# Copyright 2018 The ANGLE Project Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6# Generate library file with compressed symbols per Android build 7# process. 8# https://www.ece.villanova.edu/VECR/doc/gdb/MiniDebugInfo.html 9 10import argparse 11import subprocess 12import sys 13 14 15def main(): 16 parser = argparse.ArgumentParser(description=__doc__) 17 parser.add_argument( 18 '--objcopy', required=True, help='The objcopy binary to run', metavar='PATH') 19 parser.add_argument('--nm', required=True, help='The nm binary to run', metavar='PATH') 20 parser.add_argument('--strip', required=True, help='The strip binary to run', metavar='PATH') 21 parser.add_argument( 22 '--output', required=True, help='Final output shared object file', metavar='FILE') 23 parser.add_argument( 24 '--unstrippedsofile', 25 required=True, 26 help='Unstripped shared object file produced by linking command', 27 metavar='FILE') 28 args = parser.parse_args() 29 30 copy_cmd = ["cp", args.unstrippedsofile, args.output] 31 result = subprocess.call(copy_cmd) 32 33 nm_cmd = subprocess.Popen([args.nm, '-D', args.output, '--format=posix', '--defined-only'], 34 stdout=subprocess.PIPE) 35 36 awk_cmd = subprocess.Popen(['awk', '{ print $1}'], stdin=nm_cmd.stdout, stdout=subprocess.PIPE) 37 38 dynsym_out = open(args.output + '.dynsyms', 'w') 39 sort_cmd = subprocess.Popen(['sort'], stdin=awk_cmd.stdout, stdout=dynsym_out) 40 sort_cmd.wait() 41 dynsym_out.close() 42 43 funcsyms_out = open(args.output + '.funcsyms', 'w') 44 nm_cmd = subprocess.Popen([args.nm, args.output, '--format=posix', '--defined-only'], 45 stdout=subprocess.PIPE) 46 47 awk_cmd = subprocess.Popen(['awk', '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }'], 48 stdin=nm_cmd.stdout, 49 stdout=subprocess.PIPE) 50 51 sort_cmd = subprocess.Popen(['sort'], stdin=awk_cmd.stdout, stdout=funcsyms_out) 52 sort_cmd.wait() 53 funcsyms_out.close() 54 55 keep_symbols = open(args.output + '.keep_symbols', 'w') 56 comm_cmd = subprocess.Popen( 57 ['comm', '-13', args.output + '.dynsyms', args.output + '.funcsyms'], stdout=keep_symbols) 58 comm_cmd.wait() 59 60 # Ensure that the keep_symbols file is not empty. 61 keep_symbols.write("\n") 62 keep_symbols.close() 63 64 objcopy_cmd = [args.objcopy, '--only-keep-debug', args.output, args.output + '.debug'] 65 subprocess.check_call(objcopy_cmd) 66 67 objcopy_cmd = [ 68 args.objcopy, '-S', '--remove-section', '.gdb_index', '--remove-section', '.comment', 69 '--keep-symbols', args.output + '.keep_symbols', args.output + '.debug', 70 args.output + '.mini_debuginfo' 71 ] 72 subprocess.check_call(objcopy_cmd) 73 74 strip_cmd = [args.strip, '--strip-all', '-R', '.comment', args.output] 75 subprocess.check_call(strip_cmd) 76 77 xz_cmd = ['xz', '-f', args.output + '.mini_debuginfo'] 78 subprocess.check_call(xz_cmd) 79 80 objcopy_cmd = [ 81 args.objcopy, '--add-section', '.gnu_debugdata=' + args.output + '.mini_debuginfo.xz', 82 args.output 83 ] 84 subprocess.check_call(objcopy_cmd) 85 86 # Clean out scratch files 87 rm_cmd = [ 88 'rm', '-f', args.output + '.dynsyms', args.output + '.funcsyms', 89 args.output + '.keep_symbols', args.output + '.debug', args.output + '.mini_debuginfo', 90 args.output + '.mini_debuginfo.xz' 91 ] 92 result = subprocess.call(rm_cmd) 93 94 return result 95 96 97if __name__ == "__main__": 98 sys.exit(main()) 99