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 |