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>
50 #include <ext/hash_map>
51 #include <ext/hash_set>
53 #include <AvailabilityMacros.h>
58 #include "InputFiles.h"
59 #include "SymbolTable.h"
61 #include "parsers/lto_file.h"
69 // An ExportAtom has no content. It exists so that the linker can track which imported
70 // symbols came from which dynamic libraries.
72 class UndefinedProxyAtom
: public ld::Atom
75 UndefinedProxyAtom(const char* nm
)
76 : ld::Atom(_s_section
, ld::Atom::definitionProxy
,
77 ld::Atom::combineNever
, ld::Atom::scopeLinkageUnit
,
78 ld::Atom::typeUnclassified
,
79 ld::Atom::symbolTableIn
, false, false, false, ld::Atom::Alignment(0)),
81 // overrides of ld::Atom
82 virtual const ld::File
* file() const { return NULL
; }
83 virtual bool translationUnitSource(const char** dir
, const char** nm
) const
85 virtual const char* name() const { return _name
; }
86 virtual uint64_t size() const { return 0; }
87 virtual uint64_t objectAddress() const { return 0; }
88 virtual void copyRawContent(uint8_t buffer
[]) const { }
89 virtual void setScope(Scope
) { }
93 virtual ~UndefinedProxyAtom() {}
97 static ld::Section _s_section
;
100 ld::Section
UndefinedProxyAtom::_s_section("__TEXT", "__import", ld::Section::typeImportProxies
, true);
105 class AliasAtom
: public ld::Atom
108 AliasAtom(const ld::Atom
& target
, const char* nm
) :
109 ld::Atom(target
.section(), target
.definition(), ld::Atom::combineNever
,
110 ld::Atom::scopeGlobal
, target
.contentType(),
111 target
.symbolTableInclusion(), target
.dontDeadStrip(),
112 target
.isThumb(), true, target
.alignment()),
115 _fixup(0, ld::Fixup::k1of1
, ld::Fixup::kindNoneFollowOn
, &target
) { }
117 // overrides of ld::Atom
118 virtual const ld::File
* file() const { return _aliasOf
.file(); }
119 virtual bool translationUnitSource(const char** dir
, const char** nm
) const
120 { return _aliasOf
.translationUnitSource(dir
, nm
); }
121 virtual const char* name() const { return _name
; }
122 virtual uint64_t size() const { return 0; }
123 virtual uint64_t objectAddress() const { return _aliasOf
.objectAddress(); }
124 virtual void copyRawContent(uint8_t buffer
[]) const { }
125 virtual const uint8_t* rawContentPointer() const { return NULL
; }
126 virtual unsigned long contentHash(const class ld::IndirectBindingTable
& ibt
) const
127 { return _aliasOf
.contentHash(ibt
); }
128 virtual bool canCoalesceWith(const ld::Atom
& rhs
, const class ld::IndirectBindingTable
& ibt
) const
129 { return _aliasOf
.canCoalesceWith(rhs
,ibt
); }
130 virtual ld::Fixup::iterator
fixupsBegin() const { return (ld::Fixup
*)&_fixup
; }
131 virtual ld::Fixup::iterator
fixupsEnd() const { return &((ld::Fixup
*)&_fixup
)[1]; }
132 virtual ld::Atom::UnwindInfo::iterator
beginUnwind() const { return NULL
; }
133 virtual ld::Atom::UnwindInfo::iterator
endUnwind() const { return NULL
; }
134 virtual ld::Atom::LineInfo::iterator
beginLineInfo() const { return NULL
; }
135 virtual ld::Atom::LineInfo::iterator
endLineInfo() const { return NULL
; }
139 const ld::Atom
& _aliasOf
;
145 class SectionBoundaryAtom
: public ld::Atom
148 static SectionBoundaryAtom
* makeSectionBoundaryAtom(const char* name
, bool start
, const char* segSectName
);
149 static SectionBoundaryAtom
* makeOldSectionBoundaryAtom(const char* name
, bool start
);
151 // overrides of ld::Atom
152 virtual bool translationUnitSource(const char** dir
, const char** nm
) const
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 bool translationUnitSource(const char** dir
, const char** nm
) const
220 virtual const ld::File
* file() const { return NULL
; }
221 virtual const char* name() const { return _name
; }
222 virtual uint64_t size() const { return 0; }
223 virtual void copyRawContent(uint8_t buffer
[]) const { }
224 virtual const uint8_t* rawContentPointer() const { return NULL
; }
225 virtual uint64_t objectAddress() const { return 0; }
229 SegmentBoundaryAtom(const char* nm
, const ld::Section
& sect
,
230 ld::Atom::ContentType cont
) :
232 ld::Atom::definitionRegular
,
233 ld::Atom::combineNever
,
234 ld::Atom::scopeLinkageUnit
,
236 ld::Atom::symbolTableNotIn
,
237 false, false, true, ld::Atom::Alignment(0)),
243 SegmentBoundaryAtom
* SegmentBoundaryAtom::makeSegmentBoundaryAtom(const char* name
, bool start
, const char* segName
)
245 if ( *segName
== '\0' )
246 throwf("malformed segment$ symbol name: %s", name
);
247 if ( strlen(segName
) > 16 )
248 throwf("malformed segment$ symbol name: %s", name
);
251 const ld::Section
* section
= new ld::Section(segName
, "__start", ld::Section::typeFirstSection
, true);
252 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionStart
);
255 const ld::Section
* section
= new ld::Section(segName
, "__end", ld::Section::typeLastSection
, true);
256 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionEnd
);
260 SegmentBoundaryAtom
* SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(const char* name
, bool start
)
262 // e.g. __DATA__begin
264 strlcpy(temp
, name
, 7);
265 char* segName
= strdup(temp
);
267 warning("grandfathering in old symbol '%s' as alias for 'segment$%s$%s'", name
, start
? "start" : "end", segName
);
270 const ld::Section
* section
= new ld::Section(segName
, "__start", ld::Section::typeFirstSection
, true);
271 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionStart
);
274 const ld::Section
* section
= new ld::Section(segName
, "__end", ld::Section::typeLastSection
, true);
275 return new SegmentBoundaryAtom(name
, *section
, ld::Atom::typeSectionEnd
);
279 void Resolver::initializeState()
281 // set initial objc constraint based on command line options
282 if ( _options
.objcGc() )
283 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
284 else if ( _options
.objcGcOnly() )
285 _internal
.objcObjectConstraint
= ld::File::objcConstraintGC
;
287 _internal
.cpuSubType
= _options
.subArchitecture();
290 void Resolver::buildAtomList()
292 // each input files contributes initial atoms
293 _atoms
.reserve(1024);
294 _inputFiles
.forEachInitialAtom(*this);
295 _completedInitialObjectFiles
= true;
297 //_symbolTable.printStatistics();
300 unsigned int Resolver::ppcSubTypeIndex(uint32_t subtype
)
303 case CPU_SUBTYPE_POWERPC_ALL
:
305 case CPU_SUBTYPE_POWERPC_750
:
308 case CPU_SUBTYPE_POWERPC_7400
:
309 case CPU_SUBTYPE_POWERPC_7450
:
312 case CPU_SUBTYPE_POWERPC_970
:
313 // G5 can run everything
316 throw "Unhandled PPC cpu subtype!";
321 void Resolver::doFile(const ld::File
& file
)
323 const ld::relocatable::File
* objFile
= dynamic_cast<const ld::relocatable::File
*>(&file
);
324 const ld::dylib::File
* dylibFile
= dynamic_cast<const ld::dylib::File
*>(&file
);
326 if ( objFile
!= NULL
) {
327 // update which form of ObjC is being used
328 switch ( file
.objCConstraint() ) {
329 case ld::File::objcConstraintNone
:
331 case ld::File::objcConstraintRetainRelease
:
332 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintGC
)
333 throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", file
.path());
334 if ( _options
.objcGcOnly() )
335 throwf("command line specified -objc_gc_only, but file is retain/release based: %s", file
.path());
336 if ( _options
.objcGc() )
337 throwf("command line specified -objc_gc, but file is retain/release based: %s", file
.path());
338 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainRelease
;
340 case ld::File::objcConstraintRetainReleaseOrGC
:
341 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintNone
)
342 _internal
.objcObjectConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
344 case ld::File::objcConstraintGC
:
345 if ( _internal
.objcObjectConstraint
== ld::File::objcConstraintRetainRelease
)
346 throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", file
.path());
347 _internal
.objcObjectConstraint
= ld::File::objcConstraintGC
;
351 // in -r mode, if any .o files have dwarf then add UUID to output .o file
352 if ( objFile
->debugInfo() == ld::relocatable::File::kDebugInfoDwarf
)
353 _internal
.someObjectFileHasDwarf
= true;
355 // remember if any objc classes built for fix-and-continue
356 if ( objFile
->objcReplacementClasses() )
357 _internal
.hasObjcReplacementClasses
= true;
359 // remember if any .o file did not have MH_SUBSECTIONS_VIA_SYMBOLS bit set
360 if ( ! objFile
->canScatterAtoms() )
361 _internal
.allObjectFilesScatterable
= false;
363 // update cpu-sub-type
364 cpu_subtype_t nextObjectSubType
= file
.cpuSubType();
365 switch ( _options
.architecture() ) {
366 case CPU_TYPE_POWERPC
:
367 // no checking when -force_cpusubtype_ALL is used
368 if ( _options
.forceCpuSubtypeAll() )
370 if ( _options
.preferSubArchitecture() ) {
371 // warn if some .o file is not compatible with desired output sub-type
372 if ( _options
.subArchitecture() != nextObjectSubType
) {
373 if ( ppcSubTypeIndex(nextObjectSubType
) > ppcSubTypeIndex(_options
.subArchitecture()) ) {
374 if ( !_inputFiles
.inferredArch() )
375 warning("cpu-sub-type of %s is not compatible with command line cpu-sub-type", file
.path());
376 _internal
.cpuSubType
= nextObjectSubType
;
381 // command line to linker just had -arch ppc
382 // figure out final sub-type based on sub-type of all .o files
383 if ( ppcSubTypeIndex(nextObjectSubType
) > ppcSubTypeIndex(_internal
.cpuSubType
) ) {
384 _internal
.cpuSubType
= nextObjectSubType
;
390 if ( _options
.subArchitecture() != nextObjectSubType
) {
391 if ( (_options
.subArchitecture() == CPU_SUBTYPE_ARM_ALL
) && _options
.forceCpuSubtypeAll() ) {
392 // hack to support gcc multillib build that tries to make sub-type-all slice
394 else if ( nextObjectSubType
== CPU_SUBTYPE_ARM_ALL
) {
395 warning("CPU_SUBTYPE_ARM_ALL subtype is deprecated: %s", file
.path());
398 throwf("object file %s was built for different arm sub-type (%d) than link command line (%d)",
399 file
.path(), nextObjectSubType
, _options
.subArchitecture());
404 case CPU_TYPE_POWERPC64
:
408 _internal
.cpuSubType
= CPU_SUBTYPE_I386_ALL
;
411 case CPU_TYPE_X86_64
:
412 _internal
.cpuSubType
= CPU_SUBTYPE_X86_64_ALL
;
416 if ( dylibFile
!= NULL
) {
417 // update which form of ObjC dylibs are being linked
418 switch ( dylibFile
->objCConstraint() ) {
419 case ld::File::objcConstraintNone
:
421 case ld::File::objcConstraintRetainRelease
:
422 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintGC
)
423 throwf("%s built with incompatible Garbage Collection settings to link with previous dylibs", file
.path());
424 if ( _options
.objcGcOnly() )
425 throwf("command line specified -objc_gc_only, but dylib is retain/release based: %s", file
.path());
426 if ( _options
.objcGc() )
427 throwf("command line specified -objc_gc, but dylib is retain/release based: %s", file
.path());
428 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainRelease
;
430 case ld::File::objcConstraintRetainReleaseOrGC
:
431 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintNone
)
432 _internal
.objcDylibConstraint
= ld::File::objcConstraintRetainReleaseOrGC
;
434 case ld::File::objcConstraintGC
:
435 if ( _internal
.objcDylibConstraint
== ld::File::objcConstraintRetainRelease
)
436 throwf("%s built with incompatible Garbage Collection settings to link with previous dylibs", file
.path());
437 _internal
.objcDylibConstraint
= ld::File::objcConstraintGC
;
444 void Resolver::doAtom(const ld::Atom
& atom
)
446 //fprintf(stderr, "Resolver::doAtom(%p), name=%s, sect=%s\n", &atom, atom.name(), atom.section().sectionName());
448 // add to list of known atoms
449 _atoms
.push_back(&atom
);
452 if ( _options
.hasExportRestrictList() || _options
.hasReExportList() ) {
453 const char* name
= atom
.name();
454 switch ( atom
.scope() ) {
455 case ld::Atom::scopeTranslationUnit
:
457 case ld::Atom::scopeLinkageUnit
:
458 if ( _options
.hasExportMaskList() && _options
.shouldExport(name
) ) {
459 // <rdar://problem/5062685> ld does not report error when -r is used and exported symbols are not defined.
460 if ( _options
.outputKind() == Options::kObjectFile
)
461 throwf("cannot export hidden symbol %s", name
);
462 // .objc_class_name_* symbols are special
463 if ( atom
.section().type() != ld::Section::typeObjC1Classes
) {
464 if ( atom
.definition() == ld::Atom::definitionProxy
) {
465 // .exp file says to export a symbol, but that symbol is in some dylib being linked
466 if ( _options
.canReExportSymbols() ) {
467 // marking proxy atom as global triggers the re-export
468 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeGlobal
);
471 if ( atom
.file() != NULL
)
472 warning("cannot re-export symbol %s from %s\n", SymbolTable::demangle(name
), atom
.file()->path());
474 warning("cannot re-export symbol %s\n", SymbolTable::demangle(name
));
478 if ( atom
.file() != NULL
)
479 warning("cannot export hidden symbol %s from %s", SymbolTable::demangle(name
), atom
.file()->path());
481 warning("cannot export hidden symbol %s", SymbolTable::demangle(name
));
485 else if ( _options
.shouldReExport(name
) && _options
.canReExportSymbols() ) {
486 if ( atom
.definition() == ld::Atom::definitionProxy
) {
487 // marking proxy atom as global triggers the re-export
488 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeGlobal
);
491 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", SymbolTable::demangle(name
), atom
.file()->path());
495 case ld::Atom::scopeGlobal
:
496 // check for globals that are downgraded to hidden
497 if ( ! _options
.shouldExport(name
) ) {
498 (const_cast<ld::Atom
*>(&atom
))->setScope(ld::Atom::scopeLinkageUnit
);
499 //fprintf(stderr, "demote %s to hidden\n", name);
501 if ( _options
.canReExportSymbols() && _options
.shouldReExport(name
) ) {
502 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", SymbolTable::demangle(name
), atom
.file()->path());
508 // work around for kernel that uses 'l' labels in assembly code
509 if ( (atom
.symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
510 && (atom
.name()[0] == 'l') && (_options
.outputKind() == Options::kStaticExecutable
) )
511 (const_cast<ld::Atom
*>(&atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
514 // tell symbol table about non-static atoms
515 if ( atom
.scope() != ld::Atom::scopeTranslationUnit
) {
516 _symbolTable
.add(atom
, _options
.deadCodeStrip() && _completedInitialObjectFiles
);
518 // add symbol aliases defined on the command line
519 if ( _options
.haveCmdLineAliases() ) {
520 const std::vector
<Options::AliasPair
>& aliases
= _options
.cmdLineAliases();
521 for (std::vector
<Options::AliasPair
>::const_iterator it
=aliases
.begin(); it
!= aliases
.end(); ++it
) {
522 if ( strcmp(it
->realName
, atom
.name()) == 0 ) {
523 const ld::Atom
* alias
= new AliasAtom(atom
, it
->alias
);
524 this->doAtom(*alias
);
530 // convert references by-name or by-content to by-slot
531 this->convertReferencesToIndirect(atom
);
533 // remember if any atoms are proxies that require LTO
534 if ( atom
.contentType() == ld::Atom::typeLTOtemporary
)
535 _haveLLVMObjs
= true;
537 // if we've already partitioned into final sections, and lto needs a symbol very late, add it
538 if ( _addToFinalSection
)
539 _internal
.addAtom(atom
);
541 if ( _options
.deadCodeStrip() ) {
542 // add to set of dead-strip-roots, all symbols that the compiler marks as don't strip
543 if ( atom
.dontDeadStrip() )
544 _deadStripRoots
.insert(&atom
);
546 if ( atom
.scope() == ld::Atom::scopeGlobal
) {
547 // <rdar://problem/5524973> -exported_symbols_list that has wildcards and -dead_strip
548 // in dylibs, every global atom in initial .o files is a root
549 if ( _options
.hasWildCardExportRestrictList() || _options
.allGlobalsAreDeadStripRoots() ) {
550 if ( _options
.shouldExport(atom
.name()) )
551 _deadStripRoots
.insert(&atom
);
557 bool Resolver::isDtraceProbe(ld::Fixup::Kind kind
)
560 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
561 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
562 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
563 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
564 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
565 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
566 case ld::Fixup::kindStorePPCDtraceCallSiteNop
:
567 case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear
:
568 case ld::Fixup::kindDtraceExtra
:
576 void Resolver::convertReferencesToIndirect(const ld::Atom
& atom
)
578 // convert references by-name or by-content to by-slot
579 SymbolTable::IndirectBindingSlot slot
;
580 const ld::Atom
* dummy
;
581 ld::Fixup::iterator end
= atom
.fixupsEnd();
582 for (ld::Fixup::iterator fit
=atom
.fixupsBegin(); fit
!= end
; ++fit
) {
583 switch ( fit
->binding
) {
584 case ld::Fixup::bindingByNameUnbound
:
585 if ( isDtraceProbe(fit
->kind
) && (_options
.outputKind() != Options::kObjectFile
) ) {
586 // in final linked images, remove reference
587 fit
->binding
= ld::Fixup::bindingNone
;
590 slot
= _symbolTable
.findSlotForName(fit
->u
.name
);
591 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
592 fit
->u
.bindingIndex
= slot
;
595 case ld::Fixup::bindingByContentBound
:
596 switch ( fit
->u
.target
->combine() ) {
597 case ld::Atom::combineNever
:
598 case ld::Atom::combineByName
:
599 assert(0 && "wrong combine type for bind by content");
601 case ld::Atom::combineByNameAndContent
:
602 slot
= _symbolTable
.findSlotForContent(fit
->u
.target
, &dummy
);
603 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
604 fit
->u
.bindingIndex
= slot
;
606 case ld::Atom::combineByNameAndReferences
:
607 slot
= _symbolTable
.findSlotForReferences(fit
->u
.target
, &dummy
);
608 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
609 fit
->u
.bindingIndex
= slot
;
613 case ld::Fixup::bindingNone
:
614 case ld::Fixup::bindingDirectlyBound
:
615 case ld::Fixup::bindingsIndirectlyBound
:
622 void Resolver::addInitialUndefines()
624 // add initial undefines from -u option
625 for (Options::UndefinesIterator it
=_options
.initialUndefinesBegin(); it
!= _options
.initialUndefinesEnd(); ++it
) {
626 _symbolTable
.findSlotForName(*it
);
630 void Resolver::resolveUndefines()
632 // keep looping until no more undefines were added in last loop
633 unsigned int undefineGenCount
= 0xFFFFFFFF;
634 while ( undefineGenCount
!= _symbolTable
.updateCount() ) {
635 undefineGenCount
= _symbolTable
.updateCount();
636 std::vector
<const char*> undefineNames
;
637 _symbolTable
.undefines(undefineNames
);
638 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
639 const char* undef
= *it
;
640 // load for previous undefine may also have loaded this undefine, so check again
641 if ( ! _symbolTable
.hasName(undef
) ) {
642 _inputFiles
.searchLibraries(undef
, true, true, *this);
643 if ( !_symbolTable
.hasName(undef
) && (_options
.outputKind() != Options::kObjectFile
) ) {
644 if ( strncmp(undef
, "section$", 8) == 0 ) {
645 if ( strncmp(undef
, "section$start$", 14) == 0 ) {
646 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef
, true, &undef
[14]));
648 else if ( strncmp(undef
, "section$end$", 12) == 0 ) {
649 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef
, false, &undef
[12]));
652 else if ( strncmp(undef
, "segment$", 8) == 0 ) {
653 if ( strncmp(undef
, "segment$start$", 14) == 0 ) {
654 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef
, true, &undef
[14]));
656 else if ( strncmp(undef
, "segment$end$", 12) == 0 ) {
657 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef
, false, &undef
[12]));
660 else if ( _options
.outputKind() == Options::kPreload
) {
661 // for iBoot grandfather in old style section labels
662 int undefLen
= strlen(undef
);
663 if ( strcmp(&undef
[undefLen
-7], "__begin") == 0 ) {
665 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef
, true));
667 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef
, true));
669 else if ( strcmp(&undef
[undefLen
-5], "__end") == 0 ) {
671 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef
, false));
673 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef
, false));
679 // <rdar://problem/5894163> need to search archives for overrides of common symbols
680 if ( _symbolTable
.hasExternalTentativeDefinitions() ) {
681 bool searchDylibs
= (_options
.commonsMode() == Options::kCommonsOverriddenByDylibs
);
682 std::vector
<const char*> tents
;
683 _symbolTable
.tentativeDefs(tents
);
684 for(std::vector
<const char*>::iterator it
= tents
.begin(); it
!= tents
.end(); ++it
) {
685 // load for previous tentative may also have loaded this tentative, so check again
686 const ld::Atom
* curAtom
= _symbolTable
.atomForSlot(_symbolTable
.findSlotForName(*it
));
687 assert(curAtom
!= NULL
);
688 if ( curAtom
->definition() == ld::Atom::definitionTentative
) {
689 _inputFiles
.searchLibraries(*it
, searchDylibs
, true, *this);
695 // create proxies as needed for undefined symbols
696 if ( (_options
.undefinedTreatment() != Options::kUndefinedError
) || (_options
.outputKind() == Options::kObjectFile
) ) {
697 std::vector
<const char*> undefineNames
;
698 _symbolTable
.undefines(undefineNames
);
699 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
701 this->doAtom(*new UndefinedProxyAtom(*it
));
706 if ( _options
.someAllowedUndefines() ) {
707 std::vector
<const char*> undefineNames
;
708 _symbolTable
.undefines(undefineNames
);
709 for(std::vector
<const char*>::iterator it
= undefineNames
.begin(); it
!= undefineNames
.end(); ++it
) {
710 if ( _options
.allowedUndefined(*it
) ) {
712 this->doAtom(*new UndefinedProxyAtom(*it
));
720 void Resolver::markLive(const ld::Atom
& atom
, WhyLiveBackChain
* previous
)
722 //fprintf(stderr, "markLive(%p) %s\n", &atom, atom.name());
723 // if -why_live cares about this symbol, then dump chain
724 if ( (previous
->referer
!= NULL
) && _options
.printWhyLive(atom
.name()) ) {
725 fprintf(stderr
, "%s from %s\n", atom
.name(), atom
.file()->path());
727 for(WhyLiveBackChain
* p
= previous
; p
!= NULL
; p
= p
->previous
, ++depth
) {
728 for(int i
=depth
; i
> 0; --i
)
729 fprintf(stderr
, " ");
730 fprintf(stderr
, "%s from %s\n", p
->referer
->name(), p
->referer
->file()->path());
734 // if already marked live, then done (stop recursion)
738 // mark this atom is live
739 (const_cast<ld::Atom
*>(&atom
))->setLive();
741 // mark all atoms it references as live
742 WhyLiveBackChain thisChain
;
743 thisChain
.previous
= previous
;
744 thisChain
.referer
= &atom
;
745 for (ld::Fixup::iterator fit
= atom
.fixupsBegin(), end
=atom
.fixupsEnd(); fit
!= end
; ++fit
) {
746 const ld::Atom
* target
;
747 switch ( fit
->kind
) {
748 case ld::Fixup::kindNone
:
749 case ld::Fixup::kindNoneFollowOn
:
750 case ld::Fixup::kindNoneGroupSubordinate
:
751 case ld::Fixup::kindNoneGroupSubordinateFDE
:
752 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
753 case ld::Fixup::kindSetTargetAddress
:
754 case ld::Fixup::kindSubtractTargetAddress
:
755 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
756 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
757 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
758 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
759 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
760 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
761 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
762 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
763 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
764 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
765 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
766 if ( fit
->binding
== ld::Fixup::bindingByContentBound
) {
767 // normally this was done in convertReferencesToIndirect()
768 // but a archive loaded .o file may have a forward reference
769 SymbolTable::IndirectBindingSlot slot
;
770 const ld::Atom
* dummy
;
771 switch ( fit
->u
.target
->combine() ) {
772 case ld::Atom::combineNever
:
773 case ld::Atom::combineByName
:
774 assert(0 && "wrong combine type for bind by content");
776 case ld::Atom::combineByNameAndContent
:
777 slot
= _symbolTable
.findSlotForContent(fit
->u
.target
, &dummy
);
778 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
779 fit
->u
.bindingIndex
= slot
;
781 case ld::Atom::combineByNameAndReferences
:
782 slot
= _symbolTable
.findSlotForReferences(fit
->u
.target
, &dummy
);
783 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
784 fit
->u
.bindingIndex
= slot
;
788 switch ( fit
->binding
) {
789 case ld::Fixup::bindingDirectlyBound
:
790 markLive(*(fit
->u
.target
), &thisChain
);
792 case ld::Fixup::bindingByNameUnbound
:
793 // doAtom() did not convert to indirect in dead-strip mode, so that now
794 fit
->u
.bindingIndex
= _symbolTable
.findSlotForName(fit
->u
.name
);
795 fit
->binding
= ld::Fixup::bindingsIndirectlyBound
;
796 // fall into next case
797 case ld::Fixup::bindingsIndirectlyBound
:
798 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
799 if ( target
== NULL
) {
800 const char* targetName
= _symbolTable
.indirectName(fit
->u
.bindingIndex
);
801 _inputFiles
.searchLibraries(targetName
, true, true, *this);
802 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
804 if ( target
!= NULL
) {
805 if ( target
->definition() == ld::Atom::definitionTentative
) {
806 // <rdar://problem/5894163> need to search archives for overrides of common symbols
807 bool searchDylibs
= (_options
.commonsMode() == Options::kCommonsOverriddenByDylibs
);
808 _inputFiles
.searchLibraries(target
->name(), searchDylibs
, true, *this);
809 // recompute target since it may have been overridden by searchLibraries()
810 target
= _internal
.indirectBindingTable
[fit
->u
.bindingIndex
];
812 this->markLive(*target
, &thisChain
);
815 _atomsWithUnresolvedReferences
.push_back(&atom
);
819 assert(0 && "bad binding during dead stripping");
830 void Resolver::deadStripOptimize()
832 // only do this optimization with -dead_strip
833 if ( ! _options
.deadCodeStrip() )
836 // add entry point (main) to live roots
837 const ld::Atom
* entry
= this->entryPoint(true);
839 _deadStripRoots
.insert(entry
);
841 // add -exported_symbols_list, -init, and -u entries to live roots
842 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
843 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName(*uit
);
844 if ( _internal
.indirectBindingTable
[slot
] == NULL
) {
845 _inputFiles
.searchLibraries(*uit
, false, true, *this);
847 if ( _internal
.indirectBindingTable
[slot
] != NULL
)
848 _deadStripRoots
.insert(_internal
.indirectBindingTable
[slot
]);
851 // this helper is only referenced by synthesize stubs, assume it will be used
852 if ( _internal
.classicBindingHelper
!= NULL
)
853 _deadStripRoots
.insert(_internal
.classicBindingHelper
);
855 // this helper is only referenced by synthesize stubs, assume it will be used
856 if ( _internal
.compressedFastBinderProxy
!= NULL
)
857 _deadStripRoots
.insert(_internal
.compressedFastBinderProxy
);
859 // this helper is only referenced by synthesized lazy stubs, assume it will be used
860 if ( _internal
.lazyBindingHelper
!= NULL
)
861 _deadStripRoots
.insert(_internal
.lazyBindingHelper
);
863 // add all dont-dead-strip atoms as roots
864 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
865 const ld::Atom
* atom
= *it
;
866 if ( atom
->dontDeadStrip() ) {
867 //fprintf(stderr, "dont dead strip: %p %s %s\n", atom, atom->section().sectionName(), atom->name());
868 _deadStripRoots
.insert(atom
);
869 // unset liveness, so markLive() will recurse
870 (const_cast<ld::Atom
*>(atom
))->setLive(0);
874 // mark all roots as live, and all atoms they reference
875 for (std::set
<const ld::Atom
*>::iterator it
=_deadStripRoots
.begin(); it
!= _deadStripRoots
.end(); ++it
) {
876 WhyLiveBackChain rootChain
;
877 rootChain
.previous
= NULL
;
878 rootChain
.referer
= *it
;
879 this->markLive(**it
, &rootChain
);
882 // now remove all non-live atoms from _atoms
883 const bool log
= false;
885 fprintf(stderr
, "deadStripOptimize() all atoms with liveness:\n");
886 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
887 fprintf(stderr
, " live=%d name=%s\n", (*it
)->live(), (*it
)->name());
890 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), NotLive()), _atoms
.end());
894 void Resolver::liveUndefines(std::vector
<const char*>& undefs
)
897 // search all live atoms for references that are unbound
898 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
899 const ld::Atom
* atom
= *it
;
900 assert(atom
->live());
901 for (ld::Fixup::iterator fit
=atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
902 switch ( (ld::Fixup::TargetBinding
)fit
->binding
) {
903 case ld::Fixup::bindingByNameUnbound
:
904 assert(0 && "should not be by-name this late");
905 undefSet
.insert(fit
->u
.name
);
907 case ld::Fixup::bindingsIndirectlyBound
:
908 if ( _internal
.indirectBindingTable
[fit
->u
.bindingIndex
] == NULL
) {
909 undefSet
.insert(_symbolTable
.indirectName(fit
->u
.bindingIndex
));
912 case ld::Fixup::bindingByContentBound
:
913 case ld::Fixup::bindingNone
:
914 case ld::Fixup::bindingDirectlyBound
:
919 // look for any initial undefines that are still undefined
920 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
921 if ( ! _symbolTable
.hasName(*uit
) ) {
922 undefSet
.insert(*uit
);
926 // copy set to vector
927 for (StringSet::const_iterator it
=undefSet
.begin(); it
!= undefSet
.end(); ++it
) {
928 undefs
.push_back(*it
);
934 // <rdar://problem/8252819> warn when .objc_class_name_* symbol missing
935 class ExportedObjcClass
938 ExportedObjcClass(const Options
& opt
) : _options(opt
) {}
940 bool operator()(const char* name
) const {
941 if ( (strncmp(name
, ".objc_class_name_", 17) == 0) && _options
.shouldExport(name
) ) {
942 warning("ignoring undefined symbol %s from -exported_symbols_list", name
);
945 const char* s
= strstr(name
, "CLASS_$_");
947 char temp
[strlen(name
)+16];
948 strcpy(temp
, ".objc_class_name_");
950 if ( _options
.wasRemovedExport(temp
) ) {
951 warning("ignoring undefined symbol %s from -exported_symbols_list", temp
);
958 const Options
& _options
;
962 // temp hack for undefined aliases
966 UndefinedAlias(const Options
& opt
) : _aliases(opt
.cmdLineAliases()) {}
968 bool operator()(const char* name
) const {
969 for (std::vector
<Options::AliasPair
>::const_iterator it
=_aliases
.begin(); it
!= _aliases
.end(); ++it
) {
970 if ( strcmp(it
->realName
, name
) == 0 ) {
971 warning("undefined base symbol '%s' for alias '%s'", name
, it
->alias
);
978 const std::vector
<Options::AliasPair
>& _aliases
;
983 static const char* pathLeafName(const char* path
)
985 const char* shortPath
= strrchr(path
, '/');
986 if ( shortPath
== NULL
)
989 return &shortPath
[1];
992 bool Resolver::printReferencedBy(const char* name
, SymbolTable::IndirectBindingSlot slot
)
994 unsigned foundReferenceCount
= 0;
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 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
999 if ( fit
->u
.bindingIndex
== slot
) {
1000 if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
1001 const ld::Atom
* existingAtom
;
1002 unsigned int nlSlot
= _symbolTable
.findSlotForReferences(atom
, &existingAtom
);
1003 if ( printReferencedBy(name
, nlSlot
) )
1004 ++foundReferenceCount
;
1006 else if ( atom
->contentType() == ld::Atom::typeCFI
) {
1007 fprintf(stderr
, " Dwarf Exception Unwind Info (__eh_frame) in %s\n", pathLeafName(atom
->file()->path()));
1008 ++foundReferenceCount
;
1011 fprintf(stderr
, " %s in %s\n", SymbolTable::demangle(atom
->name()), pathLeafName(atom
->file()->path()));
1012 ++foundReferenceCount
;
1013 break; // if undefined used twice in a function, only show first
1018 if ( foundReferenceCount
> 6 ) {
1019 fprintf(stderr
, " ...\n");
1020 break; // only show first six uses of undefined symbol
1023 return (foundReferenceCount
!= 0);
1026 void Resolver::checkUndefines(bool force
)
1028 // when using LTO, undefines are checked after bitcode is optimized
1029 if ( _haveLLVMObjs
&& !force
)
1032 // error out on any remaining undefines
1033 bool doPrint
= true;
1034 bool doError
= true;
1035 switch ( _options
.undefinedTreatment() ) {
1036 case Options::kUndefinedError
:
1038 case Options::kUndefinedDynamicLookup
:
1041 case Options::kUndefinedWarning
:
1044 case Options::kUndefinedSuppress
:
1049 std::vector
<const char*> unresolvableUndefines
;
1050 if ( _options
.deadCodeStrip() )
1051 this->liveUndefines(unresolvableUndefines
);
1053 _symbolTable
.undefines(unresolvableUndefines
);
1055 // <rdar://problem/8252819> assert when .objc_class_name_* symbol missing
1056 if ( _options
.hasExportMaskList() ) {
1057 unresolvableUndefines
.erase(std::remove_if(unresolvableUndefines
.begin(), unresolvableUndefines
.end(), ExportedObjcClass(_options
)), unresolvableUndefines
.end());
1060 // hack to temporarily make missing aliases a warning
1061 if ( _options
.haveCmdLineAliases() ) {
1062 unresolvableUndefines
.erase(std::remove_if(unresolvableUndefines
.begin(), unresolvableUndefines
.end(), UndefinedAlias(_options
)), unresolvableUndefines
.end());
1065 const int unresolvableCount
= unresolvableUndefines
.size();
1066 int unresolvableExportsCount
= 0;
1067 if ( unresolvableCount
!= 0 ) {
1069 if ( _options
.printArchPrefix() )
1070 fprintf(stderr
, "Undefined symbols for architecture %s:\n", _options
.architectureName());
1072 fprintf(stderr
, "Undefined symbols:\n");
1073 for (int i
=0; i
< unresolvableCount
; ++i
) {
1074 const char* name
= unresolvableUndefines
[i
];
1075 unsigned int slot
= _symbolTable
.findSlotForName(name
);
1076 fprintf(stderr
, " \"%s\", referenced from:\n", SymbolTable::demangle(name
));
1077 // scan all atoms for references
1078 bool foundAtomReference
= printReferencedBy(name
, slot
);
1079 // scan command line options
1080 if ( !foundAtomReference
) {
1081 // might be from -init command line option
1082 if ( (_options
.initFunctionName() != NULL
) && (strcmp(name
, _options
.initFunctionName()) == 0) ) {
1083 fprintf(stderr
, " -init command line option\n");
1085 // or might be from exported symbol option
1086 else if ( _options
.hasExportMaskList() && _options
.shouldExport(name
) ) {
1087 fprintf(stderr
, " -exported_symbol[s_list] command line option\n");
1089 // or might be from re-exported symbol option
1090 else if ( _options
.hasReExportList() && _options
.shouldReExport(name
) ) {
1091 fprintf(stderr
, " -reexported_symbols_list command line option\n");
1094 bool isInitialUndefine
= false;
1095 for (Options::UndefinesIterator uit
=_options
.initialUndefinesBegin(); uit
!= _options
.initialUndefinesEnd(); ++uit
) {
1096 if ( strcmp(*uit
, name
) == 0 ) {
1097 isInitialUndefine
= true;
1101 if ( isInitialUndefine
)
1102 fprintf(stderr
, " -u command line option\n");
1104 ++unresolvableExportsCount
;
1106 // be helpful and check for typos
1107 bool printedStart
= false;
1108 for (SymbolTable::byNameIterator sit
=_symbolTable
.begin(); sit
!= _symbolTable
.end(); sit
++) {
1109 const ld::Atom
* atom
= *sit
;
1110 if ( (atom
!= NULL
) && (strstr(atom
->name(), name
) != NULL
) ) {
1111 if ( ! printedStart
) {
1112 fprintf(stderr
, " (maybe you meant: %s", atom
->name());
1113 printedStart
= true;
1116 fprintf(stderr
, ", %s ", atom
->name());
1121 fprintf(stderr
, ")\n");
1125 throw "symbol(s) not found";
1132 void Resolver::checkDylibSymbolCollisions()
1134 for (SymbolTable::byNameIterator it
=_symbolTable
.begin(); it
!= _symbolTable
.end(); it
++) {
1135 const ld::Atom
* atom
= *it
;
1138 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1139 // <rdar://problem/5048861> No warning about tentative definition conflicting with dylib definition
1140 // for each tentative definition in symbol table look for dylib that exports same symbol name
1141 if ( atom
->definition() == ld::Atom::definitionTentative
) {
1142 _inputFiles
.searchLibraries(atom
->name(), true, false, *this);
1144 // record any overrides of weak symbols in any linked dylib
1145 if ( (atom
->definition() == ld::Atom::definitionRegular
) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
) ) {
1146 if ( _inputFiles
.searchWeakDefInDylib(atom
->name()) )
1147 (const_cast<ld::Atom
*>(atom
))->setOverridesDylibsWeakDef();
1154 const ld::Atom
* Resolver::entryPoint(bool searchArchives
)
1156 const char* symbolName
= NULL
;
1157 switch ( _options
.outputKind() ) {
1158 case Options::kDynamicExecutable
:
1159 case Options::kStaticExecutable
:
1160 case Options::kDyld
:
1161 case Options::kPreload
:
1162 symbolName
= _options
.entryName();
1164 case Options::kDynamicLibrary
:
1165 symbolName
= _options
.initFunctionName();
1167 case Options::kObjectFile
:
1168 case Options::kDynamicBundle
:
1169 case Options::kKextBundle
:
1173 if ( symbolName
!= NULL
) {
1174 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName(symbolName
);
1175 if ( (_internal
.indirectBindingTable
[slot
] == NULL
) && searchArchives
) {
1176 // <rdar://problem/7043256> ld64 can not find a -e entry point from an archive
1177 _inputFiles
.searchLibraries(symbolName
, false, true, *this);
1179 if ( _internal
.indirectBindingTable
[slot
] == NULL
) {
1180 if ( strcmp(symbolName
, "start") == 0 )
1181 throwf("entry point (%s) undefined. Usually in crt1.o", symbolName
);
1183 throwf("entry point (%s) undefined.", symbolName
);
1185 return _internal
.indirectBindingTable
[slot
];
1191 void Resolver::fillInHelpersInInternalState()
1193 // look up well known atoms
1194 bool needsStubHelper
= true;
1195 switch ( _options
.outputKind() ) {
1196 case Options::kDynamicExecutable
:
1197 case Options::kDynamicLibrary
:
1198 case Options::kDynamicBundle
:
1199 needsStubHelper
= true;
1201 case Options::kDyld
:
1202 case Options::kKextBundle
:
1203 case Options::kObjectFile
:
1204 case Options::kStaticExecutable
:
1205 case Options::kPreload
:
1206 needsStubHelper
= false;
1210 _internal
.classicBindingHelper
= NULL
;
1211 if ( needsStubHelper
&& !_options
.makeCompressedDyldInfo() ) {
1212 // "dyld_stub_binding_helper" comes from .o file, so should already exist in symbol table
1213 if ( _symbolTable
.hasName("dyld_stub_binding_helper") ) {
1214 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_stub_binding_helper");
1215 _internal
.classicBindingHelper
= _internal
.indirectBindingTable
[slot
];
1219 _internal
.lazyBindingHelper
= NULL
;
1220 if ( _options
.usingLazyDylibLinking() ) {
1221 // "dyld_lazy_dylib_stub_binding_helper" comes from lazydylib1.o file, so should already exist in symbol table
1222 if ( _symbolTable
.hasName("dyld_lazy_dylib_stub_binding_helper") ) {
1223 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_lazy_dylib_stub_binding_helper");
1224 _internal
.lazyBindingHelper
= _internal
.indirectBindingTable
[slot
];
1226 if ( _internal
.lazyBindingHelper
== NULL
)
1227 throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
1230 _internal
.compressedFastBinderProxy
= NULL
;
1231 if ( needsStubHelper
&& _options
.makeCompressedDyldInfo() ) {
1232 // "dyld_stub_binder" comes from libSystem.dylib so will need to manually resolve
1233 if ( !_symbolTable
.hasName("dyld_stub_binder") ) {
1234 _inputFiles
.searchLibraries("dyld_stub_binder", true, false, *this);
1236 if ( _symbolTable
.hasName("dyld_stub_binder") ) {
1237 SymbolTable::IndirectBindingSlot slot
= _symbolTable
.findSlotForName("dyld_stub_binder");
1238 _internal
.compressedFastBinderProxy
= _internal
.indirectBindingTable
[slot
];
1240 if ( _internal
.compressedFastBinderProxy
== NULL
) {
1241 if ( _options
.undefinedTreatment() != Options::kUndefinedError
) {
1243 _internal
.compressedFastBinderProxy
= new UndefinedProxyAtom("dyld_stub_binder");
1244 this->doAtom(*_internal
.compressedFastBinderProxy
);
1247 warning("symbol dyld_stub_binder not found, normally in libSystem.dylib");
1254 void Resolver::fillInInternalState()
1256 // store atoms into their final section
1257 for (std::vector
<const ld::Atom
*>::iterator it
= _atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1258 _internal
.addAtom(**it
);
1261 // <rdar://problem/7783918> make sure there is a __text section so that codesigning works
1262 if ( (_options
.outputKind() == Options::kDynamicLibrary
) || (_options
.outputKind() == Options::kDynamicBundle
) )
1263 _internal
.getFinalSection(ld::Section("__TEXT", "__text", ld::Section::typeCode
));
1266 _internal
.entryPoint
= this->entryPoint(true);
1271 void Resolver::removeCoalescedAwayAtoms()
1273 _atoms
.erase(std::remove_if(_atoms
.begin(), _atoms
.end(), AtomCoalescedAway()), _atoms
.end());
1276 void Resolver::linkTimeOptimize()
1278 // only do work here if some llvm obj files where loaded
1279 if ( ! _haveLLVMObjs
)
1282 // run LLVM lto code-gen
1283 lto::OptimizeOptions optOpt
;
1284 optOpt
.outputFilePath
= _options
.outputFilePath();
1285 optOpt
.tmpObjectFilePath
= _options
.tempLtoObjectPath();
1286 optOpt
.allGlobalsAReDeadStripRoots
= _options
.allGlobalsAreDeadStripRoots();
1287 optOpt
.verbose
= _options
.verbose();
1288 optOpt
.saveTemps
= _options
.saveTempFiles();
1289 optOpt
.pie
= _options
.positionIndependentExecutable();
1290 optOpt
.mainExecutable
= _options
.linkingMainExecutable();;
1291 optOpt
.staticExecutable
= (_options
.outputKind() == Options::kStaticExecutable
);
1292 optOpt
.relocatable
= (_options
.outputKind() == Options::kObjectFile
);
1293 optOpt
.allowTextRelocs
= _options
.allowTextRelocs();
1294 optOpt
.linkerDeadStripping
= _options
.deadCodeStrip();
1295 optOpt
.arch
= _options
.architecture();
1296 optOpt
.llvmOptions
= &_options
.llvmOptions();
1298 std::vector
<const ld::Atom
*> newAtoms
;
1299 std::vector
<const char*> additionalUndefines
;
1300 if ( ! lto::optimize(_atoms
, _internal
, _inputFiles
.nextInputOrdinal(), optOpt
, *this, newAtoms
, additionalUndefines
) )
1301 return; // if nothing done
1304 // add all newly created atoms to _atoms and update symbol table
1305 for(std::vector
<const ld::Atom
*>::iterator it
= newAtoms
.begin(); it
!= newAtoms
.end(); ++it
)
1308 // some atoms might have been optimized way (marked coalesced), remove them
1309 this->removeCoalescedAwayAtoms();
1311 // add new atoms into their final section
1312 for (std::vector
<const ld::Atom
*>::iterator it
= newAtoms
.begin(); it
!= newAtoms
.end(); ++it
) {
1313 _internal
.addAtom(**it
);
1316 // remove temp lto section and move all of its atoms to their final section
1317 ld::Internal::FinalSection
* tempLTOsection
= NULL
;
1318 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=_internal
.sections
.begin(); sit
!= _internal
.sections
.end(); ++sit
) {
1319 ld::Internal::FinalSection
* sect
= *sit
;
1320 if ( sect
->type() == ld::Section::typeTempLTO
) {
1321 tempLTOsection
= sect
;
1322 // remove temp lto section from final image
1323 _internal
.sections
.erase(sit
);
1327 // lto atoms now have proper section info, so add to final section
1328 if ( tempLTOsection
!= NULL
) {
1329 for (std::vector
<const ld::Atom
*>::iterator ait
=tempLTOsection
->atoms
.begin(); ait
!= tempLTOsection
->atoms
.end(); ++ait
) {
1330 const ld::Atom
* atom
= *ait
;
1331 if ( ! atom
->coalescedAway() ) {
1332 this->convertReferencesToIndirect(*atom
);
1333 _internal
.addAtom(*atom
);
1338 // resolve new undefines (e.g calls to _malloc and _memcpy that llvm compiler conjures up)
1339 _addToFinalSection
= true;
1340 for(std::vector
<const char*>::iterator uit
= additionalUndefines
.begin(); uit
!= additionalUndefines
.end(); ++uit
) {
1341 const char *targetName
= *uit
;
1342 // these symbols may or may not already be in linker's symbol table
1343 if ( ! _symbolTable
.hasName(targetName
) ) {
1344 _inputFiles
.searchLibraries(targetName
, true, true, *this);
1347 _addToFinalSection
= false;
1349 // if -dead_strip on command line
1350 if ( _options
.deadCodeStrip() ) {
1351 // clear liveness bit
1352 for (std::vector
<const ld::Atom
*>::const_iterator it
=_atoms
.begin(); it
!= _atoms
.end(); ++it
) {
1353 (const_cast<ld::Atom
*>(*it
))->setLive((*it
)->dontDeadStrip());
1355 // and re-compute dead code
1356 this->deadStripOptimize();
1358 // remove newly dead atoms from each section
1359 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=_internal
.sections
.begin(); sit
!= _internal
.sections
.end(); ++sit
) {
1360 ld::Internal::FinalSection
* sect
= *sit
;
1361 sect
->atoms
.erase(std::remove_if(sect
->atoms
.begin(), sect
->atoms
.end(), NotLive()), sect
->atoms
.end());
1365 if ( _options
.outputKind() == Options::kObjectFile
) {
1366 // if -r mode, add proxies for new undefines (e.g. ___stack_chk_fail)
1367 _addToFinalSection
= true;
1368 this->resolveUndefines();
1369 _addToFinalSection
= false;
1372 // last chance to check for undefines
1373 this->checkUndefines(true);
1375 // check new code does not override some dylib
1376 this->checkDylibSymbolCollisions();
1381 void Resolver::resolve()
1383 this->initializeState();
1384 this->buildAtomList();
1385 this->addInitialUndefines();
1386 this->fillInHelpersInInternalState();
1387 this->resolveUndefines();
1388 this->deadStripOptimize();
1389 this->checkUndefines();
1390 this->checkDylibSymbolCollisions();
1391 this->removeCoalescedAwayAtoms();
1392 this->fillInInternalState();
1393 this->linkTimeOptimize();