Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python2 | 1 #!/usr/bin/env python2 |
| 2 | 2 |
| 3 import argparse | 3 import argparse |
| 4 import os | 4 import os |
| 5 import pipes | 5 import pipes |
| 6 import re | 6 import re |
| 7 import sys | 7 import sys |
| 8 | 8 |
| 9 from utils import shellcmd | 9 from utils import shellcmd |
| 10 from utils import FindBaseNaCl | 10 from utils import FindBaseNaCl |
| 11 | 11 |
| 12 def NewerThanOrNotThere(old_path, new_path): | |
| 13 """Returns whether old_path is newer than new_path. | |
| 14 | |
| 15 Also returns true if either path doesn't exist. | |
| 16 """ | |
| 17 if not (os.path.exists(old_path) and os.path.exists(new_path)): | |
| 18 return True | |
| 19 return os.path.getmtime(old_path) > os.path.getmtime(new_path) | |
| 20 | |
| 12 def BuildRegex(patterns, syms): | 21 def BuildRegex(patterns, syms): |
| 13 """Build a regular expression string for inclusion or exclusion. | 22 """Build a regular expression string for inclusion or exclusion. |
| 14 | 23 |
| 15 Creates a regex string from an array of patterns and an array | 24 Creates a regex string from an array of patterns and an array |
| 16 of symbol names. Each element in the patterns array is either a | 25 of symbol names. Each element in the patterns array is either a |
| 17 regex, or a range of entries in the symbol name array, e.g. '2:9'. | 26 regex, or a range of entries in the symbol name array, e.g. '2:9'. |
| 18 """ | 27 """ |
| 19 pattern_list = [] | 28 pattern_list = [] |
| 20 for pattern in patterns: | 29 for pattern in patterns: |
| 21 if pattern[0].isdigit() or pattern[0] == ':': | 30 if pattern[0].isdigit() or pattern[0] == ':': |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 'accepted' symbol, and the llc version is used for a 'rejected' | 81 'accepted' symbol, and the llc version is used for a 'rejected' |
| 73 symbol. | 82 symbol. |
| 74 | 83 |
| 75 Each --include and --exclude argument can be a regular expression | 84 Each --include and --exclude argument can be a regular expression |
| 76 or a range of lines in the symbol file. Each regular expression | 85 or a range of lines in the symbol file. Each regular expression |
| 77 is wrapped inside '^$', so if you want a substring match on 'foo', | 86 is wrapped inside '^$', so if you want a substring match on 'foo', |
| 78 use '.*foo.*' instead. Ranges use python-style 'first:last' | 87 use '.*foo.*' instead. Ranges use python-style 'first:last' |
| 79 notation, so e.g. use '0:10' or ':10' for the first 10 lines of | 88 notation, so e.g. use '0:10' or ':10' for the first 10 lines of |
| 80 the file, or '1' for the second line of the file. | 89 the file, or '1' for the second line of the file. |
| 81 | 90 |
| 82 The --init argument does first-time initialization for the pexe, | 91 This script uses file modification timestamps to determine whether |
| 83 including creation of the Subzero symbol file that is implicitly | 92 llc and Subzero re-translation are needed. It checks timestamps |
| 84 used in the --include and --exclude arguments. It can be removed | 93 of llc, llvm2ice, and the pexe against the translated object files |
| 85 from the command line for subsequent executions if the pexe | 94 to determine the minimal work necessary. The --init option |
| 86 doesn't change. | 95 suppresses those checks and re-translates everything. |
| 87 | 96 |
| 88 This scripts augments PATH so that various PNaCl and LLVM tools | 97 This script augments PATH so that various PNaCl and LLVM tools can |
| 89 can be run. These extra paths are within the native_client tree. | 98 be run. These extra paths are within the native_client tree. |
| 90 When changes are made to these tools, copy them this way: | 99 When changes are made to these tools, copy them this way: |
| 91 cd native_client | 100 cd native_client |
| 92 toolchain_build/toolchain_build_pnacl.py llvm_i686_linux \\ | 101 toolchain_build/toolchain_build_pnacl.py llvm_i686_linux \\ |
| 93 --install=toolchain/linux_x86/pnacl_newlib | 102 --install=toolchain/linux_x86/pnacl_newlib |
| 94 """ | 103 """ |
| 95 argparser = argparse.ArgumentParser( | 104 argparser = argparse.ArgumentParser( |
| 96 description=' ' + main.__doc__, | 105 description=' ' + main.__doc__, |
| 97 formatter_class=argparse.RawTextHelpFormatter) | 106 formatter_class=argparse.RawTextHelpFormatter) |
| 98 argparser.add_argument('pexe', help='Finalized pexe to translate') | 107 argparser.add_argument('pexe', help='Finalized pexe to translate') |
| 99 argparser.add_argument('--init', dest='init', action='store_true', | 108 argparser.add_argument('--init', dest='init', action='store_true', |
| 100 help='Perform first-time setup for the pexe') | 109 help='Force all re-translation of the pexe') |
|
jvoung (off chromium)
2014/09/16 00:43:58
Would it make sense to call the flag --force, or s
Jim Stichnoth
2014/09/16 03:09:48
You're right. I changed it to --force.
| |
| 101 argparser.add_argument('--include', '-i', default=[], dest='include', | 110 argparser.add_argument('--include', '-i', default=[], dest='include', |
| 102 action='append', | 111 action='append', |
| 103 help='Subzero symbols to include ' + | 112 help='Subzero symbols to include ' + |
| 104 '(regex or line range)') | 113 '(regex or line range)') |
| 105 argparser.add_argument('--exclude', '-e', default=[], dest='exclude', | 114 argparser.add_argument('--exclude', '-e', default=[], dest='exclude', |
| 106 action='append', | 115 action='append', |
| 107 help='Subzero symbols to exclude ' + | 116 help='Subzero symbols to exclude ' + |
| 108 '(regex or line range)') | 117 '(regex or line range)') |
| 109 argparser.add_argument('--output', '-o', default='a.out', dest='output', | 118 argparser.add_argument('--output', '-o', default='a.out', dest='output', |
| 110 action='store', | 119 action='store', |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 138 obj_sz = pexe_base + '.sz.o' | 147 obj_sz = pexe_base + '.sz.o' |
| 139 asm_sz = pexe_base + '.sz.s' | 148 asm_sz = pexe_base + '.sz.s' |
| 140 obj_llc_weak = pexe_base + '.weak.llc.o' | 149 obj_llc_weak = pexe_base + '.weak.llc.o' |
| 141 obj_sz_weak = pexe_base + '.weak.sz.o' | 150 obj_sz_weak = pexe_base + '.weak.sz.o' |
| 142 obj_partial = pexe_base + '.o' | 151 obj_partial = pexe_base + '.o' |
| 143 sym_llc = pexe_base + '.sym.llc.txt' | 152 sym_llc = pexe_base + '.sym.llc.txt' |
| 144 sym_sz = pexe_base + '.sym.sz.txt' | 153 sym_sz = pexe_base + '.sym.sz.txt' |
| 145 sym_sz_unescaped = pexe_base_unescaped + '.sym.sz.txt' | 154 sym_sz_unescaped = pexe_base_unescaped + '.sym.sz.txt' |
| 146 whitelist_sz = pexe_base + '.wl.sz.txt' | 155 whitelist_sz = pexe_base + '.wl.sz.txt' |
| 147 whitelist_sz_unescaped = pexe_base_unescaped + '.wl.sz.txt' | 156 whitelist_sz_unescaped = pexe_base_unescaped + '.wl.sz.txt' |
| 157 llvm2ice = ( | |
| 158 '{root}/toolchain_build/src/subzero/llvm2ice' | |
| 159 ).format(root=nacl_root) | |
| 160 llcbin = ( | |
| 161 '{root}/toolchain/linux_x86/pnacl_newlib/host_x86_32/bin/llc' | |
| 162 ).format(root=nacl_root) | |
| 163 opt_level = args.optlevel | |
| 148 | 164 |
| 149 if args.init: | 165 if args.init or NewerThanOrNotThere(pexe, obj_llc) or \ |
| 150 opt_level = args.optlevel | 166 NewerThanOrNotThere(llcbin, obj_llc): |
| 151 opt_level_map = { 'm1':'0', '-1':'0', '0':'0', '1':'1', '2':'2' } | 167 opt_level_map = { 'm1':'0', '-1':'0', '0':'0', '1':'1', '2':'2' } |
| 152 shellcmd(( | 168 shellcmd(( |
| 153 'pnacl-translate -ffunction-sections -c -arch x86-32-linux ' + | 169 'pnacl-translate -ffunction-sections -c -arch x86-32-linux ' + |
| 154 '-O{level} --pnacl-driver-append-LLC_FLAGS_EXTRA=-externalize ' + | 170 '-O{level} --pnacl-driver-append-LLC_FLAGS_EXTRA=-externalize ' + |
| 155 '-o {obj} {pexe}' | 171 '-o {obj} {pexe}' |
| 156 ).format(level=opt_level_map[opt_level], obj=obj_llc, pexe=pexe), | 172 ).format(level=opt_level_map[opt_level], obj=obj_llc, pexe=pexe), |
| 157 echo=args.verbose) | 173 echo=args.verbose) |
| 158 shellcmd(( | 174 shellcmd(( |
| 159 'objcopy --redefine-sym _start=_user_start {obj}' | 175 'objcopy --redefine-sym _start=_user_start {obj}' |
| 160 ).format(obj=obj_llc), echo=args.verbose) | 176 ).format(obj=obj_llc), echo=args.verbose) |
| 161 shellcmd(( | 177 shellcmd(( |
| 162 '{root}/toolchain_build/src/subzero/llvm2ice ' + | 178 'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}' |
| 163 '-O{level} -bitcode-format=pnacl -disable-globals ' + | 179 ).format(obj=obj_llc, sym=sym_llc), echo=args.verbose) |
| 180 if args.init or NewerThanOrNotThere(pexe, obj_sz) or \ | |
| 181 NewerThanOrNotThere(llvm2ice, obj_sz): | |
| 182 shellcmd(( | |
| 183 '{l2i} -O{level} -bitcode-format=pnacl -disable-globals ' + | |
| 164 '-externalize -ffunction-sections {pexe} -o {asm}' | 184 '-externalize -ffunction-sections {pexe} -o {asm}' |
| 165 ).format(root=nacl_root,level=opt_level, pexe=pexe, asm=asm_sz), | 185 ).format(l2i=llvm2ice, level=opt_level, pexe=pexe, asm=asm_sz), |
| 166 echo=args.verbose) | 186 echo=args.verbose) |
| 167 shellcmd(( | 187 shellcmd(( |
| 168 'llvm-mc -arch=x86 -x86-asm-syntax=intel -filetype=obj -o {obj} ' + | 188 'llvm-mc -arch=x86 -x86-asm-syntax=intel -filetype=obj -o {obj} ' + |
| 169 '{asm}' | 189 '{asm}' |
| 170 ).format(asm=asm_sz, obj=obj_sz), echo=args.verbose) | 190 ).format(asm=asm_sz, obj=obj_sz), echo=args.verbose) |
| 171 shellcmd(( | 191 shellcmd(( |
| 172 'objcopy --redefine-sym _start=_user_start {obj}' | 192 'objcopy --redefine-sym _start=_user_start {obj}' |
| 173 ).format(obj=obj_sz), echo=args.verbose) | 193 ).format(obj=obj_sz), echo=args.verbose) |
| 174 shellcmd(( | 194 shellcmd(( |
| 175 'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}' | 195 'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}' |
| 176 ).format(obj=obj_sz, sym=sym_sz), echo=args.verbose) | 196 ).format(obj=obj_sz, sym=sym_sz), echo=args.verbose) |
| 177 shellcmd(( | |
| 178 'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}' | |
| 179 ).format(obj=obj_llc, sym=sym_llc), echo=args.verbose) | |
| 180 | 197 |
| 181 with open(sym_sz_unescaped) as f: | 198 with open(sym_sz_unescaped) as f: |
| 182 sz_syms = f.read().splitlines() | 199 sz_syms = f.read().splitlines() |
| 183 re_include_str = BuildRegex(args.include, sz_syms) | 200 re_include_str = BuildRegex(args.include, sz_syms) |
| 184 re_exclude_str = BuildRegex(args.exclude, sz_syms) | 201 re_exclude_str = BuildRegex(args.exclude, sz_syms) |
| 185 re_include = re.compile(re_include_str) | 202 re_include = re.compile(re_include_str) |
| 186 re_exclude = re.compile(re_exclude_str) | 203 re_exclude = re.compile(re_exclude_str) |
| 187 # If a symbol doesn't explicitly match re_include or re_exclude, | 204 # If a symbol doesn't explicitly match re_include or re_exclude, |
| 188 # the default MatchSymbol() result is False, unless some --exclude | 205 # the default MatchSymbol() result is False, unless some --exclude |
| 189 # args are provided and no --include args are provided. | 206 # args are provided and no --include args are provided. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 # Put the extra verbose printing at the end. | 248 # Put the extra verbose printing at the end. |
| 232 if args.verbose: | 249 if args.verbose: |
| 233 print 'PATH={path}'.format(path=os.environ['PATH']) | 250 print 'PATH={path}'.format(path=os.environ['PATH']) |
| 234 print 'include={regex}'.format(regex=re_include_str) | 251 print 'include={regex}'.format(regex=re_include_str) |
| 235 print 'exclude={regex}'.format(regex=re_exclude_str) | 252 print 'exclude={regex}'.format(regex=re_exclude_str) |
| 236 print 'default_match={dm}'.format(dm=default_match) | 253 print 'default_match={dm}'.format(dm=default_match) |
| 237 print 'Number of Subzero syms = {num}'.format(num=len(sz_syms)) | 254 print 'Number of Subzero syms = {num}'.format(num=len(sz_syms)) |
| 238 | 255 |
| 239 if __name__ == '__main__': | 256 if __name__ == '__main__': |
| 240 main() | 257 main() |
| OLD | NEW |