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