|
34 | 34 | # This is the ELF section name inserted into binaries
|
35 | 35 | elfSectionName='.llvm_bc'
|
36 | 36 |
|
| 37 | +# These are the MACH_O segment and section name |
| 38 | +darwinSegmentName='__LLVM' |
| 39 | +darwinSectionName='__llvm_bc' |
| 40 | + |
| 41 | + |
37 | 42 | # Internal logger
|
38 | 43 | _logger = logging.getLogger(__name__)
|
39 | 44 |
|
@@ -182,6 +187,24 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
|
182 | 187 | '-static' : (0, ArgumentListFilter.linkUnaryCallback),
|
183 | 188 | '-nostdlib' : (0, ArgumentListFilter.linkUnaryCallback),
|
184 | 189 | '-nodefaultlibs' : (0, ArgumentListFilter.linkUnaryCallback),
|
| 190 | + # darwin flags |
| 191 | + '-dynamiclib' : (0, ArgumentListFilter.linkUnaryCallback), |
| 192 | + '-current_version' : (1, ArgumentListFilter.linkBinaryCallback), |
| 193 | + '-compatibility_version' : (1, ArgumentListFilter.linkBinaryCallback), |
| 194 | + |
| 195 | + # bd: need to warn the darwin user that these flags will rain on their parade |
| 196 | + # (the Darwin ld is a bit single minded) |
| 197 | + # |
| 198 | + # 1) compilation with -fvisibility=hidden causes trouble when we try to |
| 199 | + # attach bitcode filenames to an object file. The global symbols in object |
| 200 | + # files get turned into local symbols when we invoke 'ld -r' |
| 201 | + # |
| 202 | + # 2) all stripping commands (e.g., -dead_strip) remove the __LLVM segment after |
| 203 | + # linking |
| 204 | + # |
| 205 | + '-fvisibility=hidden' : (0, ArgumentListFilter.darwinWarningCompileUnaryCallback), |
| 206 | + '-Wl,-dead_strip' : (0, ArgumentListFilter.darwinWarningLinkUnaryCallback), |
| 207 | + |
185 | 208 | }
|
186 | 209 |
|
187 | 210 | #
|
@@ -310,6 +333,20 @@ def linkUnaryCallback(self, flag):
|
310 | 333 | def compileUnaryCallback(self, flag):
|
311 | 334 | self.compileArgs.append(flag)
|
312 | 335 |
|
| 336 | + def darwinWarningCompileUnaryCallback(self, flag): |
| 337 | + if sys.platform.startswith('darwin'): |
| 338 | + _logger.warning('The flag "{0}" cannot be used with this tool'.format(flag)) |
| 339 | + sys.exit(1) |
| 340 | + else: |
| 341 | + self.compileArgs.append(flag) |
| 342 | + |
| 343 | + def darwinWarningLinkUnaryCallback(self, flag): |
| 344 | + if sys.platform.startswith('darwin'): |
| 345 | + _logger.warning('The flag "{0}" cannot be used with this tool'.format(flag)) |
| 346 | + sys.exit(1) |
| 347 | + else: |
| 348 | + self.linkArgs.append(flag) |
| 349 | + |
313 | 350 | def defaultBinaryCallback(self, flag, arg):
|
314 | 351 | _logger.warning('Ignoring compiler arg pair: "{0} {1}"'.format(flag, arg))
|
315 | 352 |
|
@@ -395,19 +432,32 @@ def getFileType(cls, fileName):
|
395 | 432 | output = fileP.communicate()[0]
|
396 | 433 | output = output.decode()
|
397 | 434 | if 'ELF' in output and 'executable' in output:
|
398 |
| - return cls.EXECUTABLE |
| 435 | + return cls.ELF_EXECUTABLE |
| 436 | + if 'Mach-O' in output and 'executable' in output: |
| 437 | + return cls.MACH_EXECUTABLE |
399 | 438 | elif 'ELF' in output and 'shared' in output:
|
400 |
| - return cls.SHARED |
| 439 | + return cls.ELF_SHARED |
| 440 | + elif 'Mach-O' in output and 'dynamically linked shared' in output: |
| 441 | + return cls.MACH_SHARED |
401 | 442 | elif 'current ar archive' in output:
|
402 | 443 | return cls.ARCHIVE
|
403 | 444 | elif 'ELF' in output and 'relocatable' in output:
|
404 |
| - return cls.OBJECT |
| 445 | + return cls.ELF_OBJECT |
| 446 | + elif 'Mach-O' in output and 'object' in output: |
| 447 | + return cls.MACH_OBJECT |
405 | 448 | else:
|
406 | 449 | return cls.UNKNOWN
|
407 | 450 |
|
408 | 451 | @classmethod
|
409 | 452 | def init(cls):
|
410 |
| - for (index, name) in enumerate(('UNKNOWN', 'EXECUTABLE', 'OBJECT', 'ARCHIVE', 'SHARED')): |
| 453 | + for (index, name) in enumerate(('UNKNOWN', |
| 454 | + 'ELF_EXECUTABLE', |
| 455 | + 'ELF_OBJECT', |
| 456 | + 'ELF_SHARED', |
| 457 | + 'MACH_EXECUTABLE', |
| 458 | + 'MACH_OBJECT', |
| 459 | + 'MACH_SHARED', |
| 460 | + 'ARCHIVE')): |
411 | 461 | setattr(cls, name, index)
|
412 | 462 | cls.revMap[index] = name
|
413 | 463 |
|
@@ -437,8 +487,12 @@ def attachBitcodePathToObject(bcPath, outFileName):
|
437 | 487 | os.fsync(f.fileno())
|
438 | 488 | f.close()
|
439 | 489 |
|
440 |
| - # Now write our .llvm_bc section |
441 |
| - objcopyCmd = ['objcopy', '--add-section', '{0}={1}'.format(elfSectionName, f.name), outFileName] |
| 490 | + |
| 491 | + # Now write our bitcode section |
| 492 | + if (sys.platform.startswith('darwin')): |
| 493 | + objcopyCmd = ['ld', '-r', outFileName, '-sectcreate', darwinSegmentName, darwinSectionName, f.name, '-o', outFileName] |
| 494 | + else: |
| 495 | + objcopyCmd = ['objcopy', '--add-section', '{0}={1}'.format(elfSectionName, f.name), outFileName] |
442 | 496 | orc = 0
|
443 | 497 |
|
444 | 498 | try:
|
@@ -600,7 +654,7 @@ def buildAndAttachBitcode(builder):
|
600 | 654 | # "... -c -o foo.o" or even "... -c -o foo.So" which is OK, but we could also have
|
601 | 655 | # "... -c -o crazy-assed.objectfile" which we wouldn't get right (yet)
|
602 | 656 | # so we need to be careful with the objFile and bcFile
|
603 |
| - # maybe python-magic is in out future ... |
| 657 | + # maybe python-magic is in our future ... |
604 | 658 | srcFile = af.inputFiles[0]
|
605 | 659 | (objFile, bcFile) = af.getArtifactNames(srcFile, hidden)
|
606 | 660 | if af.outputFilename is not None:
|
|
0 commit comments