]> git.saurik.com Git - apple/ld64.git/blob - src/ld/InputFiles.cpp
7bf136bd848474e9e1677625645d1f53b7f27d6e
[apple/ld64.git] / src / ld / InputFiles.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
3 * Copyright (c) 2009-2011 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 #include <sys/sysctl.h>
43 #include <libkern/OSAtomic.h>
44
45 #include <string>
46 #include <map>
47 #include <set>
48 #include <string>
49 #include <vector>
50 #include <list>
51 #include <algorithm>
52 #include <dlfcn.h>
53 #include <AvailabilityMacros.h>
54
55 #include "Options.h"
56
57 #include "InputFiles.h"
58 #include "macho_relocatable_file.h"
59 #include "macho_dylib_file.h"
60 #include "archive_file.h"
61 #include "lto_file.h"
62 #include "opaque_section_file.h"
63 #include "Snapshot.h"
64
65 const bool _s_logPThreads = false;
66
67 namespace ld {
68 namespace tool {
69
70 class IgnoredFile : public ld::File {
71 public:
72 IgnoredFile(const char* pth, time_t modTime, Ordinal ord, Type type) : ld::File(pth, modTime, ord, type) {};
73 virtual bool forEachAtom(AtomHandler&) const { return false; };
74 virtual bool justInTimeforEachAtom(const char* name, AtomHandler&) const { return false; };
75 };
76
77
78 class DSOHandleAtom : public ld::Atom {
79 public:
80 DSOHandleAtom(const char* nm, ld::Atom::Scope sc,
81 ld::Atom::SymbolTableInclusion inc, ld::Section& sect=_s_section)
82 : ld::Atom(sect, ld::Atom::definitionRegular,
83 (sect == _s_section_text) ? ld::Atom::combineByName : ld::Atom::combineNever,
84 // make "weak def" so that link succeeds even if app defines __dso_handle
85 sc, ld::Atom::typeUnclassified, inc, true, false, false,
86 ld::Atom::Alignment(1)), _name(nm) {}
87
88 virtual ld::File* file() const { return NULL; }
89 virtual const char* name() const { return _name; }
90 virtual uint64_t size() const { return 0; }
91 virtual uint64_t objectAddress() const { return 0; }
92 virtual void copyRawContent(uint8_t buffer[]) const
93 { }
94 virtual void setScope(Scope) { }
95
96 virtual ~DSOHandleAtom() {}
97
98 static ld::Section _s_section;
99 static ld::Section _s_section_preload;
100 static ld::Section _s_section_text;
101 static DSOHandleAtom _s_atomAll;
102 static DSOHandleAtom _s_atomExecutable;
103 static DSOHandleAtom _s_atomDylib;
104 static DSOHandleAtom _s_atomBundle;
105 static DSOHandleAtom _s_atomDyld;
106 static DSOHandleAtom _s_atomObjectFile;
107 static DSOHandleAtom _s_atomPreload;
108 static DSOHandleAtom _s_atomPreloadDSO;
109 private:
110 const char* _name;
111 };
112 ld::Section DSOHandleAtom::_s_section("__TEXT", "__mach_header", ld::Section::typeMachHeader, true);
113 ld::Section DSOHandleAtom::_s_section_preload("__HEADER", "__mach_header", ld::Section::typeMachHeader, true);
114 ld::Section DSOHandleAtom::_s_section_text("__TEXT", "__text", ld::Section::typeCode, false);
115 DSOHandleAtom DSOHandleAtom::_s_atomAll("___dso_handle", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
116 DSOHandleAtom DSOHandleAtom::_s_atomExecutable("__mh_execute_header", ld::Atom::scopeGlobal, ld::Atom::symbolTableInAndNeverStrip);
117 DSOHandleAtom DSOHandleAtom::_s_atomDylib("__mh_dylib_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
118 DSOHandleAtom DSOHandleAtom::_s_atomBundle("__mh_bundle_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
119 DSOHandleAtom DSOHandleAtom::_s_atomDyld("__mh_dylinker_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
120 DSOHandleAtom DSOHandleAtom::_s_atomObjectFile("__mh_object_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
121 DSOHandleAtom DSOHandleAtom::_s_atomPreload("__mh_preload_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn, _s_section_preload);
122 DSOHandleAtom DSOHandleAtom::_s_atomPreloadDSO("___dso_handle", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn, _s_section_text);
123
124
125
126 class PageZeroAtom : public ld::Atom {
127 public:
128 PageZeroAtom(uint64_t sz)
129 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
130 ld::Atom::scopeTranslationUnit, ld::Atom::typeZeroFill,
131 symbolTableNotIn, true, false, false, ld::Atom::Alignment(12)),
132 _size(sz) {}
133
134 virtual ld::File* file() const { return NULL; }
135 virtual const char* name() const { return "page zero"; }
136 virtual uint64_t size() const { return _size; }
137 virtual uint64_t objectAddress() const { return 0; }
138 virtual void copyRawContent(uint8_t buffer[]) const
139 { }
140 virtual void setScope(Scope) { }
141
142 virtual ~PageZeroAtom() {}
143
144 static ld::Section _s_section;
145 static DSOHandleAtom _s_atomAll;
146 private:
147 uint64_t _size;
148 };
149 ld::Section PageZeroAtom::_s_section("__PAGEZERO", "__pagezero", ld::Section::typePageZero, true);
150
151
152 class CustomStackAtom : public ld::Atom {
153 public:
154 CustomStackAtom(uint64_t sz)
155 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
156 ld::Atom::scopeTranslationUnit, ld::Atom::typeZeroFill,
157 symbolTableNotIn, false, false, false, ld::Atom::Alignment(12)),
158 _size(sz) {}
159
160 virtual ld::File* file() const { return NULL; }
161 virtual const char* name() const { return "custom stack"; }
162 virtual uint64_t size() const { return _size; }
163 virtual uint64_t objectAddress() const { return 0; }
164 virtual void copyRawContent(uint8_t buffer[]) const
165 { }
166 virtual void setScope(Scope) { }
167
168 virtual ~CustomStackAtom() {}
169
170 private:
171 uint64_t _size;
172 static ld::Section _s_section;
173 };
174 ld::Section CustomStackAtom::_s_section("__UNIXSTACK", "__stack", ld::Section::typeStack, true);
175
176
177
178 const char* InputFiles::fileArch(const uint8_t* p, unsigned len)
179 {
180 const char* result = mach_o::relocatable::archName(p);
181 if ( result != NULL )
182 return result;
183
184 result = lto::archName(p, len);
185 if ( result != NULL )
186 return result;
187
188 if ( strncmp((const char*)p, "!<arch>\n", 8) == 0 )
189 return "archive";
190
191 char *unsupported = (char *)malloc(128);
192 strcpy(unsupported, "unsupported file format (");
193 for (unsigned i=0; i<len && i < 16; i++) {
194 char buf[8];
195 sprintf(buf, " 0x%2x", p[i]);
196 strcat(unsupported, buf);
197 }
198 strcat(unsupported, " )");
199 return unsupported;
200 }
201
202
203 ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib)
204 {
205 // map in whole file
206 uint64_t len = info.fileLen;
207 int fd = ::open(info.path, O_RDONLY, 0);
208 if ( fd == -1 )
209 throwf("can't open file, errno=%d", errno);
210 if ( info.fileLen < 20 )
211 throw "file too small";
212
213 uint8_t* p = (uint8_t*)::mmap(NULL, info.fileLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
214 if ( p == (uint8_t*)(-1) )
215 throwf("can't map file, errno=%d", errno);
216
217 // if fat file, skip to architecture we want
218 // Note: fat header is always big-endian
219 bool isFatFile = false;
220 uint32_t sliceToUse, sliceCount;
221 const fat_header* fh = (fat_header*)p;
222 if ( fh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
223 isFatFile = true;
224 const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header));
225 bool sliceFound = false;
226 sliceCount = OSSwapBigToHostInt32(fh->nfat_arch);
227 if ( _options.preferSubArchitecture() ) {
228 // first try to find a slice that match cpu-type and cpu-sub-type
229 for (uint32_t i=0; i < sliceCount; ++i) {
230 if ( (OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture())
231 && (OSSwapBigToHostInt32(archs[i].cpusubtype) == (uint32_t)_options.subArchitecture()) ) {
232 sliceToUse = i;
233 sliceFound = true;
234 break;
235 }
236 }
237 }
238 if ( !sliceFound ) {
239 // look for any slice that matches just cpu-type
240 for (uint32_t i=0; i < sliceCount; ++i) {
241 if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture() ) {
242 sliceToUse = i;
243 sliceFound = true;
244 break;
245 }
246 }
247 }
248 if ( sliceFound ) {
249 uint32_t fileOffset = OSSwapBigToHostInt32(archs[sliceToUse].offset);
250 len = OSSwapBigToHostInt32(archs[sliceToUse].size);
251 if ( fileOffset+len > info.fileLen ) {
252 throwf("truncated fat file. Slice from %u to %llu is past end of file with length %llu",
253 fileOffset, fileOffset+len, info.fileLen);
254 }
255 // if requested architecture is page aligned within fat file, then remap just that portion of file
256 if ( (fileOffset & 0x00000FFF) == 0 ) {
257 // unmap whole file
258 munmap((caddr_t)p, info.fileLen);
259 // re-map just part we need
260 p = (uint8_t*)::mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, fileOffset);
261 if ( p == (uint8_t*)(-1) )
262 throwf("can't re-map file, errno=%d", errno);
263 }
264 else {
265 p = &p[fileOffset];
266 }
267 }
268 }
269 ::close(fd);
270
271 // see if it is an object file
272 mach_o::relocatable::ParserOptions objOpts;
273 objOpts.architecture = _options.architecture();
274 objOpts.objSubtypeMustMatch = !_options.allowSubArchitectureMismatches();
275 objOpts.logAllFiles = _options.logAllFiles();
276 objOpts.convertUnwindInfo = _options.needsUnwindInfoSection();
277 objOpts.subType = _options.subArchitecture();
278 ld::relocatable::File* objResult = mach_o::relocatable::parse(p, len, info.path, info.modTime, info.ordinal, objOpts);
279 if ( objResult != NULL ) {
280 OSAtomicAdd64(len, &_totalObjectSize);
281 OSAtomicIncrement32(&_totalObjectLoaded);
282 return objResult;
283 }
284
285 // see if it is an llvm object file
286 objResult = lto::parse(p, len, info.path, info.modTime, info.ordinal, _options.architecture(), _options.subArchitecture(), _options.logAllFiles());
287 if ( objResult != NULL ) {
288 OSAtomicAdd64(len, &_totalObjectSize);
289 OSAtomicIncrement32(&_totalObjectLoaded);
290 return objResult;
291 }
292
293 // see if it is a dynamic library
294 ld::dylib::File* dylibResult = mach_o::dylib::parse(p, len, info.path, info.modTime, _options, info.ordinal, info.options.fBundleLoader, indirectDylib);
295 if ( dylibResult != NULL ) {
296 return dylibResult;
297 }
298
299 // see if it is a static library
300 ::archive::ParserOptions archOpts;
301 archOpts.objOpts = objOpts;
302 archOpts.forceLoadThisArchive = info.options.fForceLoad;
303 archOpts.forceLoadAll = _options.fullyLoadArchives();
304 archOpts.forceLoadObjC = _options.loadAllObjcObjectsFromArchives();
305 archOpts.objcABI2 = _options.objCABIVersion2POverride();
306 archOpts.verboseLoad = _options.whyLoad();
307 archOpts.logAllFiles = _options.logAllFiles();
308 ld::archive::File* archiveResult = ::archive::parse(p, len, info.path, info.modTime, info.ordinal, archOpts);
309 if ( archiveResult != NULL ) {
310 OSAtomicAdd64(len, &_totalArchiveSize);
311 OSAtomicIncrement32(&_totalArchivesLoaded);
312 return archiveResult;
313 }
314
315 // does not seem to be any valid linker input file, check LTO misconfiguration problems
316 if ( lto::archName((uint8_t*)p, len) != NULL ) {
317 if ( lto::libLTOisLoaded() ) {
318 throwf("lto file was built for %s which is not the architecture being linked (%s): %s", fileArch(p, len), _options.architectureName(), info.path);
319 }
320 else {
321 const char* libLTO = "libLTO.dylib";
322 char ldPath[PATH_MAX];
323 char tmpPath[PATH_MAX];
324 char libLTOPath[PATH_MAX];
325 uint32_t bufSize = PATH_MAX;
326 if ( _options.overridePathlibLTO() != NULL ) {
327 libLTO = _options.overridePathlibLTO();
328 }
329 else if ( _NSGetExecutablePath(ldPath, &bufSize) != -1 ) {
330 if ( realpath(ldPath, tmpPath) != NULL ) {
331 char* lastSlash = strrchr(tmpPath, '/');
332 if ( lastSlash != NULL )
333 strcpy(lastSlash, "/../lib/libLTO.dylib");
334 libLTO = tmpPath;
335 if ( realpath(tmpPath, libLTOPath) != NULL )
336 libLTO = libLTOPath;
337 }
338 }
339 throwf("could not process llvm bitcode object file, because %s could not be loaded", libLTO);
340 }
341 }
342
343 // error handling
344 if ( ((fat_header*)p)->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
345 throwf("missing required architecture %s in file %s (%u slices)", _options.architectureName(), info.path, sliceCount);
346 }
347 else {
348 if ( isFatFile )
349 throwf("file is universal (%u slices) but does not contain a(n) %s slice: %s", sliceCount, _options.architectureName(), info.path);
350 else
351 throwf("file was built for %s which is not the architecture being linked (%s): %s", fileArch(p, len), _options.architectureName(), info.path);
352 }
353 }
354
355 void InputFiles::logDylib(ld::File* file, bool indirect)
356 {
357 if ( _options.traceDylibs() ) {
358 const char* fullPath = file->path();
359 char realName[MAXPATHLEN];
360 if ( realpath(fullPath, realName) != NULL )
361 fullPath = realName;
362 const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(file);
363 if ( (dylib != NULL ) && dylib->willBeUpwardDylib() ) {
364 // don't log upward dylibs when XBS is computing dependencies
365 logTraceInfo("[Logging for XBS] Used upward dynamic library: %s\n", fullPath);
366 }
367 else {
368 if ( indirect )
369 logTraceInfo("[Logging for XBS] Used indirect dynamic library: %s\n", fullPath);
370 else
371 logTraceInfo("[Logging for XBS] Used dynamic library: %s\n", fullPath);
372 }
373 }
374 }
375
376 void InputFiles::logArchive(ld::File* file) const
377 {
378 if ( _options.traceArchives() && (_archiveFilesLogged.count(file) == 0) ) {
379 // <rdar://problem/4947347> LD_TRACE_ARCHIVES should only print out when a .o is actually used from an archive
380 _archiveFilesLogged.insert(file);
381 const char* fullPath = file->path();
382 char realName[MAXPATHLEN];
383 if ( realpath(fullPath, realName) != NULL )
384 fullPath = realName;
385 logTraceInfo("[Logging for XBS] Used static archive: %s\n", fullPath);
386 }
387 }
388
389
390 void InputFiles::logTraceInfo(const char* format, ...) const
391 {
392 // one time open() of custom LD_TRACE_FILE
393 static int trace_file = -1;
394 if ( trace_file == -1 ) {
395 const char *trace_file_path = _options.traceOutputFile();
396 if ( trace_file_path != NULL ) {
397 trace_file = open(trace_file_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
398 if ( trace_file == -1 )
399 throwf("Could not open or create trace file: %s", trace_file_path);
400 }
401 else {
402 trace_file = fileno(stderr);
403 }
404 }
405
406 char trace_buffer[MAXPATHLEN * 2];
407 va_list ap;
408 va_start(ap, format);
409 int length = vsnprintf(trace_buffer, sizeof(trace_buffer), format, ap);
410 va_end(ap);
411 char* buffer_ptr = trace_buffer;
412
413 while (length > 0) {
414 ssize_t amount_written = write(trace_file, buffer_ptr, length);
415 if(amount_written == -1)
416 /* Failure to write shouldn't fail the build. */
417 return;
418 buffer_ptr += amount_written;
419 length -= amount_written;
420 }
421 }
422
423 ld::dylib::File* InputFiles::findDylib(const char* installPath, const char* fromPath)
424 {
425 //fprintf(stderr, "findDylib(%s, %s)\n", installPath, fromPath);
426 InstallNameToDylib::iterator pos = _installPathToDylibs.find(installPath);
427 if ( pos != _installPathToDylibs.end() ) {
428 return pos->second;
429 }
430 else {
431 // allow -dylib_path option to override indirect library to use
432 for (std::vector<Options::DylibOverride>::const_iterator dit = _options.dylibOverrides().begin(); dit != _options.dylibOverrides().end(); ++dit) {
433 if ( strcmp(dit->installName,installPath) == 0 ) {
434 try {
435 Options::FileInfo info = _options.findFile(dit->useInstead);
436 _indirectDylibOrdinal = _indirectDylibOrdinal.nextIndirectDylibOrdinal();
437 info.ordinal = _indirectDylibOrdinal;
438 ld::File* reader = this->makeFile(info, true);
439 ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
440 if ( dylibReader != NULL ) {
441 addDylib(dylibReader, info);
442 //_installPathToDylibs[strdup(installPath)] = dylibReader;
443 this->logDylib(dylibReader, true);
444 return dylibReader;
445 }
446 else
447 throwf("indirect dylib at %s is not a dylib", dit->useInstead);
448 }
449 catch (const char* msg) {
450 warning("ignoring -dylib_file option, %s", msg);
451 }
452 }
453 }
454 char newPath[MAXPATHLEN];
455 // handle @loader_path
456 if ( strncmp(installPath, "@loader_path/", 13) == 0 ) {
457 strcpy(newPath, fromPath);
458 char* addPoint = strrchr(newPath,'/');
459 if ( addPoint != NULL )
460 strcpy(&addPoint[1], &installPath[13]);
461 else
462 strcpy(newPath, &installPath[13]);
463 installPath = newPath;
464 }
465 // note: @executable_path case is handled inside findFileUsingPaths()
466 // search for dylib using -F and -L paths
467 Options::FileInfo info = _options.findFileUsingPaths(installPath);
468 _indirectDylibOrdinal = _indirectDylibOrdinal.nextIndirectDylibOrdinal();
469 info.ordinal = _indirectDylibOrdinal;
470 try {
471 ld::File* reader = this->makeFile(info, true);
472 ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
473 if ( dylibReader != NULL ) {
474 //assert(_installPathToDylibs.find(installPath) != _installPathToDylibs.end());
475 //_installPathToDylibs[strdup(installPath)] = dylibReader;
476 addDylib(dylibReader, info);
477 this->logDylib(dylibReader, true);
478 return dylibReader;
479 }
480 else
481 throwf("indirect dylib at %s is not a dylib", info.path);
482 }
483 catch (const char* msg) {
484 throwf("in '%s', %s", info.path, msg);
485 }
486 }
487 }
488
489
490
491 void InputFiles::createIndirectDylibs()
492 {
493 _allDirectDylibsLoaded = true;
494 _indirectDylibOrdinal = ld::File::Ordinal::indirectDylibBase();
495
496 // mark all dylibs initially specified as required and check if they can be used
497 for (InstallNameToDylib::iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); it++) {
498 it->second->setExplicitlyLinked();
499 this->checkDylibClientRestrictions(it->second);
500 }
501
502 // keep processing dylibs until no more dylibs are added
503 unsigned long lastMapSize = 0;
504 std::set<ld::dylib::File*> dylibsProcessed;
505 while ( lastMapSize != _allDylibs.size() ) {
506 lastMapSize = _allDylibs.size();
507 // can't iterator _installPathToDylibs while modifying it, so use temp buffer
508 std::vector<ld::dylib::File*> unprocessedDylibs;
509 for (std::set<ld::dylib::File*>::iterator it=_allDylibs.begin(); it != _allDylibs.end(); it++) {
510 if ( dylibsProcessed.count(*it) == 0 )
511 unprocessedDylibs.push_back(*it);
512 }
513 for (std::vector<ld::dylib::File*>::iterator it=unprocessedDylibs.begin(); it != unprocessedDylibs.end(); it++) {
514 dylibsProcessed.insert(*it);
515 (*it)->processIndirectLibraries(this, _options.implicitlyLinkIndirectPublicDylibs());
516 }
517 }
518
519 // go back over original dylibs and mark sub frameworks as re-exported
520 if ( _options.outputKind() == Options::kDynamicLibrary ) {
521 const char* myLeaf = strrchr(_options.installPath(), '/');
522 if ( myLeaf != NULL ) {
523 for (std::vector<class ld::File*>::const_iterator it=_inputFiles.begin(); it != _inputFiles.end(); it++) {
524 ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(*it);
525 if ( dylibReader != NULL ) {
526 const char* childParent = dylibReader->parentUmbrella();
527 if ( childParent != NULL ) {
528 if ( strcmp(childParent, &myLeaf[1]) == 0 ) {
529 // mark that this dylib will be re-exported
530 dylibReader->setWillBeReExported();
531 }
532 }
533 }
534 }
535 }
536 }
537
538 }
539
540 void InputFiles::createOpaqueFileSections()
541 {
542 // extra command line section always at end
543 for (Options::ExtraSection::const_iterator it=_options.extraSectionsBegin(); it != _options.extraSectionsEnd(); ++it) {
544 _inputFiles.push_back(opaque_section::parse(it->segmentName, it->sectionName, it->path, it->data, it->dataLen));
545 }
546
547 }
548
549
550 void InputFiles::checkDylibClientRestrictions(ld::dylib::File* dylib)
551 {
552 // Check for any restrictions on who can link with this dylib
553 const char* dylibParentName = dylib->parentUmbrella() ;
554 const std::vector<const char*>* clients = dylib->allowableClients();
555 if ( (dylibParentName != NULL) || (clients != NULL) ) {
556 // only dylibs that are in an umbrella or have a client list need verification
557 const char* installName = _options.installPath();
558 const char* installNameLastSlash = strrchr(installName, '/');
559 bool isParent = false;
560 bool isSibling = false;
561 bool isAllowableClient = false;
562 // There are three cases:
563 if ( (dylibParentName != NULL) && (installNameLastSlash != NULL) ) {
564 // starts after last slash
565 const char* myName = &installNameLastSlash[1];
566 unsigned int myNameLen = strlen(myName);
567 if ( strncmp(myName, "lib", 3) == 0 )
568 myName = &myName[3];
569 // up to first dot
570 const char* firstDot = strchr(myName, '.');
571 if ( firstDot != NULL )
572 myNameLen = firstDot - myName;
573 // up to first underscore
574 const char* firstUnderscore = strchr(myName, '_');
575 if ( (firstUnderscore != NULL) && ((firstUnderscore - myName) < (int)myNameLen) )
576 myNameLen = firstUnderscore - myName;
577
578 // case 1) The dylib has a parent umbrella, and we are creating the parent umbrella
579 isParent = ( (strlen(dylibParentName) == myNameLen) && (strncmp(myName, dylibParentName, myNameLen) == 0) );
580
581 // case 2) The dylib has a parent umbrella, and we are creating a sibling with the same parent
582 isSibling = ( (_options.umbrellaName() != NULL) && (strcmp(_options.umbrellaName(), dylibParentName) == 0) );
583 }
584
585 if ( !isParent && !isSibling && (clients != NULL) ) {
586 // case 3) the dylib has a list of allowable clients, and we are creating one of them
587 const char* clientName = _options.clientName();
588 int clientNameLen = 0;
589 if ( clientName != NULL ) {
590 // use client name as specified on command line
591 clientNameLen = strlen(clientName);
592 }
593 else {
594 // infer client name from output path (e.g. xxx/libfoo_variant.A.dylib --> foo, Bar.framework/Bar_variant --> Bar)
595 clientName = installName;
596 clientNameLen = strlen(clientName);
597 // starts after last slash
598 if ( installNameLastSlash != NULL )
599 clientName = &installNameLastSlash[1];
600 if ( strncmp(clientName, "lib", 3) == 0 )
601 clientName = &clientName[3];
602 // up to first dot
603 const char* firstDot = strchr(clientName, '.');
604 if ( firstDot != NULL )
605 clientNameLen = firstDot - clientName;
606 // up to first underscore
607 const char* firstUnderscore = strchr(clientName, '_');
608 if ( (firstUnderscore != NULL) && ((firstUnderscore - clientName) < clientNameLen) )
609 clientNameLen = firstUnderscore - clientName;
610 }
611
612 // Use clientName to check if this dylib is able to link against the allowable clients.
613 for (std::vector<const char*>::const_iterator it = clients->begin(); it != clients->end(); it++) {
614 if ( strncmp(*it, clientName, clientNameLen) == 0 )
615 isAllowableClient = true;
616 }
617 }
618
619 if ( !isParent && !isSibling && !isAllowableClient ) {
620 if ( dylibParentName != NULL ) {
621 throwf("cannot link directly with %s. Link against the umbrella framework '%s.framework' instead.",
622 dylib->path(), dylibParentName);
623 }
624 else {
625 throwf("cannot link directly with %s", dylib->path());
626 }
627 }
628 }
629 }
630
631
632 void InputFiles::inferArchitecture(Options& opts, const char** archName)
633 {
634 _inferredArch = true;
635 // scan all input files, looking for a thin .o file.
636 // the first one found is presumably the architecture to link
637 uint8_t buffer[sizeof(mach_header_64)];
638 const std::vector<Options::FileInfo>& files = opts.getInputFiles();
639 for (std::vector<Options::FileInfo>::const_iterator it = files.begin(); it != files.end(); ++it) {
640 int fd = ::open(it->path, O_RDONLY, 0);
641 if ( fd != -1 ) {
642 ssize_t amount = read(fd, buffer, sizeof(buffer));
643 ::close(fd);
644 if ( amount >= (ssize_t)sizeof(buffer) ) {
645 cpu_type_t type;
646 cpu_subtype_t subtype;
647 if ( mach_o::relocatable::isObjectFile(buffer, &type, &subtype) ) {
648 opts.setArchitecture(type, subtype);
649 *archName = opts.architectureName();
650 return;
651 }
652 }
653 }
654 }
655
656 // no thin .o files found, so default to same architecture this tool was built as
657 warning("-arch not specified");
658 #if __i386__
659 opts.setArchitecture(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL);
660 #elif __x86_64__
661 opts.setArchitecture(CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL);
662 #elif __arm__
663 opts.setArchitecture(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6);
664 #else
665 #error unknown default architecture
666 #endif
667 *archName = opts.architectureName();
668 }
669
670
671 InputFiles::InputFiles(Options& opts, const char** archName)
672 : _totalObjectSize(0), _totalArchiveSize(0),
673 _totalObjectLoaded(0), _totalArchivesLoaded(0), _totalDylibsLoaded(0),
674 _options(opts), _bundleLoader(NULL),
675 _allDirectDylibsLoaded(false), _inferredArch(false),
676 _exception(NULL)
677 {
678 // fStartCreateReadersTime = mach_absolute_time();
679 if ( opts.architecture() == 0 ) {
680 // command line missing -arch, so guess arch
681 inferArchitecture(opts, archName);
682 }
683 #if HAVE_PTHREADS
684 pthread_mutex_init(&_parseLock, NULL);
685 pthread_cond_init(&_parseWorkReady, NULL);
686 pthread_cond_init(&_newFileAvailable, NULL);
687 #endif
688 const std::vector<Options::FileInfo>& files = _options.getInputFiles();
689 if ( files.size() == 0 )
690 throw "no object files specified";
691
692 _inputFiles.reserve(files.size());
693 #if HAVE_PTHREADS
694 unsigned int inputFileSlot = 0;
695 _availableInputFiles = 0;
696 _parseCursor = 0;
697 #endif
698 Options::FileInfo* entry;
699 for (std::vector<Options::FileInfo>::const_iterator it = files.begin(); it != files.end(); ++it) {
700 entry = (Options::FileInfo*)&(*it);
701 #if HAVE_PTHREADS
702 // Assign input file slots to all the FileInfos.
703 // Also chain all FileInfos into one big list to set up for worker threads to do parsing.
704 entry->inputFileSlot = inputFileSlot;
705 entry->readyToParse = !entry->fromFileList || !_options.pipelineEnabled();
706 if (entry->readyToParse)
707 _availableInputFiles++;
708 _inputFiles.push_back(NULL);
709 inputFileSlot++;
710 #else
711 // In the non-threaded case just parse the file now.
712 _inputFiles.push_back(makeFile(*entry, false));
713 #endif
714 }
715
716 #if HAVE_PTHREADS
717 _remainingInputFiles = files.size();
718
719 // initialize info for parsing input files on worker threads
720 unsigned int ncpus;
721 int mib[2];
722 size_t len = sizeof(ncpus);
723 mib[0] = CTL_HW;
724 mib[1] = HW_NCPU;
725 if (sysctl(mib, 2, &ncpus, &len, NULL, 0) != 0) {
726 ncpus = 1;
727 }
728 _availableWorkers = MIN(ncpus, files.size()); // max # workers we permit
729 _idleWorkers = 0;
730
731 if (_options.pipelineEnabled()) {
732 // start up a thread to listen for available input files
733 startThread(InputFiles::waitForInputFiles);
734 }
735
736 // Start up one parser thread. More start on demand as parsed input files get consumed.
737 startThread(InputFiles::parseWorkerThread);
738 _availableWorkers--;
739 #else
740 if (_options.pipelineEnabled()) {
741 throwf("pipelined linking not supported on this platform");
742 }
743 #endif
744 }
745
746
747 #if HAVE_PTHREADS
748 void InputFiles::startThread(void (*threadFunc)(InputFiles *)) const {
749 pthread_t thread;
750 pthread_attr_t attr;
751 pthread_attr_init(&attr);
752 // set a nice big stack (same as main thread) because some code uses potentially large stack buffers
753 pthread_attr_setstacksize(&attr, 8 * 1024 * 1024);
754 pthread_create(&thread, &attr, (void *(*)(void*))threadFunc, (void *)this);
755 pthread_detach(thread);
756 pthread_attr_destroy(&attr);
757 }
758
759 // Work loop for input file parsing threads
760 void InputFiles::parseWorkerThread() {
761 ld::File *file;
762 const char *exception = NULL;
763 pthread_mutex_lock(&_parseLock);
764 const std::vector<Options::FileInfo>& files = _options.getInputFiles();
765 if (_s_logPThreads) printf("worker starting\n");
766 do {
767 if (_availableInputFiles == 0) {
768 _idleWorkers++;
769 pthread_cond_wait(&_parseWorkReady, &_parseLock);
770 _idleWorkers--;
771 } else {
772 int slot = _parseCursor;
773 while (slot < (int)files.size() && (_inputFiles[slot] != NULL || !files[slot].readyToParse))
774 slot++;
775 assert(slot < (int)files.size());
776 Options::FileInfo& entry = (Options::FileInfo&)files[slot];
777 _parseCursor = slot+1;
778 _availableInputFiles--;
779 entry.readyToParse = false; // to avoid multiple threads finding this file
780 pthread_mutex_unlock(&_parseLock);
781 if (_s_logPThreads) printf("parsing index %u\n", slot);
782 try {
783 file = makeFile(entry, false);
784 } catch (const char *msg) {
785 if ( (strstr(msg, "architecture") != NULL) && !_options.errorOnOtherArchFiles() ) {
786 if ( _options.ignoreOtherArchInputFiles() ) {
787 // ignore, because this is about an architecture not in use
788 }
789 else {
790 warning("ignoring file %s, %s", entry.path, msg);
791 }
792 } else {
793 exception = msg;
794 }
795 file = new IgnoredFile(entry.path, entry.modTime, entry.ordinal, ld::File::Other);
796 }
797 pthread_mutex_lock(&_parseLock);
798 if (_remainingInputFiles > 0)
799 _remainingInputFiles--;
800 if (_s_logPThreads) printf("done with index %u, %d remaining\n", slot, _remainingInputFiles);
801 if (exception) {
802 // We are about to die, so set to zero to stop other threads from doing unneeded work.
803 _remainingInputFiles = 0;
804 _exception = exception;
805 } else {
806 _inputFiles[slot] = file;
807 if (_neededFileSlot == slot)
808 pthread_cond_signal(&_newFileAvailable);
809 }
810 }
811 } while (_remainingInputFiles);
812 if (_s_logPThreads) printf("worker exiting\n");
813 pthread_cond_broadcast(&_parseWorkReady);
814 pthread_cond_signal(&_newFileAvailable);
815 pthread_mutex_unlock(&_parseLock);
816 }
817
818
819 void InputFiles::parseWorkerThread(InputFiles *inputFiles) {
820 inputFiles->parseWorkerThread();
821 }
822 #endif
823
824
825 ld::File* InputFiles::addDylib(ld::dylib::File* reader, const Options::FileInfo& info)
826 {
827 _allDylibs.insert(reader);
828
829 if ( (reader->installPath() == NULL) && !info.options.fBundleLoader ) {
830 // this is a "blank" stub
831 // silently ignore it
832 return reader;
833 }
834 // store options about how dylib will be used in dylib itself
835 if ( info.options.fWeakImport )
836 reader->setForcedWeakLinked();
837 if ( info.options.fReExport )
838 reader->setWillBeReExported();
839 if ( info.options.fUpward ) {
840 if ( _options.outputKind() == Options::kDynamicLibrary )
841 reader->setWillBeUpwardDylib();
842 else
843 warning("ignoring upward dylib option for %s\n", info.path);
844 }
845 if ( info.options.fLazyLoad )
846 reader->setWillBeLazyLoadedDylb();
847
848 // add to map of loaded dylibs
849 const char* installPath = reader->installPath();
850 if ( installPath != NULL ) {
851 InstallNameToDylib::iterator pos = _installPathToDylibs.find(installPath);
852 if ( pos == _installPathToDylibs.end() ) {
853 _installPathToDylibs[strdup(installPath)] = reader;
854 }
855 else {
856 bool dylibOnCommandLineTwice = ( strcmp(pos->second->path(), reader->path()) == 0 );
857 bool isSymlink = false;
858 // ignore if this is a symlink to a dylib we've already loaded
859 if ( !dylibOnCommandLineTwice ) {
860 char existingDylibPath[PATH_MAX];
861 if ( realpath(pos->second->path(), existingDylibPath) != NULL ) {
862 char newDylibPath[PATH_MAX];
863 if ( realpath(reader->path(), newDylibPath) != NULL ) {
864 isSymlink = ( strcmp(existingDylibPath, newDylibPath) == 0 );
865 }
866 }
867 }
868 // remove warning for <rdar://problem/10860629> Same install name for CoreServices and CFNetwork?
869 //if ( !dylibOnCommandLineTwice && !isSymlink )
870 // warning("dylibs with same install name: %s and %s", pos->second->path(), reader->path());
871 }
872 }
873 else if ( info.options.fBundleLoader )
874 _bundleLoader = reader;
875
876 // log direct readers
877 if ( !_allDirectDylibsLoaded )
878 this->logDylib(reader, false);
879
880 // update stats
881 _totalDylibsLoaded++;
882
883 // just add direct libraries to search-first list
884 if ( !_allDirectDylibsLoaded )
885 _searchLibraries.push_back(LibraryInfo(reader));
886 return reader;
887 }
888
889
890 #if HAVE_PTHREADS
891 // Called during pipelined linking to listen for available input files.
892 // Available files are enqueued for parsing.
893 void InputFiles::waitForInputFiles()
894 {
895 if (_s_logPThreads) printf("starting pipeline listener\n");
896 try {
897 const char *fifo = _options.pipelineFifo();
898 assert(fifo);
899 std::map<const char *, const Options::FileInfo*, strcompclass> fileMap;
900 const std::vector<Options::FileInfo>& files = _options.getInputFiles();
901 for (std::vector<Options::FileInfo>::const_iterator it = files.begin(); it != files.end(); ++it) {
902 const Options::FileInfo& entry = *it;
903 if (entry.fromFileList) {
904 fileMap[entry.path] = &entry;
905 }
906 }
907 FILE *fileStream = fopen(fifo, "r");
908 if (!fileStream)
909 throwf("pipelined linking error - failed to open stream. fopen() returns %s for \"%s\"\n", strerror(errno), fifo);
910 while (fileMap.size() > 0) {
911 char path_buf[PATH_MAX+1];
912 if (fgets(path_buf, PATH_MAX, fileStream) == NULL)
913 throwf("pipelined linking error - %lu missing input files", fileMap.size());
914 int len = strlen(path_buf);
915 if (path_buf[len-1] == '\n')
916 path_buf[len-1] = 0;
917 std::map<const char *, const Options::FileInfo*, strcompclass>::iterator it = fileMap.find(path_buf);
918 if (it == fileMap.end())
919 throwf("pipelined linking error - not in file list: %s\n", path_buf);
920 Options::FileInfo* inputInfo = (Options::FileInfo*)it->second;
921 if (!inputInfo->checkFileExists())
922 throwf("pipelined linking error - file does not exist: %s\n", inputInfo->path);
923 pthread_mutex_lock(&_parseLock);
924 if (_idleWorkers)
925 pthread_cond_signal(&_parseWorkReady);
926 inputInfo->readyToParse = true;
927 if (_parseCursor > inputInfo->inputFileSlot)
928 _parseCursor = inputInfo->inputFileSlot;
929 _availableInputFiles++;
930 if (_s_logPThreads) printf("pipeline listener: %s slot=%d, _parseCursor=%d, _availableInputFiles = %d remaining = %ld\n", path_buf, inputInfo->inputFileSlot, _parseCursor, _availableInputFiles, fileMap.size()-1);
931 pthread_mutex_unlock(&_parseLock);
932 fileMap.erase(it);
933 }
934 } catch (const char *msg) {
935 pthread_mutex_lock(&_parseLock);
936 _exception = msg;
937 pthread_cond_signal(&_newFileAvailable);
938 pthread_mutex_unlock(&_parseLock);
939 }
940 }
941
942
943 void InputFiles::waitForInputFiles(InputFiles *inputFiles) {
944 inputFiles->waitForInputFiles();
945 }
946 #endif
947
948
949 void InputFiles::forEachInitialAtom(ld::File::AtomHandler& handler)
950 {
951 // add all direct object, archives, and dylibs
952 const std::vector<Options::FileInfo>& files = _options.getInputFiles();
953 size_t fileIndex;
954 for (fileIndex=0; fileIndex<_inputFiles.size(); fileIndex++) {
955 ld::File *file;
956 #if HAVE_PTHREADS
957 pthread_mutex_lock(&_parseLock);
958
959 // this loop waits for the needed file to be ready (parsed by worker thread)
960 while (_inputFiles[fileIndex] == NULL && _exception == NULL) {
961 // We are starved for input. If there are still files to parse and we have
962 // not maxed out the worker thread count start a new worker thread.
963 if (_availableInputFiles > 0 && _availableWorkers > 0) {
964 if (_s_logPThreads) printf("starting worker\n");
965 startThread(InputFiles::parseWorkerThread);
966 _availableWorkers--;
967 }
968 _neededFileSlot = fileIndex;
969 if (_s_logPThreads) printf("consumer blocking for %lu: %s\n", fileIndex, files[fileIndex].path);
970 pthread_cond_wait(&_newFileAvailable, &_parseLock);
971 }
972
973 if (_exception)
974 throw _exception;
975
976 // The input file is parsed. Assimilate it and call its atom iterator.
977 if (_s_logPThreads) printf("consuming slot %lu\n", fileIndex);
978 file = _inputFiles[fileIndex];
979 pthread_mutex_unlock(&_parseLock);
980 #else
981 file = _inputFiles[fileIndex];
982 #endif
983 const Options::FileInfo& info = files[fileIndex];
984 switch (file->type()) {
985 case ld::File::Reloc:
986 {
987 ld::relocatable::File* reloc = (ld::relocatable::File*)file;
988 _options.snapshot().recordObjectFile(reloc->path());
989 }
990 break;
991 case ld::File::Dylib:
992 {
993 ld::dylib::File* dylib = (ld::dylib::File*)file;
994 addDylib(dylib, info);
995 }
996 break;
997 case ld::File::Archive:
998 {
999 ld::archive::File* archive = (ld::archive::File*)file;
1000 // <rdar://problem/9740166> force loaded archives should be in LD_TRACE
1001 if ( (info.options.fForceLoad || _options.fullyLoadArchives()) && _options.traceArchives() )
1002 logArchive(archive);
1003 _searchLibraries.push_back(LibraryInfo(archive));
1004 }
1005 break;
1006 case ld::File::Other:
1007 break;
1008 default:
1009 {
1010 throwf("Unknown file type for %s", file->path());
1011 }
1012 break;
1013 }
1014 file->forEachAtom(handler);
1015 }
1016
1017 createIndirectDylibs();
1018 createOpaqueFileSections();
1019
1020 while (fileIndex < _inputFiles.size()) {
1021 ld::File *file = _inputFiles[fileIndex];
1022 file->forEachAtom(handler);
1023 fileIndex++;
1024 }
1025
1026 switch ( _options.outputKind() ) {
1027 case Options::kStaticExecutable:
1028 case Options::kDynamicExecutable:
1029 // add implicit __dso_handle label
1030 handler.doAtom(DSOHandleAtom::_s_atomExecutable);
1031 handler.doAtom(DSOHandleAtom::_s_atomAll);
1032 if ( _options.pageZeroSize() != 0 )
1033 handler.doAtom(*new PageZeroAtom(_options.pageZeroSize()));
1034 if ( _options.hasCustomStack() && !_options.needsEntryPointLoadCommand() )
1035 handler.doAtom(*new CustomStackAtom(_options.customStackSize()));
1036 break;
1037 case Options::kDynamicLibrary:
1038 // add implicit __dso_handle label
1039 handler.doAtom(DSOHandleAtom::_s_atomDylib);
1040 handler.doAtom(DSOHandleAtom::_s_atomAll);
1041 break;
1042 case Options::kDynamicBundle:
1043 // add implicit __dso_handle label
1044 handler.doAtom(DSOHandleAtom::_s_atomBundle);
1045 handler.doAtom(DSOHandleAtom::_s_atomAll);
1046 break;
1047 case Options::kDyld:
1048 // add implicit __dso_handle label
1049 handler.doAtom(DSOHandleAtom::_s_atomDyld);
1050 handler.doAtom(DSOHandleAtom::_s_atomAll);
1051 break;
1052 case Options::kPreload:
1053 // add implicit __mh_preload_header label
1054 handler.doAtom(DSOHandleAtom::_s_atomPreload);
1055 // add implicit __dso_handle label, but put it in __text section because
1056 // with -preload the mach_header is no in the address space.
1057 handler.doAtom(DSOHandleAtom::_s_atomPreloadDSO);
1058 break;
1059 case Options::kObjectFile:
1060 handler.doAtom(DSOHandleAtom::_s_atomObjectFile);
1061 break;
1062 case Options::kKextBundle:
1063 // add implicit __dso_handle label
1064 handler.doAtom(DSOHandleAtom::_s_atomAll);
1065 break;
1066 }
1067 }
1068
1069
1070 bool InputFiles::searchLibraries(const char* name, bool searchDylibs, bool searchArchives, bool dataSymbolOnly, ld::File::AtomHandler& handler) const
1071 {
1072 // Check each input library.
1073 for (std::vector<LibraryInfo>::const_iterator it=_searchLibraries.begin(); it != _searchLibraries.end(); ++it) {
1074 LibraryInfo lib = *it;
1075 if (lib.isDylib()) {
1076 if (searchDylibs) {
1077 ld::dylib::File *dylibFile = lib.dylib();
1078 //fprintf(stderr, "searchLibraries(%s), looking in linked %s\n", name, dylibFile->path() );
1079 if ( dylibFile->justInTimeforEachAtom(name, handler) ) {
1080 // we found a definition in this dylib
1081 // done, unless it is a weak definition in which case we keep searching
1082 _options.snapshot().recordDylibSymbol(dylibFile, name);
1083 if ( !dylibFile->hasWeakExternals() || !dylibFile->hasWeakDefinition(name)) {
1084 return true;
1085 }
1086 // else continue search for a non-weak definition
1087 }
1088 }
1089 } else {
1090 if (searchArchives) {
1091 ld::archive::File *archiveFile = lib.archive();
1092 if ( dataSymbolOnly ) {
1093 if ( archiveFile->justInTimeDataOnlyforEachAtom(name, handler) ) {
1094 if ( _options.traceArchives() )
1095 logArchive(archiveFile);
1096 _options.snapshot().recordArchive(archiveFile->path());
1097 // found data definition in static library, done
1098 return true;
1099 }
1100 }
1101 else {
1102 if ( archiveFile->justInTimeforEachAtom(name, handler) ) {
1103 if ( _options.traceArchives() )
1104 logArchive(archiveFile);
1105 _options.snapshot().recordArchive(archiveFile->path());
1106 // found definition in static library, done
1107 return true;
1108 }
1109 }
1110 }
1111 }
1112 }
1113
1114 // search indirect dylibs
1115 if ( searchDylibs ) {
1116 for (InstallNameToDylib::const_iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); ++it) {
1117 ld::dylib::File* dylibFile = it->second;
1118 bool searchThisDylib = false;
1119 if ( _options.nameSpace() == Options::kTwoLevelNameSpace ) {
1120 // for two level namesapce, just check all implicitly linked dylibs
1121 searchThisDylib = dylibFile->implicitlyLinked() && !dylibFile->explicitlyLinked();
1122 }
1123 else {
1124 // for flat namespace, check all indirect dylibs
1125 searchThisDylib = ! dylibFile->explicitlyLinked();
1126 }
1127 if ( searchThisDylib ) {
1128 //fprintf(stderr, "searchLibraries(%s), looking in implicitly linked %s\n", name, dylibFile->path() );
1129 if ( dylibFile->justInTimeforEachAtom(name, handler) ) {
1130 // we found a definition in this dylib
1131 // done, unless it is a weak definition in which case we keep searching
1132 _options.snapshot().recordDylibSymbol(dylibFile, name);
1133 if ( !dylibFile->hasWeakExternals() || !dylibFile->hasWeakDefinition(name)) {
1134 return true;
1135 }
1136 // else continue search for a non-weak definition
1137 }
1138 }
1139 }
1140 }
1141
1142 return false;
1143 }
1144
1145
1146 bool InputFiles::searchWeakDefInDylib(const char* name) const
1147 {
1148 // search all relevant dylibs to see if any of a weak-def with this name
1149 for (InstallNameToDylib::const_iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); ++it) {
1150 ld::dylib::File* dylibFile = it->second;
1151 if ( dylibFile->implicitlyLinked() || dylibFile->explicitlyLinked() ) {
1152 if ( dylibFile->hasWeakExternals() && dylibFile->hasWeakDefinition(name) ) {
1153 return true;
1154 }
1155 }
1156 }
1157 return false;
1158 }
1159
1160 static bool vectorContains(const std::vector<ld::dylib::File*>& vec, ld::dylib::File* key)
1161 {
1162 return std::find(vec.begin(), vec.end(), key) != vec.end();
1163 }
1164
1165 void InputFiles::dylibs(ld::Internal& state)
1166 {
1167 bool dylibsOK = false;
1168 switch ( _options.outputKind() ) {
1169 case Options::kDynamicExecutable:
1170 case Options::kDynamicLibrary:
1171 case Options::kDynamicBundle:
1172 dylibsOK = true;
1173 break;
1174 case Options::kStaticExecutable:
1175 case Options::kDyld:
1176 case Options::kPreload:
1177 case Options::kObjectFile:
1178 case Options::kKextBundle:
1179 dylibsOK = false;
1180 break;
1181 }
1182
1183 // add command line dylibs in order
1184 for (std::vector<ld::File*>::const_iterator it=_inputFiles.begin(); it != _inputFiles.end(); ++it) {
1185 ld::dylib::File* dylibFile = dynamic_cast<ld::dylib::File*>(*it);
1186 // only add dylibs that are not "blank" dylib stubs
1187 if ( (dylibFile != NULL) && ((dylibFile->installPath() != NULL) || (dylibFile == _bundleLoader)) ) {
1188 if ( dylibsOK ) {
1189 if ( ! vectorContains(state.dylibs, dylibFile) ) {
1190 state.dylibs.push_back(dylibFile);
1191 }
1192 }
1193 else
1194 warning("unexpected dylib (%s) on link line", dylibFile->path());
1195 }
1196 }
1197 // add implicitly linked dylibs
1198 if ( _options.nameSpace() == Options::kTwoLevelNameSpace ) {
1199 for (InstallNameToDylib::const_iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); ++it) {
1200 ld::dylib::File* dylibFile = it->second;
1201 if ( dylibFile->implicitlyLinked() && dylibsOK ) {
1202 if ( ! vectorContains(state.dylibs, dylibFile) ) {
1203 state.dylibs.push_back(dylibFile);
1204 }
1205 }
1206 }
1207 }
1208
1209 //fprintf(stderr, "all dylibs:\n");
1210 //for(std::vector<ld::dylib::File*>::iterator it=state.dylibs.begin(); it != state.dylibs.end(); ++it) {
1211 // const ld::dylib::File* dylib = *it;
1212 // fprintf(stderr, " %p %s\n", dylib, dylib->path());
1213 //}
1214
1215 // and -bundle_loader
1216 state.bundleLoader = _bundleLoader;
1217
1218 // <rdar://problem/10807040> give an error when -nostdlib is used and libSystem is missing
1219 if ( (state.dylibs.size() == 0) && _options.needsEntryPointLoadCommand() )
1220 throw "dynamic main executables must link with libSystem.dylib";
1221 }
1222
1223
1224 } // namespace tool
1225 } // namespace ld
1226
1227