• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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