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