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