]> git.saurik.com Git - apple/ld64.git/blame_incremental - src/ld/Resolver.cpp
ld64-409.12.tar.gz
[apple/ld64.git] / src / ld / Resolver.cpp
... / ...
CommitLineData
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
3 * Copyright (c) 2009-2010 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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
12 * file.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26#include <stdlib.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <sys/mman.h>
30#include <sys/sysctl.h>
31#include <fcntl.h>
32#include <errno.h>
33#include <limits.h>
34#include <unistd.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>
39#include <dlfcn.h>
40#include <mach-o/dyld.h>
41#include <mach-o/fat.h>
42
43#include <string>
44#include <map>
45#include <set>
46#include <string>
47#include <vector>
48#include <list>
49#include <algorithm>
50#include <dlfcn.h>
51#include <AvailabilityMacros.h>
52
53#include "Options.h"
54#include "ld.hpp"
55#include "Bitcode.hpp"
56#include "InputFiles.h"
57#include "SymbolTable.h"
58#include "Resolver.h"
59#include "parsers/lto_file.h"
60
61#include "configure.h"
62
63#define VAL(x) #x
64#define STRINGIFY(x) VAL(x)
65
66namespace ld {
67namespace tool {
68
69
70//
71// An ExportAtom has no content. It exists so that the linker can track which imported
72// symbols came from which dynamic libraries.
73//
74class UndefinedProxyAtom : public ld::Atom
75{
76public:
77 UndefinedProxyAtom(const char* nm)
78 : ld::Atom(_s_section, ld::Atom::definitionProxy,
79 ld::Atom::combineNever, ld::Atom::scopeLinkageUnit,
80 ld::Atom::typeUnclassified,
81 ld::Atom::symbolTableIn, false, false, false, ld::Atom::Alignment(0)),
82 _name(nm) {}
83 // overrides of ld::Atom
84 virtual const ld::File* file() const { return NULL; }
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) { }
90
91protected:
92
93 virtual ~UndefinedProxyAtom() {}
94
95 const char* _name;
96
97 static ld::Section _s_section;
98};
99
100ld::Section UndefinedProxyAtom::_s_section("__TEXT", "__import", ld::Section::typeImportProxies, true);
101
102
103
104
105class AliasAtom : public ld::Atom
106{
107public:
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()),
113 _name(nm),
114 _aliasOf(target),
115 _fixup(0, ld::Fixup::k1of1, ld::Fixup::kindNoneFollowOn, &target) { }
116
117 // overrides of ld::Atom
118 virtual const ld::File* file() const { return _aliasOf.file(); }
119 virtual const char* translationUnitSource() const
120 { return _aliasOf.translationUnitSource(); }
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; }
136
137 void setFinalAliasOf() const {
138 (const_cast<AliasAtom*>(this))->setAttributesFromAtom(_aliasOf);
139 (const_cast<AliasAtom*>(this))->setScope(ld::Atom::scopeGlobal);
140 }
141
142private:
143 const char* _name;
144 const ld::Atom& _aliasOf;
145 ld::Fixup _fixup;
146};
147
148
149
150class SectionBoundaryAtom : public ld::Atom
151{
152public:
153 static SectionBoundaryAtom* makeSectionBoundaryAtom(const char* name, bool start, const char* segSectName);
154 static SectionBoundaryAtom* makeOldSectionBoundaryAtom(const char* name, bool start);
155
156 // overrides of ld::Atom
157 virtual const ld::File* file() const { return NULL; }
158 virtual const char* name() const { return _name; }
159 virtual uint64_t size() const { return 0; }
160 virtual void copyRawContent(uint8_t buffer[]) const { }
161 virtual const uint8_t* rawContentPointer() const { return NULL; }
162 virtual uint64_t objectAddress() const { return 0; }
163
164private:
165
166 SectionBoundaryAtom(const char* nm, const ld::Section& sect,
167 ld::Atom::ContentType cont) :
168 ld::Atom(sect,
169 ld::Atom::definitionRegular,
170 ld::Atom::combineNever,
171 ld::Atom::scopeLinkageUnit,
172 cont,
173 ld::Atom::symbolTableNotIn,
174 false, false, true, ld::Atom::Alignment(0)),
175 _name(nm) { }
176
177 const char* _name;
178};
179
180SectionBoundaryAtom* SectionBoundaryAtom::makeSectionBoundaryAtom(const char* name, bool start, const char* segSectName)
181{
182
183 const char* segSectDividor = strrchr(segSectName, '$');
184 if ( segSectDividor == NULL )
185 throwf("malformed section$ symbol name: %s", name);
186 const char* sectionName = segSectDividor + 1;
187 int segNameLen = segSectDividor - segSectName;
188 if ( segNameLen > 16 )
189 throwf("malformed section$ symbol name: %s", name);
190 char segName[18];
191 strlcpy(segName, segSectName, segNameLen+1);
192
193 ld::Section::Type sectType = ld::Section::typeUnclassified;
194 if (!strcmp(segName, "__TEXT") && !strcmp(sectionName, "__thread_starts"))
195 sectType = ld::Section::typeThreadStarts;
196
197 const ld::Section* section = new ld::Section(strdup(segName), sectionName, sectType);
198 return new SectionBoundaryAtom(name, *section, (start ? ld::Atom::typeSectionStart : typeSectionEnd));
199}
200
201SectionBoundaryAtom* SectionBoundaryAtom::makeOldSectionBoundaryAtom(const char* name, bool start)
202{
203 // e.g. __DATA__bss__begin
204 char segName[18];
205 strlcpy(segName, name, 7);
206
207 char sectName[18];
208 int nameLen = strlen(name);
209 strlcpy(sectName, &name[6], (start ? nameLen-12 : nameLen-10));
210 warning("grandfathering in old symbol '%s' as alias for 'section$%s$%s$%s'", name, start ? "start" : "end", segName, sectName);
211 const ld::Section* section = new ld::Section(strdup(segName), strdup(sectName), ld::Section::typeUnclassified);
212 return new SectionBoundaryAtom(name, *section, (start ? ld::Atom::typeSectionStart : typeSectionEnd));
213}
214
215
216
217
218class SegmentBoundaryAtom : public ld::Atom
219{
220public:
221 static SegmentBoundaryAtom* makeSegmentBoundaryAtom(const char* name, bool start, const char* segName);
222 static SegmentBoundaryAtom* makeOldSegmentBoundaryAtom(const char* name, bool start);
223
224 // overrides of ld::Atom
225 virtual const ld::File* file() const { return NULL; }
226 virtual const char* name() const { return _name; }
227 virtual uint64_t size() const { return 0; }
228 virtual void copyRawContent(uint8_t buffer[]) const { }
229 virtual const uint8_t* rawContentPointer() const { return NULL; }
230 virtual uint64_t objectAddress() const { return 0; }
231
232private:
233
234 SegmentBoundaryAtom(const char* nm, const ld::Section& sect,
235 ld::Atom::ContentType cont) :
236 ld::Atom(sect,
237 ld::Atom::definitionRegular,
238 ld::Atom::combineNever,
239 ld::Atom::scopeLinkageUnit,
240 cont,
241 ld::Atom::symbolTableNotIn,
242 false, false, true, ld::Atom::Alignment(0)),
243 _name(nm) { }
244
245 const char* _name;
246};
247
248SegmentBoundaryAtom* SegmentBoundaryAtom::makeSegmentBoundaryAtom(const char* name, bool start, const char* segName)
249{
250 if ( *segName == '\0' )
251 throwf("malformed segment$ symbol name: %s", name);
252 if ( strlen(segName) > 16 )
253 throwf("malformed segment$ symbol name: %s", name);
254
255 if ( start ) {
256 const ld::Section* section = new ld::Section(segName, "__start", ld::Section::typeFirstSection, true);
257 return new SegmentBoundaryAtom(name, *section, ld::Atom::typeSectionStart);
258 }
259 else {
260 const ld::Section* section = new ld::Section(segName, "__end", ld::Section::typeLastSection, true);
261 return new SegmentBoundaryAtom(name, *section, ld::Atom::typeSectionEnd);
262 }
263}
264
265SegmentBoundaryAtom* SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(const char* name, bool start)
266{
267 // e.g. __DATA__begin
268 char temp[18];
269 strlcpy(temp, name, 7);
270 char* segName = strdup(temp);
271
272 warning("grandfathering in old symbol '%s' as alias for 'segment$%s$%s'", name, start ? "start" : "end", segName);
273
274 if ( start ) {
275 const ld::Section* section = new ld::Section(segName, "__start", ld::Section::typeFirstSection, true);
276 return new SegmentBoundaryAtom(name, *section, ld::Atom::typeSectionStart);
277 }
278 else {
279 const ld::Section* section = new ld::Section(segName, "__end", ld::Section::typeLastSection, true);
280 return new SegmentBoundaryAtom(name, *section, ld::Atom::typeSectionEnd);
281 }
282}
283
284void Resolver::initializeState()
285{
286 _internal.cpuSubType = _options.subArchitecture();
287
288 // In -r mode, look for -linker_option additions
289 if ( _options.outputKind() == Options::kObjectFile ) {
290 ld::relocatable::File::LinkerOptionsList lo = _options.linkerOptions();
291 for (relocatable::File::LinkerOptionsList::const_iterator it=lo.begin(); it != lo.end(); ++it) {
292 doLinkerOption(*it, "command line");
293 }
294 }
295#ifdef LD64_VERSION_NUM
296 uint32_t packedNum = Options::parseVersionNumber32(STRINGIFY(LD64_VERSION_NUM));
297 uint64_t combined = (uint64_t)TOOL_LD << 32 | packedNum;
298 _internal.toolsVersions.insert(combined);
299#endif
300}
301
302void Resolver::buildAtomList()
303{
304 // each input files contributes initial atoms
305 _atoms.reserve(1024);
306 _inputFiles.forEachInitialAtom(*this, _internal);
307
308 _completedInitialObjectFiles = true;
309
310 //_symbolTable.printStatistics();
311}
312
313
314void Resolver::doLinkerOption(const std::vector<const char*>& linkerOption, const char* fileName)
315{
316 if ( linkerOption.size() == 1 ) {
317 const char* lo1 = linkerOption.front();
318 if ( strncmp(lo1, "-l", 2) == 0) {
319 if (_internal.linkerOptionLibraries.count(&lo1[2]) == 0) {
320 _internal.unprocessedLinkerOptionLibraries.insert(&lo1[2]);
321 }
322 }
323 else {
324 warning("unknown linker option from object file ignored: '%s' in %s", lo1, fileName);
325 }
326 }
327 else if ( linkerOption.size() == 2 ) {
328 const char* lo2a = linkerOption[0];
329 const char* lo2b = linkerOption[1];
330 if ( strcmp(lo2a, "-framework") == 0) {
331 if (_internal.linkerOptionFrameworks.count(lo2b) == 0) {
332 _internal.unprocessedLinkerOptionFrameworks.insert(lo2b);
333 }
334 }
335 else {
336 warning("unknown linker option from object file ignored: '%s' '%s' from %s", lo2a, lo2b, fileName);
337 }
338 }
339 else {
340 warning("unknown linker option from object file ignored, starting with: '%s' from %s", linkerOption.front(), fileName);
341 }
342}
343
344
345void Resolver::doFile(const ld::File& file)
346{
347 const ld::relocatable::File* objFile = dynamic_cast<const ld::relocatable::File*>(&file);
348 const ld::dylib::File* dylibFile = dynamic_cast<const ld::dylib::File*>(&file);
349
350 if ( objFile != NULL ) {
351 // if file has linker options, process them
352 ld::relocatable::File::LinkerOptionsList* lo = objFile->linkerOptions();
353 if ( lo != NULL && !_options.ignoreAutoLink() ) {
354 for (relocatable::File::LinkerOptionsList::const_iterator it=lo->begin(); it != lo->end(); ++it) {
355 this->doLinkerOption(*it, file.path());
356 }
357 // <rdar://problem/23053404> process any additional linker-options introduced by this new archive member being loaded
358 if ( _completedInitialObjectFiles ) {
359 _inputFiles.addLinkerOptionLibraries(_internal, *this);
360 _inputFiles.createIndirectDylibs();
361 }
362 }
363 // update which form of ObjC is being used
364 if ( objFile->hasObjC() )
365 _internal.hasObjC = true;
366
367 // Resolve bitcode section in the object file
368 if ( _options.bundleBitcode() ) {
369 if ( objFile->getBitcode() == NULL ) {
370 // Handle the special case for compiler_rt objects. Add the file to the list to be process.
371 if ( objFile->sourceKind() == ld::relocatable::File::kSourceCompilerArchive ) {
372 _internal.filesFromCompilerRT.push_back(objFile);
373 } else if (objFile->sourceKind() != ld::relocatable::File::kSourceLTO ) {
374 // No bitcode section, figure out if the object file comes from LTO/compiler static library
375 _options.platforms().forEach(^(ld::Platform platform, uint32_t version, bool &stop) {
376 switch ( platform ) {
377 case ld::kPlatform_macOS:
378 case ld::kPlatform_bridgeOS:
379 case ld::kPlatform_iOSMac:
380 case ld::kPlatform_unknown:
381 warning("all bitcode will be dropped because '%s' was built without bitcode. "
382 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. ", file.path());
383 _internal.filesWithBitcode.clear();
384 _internal.dropAllBitcode = true;
385 break;
386 case ld::kPlatform_iOS:
387 case ld::kPlatform_iOSSimulator:
388 throwf("'%s' does not contain bitcode. "
389 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file.path());
390 break;
391 case ld::kPlatform_watchOS:
392 case ld::kPlatform_watchOSSimulator:
393 case ld::kPlatform_tvOS:
394 case ld::kPlatform_tvOSSimulator:
395 throwf("'%s' does not contain bitcode. "
396 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor", file.path());
397 break;
398 }
399 });
400 }
401 } else {
402 // contains bitcode, check if it is just a marker
403 if ( objFile->getBitcode()->isMarker() ) {
404 // if -bitcode_verify_bundle is used, check if all the object files participate in the linking have full bitcode embedded.
405 // error on any marker encountered.
406 if ( _options.verifyBitcode() )
407 throwf("bitcode bundle could not be generated because '%s' was built without full bitcode. "
408 "All object files and libraries for bitcode must be generated from Xcode Archive or Install build",
409 objFile->path());
410 // update the internal state that marker is encountered.
411 _internal.embedMarkerOnly = true;
412 _internal.filesWithBitcode.clear();
413 _internal.dropAllBitcode = true;
414 } else if ( !_internal.dropAllBitcode )
415 _internal.filesWithBitcode.push_back(objFile);
416 }
417 }
418
419 // verify all files use same version of Swift language
420 if ( file.swiftVersion() != 0 ) {
421 _internal.someObjectFileHasSwift = true;
422 if ( _internal.swiftVersion == 0 ) {
423 _internal.swiftVersion = file.swiftVersion();
424 }
425 else if ( file.swiftVersion() != _internal.swiftVersion ) {
426 char fileVersion[64];
427 char otherVersion[64];
428 Options::userReadableSwiftVersion(file.swiftVersion(), fileVersion);
429 Options::userReadableSwiftVersion(_internal.swiftVersion, otherVersion);
430 if ( file.swiftVersion() > _internal.swiftVersion ) {
431 if ( _options.warnOnSwiftABIVersionMismatches() ) {
432 warning("%s compiled with newer version of Swift language (%s) than previous files (%s)",
433 file.path(), fileVersion, otherVersion);
434 } else {
435 throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)",
436 file.path(), fileVersion, otherVersion);
437 }
438 }
439 else {
440 if ( _options.warnOnSwiftABIVersionMismatches() ) {
441 warning("%s compiled with older version of Swift language (%s) than previous files (%s)",
442 file.path(), fileVersion, otherVersion);
443 } else {
444 throwf("%s compiled with older version of Swift language (%s) than previous files (%s)",
445 file.path(), fileVersion, otherVersion);
446 }
447 }
448 }
449 }
450
451 // in -r mode, if any .o files have dwarf then add UUID to output .o file
452 if ( objFile->debugInfo() == ld::relocatable::File::kDebugInfoDwarf )
453 _internal.someObjectFileHasDwarf = true;
454
455 // remember if any .o file did not have MH_SUBSECTIONS_VIA_SYMBOLS bit set
456 if ( ! objFile->canScatterAtoms() )
457 _internal.allObjectFilesScatterable = false;
458
459 // remember if building for profiling (so we don't warn about initializers)
460 if ( objFile->hasllvmProfiling() )
461 _havellvmProfiling = true;
462
463#if MULTI
464 // update minOSVersion off all .o files
465 uint32_t objMinOS = objFile->minOSVersion();
466 if ( !objMinOS )
467 _internal.objectFileFoundWithNoVersion = true;
468 if ( (_options.outputKind() == Options::kObjectFile) && (objMinOS > _internal.minOSVersion) )
469 _internal.minOSVersion = objMinOS;
470#endif
471
472 auto objPlatforms = objFile->platforms();
473 if ( (!objPlatforms.empty()) && (_options.outputKind() == Options::kObjectFile) && (_internal.derivedPlatforms.empty()) )
474 _internal.derivedPlatforms = objPlatforms;
475 // update set of known tools used
476 for (const std::pair<uint32_t,uint32_t>& entry : objFile->toolVersions()) {
477 uint64_t combined = (uint64_t)entry.first << 32 | entry.second;
478 _internal.toolsVersions.insert(combined);
479 }
480
481 // update cpu-sub-type
482 cpu_subtype_t nextObjectSubType = file.cpuSubType();
483 switch ( _options.architecture() ) {
484 case CPU_TYPE_ARM:
485 if ( _options.subArchitecture() != nextObjectSubType ) {
486 if ( (_options.subArchitecture() == CPU_SUBTYPE_ARM_ALL) && _options.forceCpuSubtypeAll() ) {
487 // hack to support gcc multillib build that tries to make sub-type-all slice
488 }
489 else if ( nextObjectSubType == CPU_SUBTYPE_ARM_ALL ) {
490 warning("CPU_SUBTYPE_ARM_ALL subtype is deprecated: %s", file.path());
491 }
492 else if ( _options.allowSubArchitectureMismatches() ) {
493 //warning("object file %s was built for different arm sub-type (%d) than link command line (%d)",
494 // file.path(), nextObjectSubType, _options.subArchitecture());
495 }
496 else {
497 throwf("object file %s was built for different arm sub-type (%d) than link command line (%d)",
498 file.path(), nextObjectSubType, _options.subArchitecture());
499 }
500 }
501 break;
502
503 case CPU_TYPE_ARM64:
504 if ( _options.subArchitecture() != nextObjectSubType ) {
505 if ( _options.allowSubArchitectureMismatches() ) {
506 warning("object file %s was built for different arm64 sub-type (%d) than link command line (%d)",
507 file.path(), nextObjectSubType, _options.subArchitecture());
508 }
509 else {
510 throwf("object file %s was built for different arm64 sub-type (%d) than link command line (%d)",
511 file.path(), nextObjectSubType, _options.subArchitecture());
512 }
513 }
514 break;
515
516 case CPU_TYPE_I386:
517 _internal.cpuSubType = CPU_SUBTYPE_I386_ALL;
518 break;
519
520 case CPU_TYPE_X86_64:
521 if ( _options.subArchitecture() != nextObjectSubType ) {
522 if ( _options.allowSubArchitectureMismatches() ) {
523 warning("object file %s was built for different x86_64 sub-type (%d) than link command line (%d)",
524 file.path(), nextObjectSubType, _options.subArchitecture());
525 }
526 else {
527 throwf("object file %s was built for different x86_64 sub-type (%d) than link command line (%d)",
528 file.path(), nextObjectSubType, _options.subArchitecture());
529 }
530 }
531 break;
532 }
533 }
534 if ( dylibFile != NULL ) {
535 // Check dylib for bitcode, if the library install path is relative path or @rpath, it has to contain bitcode
536 if ( _options.bundleBitcode() ) {
537 bool isSystemFramework = ( dylibFile->installPath() != NULL ) && ( dylibFile->installPath()[0] == '/' );
538 if ( dylibFile->getBitcode() == NULL && !isSystemFramework ) {
539 // Check if the dylib is from toolchain by checking the path
540 char tcLibPath[PATH_MAX];
541 char ldPath[PATH_MAX];
542 char tempPath[PATH_MAX];
543 uint32_t bufSize = PATH_MAX;
544 // toolchain library path should pointed to *.xctoolchain/usr/lib
545 if ( _NSGetExecutablePath(ldPath, &bufSize) != -1 ) {
546 if ( realpath(ldPath, tempPath) != NULL ) {
547 char* lastSlash = strrchr(tempPath, '/');
548 if ( lastSlash != NULL )
549 strcpy(lastSlash, "/../lib");
550 }
551 }
552 // Compare toolchain library path to the dylib path
553 if ( realpath(tempPath, tcLibPath) == NULL ||
554 realpath(dylibFile->path(), tempPath) == NULL ||
555 strncmp(tcLibPath, tempPath, strlen(tcLibPath)) != 0 ) {
556 _options.platforms().forEach(^(ld::Platform platform, uint32_t version, bool &stop) {
557 switch ( platform ) {
558 case ld::kPlatform_macOS:
559 case ld::kPlatform_bridgeOS:
560 case ld::kPlatform_iOSMac:
561 case ld::kPlatform_unknown:
562 warning("all bitcode will be dropped because '%s' was built without bitcode. "
563 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file.path());
564 _internal.filesWithBitcode.clear();
565 _internal.dropAllBitcode = true;
566 break;
567 case ld::kPlatform_iOS:
568 case ld::kPlatform_iOSSimulator:
569 throwf("'%s' does not contain bitcode. "
570 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file.path());
571 break;
572 case ld::kPlatform_watchOS:
573 case ld::kPlatform_watchOSSimulator:
574 case ld::kPlatform_tvOS:
575 case ld::kPlatform_tvOSSimulator:
576 throwf("'%s' does not contain bitcode. "
577 "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor", file.path());
578 break;
579 }
580 });
581 }
582 }
583 // Error on bitcode marker in non-system frameworks if -bitcode_verify is used
584 if ( _options.verifyBitcode() && !isSystemFramework &&
585 dylibFile->getBitcode() != NULL && dylibFile->getBitcode()->isMarker() )
586 throwf("bitcode bundle could not be generated because '%s' was built without full bitcode. "
587 "All frameworks and dylibs for bitcode must be generated from Xcode Archive or Install build",
588 dylibFile->path());
589 }
590
591 // Don't allow swift frameworks to link other swift frameworks.
592 if ( !_internal.firstSwiftDylibFile && _options.outputKind() == Options::kDynamicLibrary
593 && file.swiftVersion() != 0 && getenv("LD_DISALLOW_SWIFT_LINKING_SWIFT")) {
594 // Check that we aren't a whitelisted path.
595 bool inWhiteList = false;
596 const char *whitelistedPaths[] = { "/System/Library/PrivateFrameworks/Swift" };
597 for (auto whitelistedPath : whitelistedPaths) {
598 if (!strncmp(whitelistedPath, dylibFile->installPath(), strlen(whitelistedPath))) {
599 inWhiteList = true;
600 break;
601 }
602 }
603 if (!inWhiteList) {
604 _internal.firstSwiftDylibFile = dylibFile;
605 }
606 }
607
608 // <rdar://problem/25680358> verify dylibs use same version of Swift language
609 if ( file.swiftVersion() != 0 ) {
610 if ( _internal.swiftVersion == 0 ) {
611 _internal.swiftVersion = file.swiftVersion();
612 }
613 else if ( file.swiftVersion() != _internal.swiftVersion ) {
614 char fileVersion[64];
615 char otherVersion[64];
616 Options::userReadableSwiftVersion(file.swiftVersion(), fileVersion);
617 Options::userReadableSwiftVersion(_internal.swiftVersion, otherVersion);
618 if ( file.swiftVersion() > _internal.swiftVersion ) {
619 if ( _options.warnOnSwiftABIVersionMismatches() ) {
620 warning("%s compiled with newer version of Swift language (%s) than previous files (%s)",
621 file.path(), fileVersion, otherVersion);
622 } else {
623 throwf("%s compiled with newer version of Swift language (%s) than previous files (%s)",
624 file.path(), fileVersion, otherVersion);
625 }
626 }
627 else {
628 if ( _options.warnOnSwiftABIVersionMismatches() ) {
629 warning("%s compiled with older version of Swift language (%s) than previous files (%s)",
630 file.path(), fileVersion, otherVersion);
631 } else {
632 throwf("%s compiled with older version of Swift language (%s) than previous files (%s)",
633 file.path(), fileVersion, otherVersion);
634 }
635 }
636 }
637 }
638
639 if ( _options.checkDylibsAreAppExtensionSafe() && !dylibFile->appExtensionSafe() ) {
640 warning("linking against a dylib which is not safe for use in application extensions: %s", file.path());
641 }
642 const char* depInstallName = dylibFile->installPath();
643 // <rdar://problem/17229513> embedded frameworks are only supported on iOS 8 and later
644 if ( (depInstallName != NULL) && (depInstallName[0] != '/') ) {
645 if ( _options.platforms().contains(ld::kPlatform_iOS) && !_options.platforms().minOS(iOS_8_0) ) {
646 // <rdar://problem/17598404> only warn about linking against embedded dylib if it is built for iOS 8 or later
647 if ( dylibFile->platforms().minOS(ld::iOS_8_0) )
648 throwf("embedded dylibs/frameworks are only supported on iOS 8.0 and later (%s)", depInstallName);
649 }
650 }
651 if ( _options.sharedRegionEligible() ) {
652 assert(depInstallName != NULL);
653 if ( depInstallName[0] == '@' ) {
654 warning("invalid -install_name (%s) in dependent dylib (%s). Dylibs/frameworks which might go in dyld shared cache "
655 "cannot link with dylib that uses @rpath, @loader_path, etc.", depInstallName, dylibFile->path());
656 } else if ( (strncmp(depInstallName, "/usr/lib/", 9) != 0) && (strncmp(depInstallName, "/System/Library/", 16) != 0) ) {
657 warning("invalid -install_name (%s) in dependent dylib (%s). Dylibs/frameworks which might go in dyld shared cache "
658 "cannot link with dylibs that won't be in the shared cache", depInstallName, dylibFile->path());
659 }
660 }
661 }
662}
663
664void Resolver::doAtom(const ld::Atom& atom)
665{
666 //fprintf(stderr, "Resolver::doAtom(%p), name=%s, sect=%s, scope=%d\n", &atom, atom.name(), atom.section().sectionName(), atom.scope());
667 if ( _ltoCodeGenFinished && (atom.contentType() == ld::Atom::typeLTOtemporary) && (atom.scope() != ld::Atom::scopeTranslationUnit) )
668 warning("'%s' is implemented in bitcode, but it was loaded too late", atom.name());
669
670 // add to list of known atoms
671 _atoms.push_back(&atom);
672
673 // adjust scope
674 if ( _options.hasExportRestrictList() || _options.hasReExportList() ) {
675 const char* name = atom.name();
676 switch ( atom.scope() ) {
677 case ld::Atom::scopeTranslationUnit:
678 break;
679 case ld::Atom::scopeLinkageUnit:
680 if ( _options.hasExportMaskList() && _options.shouldExport(name) ) {
681 // <rdar://problem/5062685> ld does not report error when -r is used and exported symbols are not defined.
682 if ( _options.outputKind() == Options::kObjectFile )
683 throwf("cannot export hidden symbol %s", name);
684 // .objc_class_name_* symbols are special
685 if ( atom.section().type() != ld::Section::typeObjC1Classes ) {
686 if ( atom.definition() == ld::Atom::definitionProxy ) {
687 // .exp file says to export a symbol, but that symbol is in some dylib being linked
688 if ( _options.canReExportSymbols() ) {
689 // marking proxy atom as global triggers the re-export
690 (const_cast<ld::Atom*>(&atom))->setScope(ld::Atom::scopeGlobal);
691 }
692 else if ( _options.outputKind() == Options::kDynamicLibrary ) {
693 if ( atom.file() != NULL )
694 warning("target OS does not support re-exporting symbol %s from %s\n", _options.demangleSymbol(name), atom.safeFilePath());
695 else
696 warning("target OS does not support re-exporting symbol %s\n", _options.demangleSymbol(name));
697 }
698 }
699 else {
700 if ( atom.file() != NULL )
701 warning("cannot export hidden symbol %s from %s", _options.demangleSymbol(name), atom.safeFilePath());
702 else
703 warning("cannot export hidden symbol %s", _options.demangleSymbol(name));
704 }
705 }
706 }
707 else if ( _options.shouldReExport(name) && _options.canReExportSymbols() ) {
708 if ( atom.definition() == ld::Atom::definitionProxy ) {
709 // marking proxy atom as global triggers the re-export
710 (const_cast<ld::Atom*>(&atom))->setScope(ld::Atom::scopeGlobal);
711 }
712 else {
713 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", _options.demangleSymbol(name), atom.safeFilePath());
714 }
715 }
716 break;
717 case ld::Atom::scopeGlobal:
718 // check for globals that are downgraded to hidden
719 if ( ! _options.shouldExport(name) ) {
720 (const_cast<ld::Atom*>(&atom))->setScope(ld::Atom::scopeLinkageUnit);
721 //fprintf(stderr, "demote %s to hidden\n", name);
722 }
723 if ( _options.canReExportSymbols() && _options.shouldReExport(name) ) {
724 throwf("requested re-export symbol %s is not from a dylib, but from %s\n", _options.demangleSymbol(name), atom.safeFilePath());
725 }
726 break;
727 }
728 }
729
730 // work around for kernel that uses 'l' labels in assembly code
731 if ( (atom.symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages)
732 && (atom.name()[0] == 'l') && (_options.outputKind() == Options::kStaticExecutable)
733 && (strncmp(atom.name(), "ltmp", 4) != 0) )
734 (const_cast<ld::Atom*>(&atom))->setSymbolTableInclusion(ld::Atom::symbolTableIn);
735
736
737 // tell symbol table about non-static atoms
738 if ( atom.scope() != ld::Atom::scopeTranslationUnit ) {
739 _symbolTable.add(atom, _options.deadCodeStrip() && (_completedInitialObjectFiles || _options.allowDeadDuplicates()));
740
741 // add symbol aliases defined on the command line
742 if ( _options.haveCmdLineAliases() ) {
743 const std::vector<Options::AliasPair>& aliases = _options.cmdLineAliases();
744 for (std::vector<Options::AliasPair>::const_iterator it=aliases.begin(); it != aliases.end(); ++it) {
745 if ( strcmp(it->realName, atom.name()) == 0 ) {
746 if ( strcmp(it->realName, it->alias) == 0 ) {
747 warning("ignoring alias of itself '%s'", it->realName);
748 }
749 else {
750 const AliasAtom* alias = new AliasAtom(atom, it->alias);
751 _aliasesFromCmdLine.push_back(alias);
752 this->doAtom(*alias);
753 }
754 }
755 }
756 }
757 }
758
759 // convert references by-name or by-content to by-slot
760 this->convertReferencesToIndirect(atom);
761
762 // remember if any atoms are proxies that require LTO
763 if ( atom.contentType() == ld::Atom::typeLTOtemporary )
764 _haveLLVMObjs = true;
765
766 // remember if any atoms are aliases
767 if ( atom.section().type() == ld::Section::typeTempAlias )
768 _haveAliases = true;
769
770 // error or warn about initializers
771 if ( (atom.section().type() == ld::Section::typeInitializerPointers) && !_havellvmProfiling ) {
772 switch ( _options.initializersTreatment() ) {
773 case Options::kError:
774 throwf("static initializer found in '%s'",atom.safeFilePath());
775 case Options::kWarning:
776 warning("static initializer found in '%s'. Use -no_inits to make this an error. Use -no_warn_inits to suppress warning",atom.safeFilePath());
777 break;
778 default:
779 break;
780 }
781 }
782
783 if ( _options.deadCodeStrip() ) {
784 // add to set of dead-strip-roots, all symbols that the compiler marks as don't strip
785 if ( atom.dontDeadStrip() )
786 _deadStripRoots.insert(&atom);
787 else if ( atom.dontDeadStripIfReferencesLive() )
788 _dontDeadStripIfReferencesLive.push_back(&atom);
789
790 if ( atom.scope() == ld::Atom::scopeGlobal ) {
791 // <rdar://problem/5524973> -exported_symbols_list that has wildcards and -dead_strip
792 // in dylibs, every global atom in initial .o files is a root
793 if ( _options.hasWildCardExportRestrictList() || _options.allGlobalsAreDeadStripRoots() ) {
794 if ( _options.shouldExport(atom.name()) )
795 _deadStripRoots.insert(&atom);
796 }
797 }
798 }
799}
800
801bool Resolver::isDtraceProbe(ld::Fixup::Kind kind)
802{
803 switch (kind) {
804 case ld::Fixup::kindStoreX86DtraceCallSiteNop:
805 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
806 case ld::Fixup::kindStoreARMDtraceCallSiteNop:
807 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
808 case ld::Fixup::kindStoreARM64DtraceCallSiteNop:
809 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear:
810 case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
811 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
812 case ld::Fixup::kindDtraceExtra:
813 return true;
814 default:
815 break;
816 }
817 return false;
818}
819
820void Resolver::convertReferencesToIndirect(const ld::Atom& atom)
821{
822 // convert references by-name or by-content to by-slot
823 SymbolTable::IndirectBindingSlot slot;
824 const ld::Atom* dummy;
825 ld::Fixup::iterator end = atom.fixupsEnd();
826 for (ld::Fixup::iterator fit=atom.fixupsBegin(); fit != end; ++fit) {
827 if ( fit->kind == ld::Fixup::kindLinkerOptimizationHint )
828 _internal.someObjectHasOptimizationHints = true;
829 switch ( fit->binding ) {
830 case ld::Fixup::bindingByNameUnbound:
831 if ( isDtraceProbe(fit->kind) && (_options.outputKind() != Options::kObjectFile ) ) {
832 // in final linked images, remove reference
833 fit->binding = ld::Fixup::bindingNone;
834 }
835 else {
836 slot = _symbolTable.findSlotForName(fit->u.name);
837 fit->binding = ld::Fixup::bindingsIndirectlyBound;
838 fit->u.bindingIndex = slot;
839 }
840 break;
841 case ld::Fixup::bindingByContentBound:
842 switch ( fit->u.target->combine() ) {
843 case ld::Atom::combineNever:
844 case ld::Atom::combineByName:
845 assert(0 && "wrong combine type for bind by content");
846 break;
847 case ld::Atom::combineByNameAndContent:
848 slot = _symbolTable.findSlotForContent(fit->u.target, &dummy);
849 fit->binding = ld::Fixup::bindingsIndirectlyBound;
850 fit->u.bindingIndex = slot;
851 break;
852 case ld::Atom::combineByNameAndReferences:
853 slot = _symbolTable.findSlotForReferences(fit->u.target, &dummy);
854 fit->binding = ld::Fixup::bindingsIndirectlyBound;
855 fit->u.bindingIndex = slot;
856 break;
857 }
858 break;
859 case ld::Fixup::bindingNone:
860 case ld::Fixup::bindingDirectlyBound:
861 case ld::Fixup::bindingsIndirectlyBound:
862 break;
863 }
864 }
865}
866
867
868void Resolver::addInitialUndefines()
869{
870 // add initial undefines from -u option
871 for (Options::UndefinesIterator it=_options.initialUndefinesBegin(); it != _options.initialUndefinesEnd(); ++it) {
872 _symbolTable.findSlotForName(*it);
873 }
874}
875
876void Resolver::resolveUndefines()
877{
878 // keep looping until no more undefines were added in last loop
879 unsigned int undefineGenCount = 0xFFFFFFFF;
880 while ( undefineGenCount != _symbolTable.updateCount() ) {
881 undefineGenCount = _symbolTable.updateCount();
882 std::vector<const char*> undefineNames;
883 _symbolTable.undefines(undefineNames);
884 for(std::vector<const char*>::iterator it = undefineNames.begin(); it != undefineNames.end(); ++it) {
885 const char* undef = *it;
886 // load for previous undefine may also have loaded this undefine, so check again
887 if ( ! _symbolTable.hasName(undef) ) {
888 _inputFiles.searchLibraries(undef, true, true, false, *this);
889 if ( !_symbolTable.hasName(undef) && (_options.outputKind() != Options::kObjectFile) ) {
890 if ( strncmp(undef, "section$", 8) == 0 ) {
891 if ( strncmp(undef, "section$start$", 14) == 0 ) {
892 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef, true, &undef[14]));
893 }
894 else if ( strncmp(undef, "section$end$", 12) == 0 ) {
895 this->doAtom(*SectionBoundaryAtom::makeSectionBoundaryAtom(undef, false, &undef[12]));
896 }
897 }
898 else if ( strncmp(undef, "segment$", 8) == 0 ) {
899 if ( strncmp(undef, "segment$start$", 14) == 0 ) {
900 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef, true, &undef[14]));
901 }
902 else if ( strncmp(undef, "segment$end$", 12) == 0 ) {
903 this->doAtom(*SegmentBoundaryAtom::makeSegmentBoundaryAtom(undef, false, &undef[12]));
904 }
905 }
906 else if ( _options.outputKind() == Options::kPreload ) {
907 // for iBoot grandfather in old style section labels
908 int undefLen = strlen(undef);
909 if ( strcmp(&undef[undefLen-7], "__begin") == 0 ) {
910 if ( undefLen > 13 )
911 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef, true));
912 else
913 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef, true));
914 }
915 else if ( strcmp(&undef[undefLen-5], "__end") == 0 ) {
916 if ( undefLen > 11 )
917 this->doAtom(*SectionBoundaryAtom::makeOldSectionBoundaryAtom(undef, false));
918 else
919 this->doAtom(*SegmentBoundaryAtom::makeOldSegmentBoundaryAtom(undef, false));
920 }
921 }
922 }
923 }
924 }
925 // <rdar://problem/5894163> need to search archives for overrides of common symbols
926 if ( _symbolTable.hasExternalTentativeDefinitions() ) {
927 bool searchDylibs = (_options.commonsMode() == Options::kCommonsOverriddenByDylibs);
928 std::vector<const char*> tents;
929 _symbolTable.tentativeDefs(tents);
930 for(std::vector<const char*>::iterator it = tents.begin(); it != tents.end(); ++it) {
931 // load for previous tentative may also have loaded this tentative, so check again
932 const ld::Atom* curAtom = _symbolTable.atomForSlot(_symbolTable.findSlotForName(*it));
933 assert(curAtom != NULL);
934 if ( curAtom->definition() == ld::Atom::definitionTentative ) {
935 _inputFiles.searchLibraries(*it, searchDylibs, true, true, *this);
936 }
937 }
938 }
939 }
940
941 // Use linker options to resolve any remaining undefined symbols
942 if ( !_internal.linkerOptionLibraries.empty() || !_internal.linkerOptionFrameworks.empty() ) {
943 std::vector<const char*> undefineNames;
944 _symbolTable.undefines(undefineNames);
945 if ( undefineNames.size() != 0 ) {
946 for (std::vector<const char*>::iterator it = undefineNames.begin(); it != undefineNames.end(); ++it) {
947 const char* undef = *it;
948 if ( ! _symbolTable.hasName(undef) ) {
949 _inputFiles.searchLibraries(undef, true, true, false, *this);
950 }
951 }
952 }
953 }
954
955 // create proxies as needed for undefined symbols
956 if ( (_options.undefinedTreatment() != Options::kUndefinedError) || (_options.outputKind() == Options::kObjectFile) ) {
957 std::vector<const char*> undefineNames;
958 _symbolTable.undefines(undefineNames);
959 for(std::vector<const char*>::iterator it = undefineNames.begin(); it != undefineNames.end(); ++it) {
960 const char* undefName = *it;
961 // <rdar://problem/14547001> "ld -r -exported_symbol _foo" has wrong error message if _foo is undefined
962 bool makeProxy = true;
963 if ( (_options.outputKind() == Options::kObjectFile) && _options.hasExportMaskList() && _options.shouldExport(undefName) )
964 makeProxy = false;
965
966 if ( makeProxy )
967 this->doAtom(*new UndefinedProxyAtom(undefName));
968 }
969 }
970
971 // support -U option
972 if ( _options.someAllowedUndefines() ) {
973 std::vector<const char*> undefineNames;
974 _symbolTable.undefines(undefineNames);
975 for(std::vector<const char*>::iterator it = undefineNames.begin(); it != undefineNames.end(); ++it) {
976 if ( _options.allowedUndefined(*it) ) {
977 // make proxy
978 this->doAtom(*new UndefinedProxyAtom(*it));
979 }
980 }
981 }
982
983 // After resolving all the undefs within the linkageUnit, record all the remaining undefs and all the proxies.
984 if (_options.bundleBitcode() && _options.hideSymbols())
985 _symbolTable.mustPreserveForBitcode(_internal.allUndefProxies);
986
987}
988
989
990void Resolver::markLive(const ld::Atom& atom, WhyLiveBackChain* previous)
991{
992 //fprintf(stderr, "markLive(%p) %s\n", &atom, atom.name());
993 // if -why_live cares about this symbol, then dump chain
994 if ( (previous->referer != NULL) && _options.printWhyLive(atom.name()) ) {
995 fprintf(stderr, "%s from %s\n", atom.name(), atom.safeFilePath());
996 int depth = 1;
997 for(WhyLiveBackChain* p = previous; p != NULL; p = p->previous, ++depth) {
998 for(int i=depth; i > 0; --i)
999 fprintf(stderr, " ");
1000 fprintf(stderr, "%s from %s\n", p->referer->name(), p->referer->safeFilePath());
1001 }
1002 }
1003
1004 // if already marked live, then done (stop recursion)
1005 if ( atom.live() )
1006 return;
1007
1008 // mark this atom is live
1009 (const_cast<ld::Atom*>(&atom))->setLive();
1010
1011 // mark all atoms it references as live
1012 WhyLiveBackChain thisChain;
1013 thisChain.previous = previous;
1014 thisChain.referer = &atom;
1015 for (ld::Fixup::iterator fit = atom.fixupsBegin(), end=atom.fixupsEnd(); fit != end; ++fit) {
1016 const ld::Atom* target;
1017 switch ( fit->kind ) {
1018 case ld::Fixup::kindNone:
1019 case ld::Fixup::kindNoneFollowOn:
1020 case ld::Fixup::kindNoneGroupSubordinate:
1021 case ld::Fixup::kindNoneGroupSubordinateFDE:
1022 case ld::Fixup::kindNoneGroupSubordinateLSDA:
1023 case ld::Fixup::kindNoneGroupSubordinatePersonality:
1024 case ld::Fixup::kindSetTargetAddress:
1025 case ld::Fixup::kindSubtractTargetAddress:
1026 case ld::Fixup::kindStoreTargetAddressLittleEndian32:
1027 case ld::Fixup::kindStoreTargetAddressLittleEndian64:
1028#if SUPPORT_ARCH_arm64e
1029 case ld::Fixup::kindStoreTargetAddressLittleEndianAuth64:
1030#endif
1031 case ld::Fixup::kindStoreTargetAddressBigEndian32:
1032 case ld::Fixup::kindStoreTargetAddressBigEndian64:
1033 case ld::Fixup::kindStoreTargetAddressX86PCRel32:
1034 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
1035 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
1036 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
1037 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad:
1038 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA:
1039 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad:
1040 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA:
1041 case ld::Fixup::kindStoreTargetAddressARMBranch24:
1042 case ld::Fixup::kindStoreTargetAddressThumbBranch22:
1043#if SUPPORT_ARCH_arm64
1044 case ld::Fixup::kindStoreTargetAddressARM64Branch26:
1045 case ld::Fixup::kindStoreTargetAddressARM64Page21:
1046 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21:
1047 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21:
1048 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPage21:
1049 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPage21:
1050#endif
1051 if ( fit->binding == ld::Fixup::bindingByContentBound ) {
1052 // normally this was done in convertReferencesToIndirect()
1053 // but a archive loaded .o file may have a forward reference
1054 SymbolTable::IndirectBindingSlot slot;
1055 const ld::Atom* dummy;
1056 switch ( fit->u.target->combine() ) {
1057 case ld::Atom::combineNever:
1058 case ld::Atom::combineByName:
1059 assert(0 && "wrong combine type for bind by content");
1060 break;
1061 case ld::Atom::combineByNameAndContent:
1062 slot = _symbolTable.findSlotForContent(fit->u.target, &dummy);
1063 fit->binding = ld::Fixup::bindingsIndirectlyBound;
1064 fit->u.bindingIndex = slot;
1065 break;
1066 case ld::Atom::combineByNameAndReferences:
1067 slot = _symbolTable.findSlotForReferences(fit->u.target, &dummy);
1068 fit->binding = ld::Fixup::bindingsIndirectlyBound;
1069 fit->u.bindingIndex = slot;
1070 break;
1071 }
1072 }
1073 switch ( fit->binding ) {
1074 case ld::Fixup::bindingDirectlyBound:
1075 markLive(*(fit->u.target), &thisChain);
1076 break;
1077 case ld::Fixup::bindingByNameUnbound:
1078 // doAtom() did not convert to indirect in dead-strip mode, so that now
1079 fit->u.bindingIndex = _symbolTable.findSlotForName(fit->u.name);
1080 fit->binding = ld::Fixup::bindingsIndirectlyBound;
1081 // fall into next case
1082 case ld::Fixup::bindingsIndirectlyBound:
1083 target = _internal.indirectBindingTable[fit->u.bindingIndex];
1084 if ( target == NULL ) {
1085 const char* targetName = _symbolTable.indirectName(fit->u.bindingIndex);
1086 _inputFiles.searchLibraries(targetName, true, true, false, *this);
1087 target = _internal.indirectBindingTable[fit->u.bindingIndex];
1088 }
1089 if ( target != NULL ) {
1090 if ( target->definition() == ld::Atom::definitionTentative ) {
1091 // <rdar://problem/5894163> need to search archives for overrides of common symbols
1092 bool searchDylibs = (_options.commonsMode() == Options::kCommonsOverriddenByDylibs);
1093 _inputFiles.searchLibraries(target->name(), searchDylibs, true, true, *this);
1094 // recompute target since it may have been overridden by searchLibraries()
1095 target = _internal.indirectBindingTable[fit->u.bindingIndex];
1096 }
1097 this->markLive(*target, &thisChain);
1098 }
1099 else {
1100 _atomsWithUnresolvedReferences.push_back(&atom);
1101 }
1102 break;
1103 default:
1104 assert(0 && "bad binding during dead stripping");
1105 }
1106 break;
1107 default:
1108 break;
1109 }
1110 }
1111
1112}
1113
1114class NotLiveLTO {
1115public:
1116 bool operator()(const ld::Atom* atom) const {
1117 if (atom->live() || atom->dontDeadStrip() )
1118 return false;
1119 // don't kill combinable atoms in first pass
1120 switch ( atom->combine() ) {
1121 case ld::Atom::combineByNameAndContent:
1122 case ld::Atom::combineByNameAndReferences:
1123 return false;
1124 default:
1125 return true;
1126 }
1127 }
1128};
1129
1130void Resolver::deadStripOptimize(bool force)
1131{
1132 // only do this optimization with -dead_strip
1133 if ( ! _options.deadCodeStrip() )
1134 return;
1135
1136 // add entry point (main) to live roots
1137 const ld::Atom* entry = this->entryPoint(true);
1138 if ( entry != NULL )
1139 _deadStripRoots.insert(entry);
1140
1141 // add -exported_symbols_list, -init, and -u entries to live roots
1142 for (Options::UndefinesIterator uit=_options.initialUndefinesBegin(); uit != _options.initialUndefinesEnd(); ++uit) {
1143 SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName(*uit);
1144 if ( _internal.indirectBindingTable[slot] == NULL ) {
1145 _inputFiles.searchLibraries(*uit, false, true, false, *this);
1146 }
1147 if ( _internal.indirectBindingTable[slot] != NULL )
1148 _deadStripRoots.insert(_internal.indirectBindingTable[slot]);
1149 }
1150
1151 // this helper is only referenced by synthesize stubs, assume it will be used
1152 if ( _internal.classicBindingHelper != NULL )
1153 _deadStripRoots.insert(_internal.classicBindingHelper);
1154
1155 // this helper is only referenced by synthesize stubs, assume it will be used
1156 if ( _internal.compressedFastBinderProxy != NULL )
1157 _deadStripRoots.insert(_internal.compressedFastBinderProxy);
1158
1159 // this helper is only referenced by synthesized lazy stubs, assume it will be used
1160 if ( _internal.lazyBindingHelper != NULL )
1161 _deadStripRoots.insert(_internal.lazyBindingHelper);
1162
1163 // add all dont-dead-strip atoms as roots
1164 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1165 const ld::Atom* atom = *it;
1166 if ( atom->dontDeadStrip() ) {
1167 //fprintf(stderr, "dont dead strip: %p %s %s\n", atom, atom->section().sectionName(), atom->name());
1168 _deadStripRoots.insert(atom);
1169 // unset liveness, so markLive() will recurse
1170 (const_cast<ld::Atom*>(atom))->setLive(0);
1171 }
1172 }
1173
1174 // mark all roots as live, and all atoms they reference
1175 for (std::set<const ld::Atom*>::iterator it=_deadStripRoots.begin(); it != _deadStripRoots.end(); ++it) {
1176 WhyLiveBackChain rootChain;
1177 rootChain.previous = NULL;
1178 rootChain.referer = *it;
1179 this->markLive(**it, &rootChain);
1180 }
1181
1182 // special case atoms that need to be live if they reference something live
1183 if ( ! _dontDeadStripIfReferencesLive.empty() ) {
1184 for (std::vector<const ld::Atom*>::iterator it=_dontDeadStripIfReferencesLive.begin(); it != _dontDeadStripIfReferencesLive.end(); ++it) {
1185 const Atom* liveIfRefLiveAtom = *it;
1186 //fprintf(stderr, "live-if-live atom: %s\n", liveIfRefLiveAtom->name());
1187 if ( liveIfRefLiveAtom->live() )
1188 continue;
1189 bool hasLiveRef = false;
1190 for (ld::Fixup::iterator fit=liveIfRefLiveAtom->fixupsBegin(); fit != liveIfRefLiveAtom->fixupsEnd(); ++fit) {
1191 const Atom* target = NULL;
1192 switch ( fit->binding ) {
1193 case ld::Fixup::bindingDirectlyBound:
1194 target = fit->u.target;
1195 break;
1196 case ld::Fixup::bindingsIndirectlyBound:
1197 target = _internal.indirectBindingTable[fit->u.bindingIndex];
1198 break;
1199 default:
1200 break;
1201 }
1202 if ( (target != NULL) && target->live() )
1203 hasLiveRef = true;
1204 }
1205 if ( hasLiveRef ) {
1206 WhyLiveBackChain rootChain;
1207 rootChain.previous = NULL;
1208 rootChain.referer = liveIfRefLiveAtom;
1209 this->markLive(*liveIfRefLiveAtom, &rootChain);
1210 }
1211 }
1212 }
1213
1214 // now remove all non-live atoms from _atoms
1215 const bool log = false;
1216 if ( log ) {
1217 fprintf(stderr, "deadStripOptimize() all %ld atoms with liveness:\n", _atoms.size());
1218 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1219 const ld::File* file = (*it)->file();
1220 fprintf(stderr, " live=%d atom=%p name=%s from=%s\n", (*it)->live(), *it, (*it)->name(), (file ? file->path() : "<internal>"));
1221 }
1222 }
1223
1224 if ( _haveLLVMObjs && !force ) {
1225 std::copy_if(_atoms.begin(), _atoms.end(), std::back_inserter(_internal.deadAtoms), NotLiveLTO() );
1226 // <rdar://problem/9777977> don't remove combinable atoms, they may come back in lto output
1227 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), NotLiveLTO()), _atoms.end());
1228 _symbolTable.removeDeadAtoms();
1229 }
1230 else {
1231 std::copy_if(_atoms.begin(), _atoms.end(), std::back_inserter(_internal.deadAtoms), NotLive() );
1232 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), NotLive()), _atoms.end());
1233 }
1234
1235 if ( log ) {
1236 fprintf(stderr, "deadStripOptimize() %ld remaining atoms\n", _atoms.size());
1237 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1238 fprintf(stderr, " live=%d atom=%p name=%s\n", (*it)->live(), *it, (*it)->name());
1239 }
1240 }
1241}
1242
1243
1244// This is called when LTO is used but -dead_strip is not used.
1245// Some undefines were eliminated by LTO, but others were not.
1246void Resolver::remainingUndefines(std::vector<const char*>& undefs)
1247{
1248 StringSet undefSet;
1249 // search all atoms for references that are unbound
1250 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1251 const ld::Atom* atom = *it;
1252 for (ld::Fixup::iterator fit=atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
1253 switch ( (ld::Fixup::TargetBinding)fit->binding ) {
1254 case ld::Fixup::bindingByNameUnbound:
1255 assert(0 && "should not be by-name this late");
1256 undefSet.insert(fit->u.name);
1257 break;
1258 case ld::Fixup::bindingsIndirectlyBound:
1259 if ( _internal.indirectBindingTable[fit->u.bindingIndex] == NULL ) {
1260 undefSet.insert(_symbolTable.indirectName(fit->u.bindingIndex));
1261 }
1262 break;
1263 case ld::Fixup::bindingByContentBound:
1264 case ld::Fixup::bindingNone:
1265 case ld::Fixup::bindingDirectlyBound:
1266 break;
1267 }
1268 }
1269 }
1270 // look for any initial undefines that are still undefined
1271 for (Options::UndefinesIterator uit=_options.initialUndefinesBegin(); uit != _options.initialUndefinesEnd(); ++uit) {
1272 if ( ! _symbolTable.hasName(*uit) ) {
1273 undefSet.insert(*uit);
1274 }
1275 }
1276
1277 // copy set to vector
1278 for (StringSet::const_iterator it=undefSet.begin(); it != undefSet.end(); ++it) {
1279 fprintf(stderr, "undef: %s\n", *it);
1280 undefs.push_back(*it);
1281 }
1282}
1283
1284void Resolver::liveUndefines(std::vector<const char*>& undefs)
1285{
1286 StringSet undefSet;
1287 // search all live atoms for references that are unbound
1288 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1289 const ld::Atom* atom = *it;
1290 if ( ! atom->live() )
1291 continue;
1292 for (ld::Fixup::iterator fit=atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
1293 switch ( (ld::Fixup::TargetBinding)fit->binding ) {
1294 case ld::Fixup::bindingByNameUnbound:
1295 assert(0 && "should not be by-name this late");
1296 undefSet.insert(fit->u.name);
1297 break;
1298 case ld::Fixup::bindingsIndirectlyBound:
1299 if ( _internal.indirectBindingTable[fit->u.bindingIndex] == NULL ) {
1300 undefSet.insert(_symbolTable.indirectName(fit->u.bindingIndex));
1301 }
1302 break;
1303 case ld::Fixup::bindingByContentBound:
1304 case ld::Fixup::bindingNone:
1305 case ld::Fixup::bindingDirectlyBound:
1306 break;
1307 }
1308 }
1309 }
1310 // look for any initial undefines that are still undefined
1311 for (Options::UndefinesIterator uit=_options.initialUndefinesBegin(); uit != _options.initialUndefinesEnd(); ++uit) {
1312 if ( ! _symbolTable.hasName(*uit) ) {
1313 undefSet.insert(*uit);
1314 }
1315 }
1316
1317 // copy set to vector
1318 for (StringSet::const_iterator it=undefSet.begin(); it != undefSet.end(); ++it) {
1319 undefs.push_back(*it);
1320 }
1321}
1322
1323
1324
1325// <rdar://problem/8252819> warn when .objc_class_name_* symbol missing
1326class ExportedObjcClass
1327{
1328public:
1329 ExportedObjcClass(const Options& opt) : _options(opt) {}
1330
1331 bool operator()(const char* name) const {
1332 if ( (strncmp(name, ".objc_class_name_", 17) == 0) && _options.shouldExport(name) ) {
1333 warning("ignoring undefined symbol %s from -exported_symbols_list", name);
1334 return true;
1335 }
1336 const char* s = strstr(name, "CLASS_$_");
1337 if ( s != NULL ) {
1338 char temp[strlen(name)+16];
1339 strcpy(temp, ".objc_class_name_");
1340 strcat(temp, &s[8]);
1341 if ( _options.wasRemovedExport(temp) ) {
1342 warning("ignoring undefined symbol %s from -exported_symbols_list", temp);
1343 return true;
1344 }
1345 }
1346 return false;
1347 }
1348private:
1349 const Options& _options;
1350};
1351
1352
1353// temp hack for undefined aliases
1354class UndefinedAlias
1355{
1356public:
1357 UndefinedAlias(const Options& opt) : _aliases(opt.cmdLineAliases()) {}
1358
1359 bool operator()(const char* name) const {
1360 for (std::vector<Options::AliasPair>::const_iterator it=_aliases.begin(); it != _aliases.end(); ++it) {
1361 if ( strcmp(it->realName, name) == 0 ) {
1362 warning("undefined base symbol '%s' for alias '%s'", name, it->alias);
1363 return true;
1364 }
1365 }
1366 return false;
1367 }
1368private:
1369 const std::vector<Options::AliasPair>& _aliases;
1370};
1371
1372
1373
1374static const char* pathLeafName(const char* path)
1375{
1376 const char* shortPath = strrchr(path, '/');
1377 if ( shortPath == NULL )
1378 return path;
1379 else
1380 return &shortPath[1];
1381}
1382
1383bool Resolver::printReferencedBy(const char* name, SymbolTable::IndirectBindingSlot slot)
1384{
1385 unsigned foundReferenceCount = 0;
1386 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1387 const ld::Atom* atom = *it;
1388 for (ld::Fixup::iterator fit=atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
1389 if ( fit->binding == ld::Fixup::bindingsIndirectlyBound ) {
1390 if ( fit->u.bindingIndex == slot ) {
1391 if ( atom->contentType() == ld::Atom::typeNonLazyPointer ) {
1392 const ld::Atom* existingAtom;
1393 unsigned int nlSlot = _symbolTable.findSlotForReferences(atom, &existingAtom);
1394 if ( printReferencedBy(name, nlSlot) )
1395 ++foundReferenceCount;
1396 }
1397 else if ( atom->contentType() == ld::Atom::typeCFI ) {
1398 fprintf(stderr, " Dwarf Exception Unwind Info (__eh_frame) in %s\n", pathLeafName(atom->safeFilePath()));
1399 ++foundReferenceCount;
1400 }
1401 else {
1402 fprintf(stderr, " %s in %s\n", _options.demangleSymbol(atom->name()), pathLeafName(atom->safeFilePath()));
1403 ++foundReferenceCount;
1404 break; // if undefined used twice in a function, only show first
1405 }
1406 }
1407 }
1408 }
1409 if ( foundReferenceCount > 6 ) {
1410 fprintf(stderr, " ...\n");
1411 break; // only show first six uses of undefined symbol
1412 }
1413 }
1414 return (foundReferenceCount != 0);
1415}
1416
1417void Resolver::checkUndefines(bool force)
1418{
1419 // when using LTO, undefines are checked after bitcode is optimized
1420 if ( _haveLLVMObjs && !force )
1421 return;
1422
1423 // error out on any remaining undefines
1424 bool doPrint = true;
1425 bool doError = true;
1426 switch ( _options.undefinedTreatment() ) {
1427 case Options::kUndefinedError:
1428 break;
1429 case Options::kUndefinedDynamicLookup:
1430 doError = false;
1431 break;
1432 case Options::kUndefinedWarning:
1433 doError = false;
1434 break;
1435 case Options::kUndefinedSuppress:
1436 doError = false;
1437 doPrint = false;
1438 break;
1439 }
1440 std::vector<const char*> unresolvableUndefines;
1441 if ( _options.deadCodeStrip() )
1442 this->liveUndefines(unresolvableUndefines);
1443 else if( _haveLLVMObjs )
1444 this->remainingUndefines(unresolvableUndefines); // <rdar://problem/10052396> LTO may have eliminated need for some undefines
1445 else
1446 _symbolTable.undefines(unresolvableUndefines);
1447
1448 // <rdar://problem/8252819> assert when .objc_class_name_* symbol missing
1449 if ( _options.hasExportMaskList() ) {
1450 unresolvableUndefines.erase(std::remove_if(unresolvableUndefines.begin(), unresolvableUndefines.end(), ExportedObjcClass(_options)), unresolvableUndefines.end());
1451 }
1452
1453 // hack to temporarily make missing aliases a warning
1454 if ( _options.haveCmdLineAliases() ) {
1455 unresolvableUndefines.erase(std::remove_if(unresolvableUndefines.begin(), unresolvableUndefines.end(), UndefinedAlias(_options)), unresolvableUndefines.end());
1456 }
1457
1458 const int unresolvableCount = unresolvableUndefines.size();
1459 int unresolvableExportsCount = 0;
1460 if ( unresolvableCount != 0 ) {
1461 if ( doPrint ) {
1462 for (const auto& lib : _internal.missingLinkerOptionLibraries)
1463 warning("Could not find auto-linked library '%s'", lib);
1464 for (const auto& frm : _internal.missingLinkerOptionFrameworks)
1465 warning("Could not find auto-linked framework '%s'", frm);
1466 if ( _options.printArchPrefix() )
1467 fprintf(stderr, "Undefined symbols for architecture %s:\n", _options.architectureName());
1468 else
1469 fprintf(stderr, "Undefined symbols:\n");
1470 for (int i=0; i < unresolvableCount; ++i) {
1471 const char* name = unresolvableUndefines[i];
1472 unsigned int slot = _symbolTable.findSlotForName(name);
1473 fprintf(stderr, " \"%s\", referenced from:\n", _options.demangleSymbol(name));
1474 // scan all atoms for references
1475 bool foundAtomReference = printReferencedBy(name, slot);
1476 // scan command line options
1477 if ( !foundAtomReference ) {
1478 // might be from -init command line option
1479 if ( (_options.initFunctionName() != NULL) && (strcmp(name, _options.initFunctionName()) == 0) ) {
1480 fprintf(stderr, " -init command line option\n");
1481 }
1482 // or might be from exported symbol option
1483 else if ( _options.hasExportMaskList() && _options.shouldExport(name) ) {
1484 fprintf(stderr, " -exported_symbol[s_list] command line option\n");
1485 }
1486 // or might be from re-exported symbol option
1487 else if ( _options.hasReExportList() && _options.shouldReExport(name) ) {
1488 fprintf(stderr, " -reexported_symbols_list command line option\n");
1489 }
1490 else if ( (_options.outputKind() == Options::kDynamicExecutable)
1491 && (_options.entryName() != NULL) && (strcmp(name, _options.entryName()) == 0) ) {
1492 fprintf(stderr, " implicit entry/start for main executable\n");
1493 }
1494 else {
1495 bool isInitialUndefine = false;
1496 for (Options::UndefinesIterator uit=_options.initialUndefinesBegin(); uit != _options.initialUndefinesEnd(); ++uit) {
1497 if ( strcmp(*uit, name) == 0 ) {
1498 isInitialUndefine = true;
1499 break;
1500 }
1501 }
1502 if ( isInitialUndefine )
1503 fprintf(stderr, " -u command line option\n");
1504 }
1505 ++unresolvableExportsCount;
1506 }
1507 // be helpful and check for typos
1508 bool printedStart = false;
1509 for (SymbolTable::byNameIterator sit=_symbolTable.begin(); sit != _symbolTable.end(); sit++) {
1510 const ld::Atom* atom = *sit;
1511 if ( (atom != NULL) && (atom->symbolTableInclusion() == ld::Atom::symbolTableIn) && (strstr(atom->name(), name) != NULL) ) {
1512 if ( ! printedStart ) {
1513 fprintf(stderr, " (maybe you meant: %s", atom->name());
1514 printedStart = true;
1515 }
1516 else {
1517 fprintf(stderr, ", %s ", atom->name());
1518 }
1519 }
1520 }
1521 if ( printedStart )
1522 fprintf(stderr, ")\n");
1523 // <rdar://problem/8989530> Add comment to error message when __ZTV symbols are undefined
1524 if ( strncmp(name, "__ZTV", 5) == 0 ) {
1525 fprintf(stderr, " NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.\n");
1526 }
1527 }
1528 }
1529 if ( doError )
1530 throw "symbol(s) not found";
1531 }
1532
1533}
1534
1535
1536
1537void Resolver::checkDylibSymbolCollisions()
1538{
1539 for (SymbolTable::byNameIterator it=_symbolTable.begin(); it != _symbolTable.end(); it++) {
1540 const ld::Atom* atom = *it;
1541 if ( atom == NULL )
1542 continue;
1543 if ( atom->scope() == ld::Atom::scopeGlobal ) {
1544 // <rdar://problem/5048861> No warning about tentative definition conflicting with dylib definition
1545 // for each tentative definition in symbol table look for dylib that exports same symbol name
1546 if ( atom->definition() == ld::Atom::definitionTentative ) {
1547 _inputFiles.searchLibraries(atom->name(), true, false, false, *this);
1548 }
1549 // record any overrides of weak symbols in any linked dylib
1550 if ( (atom->definition() == ld::Atom::definitionRegular) && (atom->symbolTableInclusion() == ld::Atom::symbolTableIn) ) {
1551 if ( _inputFiles.searchWeakDefInDylib(atom->name()) )
1552 (const_cast<ld::Atom*>(atom))->setOverridesDylibsWeakDef();
1553 }
1554 }
1555 }
1556}
1557
1558
1559const ld::Atom* Resolver::entryPoint(bool searchArchives)
1560{
1561 const char* symbolName = NULL;
1562 bool makingDylib = false;
1563 switch ( _options.outputKind() ) {
1564 case Options::kDynamicExecutable:
1565 case Options::kStaticExecutable:
1566 case Options::kDyld:
1567 case Options::kPreload:
1568 symbolName = _options.entryName();
1569 break;
1570 case Options::kDynamicLibrary:
1571 symbolName = _options.initFunctionName();
1572 makingDylib = true;
1573 break;
1574 case Options::kObjectFile:
1575 case Options::kDynamicBundle:
1576 case Options::kKextBundle:
1577 return NULL;
1578 break;
1579 }
1580 if ( symbolName != NULL ) {
1581 SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName(symbolName);
1582 if ( (_internal.indirectBindingTable[slot] == NULL) && searchArchives ) {
1583 // <rdar://problem/7043256> ld64 can not find a -e entry point from an archive
1584 _inputFiles.searchLibraries(symbolName, false, true, false, *this);
1585 }
1586 if ( _internal.indirectBindingTable[slot] == NULL ) {
1587 if ( strcmp(symbolName, "start") == 0 )
1588 throwf("entry point (%s) undefined. Usually in crt1.o", symbolName);
1589 else
1590 throwf("entry point (%s) undefined.", symbolName);
1591 }
1592 else if ( _internal.indirectBindingTable[slot]->definition() == ld::Atom::definitionProxy ) {
1593 if ( makingDylib )
1594 throwf("-init function (%s) found in linked dylib, must be in dylib being linked", symbolName);
1595 }
1596 return _internal.indirectBindingTable[slot];
1597 }
1598 return NULL;
1599}
1600
1601
1602void Resolver::fillInHelpersInInternalState()
1603{
1604 // look up well known atoms
1605 bool needsStubHelper = true;
1606 switch ( _options.outputKind() ) {
1607 case Options::kDynamicExecutable:
1608 case Options::kDynamicLibrary:
1609 case Options::kDynamicBundle:
1610 needsStubHelper = true;
1611 break;
1612 case Options::kDyld:
1613 case Options::kKextBundle:
1614 case Options::kObjectFile:
1615 case Options::kStaticExecutable:
1616 case Options::kPreload:
1617 needsStubHelper = false;
1618 break;
1619 }
1620
1621 _internal.classicBindingHelper = NULL;
1622 // FIXME: What about fMakeThreadedStartsSection?
1623 if ( needsStubHelper && !_options.makeCompressedDyldInfo() ) {
1624 // "dyld_stub_binding_helper" comes from .o file, so should already exist in symbol table
1625 if ( _symbolTable.hasName("dyld_stub_binding_helper") ) {
1626 SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName("dyld_stub_binding_helper");
1627 _internal.classicBindingHelper = _internal.indirectBindingTable[slot];
1628 }
1629 }
1630
1631 _internal.lazyBindingHelper = NULL;
1632 if ( _options.usingLazyDylibLinking() ) {
1633 // "dyld_lazy_dylib_stub_binding_helper" comes from lazydylib1.o file, so should already exist in symbol table
1634 if ( _symbolTable.hasName("dyld_lazy_dylib_stub_binding_helper") ) {
1635 SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName("dyld_lazy_dylib_stub_binding_helper");
1636 _internal.lazyBindingHelper = _internal.indirectBindingTable[slot];
1637 }
1638 if ( _internal.lazyBindingHelper == NULL )
1639 throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
1640 }
1641
1642 _internal.compressedFastBinderProxy = NULL;
1643 // FIXME: What about fMakeThreadedStartsSection?
1644 if ( needsStubHelper && _options.makeCompressedDyldInfo() ) {
1645 // "dyld_stub_binder" comes from libSystem.dylib so will need to manually resolve
1646 if ( !_symbolTable.hasName("dyld_stub_binder") ) {
1647 _inputFiles.searchLibraries("dyld_stub_binder", true, false, false, *this);
1648 }
1649 if ( _symbolTable.hasName("dyld_stub_binder") ) {
1650 SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName("dyld_stub_binder");
1651 _internal.compressedFastBinderProxy = _internal.indirectBindingTable[slot];
1652 }
1653 if ( _internal.compressedFastBinderProxy == NULL ) {
1654 if ( _options.undefinedTreatment() != Options::kUndefinedError ) {
1655 // make proxy
1656 _internal.compressedFastBinderProxy = new UndefinedProxyAtom("dyld_stub_binder");
1657 this->doAtom(*_internal.compressedFastBinderProxy);
1658 }
1659 }
1660 }
1661}
1662
1663
1664void Resolver::fillInInternalState()
1665{
1666 // store atoms into their final section
1667 for (std::vector<const ld::Atom*>::iterator it = _atoms.begin(); it != _atoms.end(); ++it) {
1668 _internal.addAtom(**it);
1669 }
1670
1671 // <rdar://problem/7783918> make sure there is a __text section so that codesigning works
1672 if ( (_options.outputKind() == Options::kDynamicLibrary) || (_options.outputKind() == Options::kDynamicBundle) )
1673 _internal.getFinalSection(*new ld::Section("__TEXT", "__text", ld::Section::typeCode));
1674
1675 // Don't allow swift frameworks to link other swift frameworks.
1676 if ( _internal.someObjectFileHasSwift && _internal.firstSwiftDylibFile != nullptr )
1677 throwf("linking swift frameworks against other swift frameworks (%s) is not permitted",
1678 _internal.firstSwiftDylibFile->path());
1679}
1680
1681void Resolver::fillInEntryPoint()
1682{
1683 _internal.entryPoint = this->entryPoint(true);
1684}
1685
1686void Resolver::syncAliases()
1687{
1688 if ( !_haveAliases || (_options.outputKind() == Options::kObjectFile) )
1689 return;
1690
1691 // Set attributes of alias to match its found target
1692 for (std::vector<const ld::Atom*>::iterator it = _atoms.begin(); it != _atoms.end(); ++it) {
1693 const ld::Atom* atom = *it;
1694 if ( atom->section().type() == ld::Section::typeTempAlias ) {
1695 assert(atom->fixupsBegin() != atom->fixupsEnd());
1696 for (ld::Fixup::iterator fit = atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
1697 const ld::Atom* target;
1698 ld::Atom::Scope scope;
1699 assert(fit->kind == ld::Fixup::kindNoneFollowOn);
1700 switch ( fit->binding ) {
1701 case ld::Fixup::bindingByNameUnbound:
1702 break;
1703 case ld::Fixup::bindingsIndirectlyBound:
1704 target = _internal.indirectBindingTable[fit->u.bindingIndex];
1705 assert(target != NULL);
1706 scope = atom->scope();
1707 (const_cast<Atom*>(atom))->setAttributesFromAtom(*target);
1708 // alias has same attributes as target, except for scope
1709 (const_cast<Atom*>(atom))->setScope(scope);
1710 break;
1711 default:
1712 assert(0 && "internal error: unexpected alias binding");
1713 }
1714 }
1715 }
1716 }
1717}
1718
1719void Resolver::removeCoalescedAwayAtoms()
1720{
1721 const bool log = false;
1722 if ( log ) {
1723 fprintf(stderr, "removeCoalescedAwayAtoms() starts with %lu atoms\n", _atoms.size());
1724 }
1725 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), AtomCoalescedAway()), _atoms.end());
1726 if ( log ) {
1727 fprintf(stderr, "removeCoalescedAwayAtoms() after removing coalesced atoms, %lu remain\n", _atoms.size());
1728 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1729 fprintf(stderr, " atom=%p %s\n", *it, (*it)->name());
1730 }
1731 }
1732}
1733
1734void Resolver::linkTimeOptimize()
1735{
1736 // only do work here if some llvm obj files where loaded
1737 if ( ! _haveLLVMObjs )
1738 return;
1739
1740 // <rdar://problem/15314161> LTO: Symbol multiply defined error should specify exactly where the symbol is found
1741 _symbolTable.checkDuplicateSymbols();
1742
1743 // run LLVM lto code-gen
1744 lto::OptimizeOptions optOpt;
1745 optOpt.outputFilePath = _options.outputFilePath();
1746 optOpt.tmpObjectFilePath = _options.tempLtoObjectPath();
1747 optOpt.ltoCachePath = _options.ltoCachePath();
1748 optOpt.ltoPruneIntervalOverwrite = _options.ltoPruneIntervalOverwrite();
1749 optOpt.ltoPruneInterval = _options.ltoPruneInterval();
1750 optOpt.ltoPruneAfter = _options.ltoPruneAfter();
1751 optOpt.ltoMaxCacheSize = _options.ltoMaxCacheSize();
1752 optOpt.preserveAllGlobals = _options.allGlobalsAreDeadStripRoots() || _options.hasExportRestrictList();
1753 optOpt.verbose = _options.verbose();
1754 optOpt.saveTemps = _options.saveTempFiles();
1755 optOpt.ltoCodegenOnly = _options.ltoCodegenOnly();
1756 optOpt.pie = _options.positionIndependentExecutable();
1757 optOpt.mainExecutable = _options.linkingMainExecutable();;
1758 optOpt.staticExecutable = (_options.outputKind() == Options::kStaticExecutable);
1759 optOpt.preload = (_options.outputKind() == Options::kPreload);
1760 optOpt.relocatable = (_options.outputKind() == Options::kObjectFile);
1761 optOpt.allowTextRelocs = _options.allowTextRelocs();
1762 optOpt.linkerDeadStripping = _options.deadCodeStrip();
1763 optOpt.needsUnwindInfoSection = _options.needsUnwindInfoSection();
1764 optOpt.keepDwarfUnwind = _options.keepDwarfUnwind();
1765 optOpt.verboseOptimizationHints = _options.verboseOptimizationHints();
1766 optOpt.armUsesZeroCostExceptions = _options.armUsesZeroCostExceptions();
1767 optOpt.simulator = _options.targetIOSSimulator();
1768 optOpt.ignoreMismatchPlatform = ((_options.outputKind() == Options::kPreload) || (_options.outputKind() == Options::kStaticExecutable));
1769#if SUPPORT_ARCH_arm64e
1770 optOpt.supportsAuthenticatedPointers = _options.supportsAuthenticatedPointers();
1771#endif
1772 optOpt.bitcodeBundle = (_options.bundleBitcode() && (_options.bitcodeKind() != Options::kBitcodeMarker));
1773 optOpt.maxDefaultCommonAlignment = _options.maxDefaultCommonAlign();
1774 optOpt.arch = _options.architecture();
1775 optOpt.mcpu = _options.mcpuLTO();
1776 optOpt.platforms = _options.platforms();
1777 optOpt.llvmOptions = &_options.llvmOptions();
1778 optOpt.initialUndefines = &_options.initialUndefines();
1779
1780 std::vector<const ld::Atom*> newAtoms;
1781 std::vector<const char*> additionalUndefines;
1782 if ( ! lto::optimize(_atoms, _internal, optOpt, *this, newAtoms, additionalUndefines) )
1783 return; // if nothing done
1784 _ltoCodeGenFinished = true;
1785
1786 // add all newly created atoms to _atoms and update symbol table
1787 for(std::vector<const ld::Atom*>::iterator it = newAtoms.begin(); it != newAtoms.end(); ++it)
1788 this->doAtom(**it);
1789
1790 // some atoms might have been optimized way (marked coalesced), remove them
1791 this->removeCoalescedAwayAtoms();
1792
1793 // run through all atoms again and make sure newly codegened atoms have references bound
1794 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it)
1795 this->convertReferencesToIndirect(**it);
1796
1797 // adjust section of any new
1798 for (std::vector<const AliasAtom*>::const_iterator it=_aliasesFromCmdLine.begin(); it != _aliasesFromCmdLine.end(); ++it) {
1799 const AliasAtom* aliasAtom = *it;
1800 // update fields in AliasAtom to match newly constructed mach-o atom
1801 aliasAtom->setFinalAliasOf();
1802 }
1803
1804 // <rdar://problem/14609792> add any auto-link libraries requested by LTO output to dylibs to search
1805 _inputFiles.addLinkerOptionLibraries(_internal, *this);
1806 _inputFiles.createIndirectDylibs();
1807
1808 // resolve new undefines (e.g calls to _malloc and _memcpy that llvm compiler conjures up)
1809 for(std::vector<const char*>::iterator uit = additionalUndefines.begin(); uit != additionalUndefines.end(); ++uit) {
1810 const char *targetName = *uit;
1811 // these symbols may or may not already be in linker's symbol table
1812 if ( ! _symbolTable.hasName(targetName) ) {
1813 _inputFiles.searchLibraries(targetName, true, true, false, *this);
1814 }
1815 }
1816
1817 // if -dead_strip on command line
1818 if ( _options.deadCodeStrip() ) {
1819 // run through all atoms again and make live_section LTO atoms are preserved from dead_stripping if needed
1820 _dontDeadStripIfReferencesLive.clear();
1821 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1822 const ld::Atom* atom = *it;
1823 if ( atom->dontDeadStripIfReferencesLive() ) {
1824 _dontDeadStripIfReferencesLive.push_back(atom);
1825 }
1826
1827 // clear liveness bit
1828 (const_cast<ld::Atom*>(*it))->setLive((*it)->dontDeadStrip());
1829 }
1830 // and re-compute dead code
1831 this->deadStripOptimize(true);
1832 }
1833
1834 // <rdar://problem/12386559> if -exported_symbols_list on command line, re-force scope
1835 if ( _options.hasExportMaskList() ) {
1836 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1837 const ld::Atom* atom = *it;
1838 if ( atom->scope() == ld::Atom::scopeGlobal ) {
1839 if ( !_options.shouldExport(atom->name()) ) {
1840 (const_cast<ld::Atom*>(atom))->setScope(ld::Atom::scopeLinkageUnit);
1841 }
1842 }
1843 }
1844 }
1845
1846 if ( _options.outputKind() == Options::kObjectFile ) {
1847 // if -r mode, add proxies for new undefines (e.g. ___stack_chk_fail)
1848 this->resolveUndefines();
1849 }
1850 else {
1851 // last chance to check for undefines
1852 this->resolveUndefines();
1853 this->checkUndefines(true);
1854
1855 // check new code does not override some dylib
1856 this->checkDylibSymbolCollisions();
1857
1858 // <rdar://problem/33853815> remove undefs from LTO objects that gets optimized away
1859 std::unordered_set<const ld::Atom*> mustPreserve;
1860 if ( _internal.classicBindingHelper != NULL )
1861 mustPreserve.insert(_internal.classicBindingHelper);
1862 if ( _internal.compressedFastBinderProxy != NULL )
1863 mustPreserve.insert(_internal.compressedFastBinderProxy);
1864 if ( _internal.lazyBindingHelper != NULL )
1865 mustPreserve.insert(_internal.lazyBindingHelper);
1866 if ( const ld::Atom* entry = this->entryPoint(true) )
1867 mustPreserve.insert(entry);
1868 for (Options::UndefinesIterator uit=_options.initialUndefinesBegin(); uit != _options.initialUndefinesEnd(); ++uit) {
1869 SymbolTable::IndirectBindingSlot slot = _symbolTable.findSlotForName(*uit);
1870 if ( _internal.indirectBindingTable[slot] != NULL )
1871 mustPreserve.insert(_internal.indirectBindingTable[slot]);
1872 }
1873 _symbolTable.removeDeadUndefs(_atoms, mustPreserve);
1874 }
1875}
1876
1877
1878void Resolver::tweakWeakness()
1879{
1880 // <rdar://problem/7977374> Add command line options to control symbol weak-def bit on exported symbols
1881 if ( _options.hasWeakBitTweaks() ) {
1882 for (std::vector<ld::Internal::FinalSection*>::iterator sit = _internal.sections.begin(); sit != _internal.sections.end(); ++sit) {
1883 ld::Internal::FinalSection* sect = *sit;
1884 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
1885 const ld::Atom* atom = *ait;
1886 if ( atom->definition() != ld::Atom::definitionRegular )
1887 continue;
1888 const char* name = atom->name();
1889 if ( atom->scope() == ld::Atom::scopeGlobal ) {
1890 if ( atom->combine() == ld::Atom::combineNever ) {
1891 if ( _options.forceWeak(name) )
1892 (const_cast<ld::Atom*>(atom))->setCombine(ld::Atom::combineByName);
1893 }
1894 else if ( atom->combine() == ld::Atom::combineByName ) {
1895 if ( _options.forceNotWeak(name) )
1896 (const_cast<ld::Atom*>(atom))->setCombine(ld::Atom::combineNever);
1897 }
1898 }
1899 else {
1900 if ( _options.forceWeakNonWildCard(name) )
1901 warning("cannot force to be weak, non-external symbol %s", name);
1902 else if ( _options.forceNotWeakNonWildcard(name) )
1903 warning("cannot force to be not-weak, non-external symbol %s", name);
1904 }
1905 }
1906 }
1907 }
1908}
1909
1910void Resolver::buildArchivesList()
1911{
1912 // Determine which archives were linked and update the internal state.
1913 _inputFiles.archives(_internal);
1914}
1915
1916void Resolver::dumpAtoms()
1917{
1918 fprintf(stderr, "Resolver all atoms:\n");
1919 for (std::vector<const ld::Atom*>::const_iterator it=_atoms.begin(); it != _atoms.end(); ++it) {
1920 const ld::Atom* atom = *it;
1921 fprintf(stderr, " %p name=%s, def=%d\n", atom, atom->name(), atom->definition());
1922 }
1923}
1924
1925void Resolver::resolve()
1926{
1927 this->initializeState();
1928 this->buildAtomList();
1929 this->addInitialUndefines();
1930 this->fillInHelpersInInternalState();
1931 this->resolveUndefines();
1932 this->deadStripOptimize();
1933 this->checkUndefines();
1934 this->checkDylibSymbolCollisions();
1935 this->syncAliases();
1936 this->removeCoalescedAwayAtoms();
1937 this->fillInEntryPoint();
1938 this->linkTimeOptimize();
1939 this->fillInInternalState();
1940 this->tweakWeakness();
1941 _symbolTable.checkDuplicateSymbols();
1942 this->buildArchivesList();
1943}
1944
1945
1946
1947} // namespace tool
1948} // namespace ld
1949
1950
1951