Skip to content

Commit be9297b

Browse files
authored
Merge pull request travitch#78 from SRI-CSL/master
SRI fork updates
2 parents 37ec6ab + 7cfcb69 commit be9297b

File tree

10 files changed

+130
-30
lines changed

10 files changed

+130
-30
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ Cross-Compilation
242242

243243
To support cross-compilation WLLVM supports the `-target` triple used by clang.
244244
More information can be found
245-
[here.](https://clang.llvm.org/docs/CrossCompilation.html#target-triple).
245+
[here.](https://clang.llvm.org/docs/CrossCompilation.html#target-triple)
246246

247-
Additionall, WLLVM leverages `objcopy` for some of its heavy lifting. When
247+
Additionally, WLLVM leverages `objcopy` for some of its heavy lifting. When
248248
cross-compiling you must ensure to use the appropriate `objcopy` for the target
249249
architecture. The `BINUTILS_TARGET_PREFIX` environment variable can be used to
250250
set the objcopy of choice, for example, `arm-linux-gnueabihf`.

doc/tutorial-ubuntu-16.04.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Extract the bitcode.
7575
-rw-r--r-- 1 vagrant vagrant 1119584 Aug 4 20:02 httpd.bc
7676
```
7777

78-
## Step 6.
78+
## Step 6.
7979

8080
Turn the bitcode into a second executable binary. (optional -- just for fun and sanity checking)
8181

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
description='Whole Program LLVM',
2121
long_description=long_description,
2222
url='https://github.com/SRI-CSL/whole-program-llvm',
23-
author='Ian A. Mason, Tristan Ravitch, Dan Liew, Bruno Dutertre, Benjamin Schubert, Berkeley Churchill, Marko Dimjasevic, Will Dietz, Fabian Mager, Ben Liblit, Andrew Santosa, Tomas Kalibera, Loic Gelle, Joshua Cranmer, Alexander Bakst.',
23+
author='Ian A. Mason, Tristan Ravitch, Dan Liew, Bruno Dutertre, Benjamin Schubert, Berkeley Churchill, Marko Dimjasevic, Will Dietz, Fabian Mager, Ben Liblit, Andrew Santosa, Tomas Kalibera, Loic Gelle, Joshua Cranmer, Alexander Bakst, Miguel Arroyo.',
2424
author_email='iam@csl.sri.com',
2525

2626

test/test_files/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ link_with_archive:: archive
6161
$(CC) main.o libfoo.a -o main.arch
6262

6363
clean:
64-
rm -f *.o main main.arch .*.o.bc .*.o *.bc .*.bc a.out *.s *.i hello *.a *.bca *.dylib *.manifest
64+
rm -f *.o main main.arch .*.o.bc .*.o *.bc .*.bc a.out *.s *.i hello *.a *.bca *.dylib *.manifest *.ll
6565

6666
mystery:
6767
otool -X -s __WLLVM __llvm_bc main > main.otool

wllvm/arglistfilter.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
3939
'-S' : (0, ArgumentListFilter.assembleOnlyCallback),
4040

4141
'--verbose' : (0, ArgumentListFilter.verboseFlagCallback),
42-
'--param' : (1, ArgumentListFilter.defaultBinaryCallback),
42+
'--param' : (1, ArgumentListFilter.compileBinaryCallback),
4343
'-aux-info' : (1, ArgumentListFilter.defaultBinaryCallback),
4444

4545
#iam: presumably the len(inputFiles) == 0 in this case
@@ -103,6 +103,8 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
103103
'-D' : (1, ArgumentListFilter.compileBinaryCallback),
104104
'-U' : (1, ArgumentListFilter.compileBinaryCallback),
105105

106+
'-arch' : (1, ArgumentListFilter.compileBinaryCallback), #iam: openssl
107+
106108
# Dependency generation
107109
'-M' : (0, ArgumentListFilter.dependencyOnlyCallback),
108110
'-MM' : (0, ArgumentListFilter.dependencyOnlyCallback),
@@ -223,7 +225,8 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
223225
# Update: found a fix for problem 1: add flag -keep_private_externs when
224226
# calling ld -r.
225227
#
226-
'-Wl,-dead_strip' : (0, ArgumentListFilter.darwinWarningLinkUnaryCallback),
228+
'-Wl,-dead_strip' : (0, ArgumentListFilter.warningLinkUnaryCallback),
229+
'-dead_strip' : (0, ArgumentListFilter.warningLinkUnaryCallback),
227230
'-Oz' : (0, ArgumentListFilter.compileUnaryCallback), #did not find this in the GCC options.
228231
'-mno-global-merge' : (0, ArgumentListFilter.compileUnaryCallback), #clang (do not merge globals)
229232

@@ -254,6 +257,7 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
254257
r'^-U.+$' : (0, ArgumentListFilter.compileUnaryCallback),
255258
r'^-Wl,.+$' : (0, ArgumentListFilter.linkUnaryCallback),
256259
r'^-W(?!l,).*$' : (0, ArgumentListFilter.compileUnaryCallback),
260+
r'^-fsanitize=.+$' : (0, ArgumentListFilter.compileLinkUnaryCallback),
257261
r'^-f.+$' : (0, ArgumentListFilter.compileUnaryCallback),
258262
r'^-rtlib=.+$' : (0, ArgumentListFilter.linkUnaryCallback),
259263
r'^-std=.+$' : (0, ArgumentListFilter.compileUnaryCallback),
@@ -289,6 +293,8 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
289293
#iam: try and split the args into linker and compiler switches
290294
self.compileArgs = []
291295
self.linkArgs = []
296+
# currently only dead_strip belongs here; but I guess there could be more.
297+
self.forbiddenArgs = []
292298

293299

294300
self.isVerbose = False
@@ -423,13 +429,10 @@ def compileUnaryCallback(self, flag):
423429
_logger.debug('compileUnaryCallback: %s', flag)
424430
self.compileArgs.append(flag)
425431

426-
def darwinWarningLinkUnaryCallback(self, flag):
427-
_logger.debug('darwinWarningLinkUnaryCallback: %s', flag)
428-
if sys.platform.startswith('darwin'):
429-
_logger.warning('The flag "%s" cannot be used with this tool', flag)
430-
sys.exit(1)
431-
else:
432-
self.linkArgs.append(flag)
432+
def warningLinkUnaryCallback(self, flag):
433+
_logger.debug('warningLinkUnaryCallback: %s', flag)
434+
_logger.warning('The flag "%s" cannot be used with this tool; we are ignoring it', flag)
435+
self.forbiddenArgs.append(flag)
433436

434437
def defaultBinaryCallback(self, flag, arg):
435438
_logger.warning('Ignoring compiler arg pair: "%s %s"', flag, arg)

wllvm/as.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def outFileCallback(self, flag, name):
6262
self.outFileName = name
6363

6464
def main():
65-
""" Entry point to the assebler 'as' in the dragonegg realm.
65+
""" Entry point to the assembler 'as' in the dragonegg realm.
6666
"""
6767
argFilter = BCFilter(sys.argv[1:])
6868
# Since this is just the assembler, there should only ever be one file

wllvm/compilers.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def wcompile(mode):
3131
try:
3232
cmd = list(sys.argv)
3333
cmd = cmd[1:]
34+
3435
builder = getBuilder(cmd, mode)
3536

3637
af = builder.getBitcodeArglistFilter()
@@ -188,6 +189,16 @@ def __init__(self, cmd, mode, prefixPath=None):
188189
else:
189190
self.prefixPath = ''
190191

192+
def getCommand(self):
193+
if self.af is not None:
194+
# need to remove things like "-dead_strip"
195+
forbidden = self.af.forbiddenArgs
196+
if forbidden:
197+
for baddy in forbidden:
198+
self.cmd.remove(baddy)
199+
return self.cmd
200+
201+
191202
class ClangBuilder(BuilderBase):
192203
def getBitcodeCompiler(self):
193204
cc = self.getCompiler()
@@ -264,7 +275,7 @@ def getBuilder(cmd, mode):
264275

265276
def buildObject(builder):
266277
objCompiler = builder.getCompiler()
267-
objCompiler.extend(builder.cmd)
278+
objCompiler.extend(builder.getCommand())
268279
proc = Popen(objCompiler)
269280
rc = proc.wait()
270281
_logger.debug('buildObject rc = %d', rc)

wllvm/extraction.py

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
from .filetype import FileType
2222

23-
from .logconfig import logConfig
23+
from .logconfig import logConfig, informUser
24+
2425

2526

2627
_logger = logConfig(__name__)
@@ -236,7 +237,7 @@ def archiveFiles(pArgs, fileNames):
236237
break
237238

238239
if retCode == 0:
239-
_logger.info('Generated LLVM bitcode archive %s', pArgs.outputFile)
240+
informUser('Generated LLVM bitcode archive {0}\n'.format(pArgs.outputFile))
240241
else:
241242
_logger.error('Failed to generate LLVM bitcode archive')
242243

@@ -342,12 +343,86 @@ def extractFile(archive, filename, instance):
342343

343344

344345

346+
def handleArchiveDarwin(pArgs):
347+
originalDir = os.getcwd() # This will be the destination
348+
349+
pArgs.arCmd.append(pArgs.inputFile)
350+
351+
# Make temporary directory to extract objects to
352+
tempDir = ''
353+
bitCodeFiles = []
354+
355+
try:
356+
357+
358+
tempDir = tempfile.mkdtemp(suffix='wllvm')
359+
os.chdir(tempDir)
360+
361+
# Extract objects from archive
362+
try:
363+
arP = Popen(pArgs.arCmd)
364+
except OSError as e:
365+
if e.errno == 2:
366+
errorMsg = 'Your ar does not seem to be easy to find.\n'
367+
else:
368+
errorMsg = 'OS error({0}): {1}'.format(e.errno, e.strerror)
369+
_logger.error(errorMsg)
370+
raise Exception(errorMsg)
371+
372+
arPE = arP.wait()
373+
374+
if arPE != 0:
375+
errorMsg = 'Failed to execute archiver with command {0}'.format(pArgs.arCmd)
376+
_logger.error(errorMsg)
377+
raise Exception(errorMsg)
378+
379+
_logger.debug(2)
380+
381+
# Iterate over objects and examine their bitcode inserts
382+
for (root, _, files) in os.walk(tempDir):
383+
_logger.debug('Exploring "%s"', root)
384+
for f in files:
385+
fPath = os.path.join(root, f)
386+
if FileType.getFileType(fPath) == pArgs.fileType:
387+
388+
# Extract bitcode locations from object
389+
contents = pArgs.extractor(fPath)
390+
391+
for bcFile in contents:
392+
if bcFile != '':
393+
if not os.path.exists(bcFile):
394+
_logger.warning('%s lists bitcode library "%s" but it could not be found', f, bcFile)
395+
else:
396+
bitCodeFiles.append(bcFile)
397+
else:
398+
_logger.info('Ignoring file "%s" in archive', f)
399+
400+
_logger.info('Found the following bitcode file names to build bitcode archive:\n%s', pprint.pformat(bitCodeFiles))
401+
402+
finally:
403+
# Delete the temporary folder
404+
_logger.debug('Deleting temporary folder "%s"', tempDir)
405+
shutil.rmtree(tempDir)
406+
407+
#write the manifest file if asked for
408+
if pArgs.manifestFlag:
409+
manifestFile = '{0}.llvm.manifest'.format(pArgs.inputFile)
410+
with open(manifestFile, 'w') as output:
411+
for f in bitCodeFiles:
412+
output.write('{0}\n'.format(f))
413+
414+
# Build bitcode archive
415+
os.chdir(originalDir)
416+
417+
return buildArchive(pArgs, bitCodeFiles)
418+
419+
345420

346421
#iam: 5/1/2018
347-
def handleArchive(pArgs):
348-
""" handleArchive processes a archive, and creates either a bitcode archive, or a module, depending on the flags used.
422+
def handleArchiveLinux(pArgs):
423+
""" handleArchiveLinux processes a archive, and creates either a bitcode archive, or a module, depending on the flags used.
349424
350-
Archives are strange beasts. handleArchive processes the archive by:
425+
Archives on Linux are strange beasts. handleArchive processes the archive by:
351426
352427
1. first creating a table of contents of the archive, which maps file names (in the archive) to the number of
353428
times a file with that name is stored in the archive.
@@ -430,8 +505,7 @@ def buildArchive(pArgs, bitCodeFiles):
430505
pArgs.outputFile = pArgs.inputFile
431506
pArgs.outputFile += '.' + moduleExtension
432507

433-
_logger.info('Writing output to %s', pArgs.outputFile)
434-
508+
informUser('Writing output to {0}\n'.format(pArgs.outputFile))
435509
return linkFiles(pArgs, bitCodeFiles)
436510

437511
else:
@@ -446,8 +520,7 @@ def buildArchive(pArgs, bitCodeFiles):
446520
else:
447521
pArgs.outputFile = pArgs.inputFile + bcaExtension
448522

449-
_logger.info('Writing output to %s', pArgs.outputFile)
450-
523+
informUser('Writing output to {0}\n'.format(pArgs.outputFile))
451524
return archiveFiles(pArgs, bitCodeFiles)
452525

453526

@@ -567,7 +640,7 @@ def process_file_unix(pArgs):
567640
_logger.info('Generating LLVM Bitcode module')
568641
retval = handleExecutable(pArgs)
569642
elif ft == FileType.ARCHIVE:
570-
retval = handleArchive(pArgs)
643+
retval = handleArchiveLinux(pArgs)
571644
elif ft == FileType.THIN_ARCHIVE:
572645
retval = handleThinArchive(pArgs)
573646
else:
@@ -589,7 +662,10 @@ def process_file_darwin(pArgs):
589662
_logger.info('Generating LLVM Bitcode module')
590663
retval = handleExecutable(pArgs)
591664
elif ft == FileType.ARCHIVE:
592-
retval = handleArchive(pArgs)
665+
_logger.info('Handling archive')
666+
retval = handleArchiveDarwin(pArgs)
667+
668+
593669
else:
594670
_logger.error('File "%s" of type %s cannot be used', pArgs.inputFile, FileType.revMap[ft])
595671
return retval

wllvm/logconfig.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,7 @@ def loggingConfiguration():
5050
destination = os.getenv(_loggingDestination)
5151
level = os.getenv(_loggingEnvLevel_new)
5252
return (destination, level)
53+
54+
55+
def informUser(msg):
56+
sys.stderr.write(msg)

wllvm/version.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,17 @@
6060
6161
1.1.5 - 3/14/2018 fixes suggested by Alexander Bakst
6262
63-
1.1.6 - 4/24/2018 fixes suggested by building the Linux kernel and trying to harmonize with gllvm.
63+
1.2.0 - 4/24/2018 fixes suggested by building the Linux kernel and trying to harmonize with gllvm.
6464
4/28/2018 can handle thin archives, can sort bitcode input to llvm-{ar, link} and manifest via the -s switch.
6565
5/1/2018 can handle archives correctly (deal with multiple files with the same name in the archive).
6666
67+
1.2.1 - 5/13/2018 -fsanitize= now recognized as a compile AND link flag (mothers day edition)
68+
69+
1.2.2 - 6/1/2018 lots of minor fixes from building big projects (and their dependencies) like tor
70+
71+
1.2.3 - 4/15/2019 The tax day version. Almost a years worth of tweaks from building large things like the Linux kernel.
72+
6773
"""
6874

69-
wllvm_version = '1.1.6'
70-
wllvm_date = 'May 1st 2018'
75+
wllvm_version = '1.2.3'
76+
wllvm_date = 'April 15 2019'

0 commit comments

Comments
 (0)