| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/python | |
| 2 # Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 # | |
| 6 # IMPORTANT NOTE: If you make local mods to this file, you must run: | |
| 7 # % tools/llvm/utman.sh driver | |
| 8 # in order for them to take effect in the scons build. This command | |
| 9 # updates the copy in the toolchain/ tree. | |
| 10 # | |
| 11 | |
| 12 from driver_tools import * | |
| 13 | |
| 14 EXTRA_ENV = { | |
| 15 'PIC' : '0', | |
| 16 | |
| 17 # These are temporary. Since we don't have | |
| 18 # DT_NEEDED metadata in bitcode yet, it must be provided | |
| 19 # on the command-line. | |
| 20 'EXTRA_LD_FLAGS': '', | |
| 21 | |
| 22 # If translating a .pexe which was linked statically against | |
| 23 # glibc, then you must do pnacl-translate -static. This will | |
| 24 # be removed once we can detect .pexe type. | |
| 25 'STATIC' : '0', | |
| 26 | |
| 27 'INPUTS' : '', | |
| 28 'OUTPUT' : '', | |
| 29 'OUTPUT_TYPE' : '', | |
| 30 'LLC' : '${SANDBOXED ? ${LLC_SB} : ${LLVM_LLC}}', | |
| 31 | |
| 32 'TRIPLE' : '${TRIPLE_%ARCH%}', | |
| 33 'TRIPLE_ARM' : 'armv7a-none-nacl-gnueabi', | |
| 34 'TRIPLE_X8632': 'i686-none-nacl-gnu', | |
| 35 'TRIPLE_X8664': 'x86_64-none-nacl-gnu', | |
| 36 | |
| 37 'LLC_FLAGS_COMMON': '-asm-verbose=false ' + | |
| 38 '-tail-merge-threshold=50 ' + | |
| 39 '${PIC ? -relocation-model=pic} ' + | |
| 40 '${PIC && ARCH==X8664 && LIBMODE_NEWLIB ? ' + | |
| 41 ' -force-tls-non-pic }', | |
| 42 'LLC_FLAGS_ARM' : | |
| 43 # The following options might come in handy and are left here as comments: | |
| 44 # TODO(robertm): describe their purpose | |
| 45 # '-soft-float -aeabi-calls -sfi-zero-mask', | |
| 46 # NOTE: we need a fairly high fudge factor because of | |
| 47 # some vfp instructions which only have a 9bit offset | |
| 48 ('-arm-reserve-r9 -sfi-disable-cp -arm_static_tls ' + | |
| 49 '-sfi-load -sfi-store -sfi-stack -sfi-branch -sfi-data ' + | |
| 50 '-no-inline-jumptables'), | |
| 51 | |
| 52 'LLC_FLAGS_X8632' : '', | |
| 53 'LLC_FLAGS_X8664' : '', | |
| 54 | |
| 55 # LLC flags which set the target and output type. | |
| 56 # These are handled separately by libLTO. | |
| 57 'LLC_FLAGS_TARGET' : '-march=${LLC_MARCH} -mcpu=${LLC_MCPU_%ARCH%} ' + | |
| 58 '-mtriple=${TRIPLE} -filetype=${filetype}', | |
| 59 'LLC_FLAGS_BASE': '${LLC_FLAGS_COMMON} ${LLC_FLAGS_%ARCH%}', | |
| 60 'LLC_FLAGS' : '${LLC_FLAGS_TARGET} ${LLC_FLAGS_BASE}', | |
| 61 | |
| 62 'LLC_MARCH' : '${LLC_MARCH_%ARCH%}', | |
| 63 'LLC_MARCH_ARM' : 'arm', | |
| 64 'LLC_MARCH_X8632' : 'x86', | |
| 65 'LLC_MARCH_X8664' : 'x86-64', | |
| 66 | |
| 67 'LLC_MCPU' : '${LLC_MCPU_%ARCH%}', | |
| 68 'LLC_MCPU_ARM' : 'cortex-a8', | |
| 69 'LLC_MCPU_X8632' : 'pentium4', | |
| 70 'LLC_MCPU_X8664' : 'core2', | |
| 71 | |
| 72 'RUN_LLC' : '${LLC} ${LLC_FLAGS} ${input} -o ${output}', | |
| 73 } | |
| 74 env.update(EXTRA_ENV) | |
| 75 | |
| 76 | |
| 77 TranslatorPatterns = [ | |
| 78 ( '-o(.+)', "env.set('OUTPUT', pathtools.normalize($0))"), | |
| 79 ( ('-o', '(.+)'), "env.set('OUTPUT', pathtools.normalize($0))"), | |
| 80 | |
| 81 ( '-S', "env.set('OUTPUT_TYPE', 's')"), # Stop at .s | |
| 82 ( '-c', "env.set('OUTPUT_TYPE', 'o')"), # Stop at .o | |
| 83 | |
| 84 # Expose a very limited set of llc flags. Used primarily for | |
| 85 # the shared lib ad-hoc tests, c.f. tests/pnacl_ld_example | |
| 86 ( '(-sfi-.+)', "env.append('LLC_FLAGS', $0)"), | |
| 87 ( '(-mtls-use-call)', "env.append('LLC_FLAGS', $0)"), | |
| 88 | |
| 89 ( '-static', "env.set('STATIC', '1')"), | |
| 90 ( '-fPIC', "env.set('PIC', '1')"), | |
| 91 | |
| 92 ( '(-L.*)', "env.append('EXTRA_LD_FLAGS', $0)"), | |
| 93 ( ('(-L)','(.*)'), "env.append('EXTRA_LD_FLAGS', $0, $1)"), | |
| 94 ( '(-l.*)', "env.append('EXTRA_LD_FLAGS', $0)"), | |
| 95 ( '(-Wl,.*)', "env.append('EXTRA_LD_FLAGS', $0)"), | |
| 96 | |
| 97 ( '(-*)', UnrecognizedOption), | |
| 98 | |
| 99 ( '(.*)', "env.append('INPUTS', pathtools.normalize($0))"), | |
| 100 ] | |
| 101 | |
| 102 | |
| 103 def main(argv): | |
| 104 ParseArgs(argv, TranslatorPatterns) | |
| 105 | |
| 106 GetArch(required = True) | |
| 107 | |
| 108 inputs = env.get('INPUTS') | |
| 109 output = env.getone('OUTPUT') | |
| 110 output_type = env.getone('OUTPUT_TYPE') | |
| 111 | |
| 112 if len(inputs) != 1: | |
| 113 Log.Fatal('Expecting exactly one input file') | |
| 114 | |
| 115 infile = inputs[0] | |
| 116 | |
| 117 if not IsBitcode(infile): | |
| 118 Log.Fatal('%s: File is not bitcode', pathtools.touser(infile)) | |
| 119 | |
| 120 intype = FileType(infile) | |
| 121 if intype not in ('pso', 'po', 'pexe'): | |
| 122 Log.Fatal('Expecting input file to be bitcode (.pexe, .pso, .po, or .bc)') | |
| 123 | |
| 124 if intype == 'pso': | |
| 125 env.set('PIC', '1') | |
| 126 | |
| 127 # Normally, only pso files need to be translated with PIC, but since we | |
| 128 # are linking executables with unresolved symbols, dynamic nexe's | |
| 129 # also need to be PIC to be able to generate the correct relocations. | |
| 130 # BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 | |
| 131 if intype == 'pexe' and env.getbool('LIBMODE_GLIBC'): | |
| 132 env.set('PIC', '1') | |
| 133 env.append('EXTRA_LD_FLAGS', '-Wl,--unresolved-symbols=ignore-all') | |
| 134 | |
| 135 # Read the bitcode metadata to extract library | |
| 136 # dependencies and SOName. | |
| 137 metadata = GetBitcodeMetadata(infile) | |
| 138 for lib in metadata['NeedsLibrary']: | |
| 139 env.append('EXTRA_LD_FLAGS', '-Wl,--pnacl-add-libdep=' + lib) | |
| 140 | |
| 141 if intype == 'pso': | |
| 142 soname = metadata['SOName'] | |
| 143 if soname: | |
| 144 env.append('EXTRA_LD_FLAGS', '-Wl,-soname=' + soname) | |
| 145 | |
| 146 if output_type == '': | |
| 147 DefaultOutputTypes = { | |
| 148 'pso' : 'so', | |
| 149 'pexe': 'nexe', | |
| 150 'po' : 'o', | |
| 151 } | |
| 152 output_type = DefaultOutputTypes[intype] | |
| 153 | |
| 154 if output == '': | |
| 155 output = DefaultOutputName(infile, output_type) | |
| 156 | |
| 157 tng = TempNameGen([infile], output) | |
| 158 chain = DriverChain(infile, output, tng) | |
| 159 SetupChain(chain, output_type) | |
| 160 chain.run() | |
| 161 return 0 | |
| 162 | |
| 163 def SetupChain(chain, output_type): | |
| 164 assert output_type in ('o','s','so','nexe') | |
| 165 | |
| 166 if output_type == 's' or not env.getbool('MC_DIRECT'): | |
| 167 chain.add(RunLLC, 's', filetype='asm') | |
| 168 if output_type == 's': | |
| 169 return | |
| 170 chain.add(RunAS, 'o') | |
| 171 else: | |
| 172 chain.add(RunLLC, 'o', filetype='obj') | |
| 173 | |
| 174 if output_type == 'o': | |
| 175 return | |
| 176 | |
| 177 if output_type == 'so': | |
| 178 chain.add(RunLD, 'so', shared = True) | |
| 179 elif output_type == 'nexe': | |
| 180 chain.add(RunLD, 'nexe', shared = False) | |
| 181 | |
| 182 def RunAS(infile, outfile): | |
| 183 RunDriver('pnacl-as', [infile, '-o', outfile]) | |
| 184 | |
| 185 # For now, we use pnacl-g++ instead of ld, | |
| 186 # because we need to link against native libraries. | |
| 187 def RunLD(infile, outfile, shared): | |
| 188 args = ['--pnacl-native-hack', infile, '-o', outfile] | |
| 189 | |
| 190 if shared: | |
| 191 args += ['-shared'] | |
| 192 elif env.getbool('STATIC'): | |
| 193 args += ['-static'] | |
| 194 | |
| 195 extra_ld_flags = env.get('EXTRA_LD_FLAGS') | |
| 196 RunDriver('pnacl-g++', args + extra_ld_flags) | |
| 197 | |
| 198 | |
| 199 def RunLLC(infile, outfile, filetype): | |
| 200 UseSRPC = env.getbool('SANDBOXED') and env.getbool('SRPC') | |
| 201 # For now, sel_universal doesn't properly support dynamic sb translator | |
| 202 if env.getbool('SANDBOXED') and env.getbool('SB_DYNAMIC'): | |
| 203 CheckTranslatorPrerequisites() | |
| 204 UseSRPC = False | |
| 205 env.push() | |
| 206 env.setmany(input=infile, output=outfile, filetype=filetype) | |
| 207 if UseSRPC: | |
| 208 RunLLCSRPC() | |
| 209 else: | |
| 210 RunWithLog("${RUN_LLC}") | |
| 211 env.pop() | |
| 212 return 0 | |
| 213 | |
| 214 def RunLLCSRPC(): | |
| 215 CheckTranslatorPrerequisites() | |
| 216 infile = env.getone("input") | |
| 217 outfile = env.getone("output") | |
| 218 flags = env.get("LLC_FLAGS") | |
| 219 script = MakeSelUniversalScriptForLLC(infile, outfile, flags) | |
| 220 | |
| 221 RunWithLog('${SEL_UNIVERSAL_PREFIX} ${SEL_UNIVERSAL} ' + | |
| 222 '${SEL_UNIVERSAL_FLAGS} -- ${LLC_SRPC}', | |
| 223 stdin=script, echo_stdout = False, echo_stderr = False) | |
| 224 | |
| 225 def MakeSelUniversalScriptForLLC(infile, outfile, flags): | |
| 226 script = [] | |
| 227 script.append('readonly_file myfile %s' % infile) | |
| 228 for f in flags: | |
| 229 script.append('rpc AddArg s("%s") *' % f) | |
| 230 script.append('rpc Translate h(myfile) * h() i()') | |
| 231 script.append('set_variable out_handle ${result0}') | |
| 232 script.append('set_variable out_size ${result1}') | |
| 233 script.append('map_shmem ${out_handle} addr') | |
| 234 script.append('save_to_file %s ${addr} 0 ${out_size}' % outfile) | |
| 235 script.append('') | |
| 236 return '\n'.join(script) | |
| 237 | |
| 238 if __name__ == "__main__": | |
| 239 DriverMain(main) | |
| OLD | NEW |