blob: c3c4f03cc72302562f98607d25f12eeff2236418 [file] [log] [blame]
#!src/build/run_python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tool to interact with a symbol list.
Usage:
1) Dump defined symbols
$ ./src/build/symbol_tool --dump-defined foo.so > defined.list
2) Dump undefined symbols
$ ./src/build/symbol_tool --dump-undefined foo.so > undefined.list
3) Clean up symbols file (remove comments and sort)
$ ./src/build/symbol_tool --clean foo.list > clean.list
4) Verify symbols
$ ./src/build/symbol_tool --verify input.list disallowed.list
(Reports errors if input.list contains symbols listed in disallowed.list)
"""
import argparse
import subprocess
import sys
from src.build import toolchain
from src.build.build_options import OPTIONS
def main():
description = 'Tool to manipulate symbol list files.'
parser = argparse.ArgumentParser(description=description)
parser.add_argument(
'--dump-defined', action='store_true',
help='Dump defined symbols from the given shared object.')
parser.add_argument(
'--dump-undefined', action='store_true',
help='Dump defined symbols from the given shared object.')
parser.add_argument(
'--clean', action='store_true',
help='Copy symbols file with comments stripped.')
parser.add_argument(
'--verify', action='store_true',
help='Verify that file 1 does not contain symbols listed in file 2.')
parser.add_argument('args', nargs=argparse.REMAINDER)
args = parser.parse_args()
OPTIONS.parse_configure_file()
nm = toolchain.get_tool(OPTIONS.target(), 'nm')
if args.dump_defined:
command = (nm + ' --defined-only --extern-only --format=posix %s | '
'sed -n \'s/^\(.*\) [A-Za-z].*$/\\1/p\' | '
'LC_ALL=C sort -u' % args.args[0])
return subprocess.check_call(command, shell=True)
elif args.dump_undefined:
command = (nm + ' --undefined-only --format=posix %s | '
'sed -n \'s/^\(.*\) U.*$/\\1/p\' | '
'LC_ALL=C sort -u' % args.args[0])
return subprocess.check_call(command, shell=True)
elif args.clean:
command = ('egrep -ve "^#" %s | LC_ALL=C sort' % args.args[0])
return subprocess.check_call(command, shell=True)
elif args.verify:
command = ('LC_ALL=C comm -12 %s %s' % (args.args[0], args.args[1]))
try:
diff = subprocess.check_output(command, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
# This can happen if files are not sorted
print e.output.rstrip()
return 1
if diff:
print '%s has disallowed symbols: ' % (args.args[0])
print diff.rstrip()
return 1
return 0
print 'No command specified.'
return 1
if __name__ == '__main__':
sys.exit(main())