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