blob: eee5b49dac615698e1a53c43d70eb48b6ae88c3d [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'],
Srdjan Obucina623f8ce2016-09-26 20:03:20 -070023 'mips32': ['-triple=%s' % (
24 'mipsel-nacl' if sandboxed else 'mipsel'),
25 '-mcpu=mips32'] }
Jan Voungb2d50842015-05-12 09:53:50 -070026 return flags[target]
27
28
29def TargetDisassemblerFlags(target):
30 flags = { 'x8632': ['-Mintel'],
John Porto56958cb2016-01-14 09:18:18 -080031 'x8664': ['-Mintel'],
Reed Kotlerd00d48d2015-07-08 09:49:07 -070032 'arm32': [],
33 'mips32':[] }
Jan Voungb2d50842015-05-12 09:53:50 -070034 return flags[target]
35
Karl Schimpf2a5324a2014-09-25 09:37:49 -070036def main():
Jim Stichnothfa0cfa52015-02-26 09:42:36 -080037 """Run the pnacl-sz compiler on an llvm file.
Karl Schimpf2a5324a2014-09-25 09:37:49 -070038
39 Takes an llvm input file, freezes it into a pexe file, converts
40 it to a Subzero program, and finally compiles it.
41 """
42 argparser = argparse.ArgumentParser(
43 description=' ' + main.__doc__,
44 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
45 argparser.add_argument('--input', '-i', required=True,
46 help='LLVM source file to compile')
David Sehrb19d39c2016-01-13 14:17:37 -080047 argparser.add_argument('--output', '-o', required=False,
48 help='Output file to write')
Karl Schimpf2a5324a2014-09-25 09:37:49 -070049 argparser.add_argument('--insts', required=False,
50 action='store_true',
51 help='Stop after translating to ' +
52 'Subzero instructions')
53 argparser.add_argument('--no-local-syms', required=False,
54 action='store_true',
55 help="Don't keep local symbols in the pexe file")
56 argparser.add_argument('--llvm', required=False,
57 action='store_true',
58 help='Parse pexe into llvm IR first, then ' +
59 'convert to Subzero')
60 argparser.add_argument('--llvm-source', required=False,
61 action='store_true',
62 help='Parse source directly into llvm IR ' +
63 '(without generating a pexe), then ' +
64 'convert to Subzero')
65 argparser.add_argument(
Jim Stichnothfa0cfa52015-02-26 09:42:36 -080066 '--pnacl-sz', required=False, default='./pnacl-sz', metavar='PNACL-SZ',
67 help="Subzero translator 'pnacl-sz'")
Jim Stichnoth0a9e1262015-04-21 09:59:21 -070068 argparser.add_argument('--pnacl-bin-path', required=False,
Jim Stichnoth79fe4902015-12-10 11:08:49 -080069 default=(
70 '{root}/toolchain/linux_x86/pnacl_newlib_raw/bin'
71 ).format(root=FindBaseNaCl()),
72 metavar='PNACL_BIN_PATH',
Jim Stichnoth0a9e1262015-04-21 09:59:21 -070073 help='Path to LLVM & Binutils executables ' +
74 '(e.g. for building PEXE files)')
Jan Vounga2703ae2015-02-19 11:27:44 -080075 argparser.add_argument('--assemble', required=False,
76 action='store_true',
77 help='Assemble the output')
78 argparser.add_argument('--disassemble', required=False,
79 action='store_true',
80 help='Disassemble the assembled output')
81 argparser.add_argument('--dis-flags', required=False,
82 action='append', default=[],
83 help='Add a disassembler flag')
Jan Voungb5447a02015-02-24 16:57:17 -080084 argparser.add_argument('--filetype', default='iasm', dest='filetype',
85 choices=['obj', 'asm', 'iasm'],
David Sehrb19d39c2016-01-13 14:17:37 -080086 help='Output file type. Default %(default)s')
87 argparser.add_argument('--forceasm', required=False, action='store_true',
88 help='Force --filetype=asm')
Jan Voungb2d50842015-05-12 09:53:50 -070089 argparser.add_argument('--target', default='x8632', dest='target',
John Porto56958cb2016-01-14 09:18:18 -080090 choices=['x8632','x8664','arm32','mips32'],
David Sehrb19d39c2016-01-13 14:17:37 -080091 help='Target architecture. Default %(default)s')
Karl Schimpf2a5324a2014-09-25 09:37:49 -070092 argparser.add_argument('--echo-cmd', required=False,
93 action='store_true',
94 help='Trace command that generates ICE instructions')
Karl Schimpf6c17dd82015-06-30 10:25:27 -070095 argparser.add_argument('--tbc', required=False, action='store_true',
96 help='Input is textual bitcode (not .ll)')
97 argparser.add_argument('--expect-fail', required=False, action='store_true',
98 help='Negate success of run by using LLVM not')
Karl Schimpfe8457a22016-03-31 10:20:23 -070099 argparser.add_argument('--allow-pnacl-reader-error-recovery',
100 action='store_true',
101 help='Continue parsing after first error')
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700102 argparser.add_argument('--args', '-a', nargs=argparse.REMAINDER,
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800103 default=[],
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800104 help='Remaining arguments are passed to pnacl-sz')
John Porto52b51572015-12-05 14:16:25 -0800105 argparser.add_argument('--sandbox', required=False, action='store_true',
David Sehrb19d39c2016-01-13 14:17:37 -0800106 help='Sandboxes the generated code')
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700107
108 args = argparser.parse_args()
Jim Stichnoth0a9e1262015-04-21 09:59:21 -0700109 pnacl_bin_path = args.pnacl_bin_path
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700110 llfile = args.input
111
112 if args.llvm and args.llvm_source:
113 raise RuntimeError("Can't specify both '--llvm' and '--llvm-source'")
114
115 if args.llvm_source and args.no_local_syms:
116 raise RuntimeError("Can't specify both '--llvm-source' and " +
117 "'--no-local-syms'")
118
Karl Schimpf6c17dd82015-06-30 10:25:27 -0700119 if args.llvm_source and args.tbc:
120 raise RuntimeError("Can't specify both '--tbc' and '--llvm-source'")
121
122 if args.llvm and args.tbc:
123 raise RuntimeError("Can't specify both '--tbc' and '--llvm'")
124
David Sehrb19d39c2016-01-13 14:17:37 -0800125 if args.forceasm:
Karl Schimpfe8457a22016-03-31 10:20:23 -0700126 if args.expect_fail:
127 args.forceasm = False
128 elif args.filetype == 'asm':
David Sehrb19d39c2016-01-13 14:17:37 -0800129 pass
130 elif args.filetype == 'iasm':
131 # TODO(sehr) implement forceasm for iasm.
132 pass
133 elif args.filetype == 'obj':
134 args.filetype = 'asm'
135 args.assemble = True
136
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700137 cmd = []
Karl Schimpf6c17dd82015-06-30 10:25:27 -0700138 if args.tbc:
139 cmd = [os.path.join(pnacl_bin_path, 'pnacl-bcfuzz'), llfile,
140 '-bitcode-as-text', '-output', '-', '|']
141 elif not args.llvm_source:
Jim Stichnoth0a9e1262015-04-21 09:59:21 -0700142 cmd = [os.path.join(pnacl_bin_path, 'llvm-as'), llfile, '-o', '-', '|',
143 os.path.join(pnacl_bin_path, 'pnacl-freeze')]
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700144 if not args.no_local_syms:
145 cmd += ['--allow-local-symbol-tables']
146 cmd += ['|']
Karl Schimpf6c17dd82015-06-30 10:25:27 -0700147 if args.expect_fail:
148 cmd += [os.path.join(pnacl_bin_path, 'not')]
Jim Stichnothfa0cfa52015-02-26 09:42:36 -0800149 cmd += [args.pnacl_sz]
Jan Voungb2d50842015-05-12 09:53:50 -0700150 cmd += ['--target', args.target]
John Porto52b51572015-12-05 14:16:25 -0800151 if args.sandbox:
152 cmd += ['-sandbox']
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700153 if args.insts:
Jim Stichnothbbca7542015-02-11 16:08:31 -0800154 # If the tests are based on '-verbose inst' output, force
155 # single-threaded translation because dump output does not get
156 # reassembled into order.
Jim Stichnothb6dcf3c2016-02-29 09:34:01 -0800157 cmd += ['-verbose', 'inst,global_init', '-notranslate', '-threads=0']
Karl Schimpfe8457a22016-03-31 10:20:23 -0700158 elif args.allow_pnacl_reader_error_recovery:
159 cmd += ['-allow-pnacl-reader-error-recovery', '-threads=0']
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700160 if not args.llvm_source:
161 cmd += ['--bitcode-format=pnacl']
162 if not args.no_local_syms:
163 cmd += ['--allow-local-symbol-tables']
Karl Schimpfab06df32014-10-29 14:58:25 -0700164 if args.llvm or args.llvm_source:
165 cmd += ['--build-on-read=0']
166 else:
167 cmd += ['--build-on-read=1']
Jan Voungb5447a02015-02-24 16:57:17 -0800168 cmd += ['--filetype=' + args.filetype]
Jim Stichnoth54cf1a22016-08-08 14:15:00 -0700169 cmd += ['--emit-revision=0']
David Sehrb19d39c2016-01-13 14:17:37 -0800170 script_name = os.path.basename(sys.argv[0])
171 for _, arg in enumerate(args.args):
172 # Redirecting the output file needs to be done through the script
173 # because forceasm may introduce a new temporary file between pnacl-sz
174 # and llvm-mc. Similar issues could occur when setting filetype, target,
175 # or sandbox through --args. Filter and report an error.
176 if re.search('^-?-(o|output|filetype|target|sandbox)(=.+)?$', arg):
177 preferred_option = '--output' if re.search('^-?-o(=.+)?$', arg) else arg
178 print 'Option should be set using:'
179 print ' %s ... %s ... --args' % (script_name, preferred_option)
180 print 'rather than:'
181 print ' %s ... --args %s ...' % (script_name, arg)
182 exit(1)
183 asm_temp = None
184 output_file_name = None
185 keep_output_file = False
186 if args.output:
187 output_file_name = args.output
188 keep_output_file = True
Karl Schimpf6fcbddd2014-11-06 09:49:24 -0800189 cmd += args.args
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700190 if args.llvm_source:
191 cmd += [llfile]
Jan Vounga2703ae2015-02-19 11:27:44 -0800192 if args.assemble or args.disassemble:
David Sehrb19d39c2016-01-13 14:17:37 -0800193 if not output_file_name:
194 # On windows we may need to close the file first before it can be
195 # re-opened by the other tools, so don't do delete-on-close,
196 # and instead manually delete.
197 asm_temp = tempfile.NamedTemporaryFile(delete=False)
198 asm_temp.close()
199 output_file_name = asm_temp.name
Jan Voungb5447a02015-02-24 16:57:17 -0800200 if args.assemble and args.filetype != 'obj':
Jan Voungb2d50842015-05-12 09:53:50 -0700201 cmd += (['|', os.path.join(pnacl_bin_path, 'llvm-mc')] +
John Porto52b51572015-12-05 14:16:25 -0800202 TargetAssemblerFlags(args.target, args.sandbox) +
David Sehrb19d39c2016-01-13 14:17:37 -0800203 ['-filetype=obj', '-o', output_file_name])
204 elif output_file_name:
205 cmd += ['-o', output_file_name]
Jan Vounga2703ae2015-02-19 11:27:44 -0800206 if args.disassemble:
Srdjan Obucina8fbddc62016-09-15 17:26:40 -0700207 # Show wide instruction encodings, diassemble, show relocs and
208 # dissasemble zeros.
Srdjan Obucina623f8ce2016-09-26 20:03:20 -0700209 cmd += (['&&', os.path.join(pnacl_bin_path, GetObjdumpCmd(args.target))] +
Jan Vounga2703ae2015-02-19 11:27:44 -0800210 args.dis_flags +
Srdjan Obucina8fbddc62016-09-15 17:26:40 -0700211 ['-w', '-d', '-r', '-z'] + TargetDisassemblerFlags(args.target) +
David Sehrb19d39c2016-01-13 14:17:37 -0800212 [output_file_name])
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700213
214 stdout_result = shellcmd(cmd, echo=args.echo_cmd)
215 if not args.echo_cmd:
216 sys.stdout.write(stdout_result)
David Sehrb19d39c2016-01-13 14:17:37 -0800217 if asm_temp and not keep_output_file:
218 os.remove(output_file_name)
Karl Schimpf2a5324a2014-09-25 09:37:49 -0700219
220if __name__ == '__main__':
221 main()