@@ -289,8 +289,106 @@ def handleThinArchive(pArgs):
289289
290290 return buildArchive (pArgs , bcFiles )
291291
292+ #iam: do we want to preserve the order in the archive? if so we need to return both the list and the dict.
293+ def fetchTOC (pArgs , inputFile ):
294+ toc = {}
292295
296+ arCmd = ['ar' , '-t' , inputFile ] #iam: check if this might be os dependent
297+ arProc = Popen (arCmd , stdout = sp .PIPE )
298+
299+ arOutput = arProc .communicate ()[0 ]
300+ if arProc .returncode != 0 :
301+ _logger .error ('ar failed on %s' , inputFile )
302+ return toc
303+
304+ lines = arOutput .splitlines ()
305+
306+ for line in lines :
307+ if line in toc :
308+ toc [line ] += 1
309+ else :
310+ toc [line ] = 1
311+
312+ return toc
313+
314+
315+ #iam: 5/1/2018
293316def handleArchive (pArgs ):
317+ """ handleArchive processes a archive, and creates either a bitcode archive, or a module, depending on the flags used.
318+
319+ Archives are strange beasts. handleArchive processes the archive by:
320+
321+ 1. first creating a table of contents of the archive, which maps file names (in the archive) to the number of
322+ times a file with that name is stored in the archive.
323+
324+ 2. for each OCCURENCE of a file (name and count) it extracts the section from the object file, and adds the
325+ bitcode paths to the bitcode list.
326+
327+ 3. it then either links all these bitcode files together using llvm-link, or else is creates a bitcode
328+ archive using llvm-ar
329+
330+ """
331+
332+ inputFile = pArgs .inputFile
333+
334+ originalDir = os .getcwd () # We want to end up back where we started.
335+
336+ toc = fetchTOC (pArgs , inputFile )
337+
338+ if not toc :
339+ _logger .warning ('No files found, so nothing to be done.' )
340+ return
341+
342+ bitCodeFiles = []
343+
344+ try :
345+ tempDir = tempfile .mkdtemp (suffix = 'wllvm' )
346+ os .chdir (tempDir )
347+
348+ for filename in toc :
349+ count = toc [filename ]
350+ for i in range (1 , count + 1 ):
351+ arCmd = ['ar' , 'xN' , str (i ), inputFile , filename ] #iam: check if this might be os dependent
352+ try :
353+ arP = Popen (arCmd )
354+ except OSError as e :
355+ errorMsg = 'OS error({0}): {1}' .format (e .errno , e .strerror )
356+ _logger .error (errorMsg )
357+ raise Exception (errorMsg )
358+
359+ arPE = arP .wait ()
360+
361+ if arPE != 0 :
362+ errorMsg = 'Failed to execute archiver with command {0}' .format (arCmd )
363+ _logger .error (errorMsg )
364+ raise Exception (errorMsg )
365+
366+ # Extract bitcode locations from object
367+ contents = pArgs .extractor (filename )
368+ _logger .debug ('From instance {0} of {1} in {2} we extracted\n \t {3}\n ' .format (i , filename , inputFile , contents ))
369+ if contents :
370+ for path in contents :
371+ if path :
372+ bitCodeFiles .append (path )
373+ finally :
374+ # Delete the temporary folder
375+ _logger .debug ('Deleting temporary folder "%s"' , tempDir )
376+ shutil .rmtree (tempDir )
377+
378+ _logger .debug ('From instance {0} we extracted\n \t {1}\n ' .format (inputFile , bitCodeFiles ))
379+
380+ # Build bitcode archive
381+ os .chdir (originalDir )
382+
383+ return buildArchive (pArgs , bitCodeFiles )
384+
385+
386+
387+
388+
389+
390+ #iam: 5/1/2018 (soon to be given the flick from the codebase).
391+ def old_buggy_handleArchive (pArgs ):
294392
295393 originalDir = os .getcwd () # This will be the destination
296394
0 commit comments