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