Skip to content

Commit 955fac7

Browse files
committed
Fixed the buggy handling of archives. Still need to check that the bca files are correct, but at least now they are created from the same list of bitcode files as in the thin archive case.
1 parent 474a55f commit 955fac7

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

wllvm/extraction.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
293316
def 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

Comments
 (0)