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