1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
   3  * Copyright (c) 2006-2010 Apple Inc. All rights reserved. 
   5  * @APPLE_LICENSE_HEADER_START@ 
   7  * This file contains Original Code and/or Modifications of Original Code 
   8  * as defined in and that are subject to the Apple Public Source License 
   9  * Version 2.0 (the 'License'). You may not use this file except in 
  10  * compliance with the License. Please obtain a copy of the License at 
  11  * http://www.opensource.apple.com/apsl/ and read it before using this 
  14  * The Original Code and all software distributed under the License are 
  15  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  16  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  17  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  18  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  19  * Please see the License for the specific language governing rights and 
  20  * limitations under the License. 
  22  * @APPLE_LICENSE_HEADER_END@ 
  25 #ifndef __LTO_READER_H__ 
  26 #define __LTO_READER_H__ 
  29 #include <sys/param.h> 
  30 #include <sys/fcntl.h> 
  34 #include <mach-o/dyld.h> 
  37 #include <unordered_set> 
  38 #include <unordered_map> 
  40 #include "MachOFileAbstraction.hpp" 
  41 #include "Architectures.hpp" 
  43 #include "macho_relocatable_file.h" 
  46 // #defines are a work around for <rdar://problem/8760268> 
  47 #define __STDC_LIMIT_MACROS 1 
  48 #define __STDC_CONSTANT_MACROS 1 
  49 #include "llvm-c/lto.h" 
  55 // ld64 only tracks non-internal symbols from an llvm bitcode file.   
  56 // We model this by having an InternalAtom which represent all internal functions and data. 
  57 // All non-interal symbols from a bitcode file are represented by an Atom 
  58 // and each Atom has a reference to the InternalAtom.  The InternalAtom 
  59 // also has references to each symbol external to the bitcode file.  
  61 class InternalAtom 
: public ld::Atom
 
  64                                                                                                 InternalAtom(class File
& f
); 
  65         // overrides of ld::Atom 
  66         virtual ld::File
*                                                       file() const            { return &_file
; } 
  67         virtual const char*                                                     name() const            { return "import-atom"; } 
  68         virtual uint64_t                                                        size() const            { return 0; } 
  69         virtual uint64_t                                                        objectAddress() const { return 0; } 
  70         virtual void                                                            copyRawContent(uint8_t buffer
[]) const { } 
  71         virtual void                                                            setScope(Scope
)         { } 
  72         virtual ld::Fixup::iterator                                     
fixupsBegin() const     { return &_undefs
[0]; } 
  73         virtual ld::Fixup::iterator                                     
fixupsEnd()     const   { return &_undefs
[_undefs
.size()]; } 
  75         // for adding references to symbols outside bitcode file 
  76         void                                                                            addReference(const char* nm
) 
  77                                                                                                                                         { _undefs
.push_back(ld::Fixup(0, ld::Fixup::k1of1
,  
  78                                                                                                                                                                 ld::Fixup::kindNone
, false, strdup(nm
))); } 
  82         mutable std::vector
<ld::Fixup
>                          _undefs
; 
  89 class File 
: public ld::relocatable::File
 
  92                                                                                         File(const char* path
, time_t mTime
, ld::File::Ordinal ordinal
,  
  93                                                                                                          const uint8_t* content
, uint32_t contentLength
, cpu_type_t arch
); 
  96         // overrides of ld::File 
  97         virtual bool                                                                            forEachAtom(ld::File::AtomHandler
&) const; 
  98         virtual bool                                                                            justInTimeforEachAtom(const char* name
, ld::File::AtomHandler
&) const  
 100         virtual uint32_t                                                                        cpuSubType() const                      { return _cpuSubType
; } 
 102         // overrides of ld::relocatable::File  
 103         virtual DebugInfoKind                                                           
debugInfo()     const                   { return _debugInfo
; } 
 104         virtual const char*                                                                     debugInfoPath() const           { return _debugInfoPath
; } 
 105         virtual time_t                                                                          debugInfoModificationTime() const  
 106                                                                                                                                                                         { return _debugInfoModTime
; } 
 107         virtual const std::vector
<ld::relocatable::File::Stab
>* stabs() const                   { return NULL
; } 
 108         virtual bool                                                                            canScatterAtoms() const         { return true; } 
 109         virtual LinkerOptionsList
*                                                      linkerOptions() const           { return NULL
; } 
 113         lto_module_t                                                                            
module()                                        { return _module
; } 
 114         class InternalAtom
&                                                                     internalAtom()                          { return _internalAtom
; } 
 115         void                                                                                            setDebugInfo(ld::relocatable::File::DebugInfoKind k
, 
 116                                                                                                                                         const char* pth
, time_t modTime
, uint32_t subtype
) 
 118                                                                                                                                                                                 _debugInfoPath 
= pth
;  
 119                                                                                                                                                                                 _debugInfoModTime 
= modTime
;  
 120                                                                                                                                                                                 _cpuSubType 
= subtype
;} 
 122     static bool                                         sSupportsLocalContext
; 
 123     static bool                                         sHasTriedLocalContext
; 
 124     bool                                                mergeIntoGenerator(lto_code_gen_t generator
, bool useSetModule
); 
 127         friend class InternalAtom
; 
 130         cpu_type_t                                                              _architecture
; 
 131         class InternalAtom                                              _internalAtom
; 
 132         class Atom
*                                                             _atomArray
; 
 133         uint32_t                                                                _atomArrayCount
; 
 134         lto_module_t                                                    _module
; 
 136         const uint8_t*                          _content
; 
 137         uint32_t                                _contentLength
; 
 138         const char*                                                             _debugInfoPath
; 
 139         time_t                                                                  _debugInfoModTime
; 
 140         ld::Section                                                             _section
; 
 141         ld::Fixup                                                               _fixupToInternal
; 
 142         ld::relocatable::File::DebugInfoKind    _debugInfo
;  
 143         uint32_t                                                                _cpuSubType
; 
 147 // Atom acts as a proxy Atom for the symbols that are exported by LLVM bitcode file. Initially, 
 148 // Reader creates Atoms to allow linker proceed with usual symbol resolution phase. After 
 149 // optimization is performed, real Atoms are created for these symobls. However these real Atoms 
 150 // are not inserted into global symbol table. Atom holds real Atom and forwards appropriate 
 151 // methods to real atom. 
 153 class Atom 
: public ld::Atom
 
 156                                                                                 Atom(File
& f
, const char* name
, ld::Atom::Scope s
,  
 157                                                                                                 ld::Atom::Definition d
, ld::Atom::Combine c
, ld::Atom::Alignment a
, bool ah
); 
 159         // overrides of ld::Atom 
 160         virtual ld::File
*                                       file() const            { return &_file
; } 
 161         virtual const char*                                     translationUnitSource() const 
 162                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->translationUnitSource() : NULL
); } 
 163         virtual const char*                                     name() const            { return _name
; } 
 164         virtual uint64_t                                        size() const            { return (_compiledAtom 
? _compiledAtom
->size() : 0); } 
 165         virtual uint64_t                                        objectAddress() const { return (_compiledAtom 
? _compiledAtom
->objectAddress() : 0); } 
 166         virtual void                                            copyRawContent(uint8_t buffer
[]) const  
 167                                                                                                                         { if (_compiledAtom
) _compiledAtom
->copyRawContent(buffer
); } 
 168         virtual const uint8_t*                          rawContentPointer() const  
 169                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->rawContentPointer() : NULL
);  } 
 170         virtual unsigned long                           contentHash(const class ld::IndirectBindingTable
& ibt
) const  
 171                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->contentHash(ibt
) : 0);  } 
 172         virtual bool                                            canCoalesceWith(const ld::Atom
& rhs
, const class ld::IndirectBindingTable
& ibt
) const  
 173                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->canCoalesceWith(rhs
,ibt
) : false); } 
 174         virtual ld::Fixup::iterator                             
fixupsBegin() const      
 175                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->fixupsBegin() : (ld::Fixup
*)&_file
._fixupToInternal
); } 
 176         virtual ld::Fixup::iterator                             
fixupsEnd() const        
 177                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->fixupsEnd() : &((ld::Fixup
*)&_file
._fixupToInternal
)[1]); } 
 178         virtual ld::Atom::UnwindInfo::iterator  
beginUnwind() const  
 179                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->beginUnwind() : NULL
); } 
 180         virtual ld::Atom::UnwindInfo::iterator  
endUnwind() const        
 181                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->endUnwind() : NULL
); } 
 182         virtual ld::Atom::LineInfo::iterator    
beginLineInfo() const  
 183                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->beginLineInfo() : NULL
); } 
 184         virtual ld::Atom::LineInfo::iterator    
endLineInfo() const  
 185                                                                                                                         { return (_compiledAtom 
? _compiledAtom
->endLineInfo() : NULL
); } 
 187         const ld::Atom
*                                         compiledAtom()          { return _compiledAtom
; } 
 188         void                                                            setCompiledAtom(const ld::Atom
& atom
); 
 194         const ld::Atom
*                                         _compiledAtom
; 
 206         static bool                                             validFile(const uint8_t* fileContent
, uint64_t fileLength
, cpu_type_t architecture
, cpu_subtype_t subarch
); 
 207         static const char*                              fileKind(const uint8_t* fileContent
, uint64_t fileLength
); 
 208         static File
*                                    parse(const uint8_t* fileContent
, uint64_t fileLength
, const char* path
,  
 209                                                                                         time_t modTime
, ld::File::Ordinal ordinal
, cpu_type_t architecture
, cpu_subtype_t subarch
, 
 210                                                                                         bool logAllFiles
, bool verboseOptimizationHints
); 
 211         static bool                                             libLTOisLoaded() { return (::lto_get_version() != NULL
); } 
 212         static bool                                             optimize(   const std::vector
<const ld::Atom
*>& allAtoms
, 
 214                                                                                                 const OptimizeOptions
&                          options
, 
 215                                                                                                 ld::File::AtomHandler
&                          handler
, 
 216                                                                                                 std::vector
<const ld::Atom
*>&           newAtoms
,  
 217                                                                                                 std::vector
<const char*>&                       additionalUndefines
); 
 219         static const char*                      ltoVersion()    { return ::lto_get_version(); } 
 222         static const char*                              tripletPrefixForArch(cpu_type_t arch
); 
 223         static ld::relocatable::File
*   parseMachOFile(const uint8_t* p
, size_t len
, const OptimizeOptions
& options
); 
 224 #if LTO_API_VERSION >= 7 
 225         static void ltoDiagnosticHandler(lto_codegen_diagnostic_severity_t
, const char*, void*); 
 228         typedef std::unordered_set
<const char*, ld::CStringHash
, ld::CStringEquals
>  CStringSet
; 
 229         typedef std::unordered_map
<const char*, Atom
*, ld::CStringHash
, ld::CStringEquals
> CStringToAtom
; 
 231         class AtomSyncer 
: public ld::File::AtomHandler 
{ 
 233                                                         AtomSyncer(std::vector
<const char*>& a
, std::vector
<const ld::Atom
*>&na
, 
 234                                                                                 CStringToAtom la
, CStringToAtom dla
, const OptimizeOptions
& options
) : 
 235                                                                                 _options(options
), _additionalUndefines(a
), _newAtoms(na
), _llvmAtoms(la
), _deadllvmAtoms(dla
) { } 
 236                 virtual void            doAtom(const class ld::Atom
&); 
 237                 virtual void            doFile(const class ld::File
&) { } 
 240                 const OptimizeOptions
&                  _options
; 
 241                 std::vector
<const char*>&               _additionalUndefines
; 
 242                 std::vector
<const ld::Atom
*>&   _newAtoms
; 
 243                 CStringToAtom                                   _llvmAtoms
; 
 244                 CStringToAtom                                   _deadllvmAtoms
; 
 247         static std::vector
<File
*>               _s_files
; 
 250 std::vector
<File
*> Parser::_s_files
; 
 253 bool Parser::validFile(const uint8_t* fileContent
, uint64_t fileLength
, cpu_type_t architecture
, cpu_subtype_t subarch
) 
 255         for (const ArchInfo
* t
=archInfoArray
; t
->archName 
!= NULL
; ++t
) { 
 256                 if ( (architecture 
== t
->cpuType
) && (!(t
->isSubType
) || (subarch 
== t
->cpuSubType
)) ) { 
 257                         bool result 
= ::lto_module_is_object_file_in_memory_for_target(fileContent
, fileLength
, t
->llvmTriplePrefix
); 
 259                                 // <rdar://problem/8434487> LTO only supports thumbv7 not armv7 
 260                                 if ( t
->llvmTriplePrefixAlt
[0] != '\0' ) { 
 261                                         result 
= ::lto_module_is_object_file_in_memory_for_target(fileContent
, fileLength
, t
->llvmTriplePrefixAlt
); 
 270 const char* Parser::fileKind(const uint8_t* p
, uint64_t fileLength
) 
 272         if ( (p
[0] == 0xDE) && (p
[1] == 0xC0) && (p
[2] == 0x17) && (p
[3] == 0x0B) ) { 
 273                 cpu_type_t arch 
= LittleEndian::get32(*((uint32_t*)(&p
[16]))); 
 274                 for (const ArchInfo
* t
=archInfoArray
; t
->archName 
!= NULL
; ++t
) { 
 275                         if ( arch 
== t
->cpuType 
) { 
 276                                  if ( t
->isSubType 
) { 
 277                                         if ( ::lto_module_is_object_file_in_memory_for_target(p
, fileLength
, t
->llvmTriplePrefix
) ) 
 285                 return "unknown bitcode architecture"; 
 290 File
* Parser::parse(const uint8_t* fileContent
, uint64_t fileLength
, const char* path
, time_t modTime
, ld::File::Ordinal ordinal
, 
 291                                                                                                         cpu_type_t architecture
, cpu_subtype_t subarch
, bool logAllFiles
, bool verboseOptimizationHints
)  
 293         File
* f 
= new File(path
, modTime
, ordinal
, fileContent
, fileLength
, architecture
); 
 294         _s_files
.push_back(f
); 
 296                 printf("%s\n", path
); 
 301 ld::relocatable::File
* Parser::parseMachOFile(const uint8_t* p
, size_t len
, const OptimizeOptions
& options
)  
 303         mach_o::relocatable::ParserOptions objOpts
; 
 304         objOpts
.architecture            
= options
.arch
; 
 305         objOpts
.objSubtypeMustMatch 
= false;  
 306         objOpts
.logAllFiles                     
= false; 
 307         objOpts
.warnUnwindConversionProblems    
= options
.needsUnwindInfoSection
; 
 308         objOpts
.keepDwarfUnwind         
= options
.keepDwarfUnwind
; 
 309         objOpts
.forceDwarfConversion 
= false; 
 310         objOpts
.neverConvertDwarf   
= false; 
 311         objOpts
.verboseOptimizationHints 
= options
.verboseOptimizationHints
; 
 312         objOpts
.armUsesZeroCostExceptions 
= options
.armUsesZeroCostExceptions
; 
 313         objOpts
.simulator                       
= options
.simulator
; 
 314         objOpts
.ignoreMismatchPlatform 
= options
.ignoreMismatchPlatform
; 
 315         objOpts
.platform                        
= options
.platform
; 
 317         objOpts
.srcKind                         
= ld::relocatable::File::kSourceLTO
; 
 318         objOpts
.treateBitcodeAsData 
= false; 
 319         objOpts
.usingBitcode            
= options
.bitcodeBundle
; 
 321         // mach-o parsing is done in-memory, but need path for debug notes 
 322         const char* path 
= "/tmp/lto.o"; 
 324         if ( options
.tmpObjectFilePath 
!= NULL 
) { 
 325                 path 
= options
.tmpObjectFilePath
; 
 326                 struct stat statBuffer
; 
 327                 if ( stat(options
.tmpObjectFilePath
, &statBuffer
) == 0 ) 
 328                         modTime 
= statBuffer
.st_mtime
; 
 331         ld::relocatable::File
* result 
= mach_o::relocatable::parse(p
, len
, path
, modTime
, ld::File::Ordinal::LTOOrdinal(), objOpts
); 
 332         if ( result 
!= NULL 
) 
 334         throw "LLVM LTO, file is not of required architecture"; 
 339 File::File(const char* pth
, time_t mTime
, ld::File::Ordinal ordinal
, const uint8_t* content
, uint32_t contentLength
, cpu_type_t arch
)  
 340         : ld::relocatable::File(pth
,mTime
,ordinal
), _architecture(arch
), _internalAtom(*this),  
 341         _atomArray(NULL
), _atomArrayCount(0), _module(NULL
), _path(pth
), 
 342         _content(content
), _contentLength(contentLength
), _debugInfoPath(pth
), 
 343         _section("__TEXT_", "__tmp_lto", ld::Section::typeTempLTO
), 
 344         _fixupToInternal(0, ld::Fixup::k1of1
, ld::Fixup::kindNone
, &_internalAtom
), 
 345         _debugInfo(ld::relocatable::File::kDebugInfoNone
), _cpuSubType(0) 
 347         const bool log 
= false; 
 349         // create llvm module 
 350 #if LTO_API_VERSION >= 11 
 351         if ( sSupportsLocalContext 
|| !sHasTriedLocalContext 
) { 
 352                 _module 
= ::lto_module_create_in_local_context(content
, contentLength
, pth
); 
 354         if ( !sHasTriedLocalContext 
) { 
 355                 sHasTriedLocalContext 
= true; 
 356                 sSupportsLocalContext 
= (_module 
!= NULL
); 
 358         if ( (_module 
== NULL
) && !sSupportsLocalContext 
) 
 360 #if LTO_API_VERSION >= 9 
 361         _module 
= ::lto_module_create_from_memory_with_path(content
, contentLength
, pth
); 
 362         if ( _module 
== NULL 
&& !sSupportsLocalContext 
) 
 364         _module 
= ::lto_module_create_from_memory(content
, contentLength
); 
 365     if ( _module 
== NULL 
) 
 366                 throwf("could not parse object file %s: '%s', using libLTO version '%s'", pth
, ::lto_get_error_message(), ::lto_get_version()); 
 368         if ( log 
) fprintf(stderr
, "bitcode file: %s\n", pth
); 
 370         // create atom for each global symbol in module 
 371         uint32_t count 
= ::lto_module_get_num_symbols(_module
); 
 372         _atomArray 
= (Atom
*)malloc(sizeof(Atom
)*count
); 
 373         for (uint32_t i
=0; i 
< count
; ++i
) { 
 374                 const char* name 
= ::lto_module_get_symbol_name(_module
, i
); 
 375                 lto_symbol_attributes attr 
= lto_module_get_symbol_attribute(_module
, i
); 
 377                 // <rdar://problem/6378110> LTO doesn't like dtrace symbols 
 378                 // ignore dtrace static probes for now 
 379                 // later when codegen is done and a mach-o file is produces the probes will be processed 
 380                 if ( (strncmp(name
, "___dtrace_probe$", 16) == 0) || (strncmp(name
, "___dtrace_isenabled$", 20) == 0) ) 
 383                 ld::Atom::Definition def
; 
 384                 ld::Atom::Combine combine 
= ld::Atom::combineNever
; 
 385                 switch ( attr 
& LTO_SYMBOL_DEFINITION_MASK 
) { 
 386                         case LTO_SYMBOL_DEFINITION_REGULAR
: 
 387                                 def 
= ld::Atom::definitionRegular
; 
 389                         case LTO_SYMBOL_DEFINITION_TENTATIVE
: 
 390                                 def 
= ld::Atom::definitionTentative
; 
 392                         case LTO_SYMBOL_DEFINITION_WEAK
: 
 393                                 def 
= ld::Atom::definitionRegular
; 
 394                                 combine 
= ld::Atom::combineByName
; 
 396                         case LTO_SYMBOL_DEFINITION_UNDEFINED
: 
 397                         case LTO_SYMBOL_DEFINITION_WEAKUNDEF
: 
 398                                 def 
= ld::Atom::definitionProxy
; 
 401                                 throwf("unknown definition kind for symbol %s in bitcode file %s", name
, pth
); 
 404                 // make LLVM atoms for definitions and a reference for undefines 
 405                 if ( def 
!= ld::Atom::definitionProxy 
) { 
 406                         ld::Atom::Scope scope
; 
 407                         bool autohide 
= false; 
 408                         switch ( attr 
& LTO_SYMBOL_SCOPE_MASK
) { 
 409                                 case LTO_SYMBOL_SCOPE_INTERNAL
: 
 410                                         scope 
= ld::Atom::scopeTranslationUnit
; 
 412                                 case LTO_SYMBOL_SCOPE_HIDDEN
: 
 413                                         scope 
= ld::Atom::scopeLinkageUnit
; 
 415                                 case LTO_SYMBOL_SCOPE_DEFAULT
: 
 416                                         scope 
= ld::Atom::scopeGlobal
; 
 418 #if LTO_API_VERSION >= 4 
 419                                 case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN
: 
 420                                         scope 
= ld::Atom::scopeGlobal
; 
 425                                         throwf("unknown scope for symbol %s in bitcode file %s", name
, pth
); 
 427                         // only make atoms for non-internal symbols  
 428                         if ( scope 
== ld::Atom::scopeTranslationUnit 
) 
 430                         uint8_t alignment 
= (attr 
& LTO_SYMBOL_ALIGNMENT_MASK
); 
 431                         // make Atom using placement new operator 
 432                         new (&_atomArray
[_atomArrayCount
++]) Atom(*this, name
, scope
, def
, combine
, alignment
, autohide
); 
 433                         if ( scope 
!= ld::Atom::scopeTranslationUnit 
) 
 434                                 _internalAtom
.addReference(name
); 
 435                         if ( log 
) fprintf(stderr
, "\t0x%08X %s\n", attr
, name
); 
 438                         // add to list of external references 
 439                         _internalAtom
.addReference(name
); 
 440                         if ( log 
) fprintf(stderr
, "\t%s (undefined)\n", name
); 
 444 #if LTO_API_VERSION >= 11 
 445         if ( sSupportsLocalContext 
) 
 455 bool File::mergeIntoGenerator(lto_code_gen_t generator
, bool useSetModule
) { 
 456 #if LTO_API_VERSION >= 11 
 457     if ( sSupportsLocalContext 
) { 
 458         assert(!_module 
&& "Expected module to be disposed"); 
 459         _module 
= ::lto_module_create_in_codegen_context(_content
, _contentLength
, 
 461         if ( _module 
== NULL 
) 
 462             throwf("could not reparse object file %s: '%s', using libLTO version '%s'", 
 463                   _path
, ::lto_get_error_message(), ::lto_get_version()); 
 466     assert(_module 
&& "Expected module to stick around"); 
 467 #if LTO_API_VERSION >= 13 
 469         // lto_codegen_set_module will transfer ownership of the module to LTO code generator, 
 470         // so we don't need to release the module here. 
 471         ::lto_codegen_set_module(generator
, _module
); 
 475     if ( ::lto_codegen_add_module(generator
, _module
) ) 
 478     // <rdar://problem/15471128> linker should release module as soon as possible 
 485         if ( _module 
!= NULL 
) 
 486                 ::lto_module_dispose(_module
); 
 490 bool File::forEachAtom(ld::File::AtomHandler
& handler
) const 
 492         handler
.doAtom(_internalAtom
); 
 493         for(uint32_t i
=0; i 
< _atomArrayCount
; ++i
) { 
 494                 handler
.doAtom(_atomArray
[i
]); 
 499 InternalAtom::InternalAtom(File
& f
) 
 500         : ld::Atom(f
._section
, ld::Atom::definitionRegular
, ld::Atom::combineNever
, ld::Atom::scopeTranslationUnit
,  
 501                                 ld::Atom::typeLTOtemporary
, ld::Atom::symbolTableNotIn
, true, false, false, ld::Atom::Alignment(0)), 
 506 Atom::Atom(File
& f
, const char* nm
, ld::Atom::Scope s
, ld::Atom::Definition d
, ld::Atom::Combine c
,  
 507                         ld::Atom::Alignment a
, bool ah
) 
 508         : ld::Atom(f
._section
, d
, c
, s
, ld::Atom::typeLTOtemporary
,  
 509                                 ld::Atom::symbolTableIn
, false, false, false, a
), 
 510                 _file(f
), _name(strdup(nm
)), _compiledAtom(NULL
) 
 516 void Atom::setCompiledAtom(const ld::Atom
& atom
) 
 518         // set delegate so virtual methods go to it 
 519         _compiledAtom 
= &atom
; 
 521         //fprintf(stderr, "setting lto atom %p to delegate to mach-o atom %p (%s)\n", this, &atom, atom.name()); 
 523         // update fields in ld::Atom to match newly constructed mach-o atom 
 524         (const_cast<Atom
*>(this))->setAttributesFromAtom(atom
); 
 529 // <rdar://problem/12379604> The order that files are merged must match command line order 
 530 struct CommandLineOrderFileSorter
 
 532      bool operator()(File
* left
, File
* right
) 
 534         return ( left
->ordinal() < right
->ordinal() ); 
 539 #if LTO_API_VERSION >= 7 
 540 void Parser::ltoDiagnosticHandler(lto_codegen_diagnostic_severity_t severity
, const char* message
, void*)  
 542         switch ( severity 
) { 
 543 #if LTO_API_VERSION >= 10 
 545                         fprintf(stderr
, "ld: LTO remark: %s\n", message
); 
 550                         warning("%s", message
); 
 553                         throwf("%s", message
); 
 558 bool Parser::optimize(  const std::vector
<const ld::Atom
*>&     allAtoms
, 
 560                                                 const OptimizeOptions
&                          options
, 
 561                                                 ld::File::AtomHandler
&                          handler
, 
 562                                                 std::vector
<const ld::Atom
*>&           newAtoms
,  
 563                                                 std::vector
<const char*>&                       additionalUndefines
) 
 565         const bool logMustPreserve 
= false; 
 566         const bool logExtraOptions 
= false; 
 567         const bool logBitcodeFiles 
= false; 
 568         const bool logAtomsBeforeSync 
= false; 
 570         // exit quickly if nothing to do 
 571         if ( _s_files
.size() == 0 )  
 574         // print out LTO version string if -v was used 
 575         if ( options
.verbose 
) 
 576                 fprintf(stderr
, "%s\n", ::lto_get_version()); 
 578         // create optimizer and add each Reader 
 579         lto_code_gen_t generator 
= NULL
; 
 580 #if LTO_API_VERSION >= 11 
 581         if ( File::sSupportsLocalContext 
) 
 582                 generator 
= ::lto_codegen_create_in_local_context(); 
 585                 generator 
= ::lto_codegen_create(); 
 586 #if LTO_API_VERSION >= 7 
 587         lto_codegen_set_diagnostic_handler(generator
, ltoDiagnosticHandler
, NULL
); 
 590         // <rdar://problem/12379604> The order that files are merged must match command line order 
 591         std::sort(_s_files
.begin(), _s_files
.end(), CommandLineOrderFileSorter()); 
 592         ld::File::Ordinal lastOrdinal
; 
 594         // When flto_codegen_only is on and we have a single .bc file, use lto_codegen_set_module instead of 
 595         // lto_codegen_add_module, to make sure the the destination module will be the same as the input .bc file. 
 596         bool useSetModule 
= false; 
 597 #if LTO_API_VERSION >= 13 
 598         useSetModule 
= (_s_files
.size() == 1) && options
.ltoCodegenOnly 
&& (::lto_api_version() >= 13); 
 600         for (std::vector
<File
*>::iterator it
=_s_files
.begin(); it 
!= _s_files
.end(); ++it
) { 
 602                 assert(f
->ordinal() > lastOrdinal
); 
 603                 if ( logBitcodeFiles 
&& !useSetModule
) fprintf(stderr
, "lto_codegen_add_module(%s)\n", f
->path()); 
 604                 if ( logBitcodeFiles 
&& useSetModule
) fprintf(stderr
, "lto_codegen_set_module(%s)\n", f
->path()); 
 605                 if ( f
->mergeIntoGenerator(generator
, useSetModule
) ) 
 606                         throwf("lto: could not merge in %s because '%s', using libLTO version '%s'", f
->path(), ::lto_get_error_message(), ::lto_get_version()); 
 607                 lastOrdinal 
= f
->ordinal(); 
 610         // add any -mllvm command line options 
 611         for (std::vector
<const char*>::const_iterator it
=options
.llvmOptions
->begin(); it 
!= options
.llvmOptions
->end(); ++it
) { 
 612                 if ( logExtraOptions 
) fprintf(stderr
, "passing option to llvm: %s\n", *it
); 
 613                 ::lto_codegen_debug_options(generator
, *it
); 
 616         // <rdar://problem/13687397> Need a way for LTO to get cpu variants (until that info is in bitcode) 
 617         if ( options
.mcpu 
!= NULL 
) 
 618                 ::lto_codegen_set_cpu(generator
, options
.mcpu
); 
 620         // The atom graph uses directed edges (references). Collect all references where  
 621         // originating atom is not part of any LTO Reader. This allows optimizer to optimize an  
 622         // external (i.e. not originated from same .o file) reference if all originating atoms are also  
 623         // defined in llvm bitcode file. 
 624         CStringSet nonLLVMRefs
; 
 625         CStringToAtom llvmAtoms
; 
 626     bool hasNonllvmAtoms 
= false; 
 627         for (std::vector
<const ld::Atom
*>::const_iterator it 
= allAtoms
.begin(); it 
!= allAtoms
.end(); ++it
) { 
 628                 const ld::Atom
* atom 
= *it
; 
 629                 // only look at references that come from an atom that is not an llvm atom 
 630                 if ( atom
->contentType() != ld::Atom::typeLTOtemporary 
) { 
 631                         if ( (atom
->section().type() != ld::Section::typeMachHeader
) && (atom
->definition() != ld::Atom::definitionProxy
) ) { 
 632                                 hasNonllvmAtoms 
= true; 
 634                         const ld::Atom
* target
; 
 635                         for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit 
!= atom
->fixupsEnd(); ++fit
) { 
 636                                 switch ( fit
->binding 
) { 
 637                                         case ld::Fixup::bindingDirectlyBound
: 
 638                                                 // that reference an llvm atom 
 639                                                 if ( fit
->u
.target
->contentType() == ld::Atom::typeLTOtemporary 
)  
 640                                                         nonLLVMRefs
.insert(fit
->u
.target
->name()); 
 642                                         case ld::Fixup::bindingsIndirectlyBound
: 
 643                                                 target 
= state
.indirectBindingTable
[fit
->u
.bindingIndex
]; 
 644                                                 if ( (target 
!= NULL
) && (target
->contentType() == ld::Atom::typeLTOtemporary
) ) 
 645                                                         nonLLVMRefs
.insert(target
->name()); 
 651                 else if ( atom
->scope() >= ld::Atom::scopeLinkageUnit 
) { 
 652                         llvmAtoms
[atom
->name()] = (Atom
*)atom
; 
 655         // if entry point is in a llvm bitcode file, it must be preserved by LTO 
 656         if ( state
.entryPoint
!= NULL 
) { 
 657                 if ( state
.entryPoint
->contentType() == ld::Atom::typeLTOtemporary 
)  
 658                         nonLLVMRefs
.insert(state
.entryPoint
->name()); 
 661         // deadAtoms are the atoms that the linker coalesced.  For instance weak or tentative definitions 
 662         // overriden by another atom.  If any of these deadAtoms are llvm atoms and they were replaced 
 663         // with a mach-o atom, we need to tell the lto engine to preserve (not optimize away) its dead  
 664         // atom so that the linker can replace it with the mach-o one later. 
 665         CStringToAtom deadllvmAtoms
; 
 666         for (std::vector
<const ld::Atom
*>::const_iterator it 
= allAtoms
.begin(); it 
!= allAtoms
.end(); ++it
) { 
 667                 const ld::Atom
* atom 
= *it
; 
 668                 if ( atom
->coalescedAway() && (atom
->contentType() == ld::Atom::typeLTOtemporary
) ) { 
 669                         const char* name 
= atom
->name(); 
 670                         if ( logMustPreserve 
) fprintf(stderr
, "lto_codegen_add_must_preserve_symbol(%s) because linker coalesce away and replace with a mach-o atom\n", name
); 
 671                         ::lto_codegen_add_must_preserve_symbol(generator
, name
); 
 672                         deadllvmAtoms
[name
] = (Atom
*)atom
; 
 675         for (std::vector
<File
*>::iterator it
=_s_files
.begin(); it 
!= _s_files
.end(); ++it
) { 
 677                 for(uint32_t i
=0; i 
< file
->_atomArrayCount
; ++i
) { 
 678                         Atom
* llvmAtom 
= &file
->_atomArray
[i
]; 
 679                         if ( llvmAtom
->coalescedAway()  ) { 
 680                                 const char* name 
= llvmAtom
->name(); 
 681                                 if ( deadllvmAtoms
.find(name
) == deadllvmAtoms
.end() ) { 
 682                                         if ( logMustPreserve 
)  
 683                                                 fprintf(stderr
, "lto_codegen_add_must_preserve_symbol(%s) because linker coalesce away and replace with a mach-o atom\n", name
); 
 684                                         ::lto_codegen_add_must_preserve_symbol(generator
, name
); 
 685                                         deadllvmAtoms
[name
] = (Atom
*)llvmAtom
; 
 688                         else if ( options
.linkerDeadStripping 
&& !llvmAtom
->live() ) { 
 689                                 const char* name 
= llvmAtom
->name(); 
 690                                 deadllvmAtoms
[name
] = (Atom
*)llvmAtom
; 
 695         // tell code generator about symbols that must be preserved 
 696         for (CStringToAtom::iterator it 
= llvmAtoms
.begin(); it 
!= llvmAtoms
.end(); ++it
) { 
 697                 const char* name 
= it
->first
; 
 698                 Atom
* atom 
= it
->second
; 
 699                 // Include llvm Symbol in export list if it meets one of following two conditions 
 700                 // 1 - atom scope is global (and not linkage unit). 
 701                 // 2 - included in nonLLVMRefs set. 
 702                 // If a symbol is not listed in exportList then LTO is free to optimize it away. 
 703                 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && options
.preserveAllGlobals 
) {  
 704                         if ( logMustPreserve 
) fprintf(stderr
, "lto_codegen_add_must_preserve_symbol(%s) because global symbol\n", name
); 
 705                         ::lto_codegen_add_must_preserve_symbol(generator
, name
); 
 707                 else if ( nonLLVMRefs
.find(name
) != nonLLVMRefs
.end() ) { 
 708                         if ( logMustPreserve 
) fprintf(stderr
, "lto_codegen_add_must_preserve_symbol(%s) because referenced by a mach-o atom\n", name
); 
 709                         ::lto_codegen_add_must_preserve_symbol(generator
, name
); 
 711                 else if ( options
.relocatable 
&& hasNonllvmAtoms 
) { 
 712                         // <rdar://problem/14334895> ld -r mode but merging in some mach-o files, so need to keep libLTO from optimizing away anything 
 713                         if ( logMustPreserve 
) fprintf(stderr
, "lto_codegen_add_must_preserve_symbol(%s) because -r mode disable LTO dead stripping\n", name
); 
 714                         ::lto_codegen_add_must_preserve_symbol(generator
, name
); 
 718         // <rdar://problem/16165191> tell code generator to preserve initial undefines 
 719         for( std::vector
<const char*>::const_iterator it
=options
.initialUndefines
->begin(); it 
!= options
.initialUndefines
->end(); ++it
) { 
 720                 if ( logMustPreserve 
) fprintf(stderr
, "lto_codegen_add_must_preserve_symbol(%s) because it is an initial undefine\n", *it
); 
 721                 ::lto_codegen_add_must_preserve_symbol(generator
, *it
); 
 724     // special case running ld -r on all bitcode files to produce another bitcode file (instead of mach-o) 
 725     if ( options
.relocatable 
&& !hasNonllvmAtoms 
) { 
 726 #if LTO_API_VERSION >= 15 
 727                 ::lto_codegen_set_should_embed_uselists(generator
, false); 
 729                 if ( ! ::lto_codegen_write_merged_modules(generator
, options
.outputFilePath
) ) { 
 730                         // HACK, no good way to tell linker we are all done, so just quit 
 733                 warning("could not produce merged bitcode file"); 
 736         // set code-gen model 
 737         lto_codegen_model model 
= LTO_CODEGEN_PIC_MODEL_DYNAMIC
; 
 738         if ( options
.mainExecutable 
) { 
 739                 if ( options
.staticExecutable 
) { 
 740                         // x86_64 "static" or any "-static -pie" is really dynamic code model 
 741                         if ( (options
.arch 
== CPU_TYPE_X86_64
) || options
.pie 
) 
 742                                 model 
= LTO_CODEGEN_PIC_MODEL_DYNAMIC
; 
 744                                 model 
= LTO_CODEGEN_PIC_MODEL_STATIC
; 
 748                                 model 
= LTO_CODEGEN_PIC_MODEL_DYNAMIC
; 
 750                                 model 
= LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC
; 
 754                 if ( options
.allowTextRelocs 
) 
 755                         model 
= LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC
; 
 757                         model 
= LTO_CODEGEN_PIC_MODEL_DYNAMIC
; 
 759         if ( ::lto_codegen_set_pic_model(generator
, model
) ) 
 760                 throwf("could not create set codegen model: %s", lto_get_error_message()); 
 762     // if requested, save off merged bitcode file 
 763     if ( options
.saveTemps 
) { 
 764         char tempBitcodePath
[MAXPATHLEN
]; 
 765         strcpy(tempBitcodePath
, options
.outputFilePath
); 
 766         strcat(tempBitcodePath
, ".lto.bc"); 
 767 #if LTO_API_VERSION >= 15 
 768         ::lto_codegen_set_should_embed_uselists(generator
, true); 
 770         ::lto_codegen_write_merged_modules(generator
, tempBitcodePath
); 
 773 #if LTO_API_VERSION >= 3 
 774         // find assembler next to linker 
 776         uint32_t bufSize 
= PATH_MAX
; 
 777         if ( _NSGetExecutablePath(path
, &bufSize
) != -1 ) { 
 778                 char* lastSlash 
= strrchr(path
, '/'); 
 779                 if ( lastSlash 
!= NULL 
) { 
 780                         strcpy(lastSlash
+1, "as"); 
 781                         struct stat statInfo
; 
 782                         if ( stat(path
, &statInfo
) == 0 ) 
 783                                 ::lto_codegen_set_assembler_path(generator
, path
); 
 788         // When lto API version is greater than or equal to 12, we use lto_codegen_optimize and lto_codegen_compile_optimized 
 789         // instead of lto_codegen_compile, and we save the merged bitcode file in between. 
 790         bool useSplitAPI 
= false; 
 791 #if LTO_API_VERSION >= 12 
 792         if ( ::lto_api_version() >= 12) 
 796         size_t machOFileLen 
= 0; 
 797         const uint8_t* machOFile 
= NULL
; 
 799 #if LTO_API_VERSION >= 12 
 800 #if LTO_API_VERSION >= 14 
 801         if ( ::lto_api_version() >= 14 && options
.ltoCodegenOnly
) 
 802           lto_codegen_set_should_internalize(generator
, false); 
 805                 if ( !options
.ltoCodegenOnly 
&& ::lto_codegen_optimize(generator
) ) 
 806                         throwf("could not do LTO optimization: '%s', using libLTO version '%s'", ::lto_get_error_message(), ::lto_get_version()); 
 808                 if ( options
.saveTemps 
|| options
.bitcodeBundle 
) { 
 809                         // save off merged bitcode file 
 810                         char tempOptBitcodePath
[MAXPATHLEN
]; 
 811                         strcpy(tempOptBitcodePath
, options
.outputFilePath
); 
 812                         strcat(tempOptBitcodePath
, ".lto.opt.bc"); 
 813 #if LTO_API_VERSION >= 15 
 814                         ::lto_codegen_set_should_embed_uselists(generator
, true); 
 816                         ::lto_codegen_write_merged_modules(generator
, tempOptBitcodePath
); 
 817                         if ( options
.bitcodeBundle 
) 
 818                                 state
.ltoBitcodePath 
= tempOptBitcodePath
; 
 821                 // run code generator 
 822                 machOFile 
= (uint8_t*)::lto_codegen_compile_optimized(generator
, &machOFileLen
); 
 824                 if ( machOFile 
== NULL 
) 
 825                         throwf("could not do LTO codegen: '%s', using libLTO version '%s'", ::lto_get_error_message(), ::lto_get_version()); 
 828                 // run optimizer and code generator 
 829                 machOFile 
= (uint8_t*)::lto_codegen_compile(generator
, &machOFileLen
); 
 830                 if ( machOFile 
== NULL 
) 
 831                         throwf("could not do LTO codegen: '%s', using libLTO version '%s'", ::lto_get_error_message(), ::lto_get_version()); 
 832                 if ( options
.saveTemps 
) { 
 833                         // save off merged bitcode file 
 834                         char tempOptBitcodePath
[MAXPATHLEN
]; 
 835                         strcpy(tempOptBitcodePath
, options
.outputFilePath
); 
 836                         strcat(tempOptBitcodePath
, ".lto.opt.bc"); 
 837 #if LTO_API_VERSION >= 15 
 838                         ::lto_codegen_set_should_embed_uselists(generator
, true); 
 840                         ::lto_codegen_write_merged_modules(generator
, tempOptBitcodePath
); 
 844     // if requested, save off temp mach-o file 
 845     if ( options
.saveTemps 
) { 
 846         char tempMachoPath
[MAXPATHLEN
]; 
 847         strcpy(tempMachoPath
, options
.outputFilePath
); 
 848         strcat(tempMachoPath
, ".lto.o"); 
 849         int fd 
= ::open(tempMachoPath
, O_CREAT 
| O_WRONLY 
| O_TRUNC
, 0666); 
 851                         ::write(fd
, machOFile
, machOFileLen
); 
 856         // if needed, save temp mach-o file to specific location 
 857         if ( options
.tmpObjectFilePath 
!= NULL 
) { 
 858                 int fd 
= ::open(options
.tmpObjectFilePath
, O_CREAT 
| O_WRONLY 
| O_TRUNC
, 0666); 
 860                         ::write(fd
, machOFile
, machOFileLen
); 
 864                         warning("could not write LTO temp file '%s', errno=%d", options
.tmpObjectFilePath
, errno
); 
 868         // parse generated mach-o file into a MachOReader 
 869         ld::relocatable::File
* machoFile 
= parseMachOFile(machOFile
, machOFileLen
, options
); 
 871         // sync generated mach-o atoms with existing atoms ld knows about 
 872         if ( logAtomsBeforeSync 
) { 
 873                 fprintf(stderr
, "llvmAtoms:\n"); 
 874                 for (CStringToAtom::iterator it 
= llvmAtoms
.begin(); it 
!= llvmAtoms
.end(); ++it
) { 
 875                         const char* name 
= it
->first
; 
 876                         Atom
* atom 
= it
->second
; 
 877                         fprintf(stderr
, "\t%p\t%s\n", atom
, name
); 
 879                 fprintf(stderr
, "deadllvmAtoms:\n"); 
 880                 for (CStringToAtom::iterator it 
= deadllvmAtoms
.begin(); it 
!= deadllvmAtoms
.end(); ++it
) { 
 881                         const char* name 
= it
->first
; 
 882                         Atom
* atom 
= it
->second
; 
 883                         fprintf(stderr
, "\t%p\t%s\n", atom
, name
); 
 886         AtomSyncer 
syncer(additionalUndefines
, newAtoms
, llvmAtoms
, deadllvmAtoms
, options
); 
 887         machoFile
->forEachAtom(syncer
); 
 889         // Remove InternalAtoms from ld 
 890         for (std::vector
<File
*>::iterator it
=_s_files
.begin(); it 
!= _s_files
.end(); ++it
) { 
 891                 (*it
)->internalAtom().setCoalescedAway(); 
 893         // Remove Atoms from ld if code generator optimized them away 
 894         for (CStringToAtom::iterator li 
= llvmAtoms
.begin(), le 
= llvmAtoms
.end(); li 
!= le
; ++li
) { 
 895                 // check if setRealAtom() called on this Atom 
 896                 if ( li
->second
->compiledAtom() == NULL 
) { 
 897                         //fprintf(stderr, "llvm optimized away %p %s\n", li->second, li->second->name()); 
 898                         li
->second
->setCoalescedAway(); 
 902         // notify about file level attributes 
 903         handler
.doFile(*machoFile
); 
 905         // if final mach-o file has debug info, update original bitcode files to match 
 906         for (std::vector
<File
*>::iterator it
=_s_files
.begin(); it 
!= _s_files
.end(); ++it
) { 
 907                 (*it
)->setDebugInfo(machoFile
->debugInfo(), machoFile
->path(), 
 908                                                         machoFile
->modificationTime(), machoFile
->cpuSubType()); 
 915 void Parser::AtomSyncer::doAtom(const ld::Atom
& machoAtom
) 
 917         static const bool log 
= false; 
 918         static const ld::Atom
* lastProxiedAtom 
= NULL
; 
 919         static const ld::File
* lastProxiedFile 
= NULL
; 
 920         // update proxy atoms to point to real atoms and find new atoms 
 921         const char* name 
= machoAtom
.name(); 
 922         CStringToAtom::iterator pos 
= _llvmAtoms
.find(name
); 
 923         if ( pos 
!= _llvmAtoms
.end() ) { 
 924                 // turn Atom into a proxy for this mach-o atom 
 925                 pos
->second
->setCompiledAtom(machoAtom
); 
 926                 lastProxiedAtom 
= &machoAtom
; 
 927                 lastProxiedFile 
= pos
->second
->file(); 
 928                 if (log
) fprintf(stderr
, "AtomSyncer, mach-o atom %p synced to lto atom %p (name=%s)\n", &machoAtom
, pos
->second
, machoAtom
.name()); 
 931                 // an atom of this name was not in the allAtoms list the linker gave us 
 932                 if ( _deadllvmAtoms
.find(name
) != _deadllvmAtoms
.end() ) { 
 933                         // this corresponding to an atom that the linker coalesced away or marked not-live 
 934                         if ( _options
.linkerDeadStripping 
) { 
 935                                 // llvm seems to want this atom and -dead_strip is enabled, so it will be deleted if not needed, so add back 
 936                                 Atom
* llvmAtom 
= _deadllvmAtoms
[name
]; 
 937                                 llvmAtom
->setCompiledAtom(machoAtom
); 
 938                                 _newAtoms
.push_back(&machoAtom
); 
 939                                 if (log
) fprintf(stderr
, "AtomSyncer, mach-o atom %p matches dead lto atom %p but adding back (name=%s)\n", &machoAtom
, llvmAtom
, machoAtom
.name()); 
 942                                 // Don't pass it back as a new atom 
 943                                 if (log
) fprintf(stderr
, "AtomSyncer, mach-o atom %p matches dead lto atom %p (name=%s)\n", &machoAtom
, _deadllvmAtoms
[name
], machoAtom
.name()); 
 948                         // this is something new that lto conjured up, tell ld its new 
 949                         _newAtoms
.push_back(&machoAtom
); 
 950                         // <rdar://problem/15469363> if new static atom in same section as previous non-static atom, assign to same file as previous 
 951                         if ( (lastProxiedAtom 
!= NULL
) && (lastProxiedAtom
->section() == machoAtom
.section()) ) { 
 952                                 ld::Atom
* ma 
= const_cast<ld::Atom
*>(&machoAtom
); 
 953                                 ma
->setFile(lastProxiedFile
); 
 955                         if (log
) fprintf(stderr
, "AtomSyncer, mach-o atom %p is totally new (name=%s)\n", &machoAtom
, machoAtom
.name()); 
 959         // adjust fixups to go through proxy atoms 
 960         if (log
) fprintf(stderr
, "  adjusting fixups in atom: %s\n", machoAtom
.name()); 
 961         for (ld::Fixup::iterator fit
=machoAtom
.fixupsBegin(); fit 
!= machoAtom
.fixupsEnd(); ++fit
) { 
 962                 switch ( fit
->binding 
) { 
 963                         case ld::Fixup::bindingNone
: 
 965                         case ld::Fixup::bindingByNameUnbound
: 
 966                                 // don't know if this target has been seen by linker before or if it is new 
 967                                 // be conservative and tell linker it is new 
 968                                 _additionalUndefines
.push_back(fit
->u
.name
); 
 969                                 if (log
) fprintf(stderr
, "    adding by-name symbol %s\n", fit
->u
.name
); 
 971                         case ld::Fixup::bindingDirectlyBound
: 
 972                                 // If mach-o atom is referencing another mach-o atom then  
 973                                 // reference is not going through Atom proxy. Fix it here to ensure that all 
 974                                 // llvm symbol references always go through Atom proxy. 
 976                                         const char* targetName 
= fit
->u
.target
->name(); 
 977                                         CStringToAtom::iterator post 
= _llvmAtoms
.find(targetName
); 
 978                                         if ( post 
!= _llvmAtoms
.end() ) { 
 979                                                 const ld::Atom
* t 
= post
->second
; 
 980                                                 if (log
) fprintf(stderr
, "    updating direct reference to %p to be ref to %p: %s\n", fit
->u
.target
, t
, targetName
); 
 984                                                 // <rdar://problem/12859831> Don't unbind follow-on reference into by-name reference  
 985                                                 if ( (_deadllvmAtoms
.find(targetName
) != _deadllvmAtoms
.end()) && (fit
->kind 
!= ld::Fixup::kindNoneFollowOn
) && (fit
->u
.target
->scope() != ld::Atom::scopeTranslationUnit
) ) { 
 986                                                         // target was coalesed away and replace by mach-o atom from a non llvm .o file 
 987                                                         fit
->binding 
= ld::Fixup::bindingByNameUnbound
; 
 988                                                         fit
->u
.name 
= targetName
; 
 992                                 //fprintf(stderr, "    direct ref to: %s (scope=%d)\n", fit->u.target->name(), fit->u.target->scope()); 
 994                         case ld::Fixup::bindingByContentBound
: 
 995                                 //fprintf(stderr, "    direct by content to: %s\n", fit->u.target->name()); 
 997                         case ld::Fixup::bindingsIndirectlyBound
: 
 998                                 assert(0 && "indirect binding found in initial mach-o file?"); 
 999                                 //fprintf(stderr, "    indirect by content to: %u\n", fit->u.bindingIndex); 
1007         static pthread_mutex_t lto_lock
; 
1009         Mutex() { pthread_mutex_lock(<o_lock
); } 
1010         ~Mutex() { pthread_mutex_unlock(<o_lock
); } 
1012 pthread_mutex_t 
Mutex::lto_lock 
= PTHREAD_MUTEX_INITIALIZER
; 
1013 bool File::sSupportsLocalContext 
= false; 
1014 bool File::sHasTriedLocalContext 
= false; 
1017 // Used by archive reader to see if member is an llvm bitcode file 
1019 bool isObjectFile(const uint8_t* fileContent
, uint64_t fileLength
, cpu_type_t architecture
, cpu_subtype_t subarch
) 
1022         return Parser::validFile(fileContent
, fileLength
, architecture
, subarch
); 
1026 static ld::relocatable::File 
*parseImpl( 
1027           const uint8_t *fileContent
, uint64_t fileLength
, const char *path
, 
1028           time_t modTime
, ld::File::Ordinal ordinal
, cpu_type_t architecture
, 
1029           cpu_subtype_t subarch
, bool logAllFiles
, 
1030           bool verboseOptimizationHints
) 
1032         if ( Parser::validFile(fileContent
, fileLength
, architecture
, subarch
) ) 
1033                 return Parser::parse(fileContent
, fileLength
, path
, modTime
, ordinal
, architecture
, subarch
, logAllFiles
, verboseOptimizationHints
); 
1039 // main function used by linker to instantiate ld::Files 
1041 ld::relocatable::File
* parse(const uint8_t* fileContent
, uint64_t fileLength
,  
1042                                                                 const char* path
, time_t modTime
, ld::File::Ordinal ordinal
, 
1043                                                                 cpu_type_t architecture
, cpu_subtype_t subarch
, bool logAllFiles
, 
1044                                                                 bool verboseOptimizationHints
) 
1046         // Note: Once lto_module_create_in_local_context() and friends are thread safe 
1047         // this lock can be removed. 
1049         return parseImpl(fileContent
, fileLength
, path
, modTime
, ordinal
, 
1050                                         architecture
, subarch
, logAllFiles
, 
1051                                         verboseOptimizationHints
); 
1055 // used by "ld -v" to report version of libLTO.dylib being used 
1057 const char* version() 
1060         return ::lto_get_version(); 
1065 // used by ld for error reporting 
1067 bool libLTOisLoaded() 
1070         return (::lto_get_version() != NULL
); 
1074 // used by ld for error reporting 
1076 const char* archName(const uint8_t* fileContent
, uint64_t fileLength
) 
1079         return Parser::fileKind(fileContent
, fileLength
); 
1083 // used by ld for doing link time optimization 
1085 bool optimize(  const std::vector
<const ld::Atom
*>&     allAtoms
, 
1086                                 ld::Internal
&                                           state
, 
1087                                 const OptimizeOptions
&                          options
, 
1088                                 ld::File::AtomHandler
&                          handler
, 
1089                                 std::vector
<const ld::Atom
*>&           newAtoms
,  
1090                                 std::vector
<const char*>&                       additionalUndefines
) 
1093         return Parser::optimize(allAtoms
, state
, options
, handler
, newAtoms
, additionalUndefines
);