1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
3 * Copyright (c) 2009-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@
27 #include <sys/types.h>
30 #include <sys/sysctl.h>
35 #include <mach/mach_time.h>
36 #include <mach/vm_statistics.h>
37 #include <mach/mach_init.h>
38 #include <mach/mach_host.h>
40 #include <mach-o/dyld.h>
41 #include <mach-o/fat.h>
51 #include <AvailabilityMacros.h>
56 #include "Bitcode.hpp"
57 #include "InputFiles.h"
58 #include "SymbolTable.h"
60 #include "parsers/lto_file.h"
68 // An ExportAtom has no content. It exists so that the linker can track which imported
69 // symbols came from which dynamic libraries.
71 class UndefinedProxyAtom
: public ld::Atom
74 UndefinedProxyAtom(const char* nm
)
75 : ld::Atom(_s_section
, ld::Atom::definitionProxy
,
76 ld::Atom::combineNever
, ld::Atom::scopeLinkageUnit
,
77 ld::Atom::typeUnclassified
,
78 ld::Atom::symbolTableIn
, false, false, false, ld::Atom::Alignment(0)),
80 // overrides of ld::Atom
81 virtual const ld::File
* file() const { return NULL
; }
82 virtual const char* name() const { return _name
; }
83 virtual uint64_t size() const { return 0; }
84 virtual uint64_t objectAddress() const { return 0; }
85 virtual void copyRawContent(uint8_t buffer
[]) const { }
86 virtual void setScope(Scope
) { }
90 virtual ~UndefinedProxyAtom() {}
94 static ld::Section _s_section
;
97 ld::Section
UndefinedProxyAtom::_s_section("__TEXT", "__import", ld::Section::typeImportProxies
, true);
102 class AliasAtom
: public ld::Atom
105 AliasAtom(const ld::Atom
& target
, const char* nm
) :
106 ld::Atom(target
.section(), target
.definition(), ld::Atom::combineNever
,
107 ld::Atom::scopeGlobal
, target
.contentType(),
108 target
.symbolTableInclusion(), target
.dontDeadStrip(),
109 target
.isThumb(), true, target
.alignment()),
112 _fixup(0, ld::Fixup::k1of1
, ld::Fixup::kindNoneFollowOn
, &target
) { }
114 // overrides of ld::Atom
115 virtual const ld::File
* file() const { return _aliasOf
.file(); }
116 virtual const char* translationUnitSource() const
117 { return _aliasOf
.translationUnitSource(); }
118 virtual const char* name() const { return _name
; }
119 virtual uint64_t size() const { return 0; }
120 virtual uint64_t objectAddress() const { return _aliasOf
.objectAddress(); }
121 virtual void copyRawContent(uint8_t buffer
[]) const { }
122 virtual const uint8_t* rawContentPointer() const { return NULL
; }
123 virtual unsigned long contentHash(const class ld::IndirectBindingTable
& ibt
) const
124 { return _aliasOf
.contentHash(ibt
); }
125 virtual bool canCoalesceWith(const ld::Atom
& rhs
, const class ld::IndirectBindingTable
& ibt
) const
126 { return _aliasOf
.canCoalesceWith(rhs
,ibt
); }
127 virtual ld::Fixup::iterator
fixupsBegin() const { return (ld::Fixup
*)&_fixup
; }
128 virtual ld::Fixup::iterator
fixupsEnd() const { return &((ld::Fixup
*)&_fixup
)[1]; }
129 virtual ld::Atom::UnwindInfo::iterator
beginUnwind() const { return NULL
; }
130 virtual ld::Atom::UnwindInfo::iterator
endUnwind() const { return NULL
; }
131 virtual ld::Atom::LineInfo::iterator
beginLineInfo() const { return NULL
; }
132 virtual ld::Atom::LineInfo::iterator
endLineInfo() const { return NULL
; }
134 void setFinalAliasOf() const {
135 (const_cast<AliasAtom
*>(this))->setAttributesFromAtom(_aliasOf
);
136 (const_cast<AliasAtom
*>(this))->setScope(ld::Atom::scopeGlobal
);
141 const ld::Atom
& _aliasOf
;
147 class SectionBoundaryAtom
: public ld::Atom
150 static SectionBoundaryAtom
* makeSectionBoundaryAtom(const char* name
, bool start
, const char* segSectName
);
151 static SectionBoundaryAtom
* makeOldSectionBoundaryAtom(const char* name
, bool start
);
153 // overrides of ld::Atom
154 virtual const ld::File
* file() const { return NULL
; }
155 virtual const char* name() const { return _name
; }
156 virtual uint64_t size() const { return 0; }
157 virtual void copyRawContent(uint8_t buffer
[]) const { }
158 virtual const uint8_t* rawContentPointer() const { return NULL
; }
159 virtual uint64_t objectAddress() const { return 0; }
163 SectionBoundaryAtom(const char* nm
, const ld::Section
& sect
,
164 ld::Atom::ContentType cont
) :
166 ld::Atom::definitionRegular
,
167 ld::Atom::combineNever
,
168 ld::Atom::scopeLinkageUnit
,
170 ld::Atom::symbolTableNotIn
,
171 false, false, true, ld::Atom::Alignment(0)),
177 SectionBoundaryAtom
* SectionBoundaryAtom::makeSectionBoundaryAtom(const char* name
, bool start
, const char* segSectName
)
180 const char* segSectDividor
= strrchr(segSectName
, '$');
181 if ( segSectDividor
== NULL
)
182 throwf("malformed section$ symbol name: %s", name
);
183 const char* sectionName
= segSectDividor
+ 1;
184 int segNameLen
= segSectDividor
- segSectName
;
185 if ( segNameLen
> 16 )
186 throwf("malformed section$ symbol name: %s", name
);
188 strlcpy(segName
, segSectName
, segNameLen
+1);
190 const ld::Section
* section
= new ld::Section(strdup(segName
), sectionName
, ld::Section::typeUnclassified
);
191 return new SectionBoundaryAtom(name
, *section
, (start
? ld::Atom::typeSectionStart
: typeSectionEnd
));
194 SectionBoundaryAtom
* SectionBoundaryAtom::makeOldSectionBoundaryAtom(const char* name
, bool start
)
196 // e.g. __DATA__bss__begin
198 strlcpy(segName
, name
, 7);
201 int nameLen
= strlen(name
);
202 strlcpy(sectName
, &name
[6], (start
? nameLen
-12 : nameLen
-10));
203 warning("grandfathering in old symbol '%s' as alias for 'section$%s$%s$%s'", name
, start
? "start" : "end", segName
, sectName
);
204 const ld::Section
* section
= new ld::Section(strdup(segName
), strdup(sectName
), ld::Section::typeUnclassified
);
205 return new SectionBoundaryAtom(name
, *section
, (start
? ld::Atom::typeSectionStart
: typeSectionEnd
));
211 class SegmentBoundaryAtom
: public ld::Atom
214 static SegmentBoundaryAtom
* makeSegmentBoundaryAtom(const char* name
, bool start
, const char* segName
);
215 static SegmentBoundaryAtom
* makeOldSegmentBoundaryAtom(const char* name
, bool start
);
217 // overrides of ld::Atom
218 virtual const ld::File
* file() const { return NULL
; }
219 virtual const char* name() const { return _name
; }
220 virtual uint64_t size() const { return 0; }
221 virtual void copyRawContent(uint8_t buffer
[]) const { }
222 virtual const uint8_t* rawContentPointer() const { return NULL
; }
223 virtual uint64_t objectAddress() const { return 0; }
227 SegmentBoundaryAtom(const char* nm
, const ld::Section
& sect
,
228 ld::Atom::ContentType cont
) :
230 ld::Atom::definitionRegular
,
231 ld::Atom::combineNever
,
232 ld::Atom::scopeLinkageUnit
,
234 ld::Atom::symbolTableNotIn
,
235 false, false, true, ld::Atom::Alignment(0)),
241 SegmentBoundaryAtom
* SegmentBoundaryAtom::makeSegmentBoundaryAtom(const char* name
, bool start
, const char* segName
)
243 if ( *segName
== '\0' )
244 throwf("malformed segment$ symbol name: %s", name
);
245 if ( strlen(segName
) > 16 )
246 throwf("malformed segment$ symbol name: %s", name
);
249 const ld::Section
* section
= new ld::Section(segName
, "__start", ld::Section::typeFirstSection
, true);
250 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionStart
);
253 const ld::Section
* section
= new ld::Section(segName
, "__end", ld::Section::typeLastSection
, true);
254 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionEnd
);
258 SegmentBoundaryAtom
* SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(const char* name
, bool start
)
260 // e.g. __DATA__begin
262 strlcpy(temp
, name
, 7);
263 char* segName
= strdup(temp
);
265 warning("grandfathering in old symbol '%s' as alias for 'segment$%s$%s'", name
, start
? "start" : "end", segName
);
268 const ld::Section
* section
= new ld::Section(segName
, "__start", ld::Section::typeFirstSection
, true);
269 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionStart
);
272 const ld::Section
* section
= new ld::Section(segName
, "__end", ld::Section::typeLastSection
, true);
273 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionEnd
);
277 void Resolver::initializeState()
279 // set initial objc constraint based on command line options
280 if ( _options
.objcGc() )
281 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
282 else if ( _options
.objcGcOnly() )
283 _internal
.objcObjectConstraint
= ld::File::objcConstraintGC
;
285 _internal
.cpuSubType
= _options
.subArchitecture();
286 _internal
.minOSVersion
= _options
.minOSversion();
287 _internal
.derivedPlatformLoadCommand
= 0;
289 // In -r mode, look for -linker_option additions
290 if ( _options
.outputKind() == Options::kObjectFile
) {
291 ld::relocatable::File::LinkerOptionsList lo
= _options
.linkerOptions();
292 for (relocatable::File::LinkerOptionsList::const_iterator it
=lo
.begin(); it
!= lo
.end(); ++it
) {
293 doLinkerOption(*it
, "command line");
298 void Resolver::buildAtomList()
300 // each input files contributes initial atoms
301 _atoms
.reserve(1024);
302 _inputFiles
.forEachInitialAtom(*this, _internal
);
304 _completedInitialObjectFiles
= true;
306 //_symbolTable.printStatistics();
310 void Resolver::doLinkerOption(const std::vector
<const char*>& linkerOption
, const char* fileName
)
312 if ( linkerOption
.size() == 1 ) {
313 const char* lo1
= linkerOption
.front();
314 if ( strncmp(lo1
, "-l", 2) == 0 ) {
315 _internal
.linkerOptionLibraries
.insert(&lo1
[2]);
318 warning("unknown linker option from object file ignored: '%s' in %s", lo1
, fileName
);
321 else if ( linkerOption
.size() == 2 ) {
322 const char* lo2a
= linkerOption
[0];
323 const char* lo2b
= linkerOption
[1];
324 if ( strcmp(lo2a
, "-framework") == 0 ) {
325 _internal
.linkerOptionFrameworks
.insert(lo2b
);
328 warning("unknown linker option from object file ignored: '%s' '%s' from %s", lo2a
, lo2b
, fileName
);
332 warning("unknown linker option from object file ignored, starting with: '%s' from %s", linkerOption
.front(), fileName
);
336 static void userReadableSwiftVersion(uint8_t value
, char versionString
[64])
340 strcpy(versionString
, "1.0");
343 strcpy(versionString
, "1.1");
346 strcpy(versionString
, "2.0");
349 sprintf(versionString
, "unknown ABI version 0x%02X", value
);
353 void Resolver::doFile(const ld::File
& file
)
355 const ld::relocatable::File
* objFile
= dynamic_cast<const ld::relocatable::File
*>(&file
);
356 const ld::dylib::File
* dylibFile
= dynamic_cast<const ld::dylib::File
*>(&file
);
358 if ( objFile
!= NULL
) {
359 // if file has linker options, process them
360 ld::relocatable::File::LinkerOptionsList
* lo
= objFile
->linkerOptions();
361 if ( lo
!= NULL
&& !_options
.ignoreAutoLink() ) {
362 for (relocatable::File::LinkerOptionsList::const_iterator it
=lo
->begin(); it
!= lo
->end(); ++it
) {
363 this->doLinkerOption(*it
, file
.path());
367 // Resolve bitcode section in the object file
368 if ( _options
.bundleBitcode() ) {
369 if ( objFile
->getBitcode() == NULL
) {
370 // No bitcode section, figure out if the object file comes from LTO/compiler static library
371 if (objFile
->sourceKind() != ld::relocatable::File::kSourceLTO
&&
372 objFile
->sourceKind() != ld::relocatable::File::kSourceCompilerArchive
) {
373 switch ( _options
.platform() ) {
374 case Options::kPlatformOSX
:
375 case Options::kPlatformUnknown
:
376 warning("all bitcode will be dropped because '%s' was built without bitcode. "
377 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. ", file
.path());
378 _internal
.filesWithBitcode
.clear();
379 _internal
.dropAllBitcode
= true;
381 case Options::kPlatformiOS
:
382 throwf("'%s' does not contain bitcode. "
383 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file
.path());
385 case Options::kPlatformWatchOS
:
386 throwf("'%s' does not contain bitcode. "
387 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor", file
.path());
390 case Options::kPlatform_tvOS
:
391 warning("URGENT: all bitcode will be dropped because '%s' was built without bitcode. "
392 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor. "
393 "Note: This will be an error in the future.", file
.path());
394 _internal
.filesWithBitcode
.clear();
395 _internal
.dropAllBitcode
= true;
401 // contains bitcode, check if it is just a marker
402 if ( objFile
->getBitcode()->isMarker() ) {
403 // if the bitcode is just a marker,
404 // the executable will be created without bitcode section.
405 // Otherwise, create a marker.
406 if ( _options
.outputKind() != Options::kDynamicExecutable
&&
407 _options
.outputKind() != Options::kStaticExecutable
)
408 _internal
.embedMarkerOnly
= true;
409 // Issue a warning if the marker is in the static library and filesWithBitcode is not empty.
410 // That means there are object files actually compiled with full bitcode but the archive only has marker.
411 // Don't warn on normal object files because it can be a debug build using archives with full bitcode.
412 if ( !_internal
.filesWithBitcode
.empty() && objFile
->sourceKind() == ld::relocatable::File::kSourceArchive
)
413 warning("full bitcode bundle could not be generated because '%s' was built only with bitcode marker. "
414 "The library must be generated from Xcode archive build with bitcode enabled (Xcode setting ENABLE_BITCODE)", objFile
->path());
415 _internal
.filesWithBitcode
.clear();
416 _internal
.dropAllBitcode
= true;
417 } else if ( !_internal
.dropAllBitcode
)
418 _internal
.filesWithBitcode
.push_back(objFile
);
422 // update which form of ObjC is being used
423 switch ( file
.objCConstraint() ) {
424 case ld::File::objcConstraintNone
:
426 case ld::File::objcConstraintRetainRelease
:
427 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintGC
)
428 throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", file
.path());
429 if ( _options
.objcGcOnly() )
430 throwf("command line specified -objc_gc_only, but file is retain/release based: %s", file
.path());
431 if ( _options
.objcGc() )
432 throwf("command line specified -objc_gc, but file is retain/release based: %s", file
.path());
433 if ( !_options
.targetIOSSimulator() && (_internal
.objcObjectConstraint
!= ld::File::objcConstraintRetainReleaseForSimulator
) )
434 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainRelease
;
436 case ld::File::objcConstraintRetainReleaseOrGC
:
437 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintNone
)
438 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
439 if ( _options
.targetIOSSimulator() )
440 warning("linking ObjC for iOS Simulator, but object file (%s) was compiled for MacOSX", file
.path());
442 case ld::File::objcConstraintGC
:
443 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintRetainRelease
)
444 throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", file
.path());
445 _internal
.objcObjectConstraint
= ld::File::objcConstraintGC
;
446 if ( _options
.targetIOSSimulator() )
447 warning("linking ObjC for iOS Simulator, but object file (%s) was compiled for MacOSX", file
.path());
449 case ld::File::objcConstraintRetainReleaseForSimulator
:
450 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintNone
) {
451 if ( !_options
.targetIOSSimulator() && (_options
.outputKind() != Options::kObjectFile
) )
452 warning("ObjC object file (%s) was compiled for iOS Simulator, but linking for MacOSX", file
.path());
453 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
455 else if ( _internal
.objcObjectConstraint
!= ld::File::objcConstraintRetainReleaseForSimulator
) {
456 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
461 // verify all files use same version of Swift language
462 if ( file
.swiftVersion() != 0 ) {
463 if ( _internal
.swiftVersion
== 0 ) {
464 _internal
.swiftVersion
= file
.swiftVersion();
466 else if ( file
.swiftVersion() != _internal
.swiftVersion
) {
467 char fileVersion
[64];
468 char otherVersion
[64];
469 userReadableSwiftVersion(file
.swiftVersion(), fileVersion
);
470 userReadableSwiftVersion(_internal
.swiftVersion
, otherVersion
);
471 if ( file
.swiftVersion() > _internal
.swiftVersion
) {
472 throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)",
473 file
.path(), fileVersion
, otherVersion
);
476 throwf("%s compiled with older version of Swift language (%s) than previous files (%s)",
477 file
.path(), fileVersion
, otherVersion
);
482 // in -r mode, if any .o files have dwarf then add UUID to output .o file
483 if ( objFile
->debugInfo() == ld::relocatable::File::kDebugInfoDwarf
)
484 _internal
.someObjectFileHasDwarf
= true;
486 // remember if any .o file did not have MH_SUBSECTIONS_VIA_SYMBOLS bit set
487 if ( ! objFile
->canScatterAtoms() )
488 _internal
.allObjectFilesScatterable
= false;
490 // update minOSVersion off all .o files
491 uint32_t objMinOS
= objFile
->minOSVersion();
493 _internal
.objectFileFoundWithNoVersion
= true;
495 uint32_t objPlatformLC
= objFile
->platformLoadCommand();
496 if ( (objPlatformLC
!= 0) && (_internal
.derivedPlatformLoadCommand
== 0) && (_options
.outputKind() == Options::kObjectFile
) )
497 _internal
.derivedPlatformLoadCommand
= objPlatformLC
;
499 if ( (_options
.outputKind() == Options::kObjectFile
) && (objMinOS
> _internal
.minOSVersion
) )
500 _internal
.minOSVersion
= objMinOS
;
502 // update cpu-sub-type
503 cpu_subtype_t nextObjectSubType
= file
.cpuSubType();
504 switch ( _options
.architecture() ) {
506 if ( _options
.subArchitecture() != nextObjectSubType
) {
507 if ( (_options
.subArchitecture() == CPU_SUBTYPE_ARM_ALL
) && _options
.forceCpuSubtypeAll() ) {
508 // hack to support gcc multillib build that tries to make sub-type-all slice
510 else if ( nextObjectSubType
== CPU_SUBTYPE_ARM_ALL
) {
511 warning("CPU_SUBTYPE_ARM_ALL subtype is deprecated: %s", file
.path());
513 else if ( _options
.allowSubArchitectureMismatches() ) {
514 //warning("object file %s was built for different arm sub-type (%d) than link command line (%d)",
515 // file.path(), nextObjectSubType, _options.subArchitecture());
518 throwf("object file %s was built for different arm sub-type (%d) than link command line (%d)",
519 file
.path(), nextObjectSubType
, _options
.subArchitecture());
525 _internal
.cpuSubType
= CPU_SUBTYPE_I386_ALL
;
528 case CPU_TYPE_X86_64
:
529 if ( _options
.subArchitecture() != nextObjectSubType
) {
530 if ( _options
.allowSubArchitectureMismatches() ) {
531 warning("object file %s was built for different x86_64 sub-type (%d) than link command line (%d)",
532 file
.path(), nextObjectSubType
, _options
.subArchitecture());
535 throwf("object file %s was built for different x86_64 sub-type (%d) than link command line (%d)",
536 file
.path(), nextObjectSubType
, _options
.subArchitecture());
542 if ( dylibFile
!= NULL
) {
543 // Check dylib for bitcode, if the library install path is relative path or @rpath, it has to contain bitcode
544 if ( _options
.bundleBitcode() ) {
545 if ( dylibFile
->getBitcode() == NULL
&&
546 dylibFile
->installPath()[0] != '/' ) {
547 // Check if the dylib is from toolchain by checking the path
548 char tcLibPath
[PATH_MAX
];
549 char ldPath
[PATH_MAX
];
550 char tempPath
[PATH_MAX
];
551 uint32_t bufSize
= PATH_MAX
;
552 // toolchain library path should pointed to *.xctoolchain/usr/lib
553 if ( _NSGetExecutablePath(ldPath
, &bufSize
) != -1 ) {
554 if ( realpath(ldPath
, tempPath
) != NULL
) {
555 char* lastSlash
= strrchr(tempPath
, '/');
556 if ( lastSlash
!= NULL
)
557 strcpy(lastSlash
, "/../lib");
560 // Compare toolchain library path to the dylib path
561 if ( realpath(tempPath
, tcLibPath
) == NULL
||
562 realpath(dylibFile
->path(), tempPath
) == NULL
||
563 strncmp(tcLibPath
, tempPath
, strlen(tcLibPath
)) != 0 ) {
564 switch ( _options
.platform() ) {
565 case Options::kPlatformOSX
:
566 case Options::kPlatformUnknown
:
567 warning("all bitcode will be dropped because '%s' was built without bitcode. "
568 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file
.path());
569 _internal
.filesWithBitcode
.clear();
570 _internal
.dropAllBitcode
= true;
572 case Options::kPlatformiOS
:
573 throwf("'%s' does not contain bitcode. "
574 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file
.path());
576 case Options::kPlatformWatchOS
:
577 throwf("'%s' does not contain bitcode. "
578 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor", file
.path());
581 case Options::kPlatform_tvOS
:
582 warning("URGENT: all bitcode will be dropped because '%s' was built without bitcode. "
583 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor. "
584 "Note: This will be an error in the future.", file
.path());
585 _internal
.filesWithBitcode
.clear();
586 _internal
.dropAllBitcode
= true;
594 // update which form of ObjC dylibs are being linked
595 switch ( dylibFile
->objCConstraint() ) {
596 case ld::File::objcConstraintNone
:
598 case ld::File::objcConstraintRetainRelease
:
599 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintGC
)
600 throwf("%s built with incompatible Garbage Collection settings to link with previous dylibs", file
.path());
601 if ( _options
.objcGcOnly() )
602 throwf("command line specified -objc_gc_only, but dylib is retain/release based: %s", file
.path());
603 if ( _options
.objcGc() )
604 throwf("command line specified -objc_gc, but dylib is retain/release based: %s", file
.path());
605 if ( _options
.targetIOSSimulator() )
606 warning("linking ObjC for iOS Simulator, but dylib (%s) was compiled for MacOSX", file
.path());
607 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainRelease
;
609 case ld::File::objcConstraintRetainReleaseOrGC
:
610 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintNone
)
611 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
612 if ( _options
.targetIOSSimulator() )
613 warning("linking ObjC for iOS Simulator, but dylib (%s) was compiled for MacOSX", file
.path());
615 case ld::File::objcConstraintGC
:
616 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintRetainRelease
)
617 throwf("%s built with incompatible Garbage Collection settings to link with previous dylibs", file
.path());
618 if ( _options
.targetIOSSimulator() )
619 warning("linking ObjC for iOS Simulator, but dylib (%s) was compiled for MacOSX", file
.path());
620 _internal
.objcDylibConstraint
= ld::File::objcConstraintGC
;
622 case ld::File::objcConstraintRetainReleaseForSimulator
:
623 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintNone
)
624 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
625 else if ( _internal
.objcDylibConstraint
!= ld::File::objcConstraintRetainReleaseForSimulator
) {
626 warning("ObjC dylib (%s) was compiled for iOS Simulator, but dylibs others were compiled for MacOSX", file
.path());
627 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
631 if ( _options
.checkDylibsAreAppExtensionSafe() && !dylibFile
->appExtensionSafe() ) {
632 warning("linking against dylib not safe for use in application extensions: %s", file
.path());
634 const char* depInstallName
= dylibFile
->installPath();
635 // <rdar://problem/17229513> embedded frameworks are only supported on iOS 8 and later
636 if ( (depInstallName
!= NULL
) && (depInstallName
[0] != '/') ) {
637 if ( (_options
.iOSVersionMin() != iOSVersionUnset
) && (_options
.iOSVersionMin() < iOS_8_0
) ) {
638 // <rdar://problem/17598404> only warn about linking against embedded dylib if it is built for iOS 8 or later
639 if ( dylibFile
->minOSVersion() >= iOS_8_0
)
640 throwf("embedded dylibs/frameworks are only supported on iOS 8.0 and later (%s)", depInstallName
);
643 if ( _options
.sharedRegionEligible() ) {
644 assert(depInstallName
!= NULL
);
645 if ( depInstallName
[0] == '@' ) {
646 warning("invalid -install_name (%s) in dependent dylib (%s). Dylibs/frameworks which might go in dyld shared cache "
647 "cannot link with dylib that uses @rpath, @loader_path, etc.", depInstallName
, dylibFile
->path());
648 } else if ( (strncmp(depInstallName
, "/usr/lib/", 9) != 0) && (strncmp(depInstallName
, "/System/Library/", 16) != 0) ) {
649 warning("invalid -install_name (%s) in dependent dylib (%s). Dylibs/frameworks which might go in dyld shared cache "
650 "cannot link with dylibs that won't be in the shared cache", depInstallName
, dylibFile
->path());
657 void Resolver::doAtom(const ld::Atom
& atom
)
659 //fprintf(stderr, "Resolver::doAtom(%p), name=%s, sect=%s, scope=%d\n", &atom, atom.name(), atom.section().sectionName(), atom.scope());
660 if ( _ltoCodeGenFinished
&& (atom
.contentType() == ld::Atom::typeLTOtemporary
) && (atom
.scope() != ld::Atom::scopeTranslationUnit
) )
661 warning("'%s' is implemented in bitcode, but it was loaded too late", atom
.name());
663 // add to list of known atoms
664 _atoms
.push_back(&atom
);
667 if ( _options
.hasExportRestrictList() || _options
.hasReExportList() ) {
668 const char* name
= atom
.name();
669 switch ( atom
.scope() ) {
670 case ld::Atom::scopeTranslationUnit
:
672 case ld::Atom::scopeLinkageUnit
:
673 if ( _options
.hasExportMaskList() && _options
.shouldExport(name
) ) {
674 // <rdar://problem/5062685> ld does not report error when -r is used and exported symbols are not defined.
675 if ( _options
.outputKind() == Options::kObjectFile
)
676 throwf("cannot export hidden symbol %s", name
);
677 // .objc_class_name_* symbols are special
678 if ( atom
.section().type() != ld::Section::typeObjC1Classes
) {
679 if ( atom
.definition() == ld::Atom::definitionProxy
) {
680 // .exp file says to export a symbol, but that symbol is in some dylib being linked
681 if ( _options
.canReExportSymbols() ) {
682 // marking proxy atom as global triggers the re-export
683 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeGlobal
);
685 else if ( _options
.outputKind() == Options::kDynamicLibrary
) {
686 if ( atom
.file() != NULL
)
687 warning("target OS does not support re-exporting symbol %s from %s\n", _options
.demangleSymbol(name
), atom
.file()->path());
689 warning("target OS does not support re-exporting symbol %s\n", _options
.demangleSymbol(name
));
693 if ( atom
.file() != NULL
)
694 warning("cannot export hidden symbol %s from %s", _options
.demangleSymbol(name
), atom
.file()->path());
696 warning("cannot export hidden symbol %s", _options
.demangleSymbol(name
));
700 else if ( _options
.shouldReExport(name
) && _options
.canReExportSymbols() ) {
701 if ( atom
.definition() == ld::Atom::definitionProxy
) {
702 // marking proxy atom as global triggers the re-export
703 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeGlobal
);
706 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", _options
.demangleSymbol(name
), atom
.file()->path());
710 case ld::Atom::scopeGlobal
:
711 // check for globals that are downgraded to hidden
712 if ( ! _options
.shouldExport(name
) ) {
713 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeLinkageUnit
);
714 //fprintf(stderr, "demote %s to hidden\n", name);
716 if ( _options
.canReExportSymbols() && _options
.shouldReExport(name
) ) {
717 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", _options
.demangleSymbol(name
), atom
.file()->path());
723 // work around for kernel that uses 'l' labels in assembly code
724 if ( (atom
.symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
725 && (atom
.name()[0] == 'l') && (_options
.outputKind() == Options::kStaticExecutable
)
726 && (strncmp(atom
.name(), "ltmp", 4) != 0) )
727 (const_cast<ld::Atom
*>(&atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
730 // tell symbol table about non-static atoms
731 if ( atom
.scope() != ld::Atom::scopeTranslationUnit
) {
732 _symbolTable
.add(atom
, _options
.deadCodeStrip() && _completedInitialObjectFiles
);
734 // add symbol aliases defined on the command line
735 if ( _options
.haveCmdLineAliases() ) {
736 const std::vector
<Options::AliasPair
>& aliases
= _options
.cmdLineAliases();
737 for (std::vector
<Options::AliasPair
>::const_iterator it
=aliases
.begin(); it
!= aliases
.end(); ++it
) {
738 if ( strcmp(it
->realName
, atom
.name()) == 0 ) {
739 const AliasAtom
* alias
= new AliasAtom(atom
, it
->alias
);
740 _aliasesFromCmdLine
.push_back(alias
);
741 this->doAtom(*alias
);
747 // convert references by-name or by-content to by-slot
748 this->convertReferencesToIndirect(atom
);
750 // remember if any atoms are proxies that require LTO
751 if ( atom
.contentType() == ld::Atom::typeLTOtemporary
)
752 _haveLLVMObjs
= true;
754 // remember if any atoms are aliases
755 if ( atom
.section().type() == ld::Section::typeTempAlias
)
758 if ( _options
.deadCodeStrip() ) {
759 // add to set of dead-strip-roots, all symbols that the compiler marks as don't strip
760 if ( atom
.dontDeadStrip() )
761 _deadStripRoots
.insert(&atom
);
762 else if ( atom
.dontDeadStripIfReferencesLive() )
763 _dontDeadStripIfReferencesLive
.push_back(&atom
);
765 if ( atom
.scope() == ld::Atom::scopeGlobal
) {
766 // <rdar://problem/5524973> -exported_symbols_list that has wildcards and -dead_strip
767 // in dylibs, every global atom in initial .o files is a root
768 if ( _options
.hasWildCardExportRestrictList() || _options
.allGlobalsAreDeadStripRoots() ) {
769 if ( _options
.shouldExport(atom
.name()) )
770 _deadStripRoots
.insert(&atom
);
776 bool Resolver::isDtraceProbe(ld::Fixup::Kind kind
)
779 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
780 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
781 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
782 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
783 case ld::Fixup::kindStoreARM64DtraceCallSiteNop
:
784 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear
:
785 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
786 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
787 case ld::Fixup::kindDtraceExtra
:
795 void Resolver::convertReferencesToIndirect(const ld::Atom
& atom
)
797 // convert references by-name or by-content to by-slot
798 SymbolTable::IndirectBindingSlot slot
;
799 const ld::Atom
* dummy
;
800 ld::Fixup::iterator end
= atom
.fixupsEnd();
801 for (ld::Fixup::iterator fit
=atom
.fixupsBegin(); fit
!= end
; ++fit
) {
802 if ( fit
->kind
== ld::Fixup::kindLinkerOptimizationHint
)
803 _internal
.someObjectHasOptimizationHints
= true;
804 switch ( fit
->binding
) {
805 case ld::Fixup::bindingByNameUnbound
:
806 if ( isDtraceProbe(fit
->kind
) && (_options
.outputKind() != Options::kObjectFile
) ) {
807 // in final linked images, remove reference
808 fit
->binding
= ld::Fixup::bindingNone
;
811 slot
= _symbolTable
.findSlotForName(fit
->u
.name
);
812 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
813 fit
->u
.bindingIndex
= slot
;
816 case ld::Fixup::bindingByContentBound
:
817 switch ( fit
->u
.target
->combine() ) {
818 case ld::Atom::combineNever
:
819 case ld::Atom::combineByName
:
820 assert(0 && "wrong combine type for bind by content");
822 case ld::Atom::combineByNameAndContent
:
823 slot
= _symbolTable
.findSlotForContent(fit
->u
.target
, &dummy
);
824 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
825 fit
->u
.bindingIndex
= slot
;
827 case ld::Atom::combineByNameAndReferences
:
828 slot
= _symbolTable
.findSlotForReferences(fit
->u
.target
, &dummy
);
829 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
830 fit
->u
.bindingIndex
= slot
;
834 case ld::Fixup::bindingNone
:
835 case ld::Fixup::bindingDirectlyBound
:
836 case ld::Fixup::bindingsIndirectlyBound
:
843 void Resolver::addInitialUndefines()
845 // add initial undefines from -u option
846 for (Options::UndefinesIterator it
=_options
.initialUndefinesBegin(); it
!= _options
.initialUndefinesEnd(); ++it
) {
847 _symbolTable
.findSlotForName(*it
);
851 void Resolver::resolveUndefines()
853 // keep looping until no more undefines were added in last loop
854 unsigned int undefineGenCount
= 0xFFFFFFFF;
855 while ( undefineGenCount
!= _symbolTable
.updateCount() ) {
856 undefineGenCount
= _symbolTable
.updateCount();
857 std::vector
<const char*> undefineNames
;
858 _symbolTable
.undefines(undefineNames
);
859 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
860 const char* undef
= *it
;
861 // load for previous undefine may also have loaded this undefine, so check again
862 if ( ! _symbolTable
.hasName(undef
) ) {
863 _inputFiles
.searchLibraries(undef
, true, true, false, *this);
864 if ( !_symbolTable
.hasName(undef
) && (_options
.outputKind() != Options::kObjectFile
) ) {
865 if ( strncmp(undef
, "section$", 8) == 0 ) {
866 if ( strncmp(undef
, "section$start$", 14) == 0 ) {
867 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef
, true, &undef
[14]));
869 else if ( strncmp(undef
, "section$end$", 12) == 0 ) {
870 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef
, false, &undef
[12]));
873 else if ( strncmp(undef
, "segment$", 8) == 0 ) {
874 if ( strncmp(undef
, "segment$start$", 14) == 0 ) {
875 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef
, true, &undef
[14]));
877 else if ( strncmp(undef
, "segment$end$", 12) == 0 ) {
878 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef
, false, &undef
[12]));
881 else if ( _options
.outputKind() == Options::kPreload
) {
882 // for iBoot grandfather in old style section labels
883 int undefLen
= strlen(undef
);
884 if ( strcmp(&undef
[undefLen
-7], "__begin") == 0 ) {
886 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef
, true));
888 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef
, true));
890 else if ( strcmp(&undef
[undefLen
-5], "__end") == 0 ) {
892 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef
, false));
894 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef
, false));
900 // <rdar://problem/5894163> need to search archives for overrides of common symbols
901 if ( _symbolTable
.hasExternalTentativeDefinitions() ) {
902 bool searchDylibs
= (_options
.commonsMode() == Options::kCommonsOverriddenByDylibs
);
903 std::vector
<const char*> tents
;
904 _symbolTable
.tentativeDefs(tents
);
905 for(std::vector
<const char*>::iterator it
= tents
.begin(); it
!= tents
.end(); ++it
) {
906 // load for previous tentative may also have loaded this tentative, so check again
907 const ld::Atom
* curAtom
= _symbolTable
.atomForSlot(_symbolTable
.findSlotForName(*it
));
908 assert(curAtom
!= NULL
);
909 if ( curAtom
->definition() == ld::Atom::definitionTentative
) {
910 _inputFiles
.searchLibraries(*it
, searchDylibs
, true, true, *this);
916 // Use linker options to resolve any remaining undefined symbols
917 if ( !_internal
.linkerOptionLibraries
.empty() || !_internal
.linkerOptionFrameworks
.empty() ) {
918 std::vector
<const char*> undefineNames
;
919 _symbolTable
.undefines(undefineNames
);
920 if ( undefineNames
.size() != 0 ) {
921 for (std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
922 const char* undef
= *it
;
923 if ( ! _symbolTable
.hasName(undef
) ) {
924 _inputFiles
.searchLibraries(undef
, true, true, false, *this);
930 // create proxies as needed for undefined symbols
931 if ( (_options
.undefinedTreatment() != Options::kUndefinedError
) || (_options
.outputKind() == Options::kObjectFile
) ) {
932 std::vector
<const char*> undefineNames
;
933 _symbolTable
.undefines(undefineNames
);
934 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
935 const char* undefName
= *it
;
936 // <rdar://problem/14547001> "ld -r -exported_symbol _foo" has wrong error message if _foo is undefined
937 bool makeProxy
= true;
938 if ( (_options
.outputKind() == Options::kObjectFile
) && _options
.hasExportMaskList() && _options
.shouldExport(undefName
) )
942 this->doAtom(*new UndefinedProxyAtom(undefName
));
947 if ( _options
.someAllowedUndefines() ) {
948 std::vector
<const char*> undefineNames
;
949 _symbolTable
.undefines(undefineNames
);
950 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
951 if ( _options
.allowedUndefined(*it
) ) {
953 this->doAtom(*new UndefinedProxyAtom(*it
));
961 void Resolver::markLive(const ld::Atom
& atom
, WhyLiveBackChain
* previous
)
963 //fprintf(stderr, "markLive(%p) %s\n", &atom, atom.name());
964 // if -why_live cares about this symbol, then dump chain
965 if ( (previous
->referer
!= NULL
) && _options
.printWhyLive(atom
.name()) ) {
966 fprintf(stderr
, "%s from %s\n", atom
.name(), atom
.file()->path());
968 for(WhyLiveBackChain
* p
= previous
; p
!= NULL
; p
= p
->previous
, ++depth
) {
969 for(int i
=depth
; i
> 0; --i
)
970 fprintf(stderr
, " ");
971 fprintf(stderr
, "%s from %s\n", p
->referer
->name(), p
->referer
->file()->path());
975 // if already marked live, then done (stop recursion)
979 // mark this atom is live
980 (const_cast<ld::Atom
*>(&atom
))->setLive();
982 // mark all atoms it references as live
983 WhyLiveBackChain thisChain
;
984 thisChain
.previous
= previous
;
985 thisChain
.referer
= &atom
;
986 for (ld::Fixup::iterator fit
= atom
.fixupsBegin(), end
=atom
.fixupsEnd(); fit
!= end
; ++fit
) {
987 const ld::Atom
* target
;
988 switch ( fit
->kind
) {
989 case ld::Fixup::kindNone
:
990 case ld::Fixup::kindNoneFollowOn
:
991 case ld::Fixup::kindNoneGroupSubordinate
:
992 case ld::Fixup::kindNoneGroupSubordinateFDE
:
993 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
994 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
995 case ld::Fixup::kindSetTargetAddress
:
996 case ld::Fixup::kindSubtractTargetAddress
:
997 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
998 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
999 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1000 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1001 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1002 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1003 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1004 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1005 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1006 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1007 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1008 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1009 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1010 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1011 #if SUPPORT_ARCH_arm64
1012 case ld::Fixup::kindStoreTargetAddressARM64Branch26
:
1013 case ld::Fixup::kindStoreTargetAddressARM64Page21
:
1014 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
:
1015 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
:
1016 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPage21
:
1017 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPage21
:
1019 if ( fit
->binding
== ld::Fixup::bindingByContentBound
) {
1020 // normally this was done in convertReferencesToIndirect()
1021 // but a archive loaded .o file may have a forward reference
1022 SymbolTable::IndirectBindingSlot slot
;
1023 const ld::Atom
* dummy
;
1024 switch ( fit
->u
.target
->combine() ) {
1025 case ld::Atom::combineNever
:
1026 case ld::Atom::combineByName
:
1027 assert(0 && "wrong combine type for bind by content");
1029 case ld::Atom::combineByNameAndContent
:
1030 slot
= _symbolTable
.findSlotForContent(fit
->u
.target
, &dummy
);
1031 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
1032 fit
->u
.bindingIndex
= slot
;
1034 case ld::Atom::combineByNameAndReferences
:
1035 slot
= _symbolTable
.findSlotForReferences(fit
->u
.target
, &dummy
);
1036 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
1037 fit
->u
.bindingIndex
= slot
;
1041 switch ( fit
->binding
) {
1042 case ld::Fixup::bindingDirectlyBound
:
1043 markLive(*(fit
->u
.target
), &thisChain
);
1045 case ld::Fixup::bindingByNameUnbound
:
1046 // doAtom() did not convert to indirect in dead-strip mode, so that now
1047 fit
->u
.bindingIndex
= _symbolTable
.findSlotForName(fit
->u
.name
);
1048 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
1049 // fall into next case
1050 case ld::Fixup::bindingsIndirectlyBound
:
1051 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
1052 if ( target
== NULL
) {
1053 const char* targetName
= _symbolTable
.indirectName(fit
->u
.bindingIndex
);
1054 _inputFiles
.searchLibraries(targetName
, true, true, false, *this);
1055 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
1057 if ( target
!= NULL
) {
1058 if ( target
->definition() == ld::Atom::definitionTentative
) {
1059 // <rdar://problem/5894163> need to search archives for overrides of common symbols
1060 bool searchDylibs
= (_options
.commonsMode() == Options::kCommonsOverriddenByDylibs
);
1061 _inputFiles
.searchLibraries(target
->name(), searchDylibs
, true, true, *this);
1062 // recompute target since it may have been overridden by searchLibraries()
1063 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
1065 this->markLive(*target
, &thisChain
);
1068 _atomsWithUnresolvedReferences
.push_back(&atom
);
1072 assert(0 && "bad binding during dead stripping");
1084 bool operator()(const ld::Atom
* atom
) const {
1085 if (atom
->live() || atom
->dontDeadStrip() )
1087 // don't kill combinable atoms in first pass
1088 switch ( atom
->combine() ) {
1089 case ld::Atom::combineByNameAndContent
:
1090 case ld::Atom::combineByNameAndReferences
:
1098 void Resolver::deadStripOptimize(bool force
)
1100 // only do this optimization with -dead_strip
1101 if ( ! _options
.deadCodeStrip() )
1104 // add entry point (main) to live roots
1105 const ld::Atom
* entry
= this->entryPoint(true);
1106 if ( entry
!= NULL
)
1107 _deadStripRoots
.insert(entry
);
1109 // add -exported_symbols_list, -init, and -u entries to live roots
1110 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1111 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName(*uit
);
1112 if ( _internal
.indirectBindingTable
[slot
] == NULL
) {
1113 _inputFiles
.searchLibraries(*uit
, false, true, false, *this);
1115 if ( _internal
.indirectBindingTable
[slot
] != NULL
)
1116 _deadStripRoots
.insert(_internal
.indirectBindingTable
[slot
]);
1119 // this helper is only referenced by synthesize stubs, assume it will be used
1120 if ( _internal
.classicBindingHelper
!= NULL
)
1121 _deadStripRoots
.insert(_internal
.classicBindingHelper
);
1123 // this helper is only referenced by synthesize stubs, assume it will be used
1124 if ( _internal
.compressedFastBinderProxy
!= NULL
)
1125 _deadStripRoots
.insert(_internal
.compressedFastBinderProxy
);
1127 // this helper is only referenced by synthesized lazy stubs, assume it will be used
1128 if ( _internal
.lazyBindingHelper
!= NULL
)
1129 _deadStripRoots
.insert(_internal
.lazyBindingHelper
);
1131 // add all dont-dead-strip atoms as roots
1132 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1133 const ld::Atom
* atom
= *it
;
1134 if ( atom
->dontDeadStrip() ) {
1135 //fprintf(stderr, "dont dead strip: %p %s %s\n", atom, atom->section().sectionName(), atom->name());
1136 _deadStripRoots
.insert(atom
);
1137 // unset liveness, so markLive() will recurse
1138 (const_cast<ld::Atom
*>(atom
))->setLive(0);
1142 // mark all roots as live, and all atoms they reference
1143 for (std::set
<const ld::Atom
*>::iterator it
=_deadStripRoots
.begin(); it
!= _deadStripRoots
.end(); ++it
) {
1144 WhyLiveBackChain rootChain
;
1145 rootChain
.previous
= NULL
;
1146 rootChain
.referer
= *it
;
1147 this->markLive(**it
, &rootChain
);
1150 // special case atoms that need to be live if they reference something live
1151 if ( ! _dontDeadStripIfReferencesLive
.empty() ) {
1152 for (std::vector
<const ld::Atom
*>::iterator it
=_dontDeadStripIfReferencesLive
.begin(); it
!= _dontDeadStripIfReferencesLive
.end(); ++it
) {
1153 const Atom
* liveIfRefLiveAtom
= *it
;
1154 //fprintf(stderr, "live-if-live atom: %s\n", liveIfRefLiveAtom->name());
1155 if ( liveIfRefLiveAtom
->live() )
1157 bool hasLiveRef
= false;
1158 for (ld::Fixup::iterator fit
=liveIfRefLiveAtom
->fixupsBegin(); fit
!= liveIfRefLiveAtom
->fixupsEnd(); ++fit
) {
1159 const Atom
* target
= NULL
;
1160 switch ( fit
->binding
) {
1161 case ld::Fixup::bindingDirectlyBound
:
1162 target
= fit
->u
.target
;
1164 case ld::Fixup::bindingsIndirectlyBound
:
1165 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
1170 if ( (target
!= NULL
) && target
->live() )
1174 WhyLiveBackChain rootChain
;
1175 rootChain
.previous
= NULL
;
1176 rootChain
.referer
= liveIfRefLiveAtom
;
1177 this->markLive(*liveIfRefLiveAtom
, &rootChain
);
1182 // now remove all non-live atoms from _atoms
1183 const bool log
= false;
1185 fprintf(stderr
, "deadStripOptimize() all %ld atoms with liveness:\n", _atoms
.size());
1186 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1187 const ld::File
* file
= (*it
)->file();
1188 fprintf(stderr
, " live=%d atom=%p name=%s from=%s\n", (*it
)->live(), *it
, (*it
)->name(), (file
? file
->path() : "<internal>"));
1192 if ( _haveLLVMObjs
&& !force
) {
1193 // <rdar://problem/9777977> don't remove combinable atoms, they may come back in lto output
1194 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), NotLiveLTO()), _atoms
.end());
1195 _symbolTable
.removeDeadAtoms();
1198 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), NotLive()), _atoms
.end());
1202 fprintf(stderr
, "deadStripOptimize() %ld remaining atoms\n", _atoms
.size());
1203 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1204 fprintf(stderr
, " live=%d atom=%p name=%s\n", (*it
)->live(), *it
, (*it
)->name());
1210 // This is called when LTO is used but -dead_strip is not used.
1211 // Some undefines were eliminated by LTO, but others were not.
1212 void Resolver::remainingUndefines(std::vector
<const char*>& undefs
)
1215 // search all atoms for references that are unbound
1216 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1217 const ld::Atom
* atom
= *it
;
1218 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
1219 switch ( (ld::Fixup::TargetBinding
)fit
->binding
) {
1220 case ld::Fixup::bindingByNameUnbound
:
1221 assert(0 && "should not be by-name this late");
1222 undefSet
.insert(fit
->u
.name
);
1224 case ld::Fixup::bindingsIndirectlyBound
:
1225 if ( _internal
.indirectBindingTable
[fit
->u
.bindingIndex
] == NULL
) {
1226 undefSet
.insert(_symbolTable
.indirectName(fit
->u
.bindingIndex
));
1229 case ld::Fixup::bindingByContentBound
:
1230 case ld::Fixup::bindingNone
:
1231 case ld::Fixup::bindingDirectlyBound
:
1236 // look for any initial undefines that are still undefined
1237 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1238 if ( ! _symbolTable
.hasName(*uit
) ) {
1239 undefSet
.insert(*uit
);
1243 // copy set to vector
1244 for (StringSet::const_iterator it
=undefSet
.begin(); it
!= undefSet
.end(); ++it
) {
1245 fprintf(stderr
, "undef: %s\n", *it
);
1246 undefs
.push_back(*it
);
1250 void Resolver::liveUndefines(std::vector
<const char*>& undefs
)
1253 // search all live atoms for references that are unbound
1254 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1255 const ld::Atom
* atom
= *it
;
1256 if ( ! atom
->live() )
1258 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
1259 switch ( (ld::Fixup::TargetBinding
)fit
->binding
) {
1260 case ld::Fixup::bindingByNameUnbound
:
1261 assert(0 && "should not be by-name this late");
1262 undefSet
.insert(fit
->u
.name
);
1264 case ld::Fixup::bindingsIndirectlyBound
:
1265 if ( _internal
.indirectBindingTable
[fit
->u
.bindingIndex
] == NULL
) {
1266 undefSet
.insert(_symbolTable
.indirectName(fit
->u
.bindingIndex
));
1269 case ld::Fixup::bindingByContentBound
:
1270 case ld::Fixup::bindingNone
:
1271 case ld::Fixup::bindingDirectlyBound
:
1276 // look for any initial undefines that are still undefined
1277 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1278 if ( ! _symbolTable
.hasName(*uit
) ) {
1279 undefSet
.insert(*uit
);
1283 // copy set to vector
1284 for (StringSet::const_iterator it
=undefSet
.begin(); it
!= undefSet
.end(); ++it
) {
1285 undefs
.push_back(*it
);
1291 // <rdar://problem/8252819> warn when .objc_class_name_* symbol missing
1292 class ExportedObjcClass
1295 ExportedObjcClass(const Options
& opt
) : _options(opt
) {}
1297 bool operator()(const char* name
) const {
1298 if ( (strncmp(name
, ".objc_class_name_", 17) == 0) && _options
.shouldExport(name
) ) {
1299 warning("ignoring undefined symbol %s from -exported_symbols_list", name
);
1302 const char* s
= strstr(name
, "CLASS_$_");
1304 char temp
[strlen(name
)+16];
1305 strcpy(temp
, ".objc_class_name_");
1306 strcat(temp
, &s
[8]);
1307 if ( _options
.wasRemovedExport(temp
) ) {
1308 warning("ignoring undefined symbol %s from -exported_symbols_list", temp
);
1315 const Options
& _options
;
1319 // temp hack for undefined aliases
1320 class UndefinedAlias
1323 UndefinedAlias(const Options
& opt
) : _aliases(opt
.cmdLineAliases()) {}
1325 bool operator()(const char* name
) const {
1326 for (std::vector
<Options::AliasPair
>::const_iterator it
=_aliases
.begin(); it
!= _aliases
.end(); ++it
) {
1327 if ( strcmp(it
->realName
, name
) == 0 ) {
1328 warning("undefined base symbol '%s' for alias '%s'", name
, it
->alias
);
1335 const std::vector
<Options::AliasPair
>& _aliases
;
1340 static const char* pathLeafName(const char* path
)
1342 const char* shortPath
= strrchr(path
, '/');
1343 if ( shortPath
== NULL
)
1346 return &shortPath
[1];
1349 bool Resolver::printReferencedBy(const char* name
, SymbolTable::IndirectBindingSlot slot
)
1351 unsigned foundReferenceCount
= 0;
1352 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1353 const ld::Atom
* atom
= *it
;
1354 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
1355 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
1356 if ( fit
->u
.bindingIndex
== slot
) {
1357 if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
1358 const ld::Atom
* existingAtom
;
1359 unsigned int nlSlot
= _symbolTable
.findSlotForReferences(atom
, &existingAtom
);
1360 if ( printReferencedBy(name
, nlSlot
) )
1361 ++foundReferenceCount
;
1363 else if ( atom
->contentType() == ld::Atom::typeCFI
) {
1364 fprintf(stderr
, " Dwarf Exception Unwind Info (__eh_frame) in %s\n", pathLeafName(atom
->file()->path()));
1365 ++foundReferenceCount
;
1368 fprintf(stderr
, " %s in %s\n", _options
.demangleSymbol(atom
->name()), pathLeafName(atom
->file()->path()));
1369 ++foundReferenceCount
;
1370 break; // if undefined used twice in a function, only show first
1375 if ( foundReferenceCount
> 6 ) {
1376 fprintf(stderr
, " ...\n");
1377 break; // only show first six uses of undefined symbol
1380 return (foundReferenceCount
!= 0);
1383 void Resolver::checkUndefines(bool force
)
1385 // when using LTO, undefines are checked after bitcode is optimized
1386 if ( _haveLLVMObjs
&& !force
)
1389 // error out on any remaining undefines
1390 bool doPrint
= true;
1391 bool doError
= true;
1392 switch ( _options
.undefinedTreatment() ) {
1393 case Options::kUndefinedError
:
1395 case Options::kUndefinedDynamicLookup
:
1398 case Options::kUndefinedWarning
:
1401 case Options::kUndefinedSuppress
:
1406 std::vector
<const char*> unresolvableUndefines
;
1407 if ( _options
.deadCodeStrip() )
1408 this->liveUndefines(unresolvableUndefines
);
1409 else if( _haveLLVMObjs
)
1410 this->remainingUndefines(unresolvableUndefines
); // <rdar://problem/10052396> LTO may have eliminated need for some undefines
1412 _symbolTable
.undefines(unresolvableUndefines
);
1414 // <rdar://problem/8252819> assert when .objc_class_name_* symbol missing
1415 if ( _options
.hasExportMaskList() ) {
1416 unresolvableUndefines
.erase(std::remove_if(unresolvableUndefines
.begin(), unresolvableUndefines
.end(), ExportedObjcClass(_options
)), unresolvableUndefines
.end());
1419 // hack to temporarily make missing aliases a warning
1420 if ( _options
.haveCmdLineAliases() ) {
1421 unresolvableUndefines
.erase(std::remove_if(unresolvableUndefines
.begin(), unresolvableUndefines
.end(), UndefinedAlias(_options
)), unresolvableUndefines
.end());
1424 const int unresolvableCount
= unresolvableUndefines
.size();
1425 int unresolvableExportsCount
= 0;
1426 if ( unresolvableCount
!= 0 ) {
1428 if ( _options
.printArchPrefix() )
1429 fprintf(stderr
, "Undefined symbols for architecture %s:\n", _options
.architectureName());
1431 fprintf(stderr
, "Undefined symbols:\n");
1432 for (int i
=0; i
< unresolvableCount
; ++i
) {
1433 const char* name
= unresolvableUndefines
[i
];
1434 unsigned int slot
= _symbolTable
.findSlotForName(name
);
1435 fprintf(stderr
, " \"%s\", referenced from:\n", _options
.demangleSymbol(name
));
1436 // scan all atoms for references
1437 bool foundAtomReference
= printReferencedBy(name
, slot
);
1438 // scan command line options
1439 if ( !foundAtomReference
) {
1440 // might be from -init command line option
1441 if ( (_options
.initFunctionName() != NULL
) && (strcmp(name
, _options
.initFunctionName()) == 0) ) {
1442 fprintf(stderr
, " -init command line option\n");
1444 // or might be from exported symbol option
1445 else if ( _options
.hasExportMaskList() && _options
.shouldExport(name
) ) {
1446 fprintf(stderr
, " -exported_symbol[s_list] command line option\n");
1448 // or might be from re-exported symbol option
1449 else if ( _options
.hasReExportList() && _options
.shouldReExport(name
) ) {
1450 fprintf(stderr
, " -reexported_symbols_list command line option\n");
1452 else if ( (_options
.outputKind() == Options::kDynamicExecutable
)
1453 && (_options
.entryName() != NULL
) && (strcmp(name
, _options
.entryName()) == 0) ) {
1454 fprintf(stderr
, " implicit entry/start for main executable\n");
1457 bool isInitialUndefine
= false;
1458 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1459 if ( strcmp(*uit
, name
) == 0 ) {
1460 isInitialUndefine
= true;
1464 if ( isInitialUndefine
)
1465 fprintf(stderr
, " -u command line option\n");
1467 ++unresolvableExportsCount
;
1469 // be helpful and check for typos
1470 bool printedStart
= false;
1471 for (SymbolTable::byNameIterator sit
=_symbolTable
.begin(); sit
!= _symbolTable
.end(); sit
++) {
1472 const ld::Atom
* atom
= *sit
;
1473 if ( (atom
!= NULL
) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
) && (strstr(atom
->name(), name
) != NULL
) ) {
1474 if ( ! printedStart
) {
1475 fprintf(stderr
, " (maybe you meant: %s", atom
->name());
1476 printedStart
= true;
1479 fprintf(stderr
, ", %s ", atom
->name());
1484 fprintf(stderr
, ")\n");
1485 // <rdar://problem/8989530> Add comment to error message when __ZTV symbols are undefined
1486 if ( strncmp(name
, "__ZTV", 5) == 0 ) {
1487 fprintf(stderr
, " NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.\n");
1492 throw "symbol(s) not found";
1499 void Resolver::checkDylibSymbolCollisions()
1501 for (SymbolTable::byNameIterator it
=_symbolTable
.begin(); it
!= _symbolTable
.end(); it
++) {
1502 const ld::Atom
* atom
= *it
;
1505 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1506 // <rdar://problem/5048861> No warning about tentative definition conflicting with dylib definition
1507 // for each tentative definition in symbol table look for dylib that exports same symbol name
1508 if ( atom
->definition() == ld::Atom::definitionTentative
) {
1509 _inputFiles
.searchLibraries(atom
->name(), true, false, false, *this);
1511 // record any overrides of weak symbols in any linked dylib
1512 if ( (atom
->definition() == ld::Atom::definitionRegular
) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
) ) {
1513 if ( _inputFiles
.searchWeakDefInDylib(atom
->name()) )
1514 (const_cast<ld::Atom
*>(atom
))->setOverridesDylibsWeakDef();
1521 const ld::Atom
* Resolver::entryPoint(bool searchArchives
)
1523 const char* symbolName
= NULL
;
1524 bool makingDylib
= false;
1525 switch ( _options
.outputKind() ) {
1526 case Options::kDynamicExecutable
:
1527 case Options::kStaticExecutable
:
1528 case Options::kDyld
:
1529 case Options::kPreload
:
1530 symbolName
= _options
.entryName();
1532 case Options::kDynamicLibrary
:
1533 symbolName
= _options
.initFunctionName();
1536 case Options::kObjectFile
:
1537 case Options::kDynamicBundle
:
1538 case Options::kKextBundle
:
1542 if ( symbolName
!= NULL
) {
1543 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName(symbolName
);
1544 if ( (_internal
.indirectBindingTable
[slot
] == NULL
) && searchArchives
) {
1545 // <rdar://problem/7043256> ld64 can not find a -e entry point from an archive
1546 _inputFiles
.searchLibraries(symbolName
, false, true, false, *this);
1548 if ( _internal
.indirectBindingTable
[slot
] == NULL
) {
1549 if ( strcmp(symbolName
, "start") == 0 )
1550 throwf("entry point (%s) undefined. Usually in crt1.o", symbolName
);
1552 throwf("entry point (%s) undefined.", symbolName
);
1554 else if ( _internal
.indirectBindingTable
[slot
]->definition() == ld::Atom::definitionProxy
) {
1556 throwf("-init function (%s) found in linked dylib, must be in dylib being linked", symbolName
);
1558 return _internal
.indirectBindingTable
[slot
];
1564 void Resolver::fillInHelpersInInternalState()
1566 // look up well known atoms
1567 bool needsStubHelper
= true;
1568 switch ( _options
.outputKind() ) {
1569 case Options::kDynamicExecutable
:
1570 case Options::kDynamicLibrary
:
1571 case Options::kDynamicBundle
:
1572 needsStubHelper
= true;
1574 case Options::kDyld
:
1575 case Options::kKextBundle
:
1576 case Options::kObjectFile
:
1577 case Options::kStaticExecutable
:
1578 case Options::kPreload
:
1579 needsStubHelper
= false;
1583 _internal
.classicBindingHelper
= NULL
;
1584 if ( needsStubHelper
&& !_options
.makeCompressedDyldInfo() ) {
1585 // "dyld_stub_binding_helper" comes from .o file, so should already exist in symbol table
1586 if ( _symbolTable
.hasName("dyld_stub_binding_helper") ) {
1587 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_stub_binding_helper");
1588 _internal
.classicBindingHelper
= _internal
.indirectBindingTable
[slot
];
1592 _internal
.lazyBindingHelper
= NULL
;
1593 if ( _options
.usingLazyDylibLinking() ) {
1594 // "dyld_lazy_dylib_stub_binding_helper" comes from lazydylib1.o file, so should already exist in symbol table
1595 if ( _symbolTable
.hasName("dyld_lazy_dylib_stub_binding_helper") ) {
1596 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_lazy_dylib_stub_binding_helper");
1597 _internal
.lazyBindingHelper
= _internal
.indirectBindingTable
[slot
];
1599 if ( _internal
.lazyBindingHelper
== NULL
)
1600 throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
1603 _internal
.compressedFastBinderProxy
= NULL
;
1604 if ( needsStubHelper
&& _options
.makeCompressedDyldInfo() ) {
1605 // "dyld_stub_binder" comes from libSystem.dylib so will need to manually resolve
1606 if ( !_symbolTable
.hasName("dyld_stub_binder") ) {
1607 _inputFiles
.searchLibraries("dyld_stub_binder", true, false, false, *this);
1609 if ( _symbolTable
.hasName("dyld_stub_binder") ) {
1610 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_stub_binder");
1611 _internal
.compressedFastBinderProxy
= _internal
.indirectBindingTable
[slot
];
1613 if ( _internal
.compressedFastBinderProxy
== NULL
) {
1614 if ( _options
.undefinedTreatment() != Options::kUndefinedError
) {
1616 _internal
.compressedFastBinderProxy
= new UndefinedProxyAtom("dyld_stub_binder");
1617 this->doAtom(*_internal
.compressedFastBinderProxy
);
1624 void Resolver::fillInInternalState()
1626 // store atoms into their final section
1627 for (std::vector
<const ld::Atom
*>::iterator it
= _atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1628 _internal
.addAtom(**it
);
1631 // <rdar://problem/7783918> make sure there is a __text section so that codesigning works
1632 if ( (_options
.outputKind() == Options::kDynamicLibrary
) || (_options
.outputKind() == Options::kDynamicBundle
) )
1633 _internal
.getFinalSection(*new ld::Section("__TEXT", "__text", ld::Section::typeCode
));
1636 void Resolver::fillInEntryPoint()
1638 _internal
.entryPoint
= this->entryPoint(true);
1641 void Resolver::syncAliases()
1643 if ( !_haveAliases
|| (_options
.outputKind() == Options::kObjectFile
) )
1646 // Set attributes of alias to match its found target
1647 for (std::vector
<const ld::Atom
*>::iterator it
= _atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1648 const ld::Atom
* atom
= *it
;
1649 if ( atom
->section().type() == ld::Section::typeTempAlias
) {
1650 assert(atom
->fixupsBegin() != atom
->fixupsEnd());
1651 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
1652 const ld::Atom
* target
;
1653 ld::Atom::Scope scope
;
1654 assert(fit
->kind
== ld::Fixup::kindNoneFollowOn
);
1655 switch ( fit
->binding
) {
1656 case ld::Fixup::bindingByNameUnbound
:
1658 case ld::Fixup::bindingsIndirectlyBound
:
1659 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
1660 assert(target
!= NULL
);
1661 scope
= atom
->scope();
1662 (const_cast<Atom
*>(atom
))->setAttributesFromAtom(*target
);
1663 // alias has same attributes as target, except for scope
1664 (const_cast<Atom
*>(atom
))->setScope(scope
);
1667 assert(0 && "internal error: unexpected alias binding");
1674 void Resolver::removeCoalescedAwayAtoms()
1676 const bool log
= false;
1678 fprintf(stderr
, "removeCoalescedAwayAtoms() starts with %lu atoms\n", _atoms
.size());
1680 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), AtomCoalescedAway()), _atoms
.end());
1682 fprintf(stderr
, "removeCoalescedAwayAtoms() after removing coalesced atoms, %lu remain\n", _atoms
.size());
1683 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1684 fprintf(stderr
, " atom=%p %s\n", *it
, (*it
)->name());
1689 void Resolver::linkTimeOptimize()
1691 // only do work here if some llvm obj files where loaded
1692 if ( ! _haveLLVMObjs
)
1695 // <rdar://problem/15314161> LTO: Symbol multiply defined error should specify exactly where the symbol is found
1696 _symbolTable
.checkDuplicateSymbols();
1698 // run LLVM lto code-gen
1699 lto::OptimizeOptions optOpt
;
1700 optOpt
.outputFilePath
= _options
.outputFilePath();
1701 optOpt
.tmpObjectFilePath
= _options
.tempLtoObjectPath();
1702 optOpt
.preserveAllGlobals
= _options
.allGlobalsAreDeadStripRoots() || _options
.hasExportRestrictList();
1703 optOpt
.verbose
= _options
.verbose();
1704 optOpt
.saveTemps
= _options
.saveTempFiles();
1705 optOpt
.ltoCodegenOnly
= _options
.ltoCodegenOnly();
1706 optOpt
.pie
= _options
.positionIndependentExecutable();
1707 optOpt
.mainExecutable
= _options
.linkingMainExecutable();;
1708 optOpt
.staticExecutable
= (_options
.outputKind() == Options::kStaticExecutable
);
1709 optOpt
.relocatable
= (_options
.outputKind() == Options::kObjectFile
);
1710 optOpt
.allowTextRelocs
= _options
.allowTextRelocs();
1711 optOpt
.linkerDeadStripping
= _options
.deadCodeStrip();
1712 optOpt
.needsUnwindInfoSection
= _options
.needsUnwindInfoSection();
1713 optOpt
.keepDwarfUnwind
= _options
.keepDwarfUnwind();
1714 optOpt
.verboseOptimizationHints
= _options
.verboseOptimizationHints();
1715 optOpt
.armUsesZeroCostExceptions
= _options
.armUsesZeroCostExceptions();
1716 optOpt
.simulator
= _options
.targetIOSSimulator();
1717 optOpt
.ignoreMismatchPlatform
= ((_options
.outputKind() == Options::kPreload
) || (_options
.outputKind() == Options::kStaticExecutable
));
1718 optOpt
.bitcodeBundle
= _options
.bundleBitcode();
1719 optOpt
.arch
= _options
.architecture();
1720 optOpt
.mcpu
= _options
.mcpuLTO();
1721 optOpt
.platform
= _options
.platform();
1722 optOpt
.llvmOptions
= &_options
.llvmOptions();
1723 optOpt
.initialUndefines
= &_options
.initialUndefines();
1725 std::vector
<const ld::Atom
*> newAtoms
;
1726 std::vector
<const char*> additionalUndefines
;
1727 if ( ! lto::optimize(_atoms
, _internal
, optOpt
, *this, newAtoms
, additionalUndefines
) )
1728 return; // if nothing done
1729 _ltoCodeGenFinished
= true;
1731 // add all newly created atoms to _atoms and update symbol table
1732 for(std::vector
<const ld::Atom
*>::iterator it
= newAtoms
.begin(); it
!= newAtoms
.end(); ++it
)
1735 // some atoms might have been optimized way (marked coalesced), remove them
1736 this->removeCoalescedAwayAtoms();
1738 // run through all atoms again and make sure newly codegened atoms have references bound
1739 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
)
1740 this->convertReferencesToIndirect(**it
);
1742 // adjust section of any new
1743 for (std::vector
<const AliasAtom
*>::const_iterator it
=_aliasesFromCmdLine
.begin(); it
!= _aliasesFromCmdLine
.end(); ++it
) {
1744 const AliasAtom
* aliasAtom
= *it
;
1745 // update fields in AliasAtom to match newly constructed mach-o atom
1746 aliasAtom
->setFinalAliasOf();
1749 // <rdar://problem/14609792> add any auto-link libraries requested by LTO output to dylibs to search
1750 _inputFiles
.addLinkerOptionLibraries(_internal
, *this);
1751 _inputFiles
.createIndirectDylibs();
1753 // resolve new undefines (e.g calls to _malloc and _memcpy that llvm compiler conjures up)
1754 for(std::vector
<const char*>::iterator uit
= additionalUndefines
.begin(); uit
!= additionalUndefines
.end(); ++uit
) {
1755 const char *targetName
= *uit
;
1756 // these symbols may or may not already be in linker's symbol table
1757 if ( ! _symbolTable
.hasName(targetName
) ) {
1758 _inputFiles
.searchLibraries(targetName
, true, true, false, *this);
1762 // if -dead_strip on command line
1763 if ( _options
.deadCodeStrip() ) {
1764 // clear liveness bit
1765 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1766 (const_cast<ld::Atom
*>(*it
))->setLive((*it
)->dontDeadStrip());
1768 // and re-compute dead code
1769 this->deadStripOptimize(true);
1772 // <rdar://problem/12386559> if -exported_symbols_list on command line, re-force scope
1773 if ( _options
.hasExportMaskList() ) {
1774 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1775 const ld::Atom
* atom
= *it
;
1776 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1777 if ( !_options
.shouldExport(atom
->name()) ) {
1778 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1784 if ( _options
.outputKind() == Options::kObjectFile
) {
1785 // if -r mode, add proxies for new undefines (e.g. ___stack_chk_fail)
1786 this->resolveUndefines();
1789 // last chance to check for undefines
1790 this->resolveUndefines();
1791 this->checkUndefines(true);
1793 // check new code does not override some dylib
1794 this->checkDylibSymbolCollisions();
1799 void Resolver::tweakWeakness()
1801 // <rdar://problem/7977374> Add command line options to control symbol weak-def bit on exported symbols
1802 if ( _options
.hasWeakBitTweaks() ) {
1803 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= _internal
.sections
.begin(); sit
!= _internal
.sections
.end(); ++sit
) {
1804 ld::Internal::FinalSection
* sect
= *sit
;
1805 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1806 const ld::Atom
* atom
= *ait
;
1807 if ( atom
->definition() != ld::Atom::definitionRegular
)
1809 const char* name
= atom
->name();
1810 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1811 if ( atom
->combine() == ld::Atom::combineNever
) {
1812 if ( _options
.forceWeak(name
) )
1813 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineByName
);
1815 else if ( atom
->combine() == ld::Atom::combineByName
) {
1816 if ( _options
.forceNotWeak(name
) )
1817 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineNever
);
1821 if ( _options
.forceWeakNonWildCard(name
) )
1822 warning("cannot force to be weak, non-external symbol %s", name
);
1823 else if ( _options
.forceNotWeakNonWildcard(name
) )
1824 warning("cannot force to be not-weak, non-external symbol %s", name
);
1831 void Resolver::dumpAtoms()
1833 fprintf(stderr
, "Resolver all atoms:\n");
1834 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1835 const ld::Atom
* atom
= *it
;
1836 fprintf(stderr
, " %p name=%s, def=%d\n", atom
, atom
->name(), atom
->definition());
1840 void Resolver::resolve()
1842 this->initializeState();
1843 this->buildAtomList();
1844 this->addInitialUndefines();
1845 this->fillInHelpersInInternalState();
1846 this->resolveUndefines();
1847 this->deadStripOptimize();
1848 this->checkUndefines();
1849 this->checkDylibSymbolCollisions();
1850 this->syncAliases();
1851 this->removeCoalescedAwayAtoms();
1852 this->fillInEntryPoint();
1853 this->linkTimeOptimize();
1854 this->fillInInternalState();
1855 this->tweakWeakness();
1856 _symbolTable
.checkDuplicateSymbols();