Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2015 The Chromium 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 """Runs 'ld -shared' and generates a .TOC file that's untouched when unchanged. | |
| 7 | |
| 8 This script exists to avoid using complex shell commands in | |
| 9 gcc_toolchain.gni's tool("solink"), in case the host running the compiler | |
| 10 does not have a POSIX-like shell (e.g. Windows). | |
| 11 """ | |
| 12 | |
| 13 import argparse | |
| 14 import os | |
| 15 import re | |
| 16 import subprocess | |
| 17 import sys | |
| 18 | |
| 19 def CollectSONAME(args): | |
| 20 """Replaces: readelf -d $sofile | grep SONAME | |
| 21 """ | |
|
Dirk Pranke
2015/10/28 22:13:03
nit: format the comments on a single line here.
Roland McGrath
2015/10/28 22:25:16
Done.
| |
| 22 toc = '' | |
| 23 soname_re = re.compile('SONAME') | |
| 24 readelf = subprocess.Popen([args.readelf, '-d', args.sofile], | |
| 25 stdout=subprocess.PIPE, bufsize=-1) | |
| 26 for line in readelf.stdout: | |
| 27 if soname_re.search(line): | |
|
Dirk Pranke
2015/10/28 22:13:03
nit: you could skip the re here and just do:
if
Roland McGrath
2015/10/28 22:25:16
Done.
| |
| 28 toc += line | |
| 29 return readelf.wait(), toc | |
| 30 | |
|
Dirk Pranke
2015/10/28 22:13:03
nit two blank lines between top-level functions.
Roland McGrath
2015/10/28 22:25:16
Done.
| |
| 31 def CollectDynSym(args): | |
| 32 """Replaces: nm --format=posix -g -D $sofile | cut -f1-2 -d | |
|
Dirk Pranke
2015/10/28 22:13:03
nit: cut -f1-2 -d' '
Roland McGrath
2015/10/28 22:25:16
Done.
| |
| 33 """ | |
| 34 toc = '' | |
| 35 nm = subprocess.Popen([args.nm, '--format=posix', '-g', '-D', args.sofile], | |
| 36 stdout=subprocess.PIPE, bufsize=-1) | |
| 37 for line in nm.stdout: | |
| 38 toc += ' '.join(line.split(' ', 2)[:2]) + '\n' | |
| 39 return nm.wait(), toc | |
| 40 | |
| 41 def CollectTOC(args): | |
| 42 result, toc = CollectSONAME(args) | |
| 43 if result == 0: | |
| 44 result, dynsym = CollectDynSym(args) | |
| 45 toc += dynsym | |
| 46 return result, toc | |
| 47 | |
| 48 def UpdateTOC(tocfile, toc): | |
| 49 if os.path.exists(tocfile): | |
| 50 old_toc = open(tocfile, 'r').read() | |
| 51 else: | |
| 52 old_toc = None | |
| 53 if toc != old_toc: | |
| 54 open(tocfile, 'w').write(toc) | |
| 55 | |
| 56 def main(): | |
| 57 parser = argparse.ArgumentParser(description=__doc__) | |
| 58 parser.add_argument('--readelf', | |
| 59 required=True, | |
| 60 help='The readelf binary to run', | |
| 61 metavar='PATH') | |
| 62 parser.add_argument('--nm', | |
| 63 required=True, | |
| 64 help='The nm binary to run', | |
| 65 metavar='PATH') | |
| 66 parser.add_argument('--strip', | |
| 67 help='The strip binary to run', | |
| 68 metavar='PATH') | |
| 69 parser.add_argument('--sofile', | |
| 70 required=True, | |
| 71 help='Shared object file produced by linking command', | |
| 72 metavar='FILE') | |
| 73 parser.add_argument('--tocfile', | |
| 74 required=True, | |
| 75 help='Output table-of-contents file', | |
| 76 metavar='FILE') | |
| 77 parser.add_argument('--output', | |
| 78 required=True, | |
| 79 help='Final output shared object file', | |
| 80 metavar='FILE') | |
| 81 parser.add_argument('command', nargs='+', | |
| 82 help='Linking command') | |
| 83 args = parser.parse_args() | |
| 84 | |
| 85 # First, run the actual link. | |
| 86 result = subprocess.call(args.command) | |
| 87 if result != 0: | |
| 88 return result | |
| 89 | |
| 90 # Next, generate the contents of the TOC file. | |
| 91 result, toc = CollectTOC(args) | |
| 92 if result != 0: | |
| 93 return result | |
| 94 | |
| 95 # If there is an existing TOC file with identical contents, leave it alone. | |
| 96 # Otherwise, write out the TOC file. | |
| 97 UpdateTOC(args.tocfile, toc) | |
| 98 | |
| 99 # Finally, strip the linked shared object file (if desired). | |
| 100 if args.strip: | |
| 101 result = subprocess.call([args.strip, '--strip-unneeded', | |
| 102 '-o', args.output, args.sofile]) | |
| 103 | |
| 104 return result | |
| 105 | |
| 106 if __name__ == "__main__": | |
| 107 sys.exit(main()) | |
| OLD | NEW |