@@ -25,19 +25,22 @@ name to __WLLVM).
2525import os
2626import sys
2727import subprocess as sp
28- #from subprocess import *
28+
2929from driver .utils import llvmCompilerPathEnv
3030from driver .popenwrapper import Popen
3131from driver .utils import elfSectionName
3232from driver .utils import darwinSegmentName
3333from driver .utils import darwinSectionName
3434from driver .utils import FileType
3535
36+ import driver .logconfig
37+
3638import logging
3739import pprint
38- import driver .logconfig
3940import tempfile
4041import shutil
42+ import argparse
43+
4144
4245# Python 2 does not have exceptions automatically
4346# imported whereas python 3 does. Handle this
@@ -49,9 +52,6 @@ except NameError:
4952bitCodeArchiveExtension = 'bca'
5053moduleExtension = 'bc'
5154
52- #verbose flag to pass to the external calls
53- verboseFlag = False
54-
5555# Use objdump on the provided binary; parse out the fields
5656# to find the given section. Return the size and offset of
5757# that section (in bytes)
@@ -140,30 +140,30 @@ def extract_section_linux(inputFile):
140140 return contents
141141
142142
143- def linkFiles (outputFile , llvmLinker , fileNames ):
144- linkCmd = [ llvmLinker , '-v' ] if verboseFlag else [ llvmLinker ]
143+ def linkFiles (pArgs , fileNames ):
144+ linkCmd = [ pArgs . llvmLinker , '-v' ] if pArgs . verboseFlag else [ pArgs . llvmLinker ]
145145
146- linkCmd .extend (['-o' , outputFile ])
146+ linkCmd .extend (['-o' , pArgs . outputFile ])
147147
148148 linkCmd .extend ([x for x in fileNames if x != '' ])
149- logging .info ('Writing output to {0}' .format (outputFile ))
149+ logging .info ('Writing output to {0}' .format (pArgs . outputFile ))
150150 try :
151151 linkProc = Popen (linkCmd )
152152 except OSError as e :
153153 if e .errno == 2 :
154- errorMsg = " Your llvm-link doesn't seem to be easy to find.\n Either install it or use the -l llvmLinker option."
154+ errorMsg = ' Your llvm-link does not seem to be easy to find.\n Either install it or use the -l llvmLinker option.'
155155 else :
156- errorMsg = " OS error({0}): {1}" .format (e .errno , e .strerror )
156+ errorMsg = ' OS error({0}): {1}' .format (e .errno , e .strerror )
157157 logging .error (errorMsg )
158158 raise Exception (errorMsg )
159159
160160 else :
161161 exitCode = linkProc .wait ()
162- logging .info ('{0} returned {1}' .format (llvmLinker , str (exitCode )))
162+ logging .info ('{0} returned {1}' .format (pArgs . llvmLinker , str (exitCode )))
163163 return exitCode
164164
165165
166- def archiveFiles (outputFile , llvmArchiver , fileNames ):
166+ def archiveFiles (pArgs , fileNames ):
167167 retCode = 0
168168 # We do not want full paths in the archive so we need to chdir into each
169169 # bitcode's folder. Handle this by calling llvm-ar once for all bitcode
@@ -185,48 +185,47 @@ def archiveFiles(outputFile, llvmArchiver, fileNames):
185185 for (dirname , bcList ) in dirToBCMap .items ():
186186 logging .debug ('Changing directory to "{0}"' .format (dirname ))
187187 os .chdir (dirname )
188- larCmd = [llvmArchiver , 'rs' , outputFile ] + bcList
188+ larCmd = [pArgs . llvmArchiver , 'rs' , pArgs . outputFile ] + bcList
189189 larProc = Popen (larCmd )
190190 retCode = larProc .wait ()
191191 if retCode != 0 :
192192 logging .error ('Failed to execute:\n {0}' .format (pprint .pformat (larCmd )))
193193 break
194194
195195 if retCode == 0 :
196- logging .info ('Generated LLVM bitcode archive {0}' .format (outputFile ))
196+ logging .info ('Generated LLVM bitcode archive {0}' .format (pArgs . outputFile ))
197197 else :
198198 logging .error ('Failed to generate LLVM bitcode archive' )
199199
200200 return retCode
201- pass
202201
203202
204- def handleExecutable (inputFile , outputFile , extractor , llvmLinker , manifestFlag ):
203+ def handleExecutable (pArgs ):
205204
206- fileNames = extractor (inputFile )
205+ fileNames = pArgs . extractor (pArgs . inputFile )
207206
208207 if not fileNames :
209208 return 1
210209
211- if manifestFlag :
212- manifestFile = '{0}.wllvm.manifest' .format (inputFile )
210+ if pArgs . manifestFlag :
211+ manifestFile = '{0}.wllvm.manifest' .format (pArgs . inputFile )
213212 with open (manifestFile , 'w' ) as output :
214213 for f in fileNames :
215214 output .write ('{0}\n ' .format (f ))
216215
217- if outputFile == None :
218- outputFile = inputFile + '.' + moduleExtension
216+ if pArgs .outputFile == None :
217+ pArgs .outputFile = pArgs .inputFile + '.' + moduleExtension
218+
219+ return linkFiles (pArgs , fileNames )
219220
220- return linkFiles (outputFile , llvmLinker , fileNames )
221221
222222
223223
224+ def handleArchive (pArgs ):
224225
225- def handleArchive (inputFile , outputFile , arCmd , fileType , extractor , llvmArchiver , manifestFlag ):
226- inputFile = os .path .abspath (inputFile )
227226 originalDir = os .getcwd () # This will be the destination
228227
229- arCmd .append (inputFile );
228+ pArgs . arCmd .append (pArgs . inputFile )
230229
231230 # Make temporary directory to extract objects to
232231 tempDir = ''
@@ -238,19 +237,19 @@ def handleArchive(inputFile, outputFile, arCmd, fileType, extractor, llvmArchive
238237
239238 # Extract objects from archive
240239 try :
241- arP = Popen (arCmd )
240+ arP = Popen (pArgs . arCmd )
242241 except OSError as e :
243242 if e .errno == 2 :
244- errorMsg = " Your ar doesn't seem to be easy to find.\n "
243+ errorMsg = ' Your ar does not seem to be easy to find.\n '
245244 else :
246- errorMsg = " OS error({0}): {1}" .format (e .errno , e .strerror )
245+ errorMsg = ' OS error({0}): {1}' .format (e .errno , e .strerror )
247246 logging .error (errorMsg )
248247 raise Exception (errorMsg )
249248
250249 arPE = arP .wait ()
251250
252251 if arPE != 0 :
253- errorMsg = 'Failed to execute archiver with command {0}' .format (arCmd )
252+ errorMsg = 'Failed to execute archiver with command {0}' .format (pArgs . arCmd )
254253 logging .error (errorMsg )
255254 raise Exception (errorMsg )
256255
@@ -259,10 +258,10 @@ def handleArchive(inputFile, outputFile, arCmd, fileType, extractor, llvmArchive
259258 logging .debug ('Exploring "{0}"' .format (root ))
260259 for f in files :
261260 fPath = os .path .join (root , f )
262- if FileType .getFileType (fPath ) == fileType :
261+ if FileType .getFileType (fPath ) == pArgs . fileType :
263262
264263 # Extract bitcode locations from object
265- contents = extractor (fPath )
264+ contents = pArgs . extractor (fPath )
266265
267266 for bcFile in contents :
268267 if bcFile != '' :
@@ -282,37 +281,42 @@ def handleArchive(inputFile, outputFile, arCmd, fileType, extractor, llvmArchive
282281 shutil .rmtree (tempDir )
283282
284283 #write the manifest file if asked for
285- if manifestFlag :
286- manifestFile = '{0}.llvm.manifest' .format (inputFile )
284+ if pArgs . manifestFlag :
285+ manifestFile = '{0}.llvm.manifest' .format (pArgs . inputFile )
287286 with open (manifestFile , 'w' ) as output :
288287 for f in bitCodeFiles :
289288 output .write ('{0}\n ' .format (f ))
290289
291290 # Build bitcode archive
292291 os .chdir (originalDir )
293292
294- return buildArchive (inputFile , outputFile , llvmArchiver , bitCodeFiles )
293+ return buildArchive (pArgs , bitCodeFiles )
295294
296- def buildArchive (inputFile , outputFile , llvmArchiver , bitCodeFiles ):
295+ def buildArchive (pArgs , bitCodeFiles ):
297296 # Pick output file path if outputFile not set
298- if outputFile == None :
299- if inputFile .endswith ('.a' ):
297+ if pArgs . outputFile == None :
298+ if pArgs . inputFile .endswith ('.a' ):
300299 # Strip off .a suffix
301- outputFile = inputFile [:- 2 ]
300+ pArgs . outputFile = pArgs . inputFile [:- 2 ]
302301 else :
303- outputFile = inputFile
304- outputFile += '.' + bitCodeArchiveExtension
302+ pArgs .outputFile = pArgs .inputFile
303+ pArgs .outputFile += '.' + bitCodeArchiveExtension
304+
305+ logging .info ('Writing output to {0}' .format (pArgs .outputFile ))
306+
307+ return archiveFiles (pArgs , bitCodeFiles )
305308
306- logging .info ('Writing output to {0}' .format (outputFile ))
307309
308- return archiveFiles ( outputFile , llvmArchiver , bitCodeFiles )
310+ class ExtractedArgs :
309311
312+ fileType = None
313+
314+ extractor = None
315+
316+ arCmd = None
310317
311318
312319def extract_bc_args (args ):
313- import argparse
314-
315- global verboseFlag
316320
317321 # do we need a path in front?
318322 llvmToolPrefix = os .getenv (llvmCompilerPathEnv )
@@ -332,109 +336,120 @@ def extract_bc_args(args):
332336 llvmArchiver = os .path .join (llvmToolPrefix , llvmArchiverName )
333337
334338 parser = argparse .ArgumentParser (description = __doc__ )
335- parser .add_argument ("wllvm_binary" , help = "A binary produced by wllvm/wllvm++" )
336- parser .add_argument ("--linker" ,"-l" ,
339+ parser .add_argument (dest = 'inputFile' ,
340+ help = 'A binary produced by wllvm/wllvm++' )
341+ parser .add_argument ('--linker' ,'-l' ,
342+ dest = 'llvmLinker' ,
337343 help = 'The LLVM bitcode linker to use. Default "%(default)s"' ,
338344 default = llvmLinker )
339- parser .add_argument ("--archiver" ,"-a" ,
345+ parser .add_argument ('--archiver' ,'-a' ,
346+ dest = 'llvmArchiver' ,
340347 help = 'The LLVM bitcode archiver to use. Default "%(default)s"' ,
341348 default = llvmArchiver )
342- parser .add_argument ("--verbose" ,"-v" ,
349+ parser .add_argument ('--verbose' ,'-v' ,
350+ dest = 'verboseFlag' ,
343351 help = 'Call the external procedures in verbose mode.' ,
344352 action = "store_true" )
345- parser .add_argument ("--manifest" ,"-m" ,
353+ parser .add_argument ('--manifest' , '-m' ,
354+ dest = 'manifestFlag' ,
346355 help = 'Write a manifest file listing all the .bc files used.' ,
347- action = "store_true" )
348- parser .add_argument ("--output" ,"-o" ,
356+ action = 'store_true' )
357+ parser .add_argument ('--bytecode' , '-b' ,
358+ dest = 'bytecodeModuleFlag' ,
359+ help = 'Extract a bytecode module rather than an archive. ' +
360+ 'Only useful when extracting from an archive.' ,
361+ action = 'store_true' )
362+ parser .add_argument ('--output' ,'-o' ,
363+ dest = 'outputFile' ,
349364 help = 'The output file. Defaults to a file in the same directory ' +
350365 'as the input with the same name as the input but with an ' +
351366 'added file extension (.' + moduleExtension + ' for bitcode ' +
352367 'modules and .' + bitCodeArchiveExtension + ' for bitcode archives)' ,
353368 default = None )
354- parsedArgs = parser .parse_args ()
369+ pArgs = parser .parse_args (namespace = ExtractedArgs () )
355370
356- inputFile = parsedArgs .wllvm_binary
357- llvmLinker = parsedArgs .linker
358- llvmArchiver = parsedArgs .archiver
359- verboseFlag = parsedArgs .verbose
360- manifestFlag = parsedArgs .manifest
361371
362372 # Check file exists
363- if not os .path .exists (inputFile ):
364- logging .error ('File "{0}" does not exist.' .format (inputFile ))
365- return (False , inputFile , '' , llvmLinker , llvmArchiver , manifestFlag )
373+ if not os .path .exists (pArgs .inputFile ):
374+ logging .error ('File "{0}" does not exist.' .format (pArgs .inputFile ))
375+ return (False , None )
376+
377+ pArgs .inputFile = os .path .abspath (pArgs .inputFile )
366378
379+
367380 # Check output destitionation if set
368- outputFile = parsedArgs . output
381+ outputFile = pArgs . outputFile
369382 if outputFile != None :
370383 # Get Absolute output path
371384 outputFile = os .path .abspath (outputFile )
372385 if not os .path .exists (os .path .dirname (outputFile )):
373- logging .error ('Output directory "{0}" does not exist.' .format (
374- os .path .dirname (outputFile )))
375- return (False , inputFile , '' , llvmLinker , llvmArchiver , manifestFlag )
386+ logging .error ('Output directory "{0}" does not exist.' .format (os .path .dirname (outputFile )))
387+ return (False , None )
376388
377- return ( True , inputFile , outputFile , llvmLinker , llvmArchiver , manifestFlag )
389+ pArgs . output = outputFile
378390
391+ return (True , pArgs )
392+
379393
380394def main (args ):
381395
382- (success , inputFile , outputFile , llvmLinker , llvmArchiver , manifestFlag ) = extract_bc_args (args )
396+ (success , pArgs ) = extract_bc_args (args )
383397
384398 if not success :
385399 return 1
386400
387- if ( sys .platform .startswith ('freebsd' ) or
388- sys .platform .startswith ('linux' ) ):
401+ if ( sys .platform .startswith ('freebsd' ) or sys .platform .startswith ('linux' ) ):
389402
390- process_file_unix (inputFile , outputFile , llvmLinker , llvmArchiver , manifestFlag )
403+ process_file_unix (pArgs )
391404
392405 elif sys .platform .startswith ('darwin' ):
393406
394- process_file_darwin (inputFile , outputFile , llvmLinker , llvmArchiver , manifestFlag )
407+ process_file_darwin (pArgs )
395408
396409 else :
397410 #iam: do we work on anything else?
398411 logging .error ('Unsupported or unrecognized platform: {0}' .format (sys .platform ))
399412 return 1
400413
401414
402- def process_file_unix (inputFile , outputFile , llvmLinker , llvmArchiver , manifestFlag ):
403- ft = FileType .getFileType (inputFile )
415+ def process_file_unix (pArgs ):
416+
417+ ft = FileType .getFileType (pArgs .inputFile )
404418 logging .debug ('Detected file type is {0}' .format (FileType .revMap [ft ]))
405419
406- extractor = extract_section_linux
407- arCmd = [ 'ar' , 'xv' ] if verboseFlag else [ 'ar' , 'x' ]
408- ofileType = FileType .ELF_OBJECT
420+ pArgs . arCmd = [ 'ar' , 'xv' ] if pArgs . verboseFlag else [ 'ar' , 'x' ]
421+ pArgs . extractor = extract_section_linux
422+ pArgs . fileType = FileType .ELF_OBJECT
409423
410424 if ft == FileType .ELF_EXECUTABLE or ft == FileType .ELF_SHARED or ft == FileType .ELF_OBJECT :
411425 logging .info ('Generating LLVM Bitcode module' )
412- return handleExecutable (inputFile , outputFile , extractor , llvmLinker , manifestFlag )
426+ return handleExecutable (pArgs )
413427 elif ft == FileType .ARCHIVE :
414428 logging .info ('Generating LLVM Bitcode archive' )
415- return handleArchive (inputFile , outputFile , arCmd , ofileType , extractor , llvmArchiver , manifestFlag )
429+ return handleArchive (pArgs )
416430 else :
417- logging .error ('File "{0}" of type {1} cannot be used' .format (inputFile ,FileType .revMap [ft ]))
431+ logging .error ('File "{0}" of type {1} cannot be used' .format (pArgs . inputFile , FileType .revMap [ft ]))
418432 return 1
419433
420434
421435
422- def process_file_darwin (inputFile , outputFile , llvmLinker , llvmArchiver , manifestFlag ):
423- ft = FileType .getFileType (inputFile )
436+ def process_file_darwin (pArgs ):
437+
438+ ft = FileType .getFileType (pArgs .inputFile )
424439 logging .debug ('Detected file type is {0}' .format (FileType .revMap [ft ]))
425440
426- extractor = extract_section_darwin
427- arCmd = [ 'ar' , '-x' , '-v' ] if verboseFlag else [ 'ar' , '-x' ]
428- ofileType = FileType .MACH_OBJECT
441+ pArgs . arCmd = [ 'ar' , '-x' , '-v' ] if pArgs . verboseFlag else [ 'ar' , '-x' ]
442+ pArgs . extractor = extract_section_darwin
443+ pArgs . fileType = FileType .MACH_OBJECT
429444
430445 if ft == FileType .MACH_EXECUTABLE or ft == FileType .MACH_SHARED or ft == FileType .MACH_OBJECT :
431446 logging .info ('Generating LLVM Bitcode module' )
432- return handleExecutable (inputFile , outputFile , extractor , llvmLinker , manifestFlag )
447+ return handleExecutable (pArgs )
433448 elif ft == FileType .ARCHIVE :
434449 logging .info ('Generating LLVM Bitcode archive' )
435- return handleArchive (inputFile , outputFile , arCmd , ofileType , extractor , llvmArchiver , manifestFlag )
450+ return handleArchive (pArgs )
436451 else :
437- logging .error ('File "{0}" of type {1} cannot be used' .format (inputFile ,FileType .revMap [ft ]))
452+ logging .error ('File "{0}" of type {1} cannot be used' .format (pArgs . inputFile , FileType .revMap [ft ]))
438453 return 1
439454
440455
0 commit comments