blob: 95a6a2c9579df5a1f71de5ec2e8e2fd1fd9fab93 [file] [log] [blame]
Jim Stichnoth10ea6982014-09-09 11:19:12 -07001#!/usr/bin/env python2
2
3import argparse
4import os
5import pipes
6import re
7import sys
8
Jim Stichnoth8ff4b282016-01-04 15:39:06 -08009from utils import shellcmd, FindBaseNaCl, get_sfi_string
Jim Stichnoth10ea6982014-09-09 11:19:12 -070010
Jim Stichnoth0fb613f2014-09-16 10:19:03 -070011def NewerThanOrNotThere(old_path, new_path):
12 """Returns whether old_path is newer than new_path.
13
14 Also returns true if either path doesn't exist.
15 """
16 if not (os.path.exists(old_path) and os.path.exists(new_path)):
17 return True
18 return os.path.getmtime(old_path) > os.path.getmtime(new_path)
19
Jim Stichnoth10ea6982014-09-09 11:19:12 -070020def BuildRegex(patterns, syms):
21 """Build a regular expression string for inclusion or exclusion.
22
23 Creates a regex string from an array of patterns and an array
24 of symbol names. Each element in the patterns array is either a
25 regex, or a range of entries in the symbol name array, e.g. '2:9'.
26 """
27 pattern_list = []
28 for pattern in patterns:
29 if pattern[0].isdigit() or pattern[0] == ':':
30 # Legitimate symbols or regexes shouldn't start with a
31 # digit or a ':', so interpret the pattern as a range.
32 interval = pattern.split(':')
33 if len(interval) == 1:
34 # Treat singleton 'n' as 'n:n+1'.
35 lower = int(interval[0])
36 upper = lower + 1
37 elif len(interval) == 2:
38 # Handle 'a:b', 'a:', and ':b' with suitable defaults.
39 lower = int(interval[0]) if len(interval[0]) else 0
40 upper = int(interval[1]) if len(interval[1]) else len(syms)
41 else:
42 print 'Invalid range syntax: {p}'.format(p=pattern)
43 exit(1)
44 pattern = '$|^'.join([re.escape(p) for p in syms[lower:upper]])
45 pattern_list.append('^' + pattern + '$')
46 return '|'.join(pattern_list) if len(pattern_list) else '^$'
47
48def MatchSymbol(sym, re_include, re_exclude, default_match):
49 """Match a symbol name against inclusion/exclusion rules.
50
51 Returns True or False depending on whether the given symbol
52 matches the compiled include or exclude regexes. The default is
53 returned if neither the include nor the exclude regex matches.
54 """
55 if re_exclude.match(sym):
56 # Always honor an explicit exclude before considering
57 # includes.
58 return False
59 if re_include.match(sym):
60 return True
61 return default_match
62
Jim Stichnothcc0ee132014-09-17 09:42:53 -070063def AddOptionalArgs(argparser):
64 argparser.add_argument('--force', dest='force', action='store_true',
65 help='Force all re-translations of the pexe')
66 argparser.add_argument('--include', '-i', default=[], dest='include',
67 action='append',
68 help='Subzero symbols to include ' +
69 '(regex or line range)')
70 argparser.add_argument('--exclude', '-e', default=[], dest='exclude',
71 action='append',
72 help='Subzero symbols to exclude ' +
73 '(regex or line range)')
74 argparser.add_argument('--output', '-o', default='a.out', dest='output',
75 action='store',
76 help='Output executable. Default %(default)s.')
77 argparser.add_argument('-O', default='2', dest='optlevel',
78 choices=['m1', '-1', '0', '1', '2'],
79 help='Optimization level ' +
80 '(m1 and -1 are equivalent).' +
81 ' Default %(default)s.')
Jim Stichnothd442e7e2015-02-12 14:01:48 -080082 argparser.add_argument('--filetype', default='iasm', dest='filetype',
83 choices=['obj', 'asm', 'iasm'],
84 help='Output file type. Default %(default)s.')
Jim Stichnoth9738a9e2015-02-23 16:39:06 -080085 argparser.add_argument('--sandbox', dest='sandbox', action='store_true',
John Portof8b4cc82015-06-09 18:06:19 -070086 help='Enable sandboxing in the translator')
Jim Stichnoth8ff4b282016-01-04 15:39:06 -080087 argparser.add_argument('--nonsfi', dest='nonsfi', action='store_true',
88 help='Enable Non-SFI in the translator')
John Portof8b4cc82015-06-09 18:06:19 -070089 argparser.add_argument('--enable-block-profile',
90 dest='enable_block_profile', action='store_true',
91 help='Enable basic block profiling.')
John Portoafc92af2015-10-16 10:34:04 -070092 argparser.add_argument('--target', default='x8632', dest='target',
John Porto3c275ce2015-12-22 08:14:00 -080093 choices=['arm32', 'x8632', 'x8664'],
John Portoafc92af2015-10-16 10:34:04 -070094 help='Generate code for specified target.')
Jim Stichnothcc0ee132014-09-17 09:42:53 -070095 argparser.add_argument('--verbose', '-v', dest='verbose',
96 action='store_true',
97 help='Display some extra debugging output')
Jim Stichnoth89906a52014-09-18 09:43:30 -070098 argparser.add_argument('--sz', dest='sz_args', action='append', default=[],
99 help='Extra arguments for Subzero')
100 argparser.add_argument('--llc', dest='llc_args', action='append',
101 default=[], help='Extra arguments for llc')
Jim Stichnoth42356fb2015-11-10 08:41:12 -0800102 argparser.add_argument('--no-sz', dest='nosz', action='store_true',
103 help='Run only post-Subzero build steps')
Jim Stichnothcc0ee132014-09-17 09:42:53 -0700104
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800105def LinkSandbox(objs, exe, target, verbose=True):
106 assert target in ('x8632', 'arm32'), \
107 '-sandbox is not available for %s' % target
108 nacl_root = FindBaseNaCl()
109 gold = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/bin/' +
110 'le32-nacl-ld.gold').format(root=nacl_root)
111 target_lib_dir = {
112 'arm32': 'arm',
113 'x8632': 'x86-32',
114 }[target]
115 linklib = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/translator/' +
116 '{target_dir}/lib').format(root=nacl_root,
117 target_dir=target_lib_dir)
118 shellcmd([gold,
119 '-nostdlib',
120 '--no-fix-cortex-a8',
121 '--eh-frame-hdr',
122 '-z', 'text',
123 #'-z', 'noexecstack',
124 '--build-id',
125 '--entry=__pnacl_start',
126 '-static', #'-pie',
127 '{linklib}/crtbegin.o'.format(linklib=linklib)] +
128 objs +
129 [('{root}/toolchain_build/src/subzero/build/runtime/' +
130 'szrt_sb_{target}.o').format(root=nacl_root, target=target),
131 '{linklib}/libpnacl_irt_shim_dummy.a'.format(linklib=linklib),
132 '--start-group',
133 '{linklib}/libgcc.a'.format(linklib=linklib),
134 '{linklib}/libcrt_platform.a'.format(linklib=linklib),
135 '--end-group',
136 '{linklib}/crtend.o'.format(linklib=linklib),
137 '--undefined=_start',
138 '--defsym=__Sz_AbsoluteZero=0',
139 #'--defsym=_begin=0',
140 '-o', exe
141 ], echo=verbose)
142
143def LinkNonsfi(objs, exe, target, verbose=True):
144 nacl_root = FindBaseNaCl()
145 gold = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/bin/' +
146 'le32-nacl-ld.gold').format(root=nacl_root)
147 target_lib_dir = {
148 'arm32': 'arm-nonsfi',
149 'x8632': 'x86-32-nonsfi',
150 }[target]
151 linklib = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/translator/' +
152 '{target_dir}/lib').format(root=nacl_root,
153 target_dir=target_lib_dir)
154 shellcmd([gold,
155 '-nostdlib',
156 '--no-fix-cortex-a8',
157 '--eh-frame-hdr',
158 '-z', 'text',
159 '-z', 'noexecstack',
160 '--build-id',
161 '--entry=__pnacl_start',
162 '-pie',
163 '{linklib}/crtbegin.o'.format(linklib=linklib)] +
164 objs +
165 [('{root}/toolchain_build/src/subzero/build/runtime/' +
166 'szrt_nonsfi_{target}.o').format(root=nacl_root, target=target),
167 '{linklib}/libpnacl_irt_shim_dummy.a'.format(linklib=linklib),
168 '--start-group',
169 '{linklib}/libgcc.a'.format(linklib=linklib),
170 '{linklib}/libcrt_platform.a'.format(linklib=linklib),
171 '--end-group',
172 '{linklib}/crtend.o'.format(linklib=linklib),
173 '--undefined=_start',
174 '--defsym=__Sz_AbsoluteZero=0',
175 '--defsym=_begin=0',
176 '-o', exe
177 ], echo=verbose)
178
179def LinkNative(objs, exe, target, verbose=True):
180 nacl_root = FindBaseNaCl()
181 linker = {
182 'arm32': '/usr/bin/arm-linux-gnueabihf-g++',
183 'x8632': ('{root}/../third_party/llvm-build/Release+Asserts/bin/clang'
184 ).format(root=nacl_root),
185 'x8664': ('{root}/../third_party/llvm-build/Release+Asserts/bin/clang'
186 ).format(root=nacl_root)
187 }[target]
188
189 extra_linker_args = {
190 'arm32': ['-mcpu=cortex-a9'],
191 'x8632': ['-m32'],
192 'x8664': ['-mx32']
193 }[target]
194
195 lib_dir = {
196 'arm32': 'arm-linux',
197 'x8632': 'x86-32-linux',
198 'x8664': 'x86-64-linux',
199 }[target]
200
201 shellcmd([linker] +
202 extra_linker_args +
203 objs +
204 ['-o', exe,
205 ('{root}/toolchain/linux_x86/pnacl_newlib_raw/translator/' +
206 '{lib_dir}/lib/' +
207 '{{unsandboxed_irt,irt_random,irt_query_list}}.o').format(
208 root=nacl_root, lib_dir=lib_dir),
209 ('{root}/toolchain_build/src/subzero/build/runtime/' +
210 'szrt_native_{target}.o').format(root=nacl_root, target=target),
211 '-lm', '-lpthread', '-lrt',
212 '-Wl,--defsym=__Sz_AbsoluteZero=0'
213 ], echo=verbose)
214
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700215def main():
216 """Create a hybrid translation from Subzero and llc.
217
Jim Stichnoth58acae32014-11-03 12:31:28 -0800218 Takes a finalized pexe and builds a native executable as a hybrid of Subzero
219 and llc translated bitcode. Linker tricks are used to determine whether
220 Subzero or llc generated symbols are used, on a per-symbol basis.
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700221
Jim Stichnoth58acae32014-11-03 12:31:28 -0800222 By default, for every symbol, its Subzero version is used. Subzero and llc
223 symbols can be selectively enabled/disabled via regular expressions on the
224 symbol name, or by ranges of lines in this program's auto-generated symbol
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700225 file.
226
Jim Stichnoth58acae32014-11-03 12:31:28 -0800227 For each symbol, the --exclude arguments are first checked (the symbol is
228 'rejected' on a match), followed by the --include arguments (the symbol is
229 'accepted' on a match), followed by unconditional 'rejection'. The Subzero
230 version is used for an 'accepted' symbol, and the llc version is used for a
231 'rejected' symbol.
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700232
Jim Stichnoth58acae32014-11-03 12:31:28 -0800233 Each --include and --exclude argument can be a regular expression or a range
234 of lines in the symbol file. Each regular expression is wrapped inside
235 '^$', so if you want a substring match on 'foo', use '.*foo.*' instead.
236 Ranges use python-style 'first:last' notation, so e.g. use '0:10' or ':10'
237 for the first 10 lines of the file, or '1' for the second line of the file.
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700238
Jim Stichnoth58acae32014-11-03 12:31:28 -0800239 If no --include or --exclude arguments are given, the executable is produced
240 entirely using Subzero, without using llc or linker tricks.
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700241
Jim Stichnoth58acae32014-11-03 12:31:28 -0800242 This script uses file modification timestamps to determine whether llc and
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800243 Subzero re-translation are needed. It checks timestamps of llc, pnacl-sz,
Jim Stichnoth58acae32014-11-03 12:31:28 -0800244 and the pexe against the translated object files to determine the minimal
245 work necessary. The --force option suppresses those checks and
246 re-translates everything.
247
Jim Stichnotha2efb9d2015-10-30 12:02:44 -0700248 This script expects various PNaCl and LLVM tools to be found within the
249 native_client tree. When changes are made to these tools, copy them this
250 way:
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700251 cd native_client
Jan Voung4c127ba2014-09-19 13:11:36 -0700252 toolchain_build/toolchain_build_pnacl.py llvm_x86_64_linux \\
Jim Stichnothbb9d11a2015-06-03 00:18:14 -0700253 --install=toolchain/linux_x86/pnacl_newlib_raw
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700254 """
255 argparser = argparse.ArgumentParser(
256 description=' ' + main.__doc__,
257 formatter_class=argparse.RawTextHelpFormatter)
Jim Stichnothcc0ee132014-09-17 09:42:53 -0700258 AddOptionalArgs(argparser)
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700259 argparser.add_argument('pexe', help='Finalized pexe to translate')
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700260 args = argparser.parse_args()
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700261 pexe = args.pexe
Jim Stichnothcc0ee132014-09-17 09:42:53 -0700262 exe = args.output
263 ProcessPexe(args, pexe, exe)
264
265def ProcessPexe(args, pexe, exe):
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700266 [pexe_base, ext] = os.path.splitext(pexe)
267 if ext != '.pexe':
268 pexe_base = pexe
269 pexe_base_unescaped = pexe_base
270 pexe_base = pipes.quote(pexe_base)
271 pexe = pipes.quote(pexe)
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700272
273 nacl_root = FindBaseNaCl()
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800274 path_addition = (
Jim Stichnothbb9d11a2015-06-03 00:18:14 -0700275 '{root}/toolchain/linux_x86/pnacl_newlib_raw/bin'
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800276 ).format(root=nacl_root)
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700277 obj_llc = pexe_base + '.llc.o'
278 obj_sz = pexe_base + '.sz.o'
279 asm_sz = pexe_base + '.sz.s'
280 obj_llc_weak = pexe_base + '.weak.llc.o'
281 obj_sz_weak = pexe_base + '.weak.sz.o'
Jim Stichnoth58acae32014-11-03 12:31:28 -0800282 obj_partial = obj_sz # overridden for hybrid mode
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700283 sym_llc = pexe_base + '.sym.llc.txt'
284 sym_sz = pexe_base + '.sym.sz.txt'
285 sym_sz_unescaped = pexe_base_unescaped + '.sym.sz.txt'
286 whitelist_sz = pexe_base + '.wl.sz.txt'
287 whitelist_sz_unescaped = pexe_base_unescaped + '.wl.sz.txt'
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800288 pnacl_sz = (
289 '{root}/toolchain_build/src/subzero/pnacl-sz'
Jim Stichnoth0fb613f2014-09-16 10:19:03 -0700290 ).format(root=nacl_root)
Jim Stichnoth8c7b0a22015-03-29 15:20:37 -0700291 llcbin = '{base}/pnacl-llc'.format(base=path_addition)
Jim Stichnotha2efb9d2015-10-30 12:02:44 -0700292 gold = '{base}/le32-nacl-ld.gold'.format(base=path_addition)
293 objcopy = '{base}/le32-nacl-objcopy'.format(base=path_addition)
Jim Stichnoth0fb613f2014-09-16 10:19:03 -0700294 opt_level = args.optlevel
Jan Voung109fa152014-10-07 17:22:51 -0700295 opt_level_map = { 'm1':'0', '-1':'0', '0':'0', '1':'1', '2':'2' }
Jim Stichnoth58acae32014-11-03 12:31:28 -0800296 hybrid = args.include or args.exclude
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800297 native = not args.sandbox and not args.nonsfi
Jim Stichnoth58acae32014-11-03 12:31:28 -0800298
299 if hybrid and (args.force or
300 NewerThanOrNotThere(pexe, obj_llc) or
301 NewerThanOrNotThere(llcbin, obj_llc)):
John Portoafc92af2015-10-16 10:34:04 -0700302 arch = {
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800303 'arm32': 'arm' + get_sfi_string(args, 'v7', '-nonsfi', '-nonsfi'),
304 'x8632': 'x86-32' + get_sfi_string(args, '', '-nonsfi', '-linux'),
305 'x8664': 'x86-64' + get_sfi_string(args, '', '', '-linux')
John Portoafc92af2015-10-16 10:34:04 -0700306 }[args.target]
307
Jim Stichnoth58acae32014-11-03 12:31:28 -0800308 # Only run pnacl-translate in hybrid mode.
Jim Stichnotha2efb9d2015-10-30 12:02:44 -0700309 shellcmd(['{base}/pnacl-translate'.format(base=path_addition),
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800310 '-split-module=1',
Jim Stichnoth89906a52014-09-18 09:43:30 -0700311 '-ffunction-sections',
Jim Stichnoth2a063e22014-10-08 11:24:51 -0700312 '-fdata-sections',
Jim Stichnoth89906a52014-09-18 09:43:30 -0700313 '-c',
John Portoafc92af2015-10-16 10:34:04 -0700314 '-arch', arch,
Jim Stichnoth89906a52014-09-18 09:43:30 -0700315 '-O' + opt_level_map[opt_level],
316 '--pnacl-driver-append-LLC_FLAGS_EXTRA=-externalize',
317 '-o', obj_llc] +
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800318 (['--pnacl-driver-verbose'] if args.verbose else []) +
Jim Stichnoth89906a52014-09-18 09:43:30 -0700319 args.llc_args +
320 [pexe],
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700321 echo=args.verbose)
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800322 if native:
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800323 shellcmd((
Jan Voung050deaa2015-06-12 15:12:05 -0700324 '{objcopy} --redefine-sym _start=_user_start {obj}'
325 ).format(objcopy=objcopy, obj=obj_llc), echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800326 # Generate llc syms file for consistency, even though it's not used.
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700327 shellcmd((
Jim Stichnoth0fb613f2014-09-16 10:19:03 -0700328 'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}'
329 ).format(obj=obj_llc, sym=sym_llc), echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800330
331 if (args.force or
332 NewerThanOrNotThere(pexe, obj_sz) or
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800333 NewerThanOrNotThere(pnacl_sz, obj_sz)):
Jim Stichnoth42356fb2015-11-10 08:41:12 -0800334 if not args.nosz:
335 # Run pnacl-sz regardless of hybrid mode.
336 shellcmd([pnacl_sz,
337 '-O' + opt_level,
338 '-bitcode-format=pnacl',
339 '-filetype=' + args.filetype,
340 '-o', obj_sz if args.filetype == 'obj' else asm_sz,
341 '-target=' + args.target] +
342 (['-externalize',
343 '-ffunction-sections',
344 '-fdata-sections'] if hybrid else []) +
345 (['-sandbox'] if args.sandbox else []) +
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800346 (['-nonsfi'] if args.nonsfi else []) +
Jim Stichnoth42356fb2015-11-10 08:41:12 -0800347 (['-enable-block-profile'] if
348 args.enable_block_profile and not args.sandbox
349 else []) +
350 args.sz_args +
351 [pexe],
352 echo=args.verbose)
Jim Stichnothd442e7e2015-02-12 14:01:48 -0800353 if args.filetype != 'obj':
John Portoafc92af2015-10-16 10:34:04 -0700354 triple = {
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800355 'arm32': 'arm' + get_sfi_string(args, '-nacl', '', ''),
356 'x8632': 'i686' + get_sfi_string(args, '-nacl', '', ''),
357 'x8664': 'x86_64' +
358 get_sfi_string(args, '-nacl', '-linux-gnux32',
359 '-linux-gnux32'),
John Portoafc92af2015-10-16 10:34:04 -0700360 }[args.target]
361
Jim Stichnoth046ec2e2015-01-31 17:57:41 -0800362 shellcmd((
Jim Stichnoth955bfdc2015-10-30 14:41:43 -0700363 '{base}/llvm-mc -triple={triple} -filetype=obj -o {obj} {asm}'
364 ).format(base=path_addition, asm=asm_sz, obj=obj_sz,
365 triple=triple),
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800366 echo=args.verbose)
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800367 if native:
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800368 shellcmd((
Jan Voung050deaa2015-06-12 15:12:05 -0700369 '{objcopy} --redefine-sym _start=_user_start {obj}'
370 ).format(objcopy=objcopy, obj=obj_sz), echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800371 if hybrid:
372 shellcmd((
373 'nm {obj} | sed -n "s/.* [a-zA-Z] //p" > {sym}'
374 ).format(obj=obj_sz, sym=sym_sz), echo=args.verbose)
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700375
Jim Stichnoth58acae32014-11-03 12:31:28 -0800376 if hybrid:
377 with open(sym_sz_unescaped) as f:
378 sz_syms = f.read().splitlines()
379 re_include_str = BuildRegex(args.include, sz_syms)
380 re_exclude_str = BuildRegex(args.exclude, sz_syms)
381 re_include = re.compile(re_include_str)
382 re_exclude = re.compile(re_exclude_str)
383 # If a symbol doesn't explicitly match re_include or re_exclude,
384 # the default MatchSymbol() result is True, unless some --include
385 # args are provided.
386 default_match = not args.include
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700387
Jim Stichnoth58acae32014-11-03 12:31:28 -0800388 whitelist_has_items = False
389 with open(whitelist_sz_unescaped, 'w') as f:
390 for sym in sz_syms:
391 if MatchSymbol(sym, re_include, re_exclude, default_match):
392 f.write(sym + '\n')
393 whitelist_has_items = True
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700394 shellcmd((
Jan Voung050deaa2015-06-12 15:12:05 -0700395 '{objcopy} --weaken {obj} {weak}'
396 ).format(objcopy=objcopy, obj=obj_sz, weak=obj_sz_weak),
397 echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800398 if whitelist_has_items:
399 # objcopy returns an error if the --weaken-symbols file is empty.
400 shellcmd((
Jan Voung050deaa2015-06-12 15:12:05 -0700401 '{objcopy} --weaken-symbols={whitelist} {obj} {weak}'
402 ).format(objcopy=objcopy,
403 whitelist=whitelist_sz, obj=obj_llc,
Jim Stichnoth58acae32014-11-03 12:31:28 -0800404 weak=obj_llc_weak),
405 echo=args.verbose)
406 else:
407 shellcmd((
Jan Voung050deaa2015-06-12 15:12:05 -0700408 '{objcopy} {obj} {weak}'
409 ).format(objcopy=objcopy, obj=obj_llc, weak=obj_llc_weak),
410 echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800411 obj_partial = pexe_base + '.o'
John Portoafc92af2015-10-16 10:34:04 -0700412 ld = {
413 'arm32': 'arm-linux-gnueabihf-ld',
414 'x8632': 'ld',
John Porto3c275ce2015-12-22 08:14:00 -0800415 'x8664': 'ld',
John Portoafc92af2015-10-16 10:34:04 -0700416 }[args.target]
417 emulation = {
418 'arm32': 'armelf_linux_eabi',
419 'x8632': 'elf_i386',
John Porto3c275ce2015-12-22 08:14:00 -0800420 'x8664': 'elf32_x86_64',
John Portoafc92af2015-10-16 10:34:04 -0700421 }[args.target]
Jim Stichnoth58acae32014-11-03 12:31:28 -0800422 shellcmd((
John Portoafc92af2015-10-16 10:34:04 -0700423 '{ld} -r -m {emulation} -o {partial} {sz} {llc}'
424 ).format(ld=ld, emulation=emulation, partial=obj_partial,
425 sz=obj_sz_weak, llc=obj_llc_weak),
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700426 echo=args.verbose)
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700427 shellcmd((
Jan Voung050deaa2015-06-12 15:12:05 -0700428 '{objcopy} -w --localize-symbol="*" {partial}'
429 ).format(objcopy=objcopy, partial=obj_partial),
430 echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800431 shellcmd((
Jim Stichnoth88ab5ca2015-08-06 14:56:42 -0700432 '{objcopy} --globalize-symbol={start} ' +
433 '--globalize-symbol=__Sz_block_profile_info {partial}'
Jan Voung050deaa2015-06-12 15:12:05 -0700434 ).format(objcopy=objcopy, partial=obj_partial,
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800435 start=get_sfi_string(args, '_start', '_start',
436 '_user_start')),
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800437 echo=args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800438
439 # Run the linker regardless of hybrid mode.
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800440 if args.sandbox:
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800441 LinkSandbox([obj_partial], exe, args.target, args.verbose)
442 elif args.nonsfi:
443 LinkNonsfi([obj_partial], exe, args.target, args.verbose)
Jim Stichnoth9738a9e2015-02-23 16:39:06 -0800444 else:
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800445 LinkNative([obj_partial], exe, args.target, args.verbose)
Jim Stichnoth58acae32014-11-03 12:31:28 -0800446
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700447 # Put the extra verbose printing at the end.
Jim Stichnotha2efb9d2015-10-30 12:02:44 -0700448 if args.verbose and hybrid:
449 print 'include={regex}'.format(regex=re_include_str)
450 print 'exclude={regex}'.format(regex=re_exclude_str)
451 print 'default_match={dm}'.format(dm=default_match)
452 print 'Number of Subzero syms = {num}'.format(num=len(sz_syms))
Jim Stichnoth10ea6982014-09-09 11:19:12 -0700453
454if __name__ == '__main__':
455 main()