blob: a9267eafba74db9c8d418e80ac7b8f3e5af55bb1 [file] [log] [blame]
Karl Schimpf2a5324a2014-09-25 09:37:49 -07001#!/usr/bin/env python2
2
3import argparse
4import itertools
5import os
6import re
7import subprocess
8import sys
Jan Vounga2703ae2015-02-19 11:27:44 -08009import tempfile
Karl Schimpf2a5324a2014-09-25 09:37:49 -070010
Sean Klein1ece70e2016-03-09 15:26:41 -080011from utils import FindBaseNaCl, GetObjdumpCmd, shellcmd
Karl Schimpf2a5324a2014-09-25 09:37:49 -070012
Jan Voungb2d50842015-05-12 09:53:50 -070013
John Porto52b51572015-12-05 14:16:25 -080014def TargetAssemblerFlags(target, sandboxed):
Reed Kotlerd00d48d2015-07-08 09:49:07 -070015 # TODO(reed kotler). Need to find out exactly we need to
16 # add here for Mips32.
John Porto52b51572015-12-05 14:16:25 -080017 flags = { 'x8632': ['-triple=%s' % ('i686-nacl' if sandboxed else 'i686')],
John Porto56958cb2016-01-14 09:18:18 -080018 'x8664': ['-triple=%s' % (
19 'x86_64-nacl' if sandboxed else 'x86_64')],
John Porto52b51572015-12-05 14:16:25 -080020 'arm32': ['-triple=%s' % (
21 'armv7a-nacl' if sandboxed else 'armv7a'),
22 '-mcpu=cortex-a9', '-mattr=+neon'],
Reed Kotlere105c742015-07-10 14:52:59 -070023 'mips32': ['-triple=mipsel' ] }
Jan Voungb2d50842015-05-12 09:53:50 -070024 return flags[target]
25
26
27def TargetDisassemblerFlags(target):
28 flags = { 'x8632': ['-Mintel'],
John Porto56958cb2016-01-14 09:18:18 -080029 'x8664': ['-Mintel'],
Reed Kotlerd00d48d2015-07-08 09:49:07 -070030 'arm32': [],
31 'mips32':[] }
Jan Voungb2d50842015-05-12 09:53:50 -070032 return flags[target]
33
Karl Schimpf2a5324a2014-09-25 09:37:49 -070034def main():
Jim Stichnothfa0cfa52015-02-26 09:42:36 -080035 """Run the pnacl-sz compiler on an llvm file.
Karl Schimpf2a5324a2014-09-25 09:37:49 -070036
37 Takes an llvm input file, freezes it into a pexe file, converts
38 it to a Subzero program, and finally compiles it.
39 """
40 argparser = argparse.ArgumentParser(
41 description=' ' + main.__doc__,
42 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
43 argparser.add_argument('--input', '-i', required=True,
44 help='LLVM source file to compile')
David Sehrb19d39c2016-01-13 14:17:37 -080045 argparser.add_argument('--output', '-o', required=False,
46 help='Output file to write')
Karl Schimpf2a5324a2014-09-25 09:37:49 -070047 argparser.add_argument('--insts', required=False,
48 action='store_true',
49 help='Stop after translating to ' +
50 'Subzero instructions')
51 argparser.add_argument('--no-local-syms', required=False,
52 action='store_true',
53 help="Don't keep local symbols in the pexe file")
54 argparser.add_argument('--llvm', required=False,
55 action='store_true',
56 help='Parse pexe into llvm IR first, then ' +
57 'convert to Subzero')
58 argparser.add_argument('--llvm-source', required=False,
59 action='store_true',
60 help='Parse source directly into llvm IR ' +
61 '(without generating a pexe), then ' +
62 'convert to Subzero')
63 argparser.add_argument(
Jim Stichnothfa0cfa52015-02-26 09:42:36 -080064 '--pnacl-sz', required=False, default='./pnacl-sz', metavar='PNACL-SZ',
65 help="Subzero translator 'pnacl-sz'")
Jim Stichnoth0a9e1262015-04-21 09:59:21 -070066 argparser.add_argument('--pnacl-bin-path', required=False,
Jim Stichnoth79fe4902015-12-10 11:08:49 -080067 default=(
68 '{root}/toolchain/linux_x86/pnacl_newlib_raw/bin'
69 ).format(root=FindBaseNaCl()),
70 metavar='PNACL_BIN_PATH',
Jim Stichnoth0a9e1262015-04-21 09:59:21 -070071 help='Path to LLVM & Binutils executables ' +
72 '(e.g. for building PEXE files)')
Jan Vounga2703ae2015-02-19 11:27:44 -080073 argparser.add_argument('--assemble', required=False,
74 action='store_true',
75 help='Assemble the output')
76 argparser.add_argument('--disassemble', required=False,
77 action='store_true',
78 help='Disassemble the assembled output')
79 argparser.add_argument('--dis-flags', required=False,
80 action='append', default=[],
81 help='Add a disassembler flag')
Jan Voungb5447a02015-02-24 16:57:17 -080082 argparser.add_argument('--filetype', default='iasm', dest='filetype',
83 choices=['obj', 'asm', 'iasm'],
David Sehrb19d39c2016-01-13 14:17:37 -080084 help='Output file type. Default %(default)s')
85 argparser.add_argument('--forceasm', required=False, action='store_true',
86 help='Force --filetype=asm')
Jan Voungb2d50842015-05-12 09:53:50 -070087 argparser.add_argument('--target', default='x8632', dest='target',
John Porto56958cb2016-01-14 09:18:18 -080088 choices=['x8632','x8664','arm32','mips32'],
David Sehrb19d39c2016-01-13 14:17:37 -080089 help='Target architecture. Default %(default)s')
Karl Schimpf2a5324a2014-09-25 09:37:49 -070090 argparser.add_argument('--echo-cmd', required=False,
91 action='store_true',
92 help='Trace command that generates ICE instructions')
Karl Schimpf6c17dd82015-06-30 10:25:27 -070093 argparser.add_argument('--tbc', required=False, action='store_true',
94 help='Input is textual bitcode (not .ll)')
95 argparser.add_argument('--expect-fail', required=False, action='store_true',
96 help='Negate success of run by using LLVM not')
Karl Schimpfe8457a22016-03-31 10:20:23 -070097 argparser.add_argument('--allow-pnacl-reader-error-recovery',
98 action='store_true',
99 help='Continue parsing after first error')
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700100 argparser.add_argument('--args', '-a', nargs=argparse.REMAINDER,
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800101 default=[],
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800102 help='Remaining arguments are passed to pnacl-sz')
John Porto52b51572015-12-05 14:16:25 -0800103 argparser.add_argument('--sandbox', required=False, action='store_true',
David Sehrb19d39c2016-01-13 14:17:37 -0800104 help='Sandboxes the generated code')
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700105
106 args = argparser.parse_args()
Jim Stichnoth0a9e1262015-04-21 09:59:21 -0700107 pnacl_bin_path = args.pnacl_bin_path
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700108 llfile = args.input
109
110 if args.llvm and args.llvm_source:
111 raise RuntimeError("Can't specify both '--llvm' and '--llvm-source'")
112
113 if args.llvm_source and args.no_local_syms:
114 raise RuntimeError("Can't specify both '--llvm-source' and " +
115 "'--no-local-syms'")
116
Karl Schimpf6c17dd82015-06-30 10:25:27 -0700117 if args.llvm_source and args.tbc:
118 raise RuntimeError("Can't specify both '--tbc' and '--llvm-source'")
119
120 if args.llvm and args.tbc:
121 raise RuntimeError("Can't specify both '--tbc' and '--llvm'")
122
David Sehrb19d39c2016-01-13 14:17:37 -0800123 if args.forceasm:
Karl Schimpfe8457a22016-03-31 10:20:23 -0700124 if args.expect_fail:
125 args.forceasm = False
126 elif args.filetype == 'asm':
David Sehrb19d39c2016-01-13 14:17:37 -0800127 pass
128 elif args.filetype == 'iasm':
129 # TODO(sehr) implement forceasm for iasm.
130 pass
131 elif args.filetype == 'obj':
132 args.filetype = 'asm'
133 args.assemble = True
134
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700135 cmd = []
Karl Schimpf6c17dd82015-06-30 10:25:27 -0700136 if args.tbc:
137 cmd = [os.path.join(pnacl_bin_path, 'pnacl-bcfuzz'), llfile,
138 '-bitcode-as-text', '-output', '-', '|']
139 elif not args.llvm_source:
Jim Stichnoth0a9e1262015-04-21 09:59:21 -0700140 cmd = [os.path.join(pnacl_bin_path, 'llvm-as'), llfile, '-o', '-', '|',
141 os.path.join(pnacl_bin_path, 'pnacl-freeze')]
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700142 if not args.no_local_syms:
143 cmd += ['--allow-local-symbol-tables']
144 cmd += ['|']
Karl Schimpf6c17dd82015-06-30 10:25:27 -0700145 if args.expect_fail:
146 cmd += [os.path.join(pnacl_bin_path, 'not')]
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800147 cmd += [args.pnacl_sz]
Jan Voungb2d50842015-05-12 09:53:50 -0700148 cmd += ['--target', args.target]
John Porto52b51572015-12-05 14:16:25 -0800149 if args.sandbox:
150 cmd += ['-sandbox']
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700151 if args.insts:
Jim Stichnothbbca7542015-02-11 16:08:31 -0800152 # If the tests are based on '-verbose inst' output, force
153 # single-threaded translation because dump output does not get
154 # reassembled into order.
Jim Stichnothb6dcf3c2016-02-29 09:34:01 -0800155 cmd += ['-verbose', 'inst,global_init', '-notranslate', '-threads=0']
Karl Schimpfe8457a22016-03-31 10:20:23 -0700156 elif args.allow_pnacl_reader_error_recovery:
157 cmd += ['-allow-pnacl-reader-error-recovery', '-threads=0']
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700158 if not args.llvm_source:
159 cmd += ['--bitcode-format=pnacl']
160 if not args.no_local_syms:
161 cmd += ['--allow-local-symbol-tables']
Karl Schimpfab06df32014-10-29 14:58:25 -0700162 if args.llvm or args.llvm_source:
163 cmd += ['--build-on-read=0']
164 else:
165 cmd += ['--build-on-read=1']
Jan Voungb5447a02015-02-24 16:57:17 -0800166 cmd += ['--filetype=' + args.filetype]
Jim Stichnoth54cf1a22016-08-08 14:15:00 -0700167 cmd += ['--emit-revision=0']
David Sehrb19d39c2016-01-13 14:17:37 -0800168 script_name = os.path.basename(sys.argv[0])
169 for _, arg in enumerate(args.args):
170 # Redirecting the output file needs to be done through the script
171 # because forceasm may introduce a new temporary file between pnacl-sz
172 # and llvm-mc. Similar issues could occur when setting filetype, target,
173 # or sandbox through --args. Filter and report an error.
174 if re.search('^-?-(o|output|filetype|target|sandbox)(=.+)?$', arg):
175 preferred_option = '--output' if re.search('^-?-o(=.+)?$', arg) else arg
176 print 'Option should be set using:'
177 print ' %s ... %s ... --args' % (script_name, preferred_option)
178 print 'rather than:'
179 print ' %s ... --args %s ...' % (script_name, arg)
180 exit(1)
181 asm_temp = None
182 output_file_name = None
183 keep_output_file = False
184 if args.output:
185 output_file_name = args.output
186 keep_output_file = True
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800187 cmd += args.args
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700188 if args.llvm_source:
189 cmd += [llfile]
Jan Vounga2703ae2015-02-19 11:27:44 -0800190 if args.assemble or args.disassemble:
David Sehrb19d39c2016-01-13 14:17:37 -0800191 if not output_file_name:
192 # On windows we may need to close the file first before it can be
193 # re-opened by the other tools, so don't do delete-on-close,
194 # and instead manually delete.
195 asm_temp = tempfile.NamedTemporaryFile(delete=False)
196 asm_temp.close()
197 output_file_name = asm_temp.name
Jan Voungb5447a02015-02-24 16:57:17 -0800198 if args.assemble and args.filetype != 'obj':
Jan Voungb2d50842015-05-12 09:53:50 -0700199 cmd += (['|', os.path.join(pnacl_bin_path, 'llvm-mc')] +
John Porto52b51572015-12-05 14:16:25 -0800200 TargetAssemblerFlags(args.target, args.sandbox) +
David Sehrb19d39c2016-01-13 14:17:37 -0800201 ['-filetype=obj', '-o', output_file_name])
202 elif output_file_name:
203 cmd += ['-o', output_file_name]
Jan Vounga2703ae2015-02-19 11:27:44 -0800204 if args.disassemble:
Srdjan Obucina8fbddc62016-09-15 17:26:40 -0700205 # Show wide instruction encodings, diassemble, show relocs and
206 # dissasemble zeros.
Sean Klein8a4675c2016-03-09 10:29:54 -0800207 cmd += (['&&', os.path.join(pnacl_bin_path, GetObjdumpCmd())] +
Jan Vounga2703ae2015-02-19 11:27:44 -0800208 args.dis_flags +
Srdjan Obucina8fbddc62016-09-15 17:26:40 -0700209 ['-w', '-d', '-r', '-z'] + TargetDisassemblerFlags(args.target) +
David Sehrb19d39c2016-01-13 14:17:37 -0800210 [output_file_name])
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700211
212 stdout_result = shellcmd(cmd, echo=args.echo_cmd)
213 if not args.echo_cmd:
214 sys.stdout.write(stdout_result)
David Sehrb19d39c2016-01-13 14:17:37 -0800215 if asm_temp and not keep_output_file:
216 os.remove(output_file_name)
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700217
218if __name__ == '__main__':
219 main()