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 "InputFiles.h"
57 #include "SymbolTable.h"
59 #include "parsers/lto_file.h"
67 // An ExportAtom has no content. It exists so that the linker can track which imported
68 // symbols came from which dynamic libraries.
70 class UndefinedProxyAtom
: public ld::Atom
73 UndefinedProxyAtom(const char* nm
)
74 : ld::Atom(_s_section
, ld::Atom::definitionProxy
,
75 ld::Atom::combineNever
, ld::Atom::scopeLinkageUnit
,
76 ld::Atom::typeUnclassified
,
77 ld::Atom::symbolTableIn
, false, false, false, ld::Atom::Alignment(0)),
79 // overrides of ld::Atom
80 virtual const ld::File
* file() const { return NULL
; }
81 virtual const char* name() const { return _name
; }
82 virtual uint64_t size() const { return 0; }
83 virtual uint64_t objectAddress() const { return 0; }
84 virtual void copyRawContent(uint8_t buffer
[]) const { }
85 virtual void setScope(Scope
) { }
89 virtual ~UndefinedProxyAtom() {}
93 static ld::Section _s_section
;
96 ld::Section
UndefinedProxyAtom::_s_section("__TEXT", "__import", ld::Section::typeImportProxies
, true);
101 class AliasAtom
: public ld::Atom
104 AliasAtom(const ld::Atom
& target
, const char* nm
) :
105 ld::Atom(target
.section(), target
.definition(), ld::Atom::combineNever
,
106 ld::Atom::scopeGlobal
, target
.contentType(),
107 target
.symbolTableInclusion(), target
.dontDeadStrip(),
108 target
.isThumb(), true, target
.alignment()),
111 _fixup(0, ld::Fixup::k1of1
, ld::Fixup::kindNoneFollowOn
, &target
) { }
113 // overrides of ld::Atom
114 virtual const ld::File
* file() const { return _aliasOf
.file(); }
115 virtual const char* translationUnitSource() const
116 { return _aliasOf
.translationUnitSource(); }
117 virtual const char* name() const { return _name
; }
118 virtual uint64_t size() const { return 0; }
119 virtual uint64_t objectAddress() const { return _aliasOf
.objectAddress(); }
120 virtual void copyRawContent(uint8_t buffer
[]) const { }
121 virtual const uint8_t* rawContentPointer() const { return NULL
; }
122 virtual unsigned long contentHash(const class ld::IndirectBindingTable
& ibt
) const
123 { return _aliasOf
.contentHash(ibt
); }
124 virtual bool canCoalesceWith(const ld::Atom
& rhs
, const class ld::IndirectBindingTable
& ibt
) const
125 { return _aliasOf
.canCoalesceWith(rhs
,ibt
); }
126 virtual ld::Fixup::iterator
fixupsBegin() const { return (ld::Fixup
*)&_fixup
; }
127 virtual ld::Fixup::iterator
fixupsEnd() const { return &((ld::Fixup
*)&_fixup
)[1]; }
128 virtual ld::Atom::UnwindInfo::iterator
beginUnwind() const { return NULL
; }
129 virtual ld::Atom::UnwindInfo::iterator
endUnwind() const { return NULL
; }
130 virtual ld::Atom::LineInfo::iterator
beginLineInfo() const { return NULL
; }
131 virtual ld::Atom::LineInfo::iterator
endLineInfo() const { return NULL
; }
133 void setFinalAliasOf() const {
134 (const_cast<AliasAtom
*>(this))->setAttributesFromAtom(_aliasOf
);
135 (const_cast<AliasAtom
*>(this))->setScope(ld::Atom::scopeGlobal
);
140 const ld::Atom
& _aliasOf
;
146 class SectionBoundaryAtom
: public ld::Atom
149 static SectionBoundaryAtom
* makeSectionBoundaryAtom(const char* name
, bool start
, const char* segSectName
);
150 static SectionBoundaryAtom
* makeOldSectionBoundaryAtom(const char* name
, bool start
);
152 // overrides of ld::Atom
153 virtual const ld::File
* file() const { return NULL
; }
154 virtual const char* name() const { return _name
; }
155 virtual uint64_t size() const { return 0; }
156 virtual void copyRawContent(uint8_t buffer
[]) const { }
157 virtual const uint8_t* rawContentPointer() const { return NULL
; }
158 virtual uint64_t objectAddress() const { return 0; }
162 SectionBoundaryAtom(const char* nm
, const ld::Section
& sect
,
163 ld::Atom::ContentType cont
) :
165 ld::Atom::definitionRegular
,
166 ld::Atom::combineNever
,
167 ld::Atom::scopeLinkageUnit
,
169 ld::Atom::symbolTableNotIn
,
170 false, false, true, ld::Atom::Alignment(0)),
176 SectionBoundaryAtom
* SectionBoundaryAtom::makeSectionBoundaryAtom(const char* name
, bool start
, const char* segSectName
)
179 const char* segSectDividor
= strrchr(segSectName
, '$');
180 if ( segSectDividor
== NULL
)
181 throwf("malformed section$ symbol name: %s", name
);
182 const char* sectionName
= segSectDividor
+ 1;
183 int segNameLen
= segSectDividor
- segSectName
;
184 if ( segNameLen
> 16 )
185 throwf("malformed section$ symbol name: %s", name
);
187 strlcpy(segName
, segSectName
, segNameLen
+1);
189 const ld::Section
* section
= new ld::Section(strdup(segName
), sectionName
, ld::Section::typeUnclassified
);
190 return new SectionBoundaryAtom(name
, *section
, (start
? ld::Atom::typeSectionStart
: typeSectionEnd
));
193 SectionBoundaryAtom
* SectionBoundaryAtom::makeOldSectionBoundaryAtom(const char* name
, bool start
)
195 // e.g. __DATA__bss__begin
197 strlcpy(segName
, name
, 7);
200 int nameLen
= strlen(name
);
201 strlcpy(sectName
, &name
[6], (start
? nameLen
-12 : nameLen
-10));
202 warning("grandfathering in old symbol '%s' as alias for 'section$%s$%s$%s'", name
, start
? "start" : "end", segName
, sectName
);
203 const ld::Section
* section
= new ld::Section(strdup(segName
), strdup(sectName
), ld::Section::typeUnclassified
);
204 return new SectionBoundaryAtom(name
, *section
, (start
? ld::Atom::typeSectionStart
: typeSectionEnd
));
210 class SegmentBoundaryAtom
: public ld::Atom
213 static SegmentBoundaryAtom
* makeSegmentBoundaryAtom(const char* name
, bool start
, const char* segName
);
214 static SegmentBoundaryAtom
* makeOldSegmentBoundaryAtom(const char* name
, bool start
);
216 // overrides of ld::Atom
217 virtual const ld::File
* file() const { return NULL
; }
218 virtual const char* name() const { return _name
; }
219 virtual uint64_t size() const { return 0; }
220 virtual void copyRawContent(uint8_t buffer
[]) const { }
221 virtual const uint8_t* rawContentPointer() const { return NULL
; }
222 virtual uint64_t objectAddress() const { return 0; }
226 SegmentBoundaryAtom(const char* nm
, const ld::Section
& sect
,
227 ld::Atom::ContentType cont
) :
229 ld::Atom::definitionRegular
,
230 ld::Atom::combineNever
,
231 ld::Atom::scopeLinkageUnit
,
233 ld::Atom::symbolTableNotIn
,
234 false, false, true, ld::Atom::Alignment(0)),
240 SegmentBoundaryAtom
* SegmentBoundaryAtom::makeSegmentBoundaryAtom(const char* name
, bool start
, const char* segName
)
242 if ( *segName
== '\0' )
243 throwf("malformed segment$ symbol name: %s", name
);
244 if ( strlen(segName
) > 16 )
245 throwf("malformed segment$ symbol name: %s", name
);
248 const ld::Section
* section
= new ld::Section(segName
, "__start", ld::Section::typeFirstSection
, true);
249 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionStart
);
252 const ld::Section
* section
= new ld::Section(segName
, "__end", ld::Section::typeLastSection
, true);
253 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionEnd
);
257 SegmentBoundaryAtom
* SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(const char* name
, bool start
)
259 // e.g. __DATA__begin
261 strlcpy(temp
, name
, 7);
262 char* segName
= strdup(temp
);
264 warning("grandfathering in old symbol '%s' as alias for 'segment$%s$%s'", name
, start
? "start" : "end", segName
);
267 const ld::Section
* section
= new ld::Section(segName
, "__start", ld::Section::typeFirstSection
, true);
268 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionStart
);
271 const ld::Section
* section
= new ld::Section(segName
, "__end", ld::Section::typeLastSection
, true);
272 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionEnd
);
276 void Resolver::initializeState()
278 // set initial objc constraint based on command line options
279 if ( _options
.objcGc() )
280 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
281 else if ( _options
.objcGcOnly() )
282 _internal
.objcObjectConstraint
= ld::File::objcConstraintGC
;
284 _internal
.cpuSubType
= _options
.subArchitecture();
286 // In -r mode, look for -linker_option additions
287 if ( _options
.outputKind() == Options::kObjectFile
) {
288 ld::relocatable::File::LinkerOptionsList lo
= _options
.linkerOptions();
289 for (relocatable::File::LinkerOptionsList::const_iterator it
=lo
.begin(); it
!= lo
.end(); ++it
) {
290 doLinkerOption(*it
, "command line");
295 void Resolver::buildAtomList()
297 // each input files contributes initial atoms
298 _atoms
.reserve(1024);
299 _inputFiles
.forEachInitialAtom(*this, _internal
);
301 _completedInitialObjectFiles
= true;
303 //_symbolTable.printStatistics();
307 void Resolver::doLinkerOption(const std::vector
<const char*>& linkerOption
, const char* fileName
)
309 if ( linkerOption
.size() == 1 ) {
310 const char* lo1
= linkerOption
.front();
311 if ( strncmp(lo1
, "-l", 2) == 0 ) {
312 _internal
.linkerOptionLibraries
.insert(&lo1
[2]);
315 warning("unknown linker option from object file ignored: '%s' in %s", lo1
, fileName
);
318 else if ( linkerOption
.size() == 2 ) {
319 const char* lo2a
= linkerOption
[0];
320 const char* lo2b
= linkerOption
[1];
321 if ( strcmp(lo2a
, "-framework") == 0 ) {
322 _internal
.linkerOptionFrameworks
.insert(lo2b
);
325 warning("unknown linker option from object file ignored: '%s' '%s' from %s", lo2a
, lo2b
, fileName
);
329 warning("unknown linker option from object file ignored, starting with: '%s' from %s", linkerOption
.front(), fileName
);
333 void Resolver::doFile(const ld::File
& file
)
335 const ld::relocatable::File
* objFile
= dynamic_cast<const ld::relocatable::File
*>(&file
);
336 const ld::dylib::File
* dylibFile
= dynamic_cast<const ld::dylib::File
*>(&file
);
338 if ( objFile
!= NULL
) {
339 // if file has linker options, process them
340 ld::relocatable::File::LinkerOptionsList
* lo
= objFile
->linkerOptions();
342 for (relocatable::File::LinkerOptionsList::const_iterator it
=lo
->begin(); it
!= lo
->end(); ++it
) {
343 this->doLinkerOption(*it
, file
.path());
347 // update which form of ObjC is being used
348 switch ( file
.objCConstraint() ) {
349 case ld::File::objcConstraintNone
:
351 case ld::File::objcConstraintRetainRelease
:
352 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintGC
)
353 throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", file
.path());
354 if ( _options
.objcGcOnly() )
355 throwf("command line specified -objc_gc_only, but file is retain/release based: %s", file
.path());
356 if ( _options
.objcGc() )
357 throwf("command line specified -objc_gc, but file is retain/release based: %s", file
.path());
358 if ( !_options
.targetIOSSimulator() && (_internal
.objcObjectConstraint
!= ld::File::objcConstraintRetainReleaseForSimulator
) )
359 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainRelease
;
361 case ld::File::objcConstraintRetainReleaseOrGC
:
362 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintNone
)
363 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
364 if ( _options
.targetIOSSimulator() )
365 warning("linking ObjC for iOS Simulator, but object file (%s) was compiled for MacOSX", file
.path());
367 case ld::File::objcConstraintGC
:
368 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintRetainRelease
)
369 throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", file
.path());
370 _internal
.objcObjectConstraint
= ld::File::objcConstraintGC
;
371 if ( _options
.targetIOSSimulator() )
372 warning("linking ObjC for iOS Simulator, but object file (%s) was compiled for MacOSX", file
.path());
374 case ld::File::objcConstraintRetainReleaseForSimulator
:
375 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintNone
) {
376 if ( !_options
.targetIOSSimulator() && (_options
.outputKind() != Options::kObjectFile
) )
377 warning("ObjC object file (%s) was compiled for iOS Simulator, but linking for MacOSX", file
.path());
378 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
380 else if ( _internal
.objcObjectConstraint
!= ld::File::objcConstraintRetainReleaseForSimulator
) {
381 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
386 // in -r mode, if any .o files have dwarf then add UUID to output .o file
387 if ( objFile
->debugInfo() == ld::relocatable::File::kDebugInfoDwarf
)
388 _internal
.someObjectFileHasDwarf
= true;
390 // remember if any .o file did not have MH_SUBSECTIONS_VIA_SYMBOLS bit set
391 if ( ! objFile
->canScatterAtoms() )
392 _internal
.allObjectFilesScatterable
= false;
394 // update cpu-sub-type
395 cpu_subtype_t nextObjectSubType
= file
.cpuSubType();
396 switch ( _options
.architecture() ) {
398 if ( _options
.subArchitecture() != nextObjectSubType
) {
399 if ( (_options
.subArchitecture() == CPU_SUBTYPE_ARM_ALL
) && _options
.forceCpuSubtypeAll() ) {
400 // hack to support gcc multillib build that tries to make sub-type-all slice
402 else if ( nextObjectSubType
== CPU_SUBTYPE_ARM_ALL
) {
403 warning("CPU_SUBTYPE_ARM_ALL subtype is deprecated: %s", file
.path());
405 else if ( _options
.allowSubArchitectureMismatches() ) {
406 //warning("object file %s was built for different arm sub-type (%d) than link command line (%d)",
407 // file.path(), nextObjectSubType, _options.subArchitecture());
410 throwf("object file %s was built for different arm sub-type (%d) than link command line (%d)",
411 file
.path(), nextObjectSubType
, _options
.subArchitecture());
417 _internal
.cpuSubType
= CPU_SUBTYPE_I386_ALL
;
420 case CPU_TYPE_X86_64
:
421 if ( _options
.subArchitecture() != nextObjectSubType
) {
422 if ( _options
.allowSubArchitectureMismatches() ) {
423 warning("object file %s was built for different x86_64 sub-type (%d) than link command line (%d)",
424 file
.path(), nextObjectSubType
, _options
.subArchitecture());
427 throwf("object file %s was built for different x86_64 sub-type (%d) than link command line (%d)",
428 file
.path(), nextObjectSubType
, _options
.subArchitecture());
434 if ( dylibFile
!= NULL
) {
435 // update which form of ObjC dylibs are being linked
436 switch ( dylibFile
->objCConstraint() ) {
437 case ld::File::objcConstraintNone
:
439 case ld::File::objcConstraintRetainRelease
:
440 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintGC
)
441 throwf("%s built with incompatible Garbage Collection settings to link with previous dylibs", file
.path());
442 if ( _options
.objcGcOnly() )
443 throwf("command line specified -objc_gc_only, but dylib is retain/release based: %s", file
.path());
444 if ( _options
.objcGc() )
445 throwf("command line specified -objc_gc, but dylib is retain/release based: %s", file
.path());
446 if ( _options
.targetIOSSimulator() )
447 warning("linking ObjC for iOS Simulator, but dylib (%s) was compiled for MacOSX", file
.path());
448 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainRelease
;
450 case ld::File::objcConstraintRetainReleaseOrGC
:
451 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintNone
)
452 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
453 if ( _options
.targetIOSSimulator() )
454 warning("linking ObjC for iOS Simulator, but dylib (%s) was compiled for MacOSX", file
.path());
456 case ld::File::objcConstraintGC
:
457 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintRetainRelease
)
458 throwf("%s built with incompatible Garbage Collection settings to link with previous dylibs", file
.path());
459 if ( _options
.targetIOSSimulator() )
460 warning("linking ObjC for iOS Simulator, but dylib (%s) was compiled for MacOSX", file
.path());
461 _internal
.objcDylibConstraint
= ld::File::objcConstraintGC
;
463 case ld::File::objcConstraintRetainReleaseForSimulator
:
464 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintNone
)
465 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
466 else if ( _internal
.objcDylibConstraint
!= ld::File::objcConstraintRetainReleaseForSimulator
) {
467 warning("ObjC dylib (%s) was compiled for iOS Simulator, but dylibs others were compiled for MacOSX", file
.path());
468 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseForSimulator
;
476 void Resolver::doAtom(const ld::Atom
& atom
)
478 //fprintf(stderr, "Resolver::doAtom(%p), name=%s, sect=%s, scope=%d\n", &atom, atom.name(), atom.section().sectionName(), atom.scope());
479 if ( _ltoCodeGenFinished
&& (atom
.contentType() == ld::Atom::typeLTOtemporary
) && (atom
.scope() != ld::Atom::scopeTranslationUnit
) )
480 warning("'%s' is implemented in bitcode, but it was loaded too late", atom
.name());
482 // add to list of known atoms
483 _atoms
.push_back(&atom
);
486 if ( _options
.hasExportRestrictList() || _options
.hasReExportList() ) {
487 const char* name
= atom
.name();
488 switch ( atom
.scope() ) {
489 case ld::Atom::scopeTranslationUnit
:
491 case ld::Atom::scopeLinkageUnit
:
492 if ( _options
.hasExportMaskList() && _options
.shouldExport(name
) ) {
493 // <rdar://problem/5062685> ld does not report error when -r is used and exported symbols are not defined.
494 if ( _options
.outputKind() == Options::kObjectFile
)
495 throwf("cannot export hidden symbol %s", name
);
496 // .objc_class_name_* symbols are special
497 if ( atom
.section().type() != ld::Section::typeObjC1Classes
) {
498 if ( atom
.definition() == ld::Atom::definitionProxy
) {
499 // .exp file says to export a symbol, but that symbol is in some dylib being linked
500 if ( _options
.canReExportSymbols() ) {
501 // marking proxy atom as global triggers the re-export
502 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeGlobal
);
504 else if ( _options
.outputKind() == Options::kDynamicLibrary
) {
505 if ( atom
.file() != NULL
)
506 warning("target OS does not support re-exporting symbol %s from %s\n", _options
.demangleSymbol(name
), atom
.file()->path());
508 warning("target OS does not support re-exporting symbol %s\n", _options
.demangleSymbol(name
));
512 if ( atom
.file() != NULL
)
513 warning("cannot export hidden symbol %s from %s", _options
.demangleSymbol(name
), atom
.file()->path());
515 warning("cannot export hidden symbol %s", _options
.demangleSymbol(name
));
519 else if ( _options
.shouldReExport(name
) && _options
.canReExportSymbols() ) {
520 if ( atom
.definition() == ld::Atom::definitionProxy
) {
521 // marking proxy atom as global triggers the re-export
522 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeGlobal
);
525 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", _options
.demangleSymbol(name
), atom
.file()->path());
529 case ld::Atom::scopeGlobal
:
530 // check for globals that are downgraded to hidden
531 if ( ! _options
.shouldExport(name
) ) {
532 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeLinkageUnit
);
533 //fprintf(stderr, "demote %s to hidden\n", name);
535 if ( _options
.canReExportSymbols() && _options
.shouldReExport(name
) ) {
536 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", _options
.demangleSymbol(name
), atom
.file()->path());
542 // work around for kernel that uses 'l' labels in assembly code
543 if ( (atom
.symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
544 && (atom
.name()[0] == 'l') && (_options
.outputKind() == Options::kStaticExecutable
)
545 && (strncmp(atom
.name(), "ltmp", 4) != 0) )
546 (const_cast<ld::Atom
*>(&atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
549 // tell symbol table about non-static atoms
550 if ( atom
.scope() != ld::Atom::scopeTranslationUnit
) {
551 _symbolTable
.add(atom
, _options
.deadCodeStrip() && _completedInitialObjectFiles
);
553 // add symbol aliases defined on the command line
554 if ( _options
.haveCmdLineAliases() ) {
555 const std::vector
<Options::AliasPair
>& aliases
= _options
.cmdLineAliases();
556 for (std::vector
<Options::AliasPair
>::const_iterator it
=aliases
.begin(); it
!= aliases
.end(); ++it
) {
557 if ( strcmp(it
->realName
, atom
.name()) == 0 ) {
558 const AliasAtom
* alias
= new AliasAtom(atom
, it
->alias
);
559 _aliasesFromCmdLine
.push_back(alias
);
560 this->doAtom(*alias
);
566 // convert references by-name or by-content to by-slot
567 this->convertReferencesToIndirect(atom
);
569 // remember if any atoms are proxies that require LTO
570 if ( atom
.contentType() == ld::Atom::typeLTOtemporary
)
571 _haveLLVMObjs
= true;
573 if ( _options
.deadCodeStrip() ) {
574 // add to set of dead-strip-roots, all symbols that the compiler marks as don't strip
575 if ( atom
.dontDeadStrip() )
576 _deadStripRoots
.insert(&atom
);
578 if ( atom
.scope() == ld::Atom::scopeGlobal
) {
579 // <rdar://problem/5524973> -exported_symbols_list that has wildcards and -dead_strip
580 // in dylibs, every global atom in initial .o files is a root
581 if ( _options
.hasWildCardExportRestrictList() || _options
.allGlobalsAreDeadStripRoots() ) {
582 if ( _options
.shouldExport(atom
.name()) )
583 _deadStripRoots
.insert(&atom
);
589 bool Resolver::isDtraceProbe(ld::Fixup::Kind kind
)
592 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
593 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
594 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
595 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
596 case ld::Fixup::kindStoreARM64DtraceCallSiteNop
:
597 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear
:
598 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
599 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
600 case ld::Fixup::kindDtraceExtra
:
608 void Resolver::convertReferencesToIndirect(const ld::Atom
& atom
)
610 // convert references by-name or by-content to by-slot
611 SymbolTable::IndirectBindingSlot slot
;
612 const ld::Atom
* dummy
;
613 ld::Fixup::iterator end
= atom
.fixupsEnd();
614 for (ld::Fixup::iterator fit
=atom
.fixupsBegin(); fit
!= end
; ++fit
) {
615 if ( fit
->kind
== ld::Fixup::kindLinkerOptimizationHint
)
616 _internal
.someObjectHasOptimizationHints
= true;
617 switch ( fit
->binding
) {
618 case ld::Fixup::bindingByNameUnbound
:
619 if ( isDtraceProbe(fit
->kind
) && (_options
.outputKind() != Options::kObjectFile
) ) {
620 // in final linked images, remove reference
621 fit
->binding
= ld::Fixup::bindingNone
;
624 slot
= _symbolTable
.findSlotForName(fit
->u
.name
);
625 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
626 fit
->u
.bindingIndex
= slot
;
629 case ld::Fixup::bindingByContentBound
:
630 switch ( fit
->u
.target
->combine() ) {
631 case ld::Atom::combineNever
:
632 case ld::Atom::combineByName
:
633 assert(0 && "wrong combine type for bind by content");
635 case ld::Atom::combineByNameAndContent
:
636 slot
= _symbolTable
.findSlotForContent(fit
->u
.target
, &dummy
);
637 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
638 fit
->u
.bindingIndex
= slot
;
640 case ld::Atom::combineByNameAndReferences
:
641 slot
= _symbolTable
.findSlotForReferences(fit
->u
.target
, &dummy
);
642 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
643 fit
->u
.bindingIndex
= slot
;
647 case ld::Fixup::bindingNone
:
648 case ld::Fixup::bindingDirectlyBound
:
649 case ld::Fixup::bindingsIndirectlyBound
:
656 void Resolver::addInitialUndefines()
658 // add initial undefines from -u option
659 for (Options::UndefinesIterator it
=_options
.initialUndefinesBegin(); it
!= _options
.initialUndefinesEnd(); ++it
) {
660 _symbolTable
.findSlotForName(*it
);
664 void Resolver::resolveUndefines()
666 // keep looping until no more undefines were added in last loop
667 unsigned int undefineGenCount
= 0xFFFFFFFF;
668 while ( undefineGenCount
!= _symbolTable
.updateCount() ) {
669 undefineGenCount
= _symbolTable
.updateCount();
670 std::vector
<const char*> undefineNames
;
671 _symbolTable
.undefines(undefineNames
);
672 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
673 const char* undef
= *it
;
674 // load for previous undefine may also have loaded this undefine, so check again
675 if ( ! _symbolTable
.hasName(undef
) ) {
676 _inputFiles
.searchLibraries(undef
, true, true, false, *this);
677 if ( !_symbolTable
.hasName(undef
) && (_options
.outputKind() != Options::kObjectFile
) ) {
678 if ( strncmp(undef
, "section$", 8) == 0 ) {
679 if ( strncmp(undef
, "section$start$", 14) == 0 ) {
680 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef
, true, &undef
[14]));
682 else if ( strncmp(undef
, "section$end$", 12) == 0 ) {
683 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef
, false, &undef
[12]));
686 else if ( strncmp(undef
, "segment$", 8) == 0 ) {
687 if ( strncmp(undef
, "segment$start$", 14) == 0 ) {
688 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef
, true, &undef
[14]));
690 else if ( strncmp(undef
, "segment$end$", 12) == 0 ) {
691 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef
, false, &undef
[12]));
694 else if ( _options
.outputKind() == Options::kPreload
) {
695 // for iBoot grandfather in old style section labels
696 int undefLen
= strlen(undef
);
697 if ( strcmp(&undef
[undefLen
-7], "__begin") == 0 ) {
699 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef
, true));
701 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef
, true));
703 else if ( strcmp(&undef
[undefLen
-5], "__end") == 0 ) {
705 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef
, false));
707 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef
, false));
713 // <rdar://problem/5894163> need to search archives for overrides of common symbols
714 if ( _symbolTable
.hasExternalTentativeDefinitions() ) {
715 bool searchDylibs
= (_options
.commonsMode() == Options::kCommonsOverriddenByDylibs
);
716 std::vector
<const char*> tents
;
717 _symbolTable
.tentativeDefs(tents
);
718 for(std::vector
<const char*>::iterator it
= tents
.begin(); it
!= tents
.end(); ++it
) {
719 // load for previous tentative may also have loaded this tentative, so check again
720 const ld::Atom
* curAtom
= _symbolTable
.atomForSlot(_symbolTable
.findSlotForName(*it
));
721 assert(curAtom
!= NULL
);
722 if ( curAtom
->definition() == ld::Atom::definitionTentative
) {
723 _inputFiles
.searchLibraries(*it
, searchDylibs
, true, true, *this);
729 // Use linker options to resolve an remaining undefined symbols
730 if ( !_internal
.linkerOptionLibraries
.empty() || !_internal
.linkerOptionFrameworks
.empty() ) {
731 std::vector
<const char*> undefineNames
;
732 _symbolTable
.undefines(undefineNames
);
733 if ( undefineNames
.size() != 0 ) {
734 for (std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
735 const char* undef
= *it
;
736 if ( ! _symbolTable
.hasName(undef
) ) {
737 _inputFiles
.searchLibraries(undef
, true, true, false, *this);
743 // create proxies as needed for undefined symbols
744 if ( (_options
.undefinedTreatment() != Options::kUndefinedError
) || (_options
.outputKind() == Options::kObjectFile
) ) {
745 std::vector
<const char*> undefineNames
;
746 _symbolTable
.undefines(undefineNames
);
747 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
748 const char* undefName
= *it
;
749 // <rdar://problem/14547001> "ld -r -exported_symbol _foo" has wrong error message if _foo is undefined
750 bool makeProxy
= true;
751 if ( (_options
.outputKind() == Options::kObjectFile
) && _options
.hasExportMaskList() && _options
.shouldExport(undefName
) )
755 this->doAtom(*new UndefinedProxyAtom(undefName
));
760 if ( _options
.someAllowedUndefines() ) {
761 std::vector
<const char*> undefineNames
;
762 _symbolTable
.undefines(undefineNames
);
763 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
764 if ( _options
.allowedUndefined(*it
) ) {
766 this->doAtom(*new UndefinedProxyAtom(*it
));
774 void Resolver::markLive(const ld::Atom
& atom
, WhyLiveBackChain
* previous
)
776 //fprintf(stderr, "markLive(%p) %s\n", &atom, atom.name());
777 // if -why_live cares about this symbol, then dump chain
778 if ( (previous
->referer
!= NULL
) && _options
.printWhyLive(atom
.name()) ) {
779 fprintf(stderr
, "%s from %s\n", atom
.name(), atom
.file()->path());
781 for(WhyLiveBackChain
* p
= previous
; p
!= NULL
; p
= p
->previous
, ++depth
) {
782 for(int i
=depth
; i
> 0; --i
)
783 fprintf(stderr
, " ");
784 fprintf(stderr
, "%s from %s\n", p
->referer
->name(), p
->referer
->file()->path());
788 // if already marked live, then done (stop recursion)
792 // mark this atom is live
793 (const_cast<ld::Atom
*>(&atom
))->setLive();
795 // mark all atoms it references as live
796 WhyLiveBackChain thisChain
;
797 thisChain
.previous
= previous
;
798 thisChain
.referer
= &atom
;
799 for (ld::Fixup::iterator fit
= atom
.fixupsBegin(), end
=atom
.fixupsEnd(); fit
!= end
; ++fit
) {
800 const ld::Atom
* target
;
801 switch ( fit
->kind
) {
802 case ld::Fixup::kindNone
:
803 case ld::Fixup::kindNoneFollowOn
:
804 case ld::Fixup::kindNoneGroupSubordinate
:
805 case ld::Fixup::kindNoneGroupSubordinateFDE
:
806 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
807 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
808 case ld::Fixup::kindSetTargetAddress
:
809 case ld::Fixup::kindSubtractTargetAddress
:
810 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
811 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
812 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
813 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
814 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
815 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
816 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
817 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
818 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
819 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
820 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
821 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
822 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
823 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
824 #if SUPPORT_ARCH_arm64
825 case ld::Fixup::kindStoreTargetAddressARM64Branch26
:
826 case ld::Fixup::kindStoreTargetAddressARM64Page21
:
827 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
:
828 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
:
830 if ( fit
->binding
== ld::Fixup::bindingByContentBound
) {
831 // normally this was done in convertReferencesToIndirect()
832 // but a archive loaded .o file may have a forward reference
833 SymbolTable::IndirectBindingSlot slot
;
834 const ld::Atom
* dummy
;
835 switch ( fit
->u
.target
->combine() ) {
836 case ld::Atom::combineNever
:
837 case ld::Atom::combineByName
:
838 assert(0 && "wrong combine type for bind by content");
840 case ld::Atom::combineByNameAndContent
:
841 slot
= _symbolTable
.findSlotForContent(fit
->u
.target
, &dummy
);
842 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
843 fit
->u
.bindingIndex
= slot
;
845 case ld::Atom::combineByNameAndReferences
:
846 slot
= _symbolTable
.findSlotForReferences(fit
->u
.target
, &dummy
);
847 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
848 fit
->u
.bindingIndex
= slot
;
852 switch ( fit
->binding
) {
853 case ld::Fixup::bindingDirectlyBound
:
854 markLive(*(fit
->u
.target
), &thisChain
);
856 case ld::Fixup::bindingByNameUnbound
:
857 // doAtom() did not convert to indirect in dead-strip mode, so that now
858 fit
->u
.bindingIndex
= _symbolTable
.findSlotForName(fit
->u
.name
);
859 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
860 // fall into next case
861 case ld::Fixup::bindingsIndirectlyBound
:
862 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
863 if ( target
== NULL
) {
864 const char* targetName
= _symbolTable
.indirectName(fit
->u
.bindingIndex
);
865 _inputFiles
.searchLibraries(targetName
, true, true, false, *this);
866 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
868 if ( target
!= NULL
) {
869 if ( target
->definition() == ld::Atom::definitionTentative
) {
870 // <rdar://problem/5894163> need to search archives for overrides of common symbols
871 bool searchDylibs
= (_options
.commonsMode() == Options::kCommonsOverriddenByDylibs
);
872 _inputFiles
.searchLibraries(target
->name(), searchDylibs
, true, true, *this);
873 // recompute target since it may have been overridden by searchLibraries()
874 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
876 this->markLive(*target
, &thisChain
);
879 _atomsWithUnresolvedReferences
.push_back(&atom
);
883 assert(0 && "bad binding during dead stripping");
895 bool operator()(const ld::Atom
* atom
) const {
896 if (atom
->live() || atom
->dontDeadStrip() )
898 // don't kill combinable atoms in first pass
899 switch ( atom
->combine() ) {
900 case ld::Atom::combineByNameAndContent
:
901 case ld::Atom::combineByNameAndReferences
:
909 void Resolver::deadStripOptimize(bool force
)
911 // only do this optimization with -dead_strip
912 if ( ! _options
.deadCodeStrip() )
915 // add entry point (main) to live roots
916 const ld::Atom
* entry
= this->entryPoint(true);
918 _deadStripRoots
.insert(entry
);
920 // add -exported_symbols_list, -init, and -u entries to live roots
921 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
922 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName(*uit
);
923 if ( _internal
.indirectBindingTable
[slot
] == NULL
) {
924 _inputFiles
.searchLibraries(*uit
, false, true, false, *this);
926 if ( _internal
.indirectBindingTable
[slot
] != NULL
)
927 _deadStripRoots
.insert(_internal
.indirectBindingTable
[slot
]);
930 // this helper is only referenced by synthesize stubs, assume it will be used
931 if ( _internal
.classicBindingHelper
!= NULL
)
932 _deadStripRoots
.insert(_internal
.classicBindingHelper
);
934 // this helper is only referenced by synthesize stubs, assume it will be used
935 if ( _internal
.compressedFastBinderProxy
!= NULL
)
936 _deadStripRoots
.insert(_internal
.compressedFastBinderProxy
);
938 // this helper is only referenced by synthesized lazy stubs, assume it will be used
939 if ( _internal
.lazyBindingHelper
!= NULL
)
940 _deadStripRoots
.insert(_internal
.lazyBindingHelper
);
942 // add all dont-dead-strip atoms as roots
943 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
944 const ld::Atom
* atom
= *it
;
945 if ( atom
->dontDeadStrip() ) {
946 //fprintf(stderr, "dont dead strip: %p %s %s\n", atom, atom->section().sectionName(), atom->name());
947 _deadStripRoots
.insert(atom
);
948 // unset liveness, so markLive() will recurse
949 (const_cast<ld::Atom
*>(atom
))->setLive(0);
953 // mark all roots as live, and all atoms they reference
954 for (std::set
<const ld::Atom
*>::iterator it
=_deadStripRoots
.begin(); it
!= _deadStripRoots
.end(); ++it
) {
955 WhyLiveBackChain rootChain
;
956 rootChain
.previous
= NULL
;
957 rootChain
.referer
= *it
;
958 this->markLive(**it
, &rootChain
);
961 // now remove all non-live atoms from _atoms
962 const bool log
= false;
964 fprintf(stderr
, "deadStripOptimize() all %ld atoms with liveness:\n", _atoms
.size());
965 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
966 const ld::File
* file
= (*it
)->file();
967 fprintf(stderr
, " live=%d atom=%p name=%s from=%s\n", (*it
)->live(), *it
, (*it
)->name(), (file
? file
->path() : "<internal>"));
971 if ( _haveLLVMObjs
&& !force
) {
972 // <rdar://problem/9777977> don't remove combinable atoms, they may come back in lto output
973 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), NotLiveLTO()), _atoms
.end());
974 _symbolTable
.removeDeadAtoms();
977 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), NotLive()), _atoms
.end());
981 fprintf(stderr
, "deadStripOptimize() %ld remaining atoms\n", _atoms
.size());
982 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
983 fprintf(stderr
, " live=%d atom=%p name=%s\n", (*it
)->live(), *it
, (*it
)->name());
989 // This is called when LTO is used but -dead_strip is not used.
990 // Some undefines were eliminated by LTO, but others were not.
991 void Resolver::remainingUndefines(std::vector
<const char*>& undefs
)
994 // search all atoms for references that are unbound
995 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
996 const ld::Atom
* atom
= *it
;
997 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
998 switch ( (ld::Fixup::TargetBinding
)fit
->binding
) {
999 case ld::Fixup::bindingByNameUnbound
:
1000 assert(0 && "should not be by-name this late");
1001 undefSet
.insert(fit
->u
.name
);
1003 case ld::Fixup::bindingsIndirectlyBound
:
1004 if ( _internal
.indirectBindingTable
[fit
->u
.bindingIndex
] == NULL
) {
1005 undefSet
.insert(_symbolTable
.indirectName(fit
->u
.bindingIndex
));
1008 case ld::Fixup::bindingByContentBound
:
1009 case ld::Fixup::bindingNone
:
1010 case ld::Fixup::bindingDirectlyBound
:
1015 // look for any initial undefines that are still undefined
1016 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1017 if ( ! _symbolTable
.hasName(*uit
) ) {
1018 undefSet
.insert(*uit
);
1022 // copy set to vector
1023 for (StringSet::const_iterator it
=undefSet
.begin(); it
!= undefSet
.end(); ++it
) {
1024 fprintf(stderr
, "undef: %s\n", *it
);
1025 undefs
.push_back(*it
);
1029 void Resolver::liveUndefines(std::vector
<const char*>& undefs
)
1032 // search all live atoms for references that are unbound
1033 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1034 const ld::Atom
* atom
= *it
;
1035 if ( ! atom
->live() )
1037 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
1038 switch ( (ld::Fixup::TargetBinding
)fit
->binding
) {
1039 case ld::Fixup::bindingByNameUnbound
:
1040 assert(0 && "should not be by-name this late");
1041 undefSet
.insert(fit
->u
.name
);
1043 case ld::Fixup::bindingsIndirectlyBound
:
1044 if ( _internal
.indirectBindingTable
[fit
->u
.bindingIndex
] == NULL
) {
1045 undefSet
.insert(_symbolTable
.indirectName(fit
->u
.bindingIndex
));
1048 case ld::Fixup::bindingByContentBound
:
1049 case ld::Fixup::bindingNone
:
1050 case ld::Fixup::bindingDirectlyBound
:
1055 // look for any initial undefines that are still undefined
1056 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1057 if ( ! _symbolTable
.hasName(*uit
) ) {
1058 undefSet
.insert(*uit
);
1062 // copy set to vector
1063 for (StringSet::const_iterator it
=undefSet
.begin(); it
!= undefSet
.end(); ++it
) {
1064 undefs
.push_back(*it
);
1070 // <rdar://problem/8252819> warn when .objc_class_name_* symbol missing
1071 class ExportedObjcClass
1074 ExportedObjcClass(const Options
& opt
) : _options(opt
) {}
1076 bool operator()(const char* name
) const {
1077 if ( (strncmp(name
, ".objc_class_name_", 17) == 0) && _options
.shouldExport(name
) ) {
1078 warning("ignoring undefined symbol %s from -exported_symbols_list", name
);
1081 const char* s
= strstr(name
, "CLASS_$_");
1083 char temp
[strlen(name
)+16];
1084 strcpy(temp
, ".objc_class_name_");
1085 strcat(temp
, &s
[8]);
1086 if ( _options
.wasRemovedExport(temp
) ) {
1087 warning("ignoring undefined symbol %s from -exported_symbols_list", temp
);
1094 const Options
& _options
;
1098 // temp hack for undefined aliases
1099 class UndefinedAlias
1102 UndefinedAlias(const Options
& opt
) : _aliases(opt
.cmdLineAliases()) {}
1104 bool operator()(const char* name
) const {
1105 for (std::vector
<Options::AliasPair
>::const_iterator it
=_aliases
.begin(); it
!= _aliases
.end(); ++it
) {
1106 if ( strcmp(it
->realName
, name
) == 0 ) {
1107 warning("undefined base symbol '%s' for alias '%s'", name
, it
->alias
);
1114 const std::vector
<Options::AliasPair
>& _aliases
;
1119 static const char* pathLeafName(const char* path
)
1121 const char* shortPath
= strrchr(path
, '/');
1122 if ( shortPath
== NULL
)
1125 return &shortPath
[1];
1128 bool Resolver::printReferencedBy(const char* name
, SymbolTable::IndirectBindingSlot slot
)
1130 unsigned foundReferenceCount
= 0;
1131 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1132 const ld::Atom
* atom
= *it
;
1133 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
1134 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
1135 if ( fit
->u
.bindingIndex
== slot
) {
1136 if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
1137 const ld::Atom
* existingAtom
;
1138 unsigned int nlSlot
= _symbolTable
.findSlotForReferences(atom
, &existingAtom
);
1139 if ( printReferencedBy(name
, nlSlot
) )
1140 ++foundReferenceCount
;
1142 else if ( atom
->contentType() == ld::Atom::typeCFI
) {
1143 fprintf(stderr
, " Dwarf Exception Unwind Info (__eh_frame) in %s\n", pathLeafName(atom
->file()->path()));
1144 ++foundReferenceCount
;
1147 fprintf(stderr
, " %s in %s\n", _options
.demangleSymbol(atom
->name()), pathLeafName(atom
->file()->path()));
1148 ++foundReferenceCount
;
1149 break; // if undefined used twice in a function, only show first
1154 if ( foundReferenceCount
> 6 ) {
1155 fprintf(stderr
, " ...\n");
1156 break; // only show first six uses of undefined symbol
1159 return (foundReferenceCount
!= 0);
1162 void Resolver::checkUndefines(bool force
)
1164 // when using LTO, undefines are checked after bitcode is optimized
1165 if ( _haveLLVMObjs
&& !force
)
1168 // error out on any remaining undefines
1169 bool doPrint
= true;
1170 bool doError
= true;
1171 switch ( _options
.undefinedTreatment() ) {
1172 case Options::kUndefinedError
:
1174 case Options::kUndefinedDynamicLookup
:
1177 case Options::kUndefinedWarning
:
1180 case Options::kUndefinedSuppress
:
1185 std::vector
<const char*> unresolvableUndefines
;
1186 if ( _options
.deadCodeStrip() )
1187 this->liveUndefines(unresolvableUndefines
);
1188 else if( _haveLLVMObjs
)
1189 this->remainingUndefines(unresolvableUndefines
); // <rdar://problem/10052396> LTO may have eliminated need for some undefines
1191 _symbolTable
.undefines(unresolvableUndefines
);
1193 // <rdar://problem/8252819> assert when .objc_class_name_* symbol missing
1194 if ( _options
.hasExportMaskList() ) {
1195 unresolvableUndefines
.erase(std::remove_if(unresolvableUndefines
.begin(), unresolvableUndefines
.end(), ExportedObjcClass(_options
)), unresolvableUndefines
.end());
1198 // hack to temporarily make missing aliases a warning
1199 if ( _options
.haveCmdLineAliases() ) {
1200 unresolvableUndefines
.erase(std::remove_if(unresolvableUndefines
.begin(), unresolvableUndefines
.end(), UndefinedAlias(_options
)), unresolvableUndefines
.end());
1203 const int unresolvableCount
= unresolvableUndefines
.size();
1204 int unresolvableExportsCount
= 0;
1205 if ( unresolvableCount
!= 0 ) {
1207 if ( _options
.printArchPrefix() )
1208 fprintf(stderr
, "Undefined symbols for architecture %s:\n", _options
.architectureName());
1210 fprintf(stderr
, "Undefined symbols:\n");
1211 for (int i
=0; i
< unresolvableCount
; ++i
) {
1212 const char* name
= unresolvableUndefines
[i
];
1213 unsigned int slot
= _symbolTable
.findSlotForName(name
);
1214 fprintf(stderr
, " \"%s\", referenced from:\n", _options
.demangleSymbol(name
));
1215 // scan all atoms for references
1216 bool foundAtomReference
= printReferencedBy(name
, slot
);
1217 // scan command line options
1218 if ( !foundAtomReference
) {
1219 // might be from -init command line option
1220 if ( (_options
.initFunctionName() != NULL
) && (strcmp(name
, _options
.initFunctionName()) == 0) ) {
1221 fprintf(stderr
, " -init command line option\n");
1223 // or might be from exported symbol option
1224 else if ( _options
.hasExportMaskList() && _options
.shouldExport(name
) ) {
1225 fprintf(stderr
, " -exported_symbol[s_list] command line option\n");
1227 // or might be from re-exported symbol option
1228 else if ( _options
.hasReExportList() && _options
.shouldReExport(name
) ) {
1229 fprintf(stderr
, " -reexported_symbols_list command line option\n");
1231 else if ( (_options
.outputKind() == Options::kDynamicExecutable
)
1232 && (_options
.entryName() != NULL
) && (strcmp(name
, _options
.entryName()) == 0) ) {
1233 fprintf(stderr
, " implicit entry/start for main executable\n");
1236 bool isInitialUndefine
= false;
1237 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1238 if ( strcmp(*uit
, name
) == 0 ) {
1239 isInitialUndefine
= true;
1243 if ( isInitialUndefine
)
1244 fprintf(stderr
, " -u command line option\n");
1246 ++unresolvableExportsCount
;
1248 // be helpful and check for typos
1249 bool printedStart
= false;
1250 for (SymbolTable::byNameIterator sit
=_symbolTable
.begin(); sit
!= _symbolTable
.end(); sit
++) {
1251 const ld::Atom
* atom
= *sit
;
1252 if ( (atom
!= NULL
) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
) && (strstr(atom
->name(), name
) != NULL
) ) {
1253 if ( ! printedStart
) {
1254 fprintf(stderr
, " (maybe you meant: %s", atom
->name());
1255 printedStart
= true;
1258 fprintf(stderr
, ", %s ", atom
->name());
1263 fprintf(stderr
, ")\n");
1264 // <rdar://problem/8989530> Add comment to error message when __ZTV symbols are undefined
1265 if ( strncmp(name
, "__ZTV", 5) == 0 ) {
1266 fprintf(stderr
, " NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.\n");
1271 throw "symbol(s) not found";
1278 void Resolver::checkDylibSymbolCollisions()
1280 for (SymbolTable::byNameIterator it
=_symbolTable
.begin(); it
!= _symbolTable
.end(); it
++) {
1281 const ld::Atom
* atom
= *it
;
1284 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1285 // <rdar://problem/5048861> No warning about tentative definition conflicting with dylib definition
1286 // for each tentative definition in symbol table look for dylib that exports same symbol name
1287 if ( atom
->definition() == ld::Atom::definitionTentative
) {
1288 _inputFiles
.searchLibraries(atom
->name(), true, false, false, *this);
1290 // record any overrides of weak symbols in any linked dylib
1291 if ( (atom
->definition() == ld::Atom::definitionRegular
) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
) ) {
1292 if ( _inputFiles
.searchWeakDefInDylib(atom
->name()) )
1293 (const_cast<ld::Atom
*>(atom
))->setOverridesDylibsWeakDef();
1300 const ld::Atom
* Resolver::entryPoint(bool searchArchives
)
1302 const char* symbolName
= NULL
;
1303 bool makingDylib
= false;
1304 switch ( _options
.outputKind() ) {
1305 case Options::kDynamicExecutable
:
1306 case Options::kStaticExecutable
:
1307 case Options::kDyld
:
1308 case Options::kPreload
:
1309 symbolName
= _options
.entryName();
1311 case Options::kDynamicLibrary
:
1312 symbolName
= _options
.initFunctionName();
1315 case Options::kObjectFile
:
1316 case Options::kDynamicBundle
:
1317 case Options::kKextBundle
:
1321 if ( symbolName
!= NULL
) {
1322 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName(symbolName
);
1323 if ( (_internal
.indirectBindingTable
[slot
] == NULL
) && searchArchives
) {
1324 // <rdar://problem/7043256> ld64 can not find a -e entry point from an archive
1325 _inputFiles
.searchLibraries(symbolName
, false, true, false, *this);
1327 if ( _internal
.indirectBindingTable
[slot
] == NULL
) {
1328 if ( strcmp(symbolName
, "start") == 0 )
1329 throwf("entry point (%s) undefined. Usually in crt1.o", symbolName
);
1331 throwf("entry point (%s) undefined.", symbolName
);
1333 else if ( _internal
.indirectBindingTable
[slot
]->definition() == ld::Atom::definitionProxy
) {
1335 throwf("-init function (%s) found in linked dylib, must be in dylib being linked", symbolName
);
1337 return _internal
.indirectBindingTable
[slot
];
1343 void Resolver::fillInHelpersInInternalState()
1345 // look up well known atoms
1346 bool needsStubHelper
= true;
1347 switch ( _options
.outputKind() ) {
1348 case Options::kDynamicExecutable
:
1349 case Options::kDynamicLibrary
:
1350 case Options::kDynamicBundle
:
1351 needsStubHelper
= true;
1353 case Options::kDyld
:
1354 case Options::kKextBundle
:
1355 case Options::kObjectFile
:
1356 case Options::kStaticExecutable
:
1357 case Options::kPreload
:
1358 needsStubHelper
= false;
1362 _internal
.classicBindingHelper
= NULL
;
1363 if ( needsStubHelper
&& !_options
.makeCompressedDyldInfo() ) {
1364 // "dyld_stub_binding_helper" comes from .o file, so should already exist in symbol table
1365 if ( _symbolTable
.hasName("dyld_stub_binding_helper") ) {
1366 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_stub_binding_helper");
1367 _internal
.classicBindingHelper
= _internal
.indirectBindingTable
[slot
];
1371 _internal
.lazyBindingHelper
= NULL
;
1372 if ( _options
.usingLazyDylibLinking() ) {
1373 // "dyld_lazy_dylib_stub_binding_helper" comes from lazydylib1.o file, so should already exist in symbol table
1374 if ( _symbolTable
.hasName("dyld_lazy_dylib_stub_binding_helper") ) {
1375 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_lazy_dylib_stub_binding_helper");
1376 _internal
.lazyBindingHelper
= _internal
.indirectBindingTable
[slot
];
1378 if ( _internal
.lazyBindingHelper
== NULL
)
1379 throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
1382 _internal
.compressedFastBinderProxy
= NULL
;
1383 if ( needsStubHelper
&& _options
.makeCompressedDyldInfo() ) {
1384 // "dyld_stub_binder" comes from libSystem.dylib so will need to manually resolve
1385 if ( !_symbolTable
.hasName("dyld_stub_binder") ) {
1386 _inputFiles
.searchLibraries("dyld_stub_binder", true, false, false, *this);
1388 if ( _symbolTable
.hasName("dyld_stub_binder") ) {
1389 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_stub_binder");
1390 _internal
.compressedFastBinderProxy
= _internal
.indirectBindingTable
[slot
];
1392 if ( _internal
.compressedFastBinderProxy
== NULL
) {
1393 if ( _options
.undefinedTreatment() != Options::kUndefinedError
) {
1395 _internal
.compressedFastBinderProxy
= new UndefinedProxyAtom("dyld_stub_binder");
1396 this->doAtom(*_internal
.compressedFastBinderProxy
);
1403 void Resolver::fillInInternalState()
1405 // store atoms into their final section
1406 for (std::vector
<const ld::Atom
*>::iterator it
= _atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1407 _internal
.addAtom(**it
);
1410 // <rdar://problem/7783918> make sure there is a __text section so that codesigning works
1411 if ( (_options
.outputKind() == Options::kDynamicLibrary
) || (_options
.outputKind() == Options::kDynamicBundle
) )
1412 _internal
.getFinalSection(*new ld::Section("__TEXT", "__text", ld::Section::typeCode
));
1415 void Resolver::fillInEntryPoint()
1417 _internal
.entryPoint
= this->entryPoint(true);
1422 void Resolver::removeCoalescedAwayAtoms()
1424 const bool log
= false;
1426 fprintf(stderr
, "removeCoalescedAwayAtoms() starts with %lu atoms\n", _atoms
.size());
1428 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), AtomCoalescedAway()), _atoms
.end());
1430 fprintf(stderr
, "removeCoalescedAwayAtoms() after removing coalesced atoms, %lu remain\n", _atoms
.size());
1431 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1432 fprintf(stderr
, " atom=%p %s\n", *it
, (*it
)->name());
1437 void Resolver::linkTimeOptimize()
1439 // only do work here if some llvm obj files where loaded
1440 if ( ! _haveLLVMObjs
)
1443 // <rdar://problem/15314161> LTO: Symbol multiply defined error should specify exactly where the symbol is found
1444 _symbolTable
.checkDuplicateSymbols();
1446 // run LLVM lto code-gen
1447 lto::OptimizeOptions optOpt
;
1448 optOpt
.outputFilePath
= _options
.outputFilePath();
1449 optOpt
.tmpObjectFilePath
= _options
.tempLtoObjectPath();
1450 optOpt
.preserveAllGlobals
= _options
.allGlobalsAreDeadStripRoots() || _options
.hasExportRestrictList();
1451 optOpt
.verbose
= _options
.verbose();
1452 optOpt
.saveTemps
= _options
.saveTempFiles();
1453 optOpt
.pie
= _options
.positionIndependentExecutable();
1454 optOpt
.mainExecutable
= _options
.linkingMainExecutable();;
1455 optOpt
.staticExecutable
= (_options
.outputKind() == Options::kStaticExecutable
);
1456 optOpt
.relocatable
= (_options
.outputKind() == Options::kObjectFile
);
1457 optOpt
.allowTextRelocs
= _options
.allowTextRelocs();
1458 optOpt
.linkerDeadStripping
= _options
.deadCodeStrip();
1459 optOpt
.needsUnwindInfoSection
= _options
.needsUnwindInfoSection();
1460 optOpt
.keepDwarfUnwind
= _options
.keepDwarfUnwind();
1461 optOpt
.arch
= _options
.architecture();
1462 optOpt
.mcpu
= _options
.mcpuLTO();
1463 optOpt
.llvmOptions
= &_options
.llvmOptions();
1465 std::vector
<const ld::Atom
*> newAtoms
;
1466 std::vector
<const char*> additionalUndefines
;
1467 if ( ! lto::optimize(_atoms
, _internal
, optOpt
, *this, newAtoms
, additionalUndefines
) )
1468 return; // if nothing done
1469 _ltoCodeGenFinished
= true;
1471 // add all newly created atoms to _atoms and update symbol table
1472 for(std::vector
<const ld::Atom
*>::iterator it
= newAtoms
.begin(); it
!= newAtoms
.end(); ++it
)
1475 // some atoms might have been optimized way (marked coalesced), remove them
1476 this->removeCoalescedAwayAtoms();
1478 // run through all atoms again and make sure newly codegened atoms have references bound
1479 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
)
1480 this->convertReferencesToIndirect(**it
);
1482 // adjust section of any new
1483 for (std::vector
<const AliasAtom
*>::const_iterator it
=_aliasesFromCmdLine
.begin(); it
!= _aliasesFromCmdLine
.end(); ++it
) {
1484 const AliasAtom
* aliasAtom
= *it
;
1485 // update fields in AliasAtom to match newly constructed mach-o atom
1486 aliasAtom
->setFinalAliasOf();
1489 // <rdar://problem/14609792> add any auto-link libraries requested by LTO output to dylibs to search
1490 _inputFiles
.addLinkerOptionLibraries(_internal
);
1491 _inputFiles
.createIndirectDylibs();
1493 // resolve new undefines (e.g calls to _malloc and _memcpy that llvm compiler conjures up)
1494 for(std::vector
<const char*>::iterator uit
= additionalUndefines
.begin(); uit
!= additionalUndefines
.end(); ++uit
) {
1495 const char *targetName
= *uit
;
1496 // these symbols may or may not already be in linker's symbol table
1497 if ( ! _symbolTable
.hasName(targetName
) ) {
1498 _inputFiles
.searchLibraries(targetName
, true, true, false, *this);
1502 // if -dead_strip on command line
1503 if ( _options
.deadCodeStrip() ) {
1504 // clear liveness bit
1505 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1506 (const_cast<ld::Atom
*>(*it
))->setLive((*it
)->dontDeadStrip());
1508 // and re-compute dead code
1509 this->deadStripOptimize(true);
1512 // <rdar://problem/12386559> if -exported_symbols_list on command line, re-force scope
1513 if ( _options
.hasExportMaskList() ) {
1514 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1515 const ld::Atom
* atom
= *it
;
1516 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1517 if ( !_options
.shouldExport(atom
->name()) ) {
1518 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1524 if ( _options
.outputKind() == Options::kObjectFile
) {
1525 // if -r mode, add proxies for new undefines (e.g. ___stack_chk_fail)
1526 this->resolveUndefines();
1529 // last chance to check for undefines
1530 this->resolveUndefines();
1531 this->checkUndefines(true);
1533 // check new code does not override some dylib
1534 this->checkDylibSymbolCollisions();
1539 void Resolver::tweakWeakness()
1541 // <rdar://problem/7977374> Add command line options to control symbol weak-def bit on exported symbols
1542 if ( _options
.hasWeakBitTweaks() ) {
1543 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= _internal
.sections
.begin(); sit
!= _internal
.sections
.end(); ++sit
) {
1544 ld::Internal::FinalSection
* sect
= *sit
;
1545 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1546 const ld::Atom
* atom
= *ait
;
1547 if ( atom
->definition() != ld::Atom::definitionRegular
)
1549 const char* name
= atom
->name();
1550 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1551 if ( atom
->combine() == ld::Atom::combineNever
) {
1552 if ( _options
.forceWeak(name
) )
1553 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineByName
);
1555 else if ( atom
->combine() == ld::Atom::combineByName
) {
1556 if ( _options
.forceNotWeak(name
) )
1557 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineNever
);
1561 if ( _options
.forceWeakNonWildCard(name
) )
1562 warning("cannot force to be weak, non-external symbol %s", name
);
1563 else if ( _options
.forceNotWeakNonWildcard(name
) )
1564 warning("cannot force to be not-weak, non-external symbol %s", name
);
1571 void Resolver::dumpAtoms()
1573 fprintf(stderr
, "Resolver all atoms:\n");
1574 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1575 const ld::Atom
* atom
= *it
;
1576 fprintf(stderr
, " %p name=%s, def=%d\n", atom
, atom
->name(), atom
->definition());
1580 void Resolver::resolve()
1582 this->initializeState();
1583 this->buildAtomList();
1584 this->addInitialUndefines();
1585 this->fillInHelpersInInternalState();
1586 this->resolveUndefines();
1587 this->deadStripOptimize();
1588 this->checkUndefines();
1589 this->checkDylibSymbolCollisions();
1590 this->removeCoalescedAwayAtoms();
1591 this->fillInEntryPoint();
1592 this->linkTimeOptimize();
1593 this->fillInInternalState();
1594 this->tweakWeakness();
1595 _symbolTable
.checkDuplicateSymbols();