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