]> git.saurik.com Git - apple/ld64.git/blame_incremental - src/ld/InputFiles.cpp
ld64-128.2.tar.gz
[apple/ld64.git] / src / ld / InputFiles.cpp
... / ...
CommitLineData
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
3 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26#include <stdlib.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <sys/mman.h>
30#include <sys/sysctl.h>
31#include <fcntl.h>
32#include <errno.h>
33#include <limits.h>
34#include <unistd.h>
35#include <mach/mach_time.h>
36#include <mach/vm_statistics.h>
37#include <mach/mach_init.h>
38#include <mach/mach_host.h>
39#include <dlfcn.h>
40#include <mach-o/dyld.h>
41#include <mach-o/fat.h>
42
43#include <string>
44#include <map>
45#include <set>
46#include <string>
47#include <vector>
48#include <list>
49#include <algorithm>
50#include <ext/hash_map>
51#include <ext/hash_set>
52#include <dlfcn.h>
53#include <AvailabilityMacros.h>
54
55#include "Options.h"
56
57#include "InputFiles.h"
58#include "macho_relocatable_file.h"
59#include "macho_dylib_file.h"
60#include "archive_file.h"
61#include "lto_file.h"
62#include "opaque_section_file.h"
63
64
65namespace ld {
66namespace tool {
67
68
69
70
71class DSOHandleAtom : public ld::Atom {
72public:
73 DSOHandleAtom(const char* nm, ld::Atom::Scope sc,
74 ld::Atom::SymbolTableInclusion inc, bool preload=false)
75 : ld::Atom(preload ? _s_section_preload : _s_section,
76 ld::Atom::definitionRegular, ld::Atom::combineNever,
77 sc, ld::Atom::typeUnclassified, inc, true, false, false,
78 ld::Atom::Alignment(1)), _name(nm) {}
79
80 virtual ld::File* file() const { return NULL; }
81 virtual bool translationUnitSource(const char** dir, const char** ) const
82 { return false; }
83 virtual const char* name() const { return _name; }
84 virtual uint64_t size() const { return 0; }
85 virtual uint64_t objectAddress() const { return 0; }
86 virtual void copyRawContent(uint8_t buffer[]) const
87 { }
88 virtual void setScope(Scope) { }
89
90 virtual ~DSOHandleAtom() {}
91
92 static ld::Section _s_section;
93 static ld::Section _s_section_preload;
94 static DSOHandleAtom _s_atomAll;
95 static DSOHandleAtom _s_atomExecutable;
96 static DSOHandleAtom _s_atomDylib;
97 static DSOHandleAtom _s_atomBundle;
98 static DSOHandleAtom _s_atomDyld;
99 static DSOHandleAtom _s_atomObjectFile;
100 static DSOHandleAtom _s_atomPreload;
101private:
102 const char* _name;
103};
104ld::Section DSOHandleAtom::_s_section("__TEXT", "__mach_header", ld::Section::typeMachHeader, true);
105ld::Section DSOHandleAtom::_s_section_preload("__HEADER", "__mach_header", ld::Section::typeMachHeader, true);
106DSOHandleAtom DSOHandleAtom::_s_atomAll("___dso_handle", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
107DSOHandleAtom DSOHandleAtom::_s_atomExecutable("__mh_execute_header", ld::Atom::scopeGlobal, ld::Atom::symbolTableInAndNeverStrip);
108DSOHandleAtom DSOHandleAtom::_s_atomDylib("__mh_dylib_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
109DSOHandleAtom DSOHandleAtom::_s_atomBundle("__mh_bundle_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
110DSOHandleAtom DSOHandleAtom::_s_atomDyld("__mh_dylinker_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
111DSOHandleAtom DSOHandleAtom::_s_atomObjectFile("__mh_object_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn);
112DSOHandleAtom DSOHandleAtom::_s_atomPreload("__mh_preload_header", ld::Atom::scopeLinkageUnit, ld::Atom::symbolTableNotIn, true);
113
114
115
116class PageZeroAtom : public ld::Atom {
117public:
118 PageZeroAtom(uint64_t sz)
119 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
120 ld::Atom::scopeTranslationUnit, ld::Atom::typeZeroFill,
121 symbolTableNotIn, true, false, false, ld::Atom::Alignment(12)),
122 _size(sz) {}
123
124 virtual ld::File* file() const { return NULL; }
125 virtual bool translationUnitSource(const char** dir, const char** ) const
126 { return false; }
127 virtual const char* name() const { return "page zero"; }
128 virtual uint64_t size() const { return _size; }
129 virtual uint64_t objectAddress() const { return 0; }
130 virtual void copyRawContent(uint8_t buffer[]) const
131 { }
132 virtual void setScope(Scope) { }
133
134 virtual ~PageZeroAtom() {}
135
136 static ld::Section _s_section;
137 static DSOHandleAtom _s_atomAll;
138private:
139 uint64_t _size;
140};
141ld::Section PageZeroAtom::_s_section("__PAGEZERO", "__pagezero", ld::Section::typePageZero, true);
142
143
144class CustomStackAtom : public ld::Atom {
145public:
146 CustomStackAtom(uint64_t sz)
147 : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
148 ld::Atom::scopeTranslationUnit, ld::Atom::typeZeroFill,
149 symbolTableNotIn, false, false, false, ld::Atom::Alignment(12)),
150 _size(sz) {}
151
152 virtual ld::File* file() const { return NULL; }
153 virtual bool translationUnitSource(const char** dir, const char** ) const
154 { return false; }
155 virtual const char* name() const { return "custom stack"; }
156 virtual uint64_t size() const { return _size; }
157 virtual uint64_t objectAddress() const { return 0; }
158 virtual void copyRawContent(uint8_t buffer[]) const
159 { }
160 virtual void setScope(Scope) { }
161
162 virtual ~CustomStackAtom() {}
163
164private:
165 uint64_t _size;
166 static ld::Section _s_section;
167};
168ld::Section CustomStackAtom::_s_section("__UNIXSTACK", "__stack", ld::Section::typeStack, true);
169
170
171
172const char* InputFiles::fileArch(const uint8_t* p, unsigned len)
173{
174 const char* result = mach_o::relocatable::archName(p);
175 if ( result != NULL )
176 return result;
177
178 result = lto::archName(p, len);
179 if ( result != NULL )
180 return result;
181
182 if ( strncmp((const char*)p, "!<arch>\n", 8) == 0 )
183 return "archive";
184
185 return "unsupported file format";
186}
187
188
189ld::File* InputFiles::makeFile(const Options::FileInfo& info, bool indirectDylib)
190{
191 // map in whole file
192 uint64_t len = info.fileLen;
193 int fd = ::open(info.path, O_RDONLY, 0);
194 if ( fd == -1 )
195 throwf("can't open file, errno=%d", errno);
196 if ( info.fileLen < 20 )
197 throw "file too small";
198
199 uint8_t* p = (uint8_t*)::mmap(NULL, info.fileLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
200 if ( p == (uint8_t*)(-1) )
201 throwf("can't map file, errno=%d", errno);
202
203 // if fat file, skip to architecture we want
204 // Note: fat header is always big-endian
205 bool isFatFile = false;
206 const fat_header* fh = (fat_header*)p;
207 if ( fh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
208 isFatFile = true;
209 const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header));
210 uint32_t sliceToUse;
211 bool sliceFound = false;
212 if ( _options.preferSubArchitecture() ) {
213 // first try to find a slice that match cpu-type and cpu-sub-type
214 for (uint32_t i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) {
215 if ( (OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture())
216 && (OSSwapBigToHostInt32(archs[i].cpusubtype) == (uint32_t)_options.subArchitecture()) ) {
217 sliceToUse = i;
218 sliceFound = true;
219 break;
220 }
221 }
222 }
223 if ( !sliceFound ) {
224 // look for any slice that matches just cpu-type
225 for (uint32_t i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) {
226 if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)_options.architecture() ) {
227 sliceToUse = i;
228 sliceFound = true;
229 break;
230 }
231 }
232 }
233 if ( sliceFound ) {
234 uint32_t fileOffset = OSSwapBigToHostInt32(archs[sliceToUse].offset);
235 len = OSSwapBigToHostInt32(archs[sliceToUse].size);
236 if ( fileOffset+len > info.fileLen ) {
237 throwf("truncated fat file. Slice from %u to %llu is past end of file with length %llu",
238 fileOffset, fileOffset+len, info.fileLen);
239 }
240 // if requested architecture is page aligned within fat file, then remap just that portion of file
241 if ( (fileOffset & 0x00000FFF) == 0 ) {
242 // unmap whole file
243 munmap((caddr_t)p, info.fileLen);
244 // re-map just part we need
245 p = (uint8_t*)::mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, fileOffset);
246 if ( p == (uint8_t*)(-1) )
247 throwf("can't re-map file, errno=%d", errno);
248 }
249 else {
250 p = &p[fileOffset];
251 }
252 }
253 }
254 ::close(fd);
255
256 // see if it is an object file
257 mach_o::relocatable::ParserOptions objOpts;
258 objOpts.architecture = _options.architecture();
259 objOpts.objSubtypeMustMatch = !_options.allowSubArchitectureMismatches();
260 objOpts.logAllFiles = _options.logAllFiles();
261 objOpts.convertUnwindInfo = _options.needsUnwindInfoSection();
262 objOpts.subType = _options.subArchitecture();
263 ld::relocatable::File* objResult = mach_o::relocatable::parse(p, len, info.path, info.modTime, _nextInputOrdinal, objOpts);
264 if ( objResult != NULL )
265 return this->addObject(objResult, info, len);
266
267 // see if it is an llvm object file
268 objResult = lto::parse(p, len, info.path, info.modTime, _nextInputOrdinal, _options.architecture(), _options.subArchitecture(), _options.logAllFiles());
269 if ( objResult != NULL )
270 return this->addObject(objResult, info, len);
271
272 // see if it is a dynamic library
273 ld::dylib::File* dylibResult = mach_o::dylib::parse(p, len, info.path, info.modTime, _options, _nextInputOrdinal, info.options.fBundleLoader, indirectDylib);
274 if ( dylibResult != NULL )
275 return this->addDylib(dylibResult, info, len);
276
277 // see if it is a static library
278 ::archive::ParserOptions archOpts;
279 archOpts.objOpts = objOpts;
280 archOpts.forceLoadThisArchive = info.options.fForceLoad;
281 archOpts.forceLoadAll = _options.fullyLoadArchives();
282 archOpts.forceLoadObjC = _options.loadAllObjcObjectsFromArchives();
283 archOpts.objcABI2 = _options.objCABIVersion2POverride();
284 archOpts.verboseLoad = _options.whyLoad();
285 archOpts.logAllFiles = _options.logAllFiles();
286 ld::archive::File* archiveResult = ::archive::parse(p, len, info.path, info.modTime, _nextInputOrdinal, archOpts);
287 if ( archiveResult != NULL ) {
288 // <rdar://problem/9740166> force loaded archives should be in LD_TRACE
289 if ( (info.options.fForceLoad || _options.fullyLoadArchives()) && _options.traceArchives() )
290 logArchive(archiveResult);
291 return this->addArchive(archiveResult, info, len);
292 }
293
294 // does not seem to be any valid linker input file, check LTO misconfiguration problems
295 if ( lto::archName((uint8_t*)p, len) != NULL ) {
296 if ( lto::libLTOisLoaded() ) {
297 throwf("file was built for %s which is not the architecture being linked (%s)", fileArch(p, len), _options.architectureName());
298 }
299 else {
300 const char* libLTO = "libLTO.dylib";
301 char ldPath[PATH_MAX];
302 char tmpPath[PATH_MAX];
303 char libLTOPath[PATH_MAX];
304 uint32_t bufSize = PATH_MAX;
305 if ( _NSGetExecutablePath(ldPath, &bufSize) != -1 ) {
306 if ( realpath(ldPath, tmpPath) != NULL ) {
307 char* lastSlash = strrchr(tmpPath, '/');
308 if ( lastSlash != NULL )
309 strcpy(lastSlash, "/../lib/libLTO.dylib");
310 libLTO = tmpPath;
311 if ( realpath(tmpPath, libLTOPath) != NULL )
312 libLTO = libLTOPath;
313 }
314 }
315 throwf("could not process llvm bitcode object file, because %s could not be loaded", libLTO);
316 }
317 }
318
319 // error handling
320 if ( ((fat_header*)p)->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
321 throwf("missing required architecture %s in file", _options.architectureName());
322 }
323 else {
324 if ( isFatFile )
325 throwf("file is universal but does not contain a(n) %s slice", _options.architectureName());
326 else
327 throwf("file was built for %s which is not the architecture being linked (%s)", fileArch(p, len), _options.architectureName());
328 }
329}
330
331void InputFiles::logDylib(ld::File* file, bool indirect)
332{
333 if ( _options.traceDylibs() ) {
334 const char* fullPath = file->path();
335 char realName[MAXPATHLEN];
336 if ( realpath(fullPath, realName) != NULL )
337 fullPath = realName;
338 const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(file);
339 if ( (dylib != NULL ) && dylib->willBeUpwardDylib() ) {
340 // don't log upward dylibs when XBS is computing dependencies
341 logTraceInfo("[Logging for XBS] Used upward dynamic library: %s\n", fullPath);
342 }
343 else {
344 if ( indirect )
345 logTraceInfo("[Logging for XBS] Used indirect dynamic library: %s\n", fullPath);
346 else
347 logTraceInfo("[Logging for XBS] Used dynamic library: %s\n", fullPath);
348 }
349 }
350}
351
352void InputFiles::logArchive(ld::File* file) const
353{
354 if ( _options.traceArchives() && (_archiveFilesLogged.count(file) == 0) ) {
355 // <rdar://problem/4947347> LD_TRACE_ARCHIVES should only print out when a .o is actually used from an archive
356 _archiveFilesLogged.insert(file);
357 const char* fullPath = file->path();
358 char realName[MAXPATHLEN];
359 if ( realpath(fullPath, realName) != NULL )
360 fullPath = realName;
361 logTraceInfo("[Logging for XBS] Used static archive: %s\n", fullPath);
362 }
363}
364
365
366void InputFiles::logTraceInfo(const char* format, ...) const
367{
368 // one time open() of custom LD_TRACE_FILE
369 static int trace_file = -1;
370 if ( trace_file == -1 ) {
371 const char *trace_file_path = _options.traceOutputFile();
372 if ( trace_file_path != NULL ) {
373 trace_file = open(trace_file_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
374 if ( trace_file == -1 )
375 throwf("Could not open or create trace file: %s", trace_file_path);
376 }
377 else {
378 trace_file = fileno(stderr);
379 }
380 }
381
382 char trace_buffer[MAXPATHLEN * 2];
383 va_list ap;
384 va_start(ap, format);
385 int length = vsnprintf(trace_buffer, sizeof(trace_buffer), format, ap);
386 va_end(ap);
387 char* buffer_ptr = trace_buffer;
388
389 while (length > 0) {
390 ssize_t amount_written = write(trace_file, buffer_ptr, length);
391 if(amount_written == -1)
392 /* Failure to write shouldn't fail the build. */
393 return;
394 buffer_ptr += amount_written;
395 length -= amount_written;
396 }
397}
398
399ld::dylib::File* InputFiles::findDylib(const char* installPath, const char* fromPath)
400{
401 //fprintf(stderr, "findDylib(%s, %s)\n", installPath, fromPath);
402 InstallNameToDylib::iterator pos = _installPathToDylibs.find(installPath);
403 if ( pos != _installPathToDylibs.end() ) {
404 return pos->second;
405 }
406 else {
407 // allow -dylib_path option to override indirect library to use
408 for (std::vector<Options::DylibOverride>::const_iterator dit = _options.dylibOverrides().begin(); dit != _options.dylibOverrides().end(); ++dit) {
409 if ( strcmp(dit->installName,installPath) == 0 ) {
410 try {
411 Options::FileInfo info = _options.findFile(dit->useInstead);
412 ld::File* reader = this->makeFile(info, true);
413 ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
414 if ( dylibReader != NULL ) {
415 //_installPathToDylibs[strdup(installPath)] = dylibReader;
416 this->logDylib(dylibReader, true);
417 return dylibReader;
418 }
419 else
420 throwf("indirect dylib at %s is not a dylib", dit->useInstead);
421 }
422 catch (const char* msg) {
423 warning("ignoring -dylib_file option, %s", msg);
424 }
425 }
426 }
427 char newPath[MAXPATHLEN];
428 // handle @loader_path
429 if ( strncmp(installPath, "@loader_path/", 13) == 0 ) {
430 strcpy(newPath, fromPath);
431 char* addPoint = strrchr(newPath,'/');
432 if ( addPoint != NULL )
433 strcpy(&addPoint[1], &installPath[13]);
434 else
435 strcpy(newPath, &installPath[13]);
436 installPath = newPath;
437 }
438 // note: @executable_path case is handled inside findFileUsingPaths()
439 // search for dylib using -F and -L paths
440 Options::FileInfo info = _options.findFileUsingPaths(installPath);
441 try {
442 ld::File* reader = this->makeFile(info, true);
443 ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
444 if ( dylibReader != NULL ) {
445 //assert(_installPathToDylibs.find(installPath) != _installPathToDylibs.end());
446 //_installPathToDylibs[strdup(installPath)] = dylibReader;
447 this->logDylib(dylibReader, true);
448 return dylibReader;
449 }
450 else
451 throwf("indirect dylib at %s is not a dylib", info.path);
452 }
453 catch (const char* msg) {
454 throwf("in %s, %s", info.path, msg);
455 }
456 }
457}
458
459
460
461void InputFiles::createIndirectDylibs()
462{
463 _allDirectDylibsLoaded = true;
464
465 // mark all dylibs initially specified as required and check if they can be used
466 for (InstallNameToDylib::iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); it++) {
467 it->second->setExplicitlyLinked();
468 this->checkDylibClientRestrictions(it->second);
469 }
470
471 // keep processing dylibs until no more dylibs are added
472 unsigned long lastMapSize = 0;
473 std::set<ld::dylib::File*> dylibsProcessed;
474 while ( lastMapSize != _allDylibs.size() ) {
475 lastMapSize = _allDylibs.size();
476 // can't iterator _installPathToDylibs while modifying it, so use temp buffer
477 std::vector<ld::dylib::File*> unprocessedDylibs;
478 for (std::set<ld::dylib::File*>::iterator it=_allDylibs.begin(); it != _allDylibs.end(); it++) {
479 if ( dylibsProcessed.count(*it) == 0 )
480 unprocessedDylibs.push_back(*it);
481 }
482 for (std::vector<ld::dylib::File*>::iterator it=unprocessedDylibs.begin(); it != unprocessedDylibs.end(); it++) {
483 dylibsProcessed.insert(*it);
484 (*it)->processIndirectLibraries(this, _options.implicitlyLinkIndirectPublicDylibs());
485 }
486 }
487
488 // go back over original dylibs and mark sub frameworks as re-exported
489 if ( _options.outputKind() == Options::kDynamicLibrary ) {
490 const char* myLeaf = strrchr(_options.installPath(), '/');
491 if ( myLeaf != NULL ) {
492 for (std::vector<class ld::File*>::const_iterator it=_inputFiles.begin(); it != _inputFiles.end(); it++) {
493 ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(*it);
494 if ( dylibReader != NULL ) {
495 const char* childParent = dylibReader->parentUmbrella();
496 if ( childParent != NULL ) {
497 if ( strcmp(childParent, &myLeaf[1]) == 0 ) {
498 // mark that this dylib will be re-exported
499 dylibReader->setWillBeReExported();
500 }
501 }
502 }
503 }
504 }
505 }
506
507}
508
509void InputFiles::createOpaqueFileSections()
510{
511 // extra command line section always at end
512 for (Options::ExtraSection::const_iterator it=_options.extraSectionsBegin(); it != _options.extraSectionsEnd(); ++it) {
513 _inputFiles.push_back(opaque_section::parse(it->segmentName, it->sectionName, it->path, it->data,
514 it->dataLen, _nextInputOrdinal));
515 // bump ordinal
516 _nextInputOrdinal++;
517 }
518
519}
520
521
522void InputFiles::checkDylibClientRestrictions(ld::dylib::File* dylib)
523{
524 // Check for any restrictions on who can link with this dylib
525 const char* dylibParentName = dylib->parentUmbrella() ;
526 const std::vector<const char*>* clients = dylib->allowableClients();
527 if ( (dylibParentName != NULL) || (clients != NULL) ) {
528 // only dylibs that are in an umbrella or have a client list need verification
529 const char* installName = _options.installPath();
530 const char* installNameLastSlash = strrchr(installName, '/');
531 bool isParent = false;
532 bool isSibling = false;
533 bool isAllowableClient = false;
534 // There are three cases:
535 if ( (dylibParentName != NULL) && (installNameLastSlash != NULL) ) {
536 // starts after last slash
537 const char* myName = &installNameLastSlash[1];
538 unsigned int myNameLen = strlen(myName);
539 if ( strncmp(myName, "lib", 3) == 0 )
540 myName = &myName[3];
541 // up to first dot
542 const char* firstDot = strchr(myName, '.');
543 if ( firstDot != NULL )
544 myNameLen = firstDot - myName;
545 // up to first underscore
546 const char* firstUnderscore = strchr(myName, '_');
547 if ( (firstUnderscore != NULL) && ((firstUnderscore - myName) < (int)myNameLen) )
548 myNameLen = firstUnderscore - myName;
549
550 // case 1) The dylib has a parent umbrella, and we are creating the parent umbrella
551 isParent = ( (strlen(dylibParentName) == myNameLen) && (strncmp(myName, dylibParentName, myNameLen) == 0) );
552
553 // case 2) The dylib has a parent umbrella, and we are creating a sibling with the same parent
554 isSibling = ( (_options.umbrellaName() != NULL) && (strcmp(_options.umbrellaName(), dylibParentName) == 0) );
555 }
556
557 if ( !isParent && !isSibling && (clients != NULL) ) {
558 // case 3) the dylib has a list of allowable clients, and we are creating one of them
559 const char* clientName = _options.clientName();
560 int clientNameLen = 0;
561 if ( clientName != NULL ) {
562 // use client name as specified on command line
563 clientNameLen = strlen(clientName);
564 }
565 else {
566 // infer client name from output path (e.g. xxx/libfoo_variant.A.dylib --> foo, Bar.framework/Bar_variant --> Bar)
567 clientName = installName;
568 clientNameLen = strlen(clientName);
569 // starts after last slash
570 if ( installNameLastSlash != NULL )
571 clientName = &installNameLastSlash[1];
572 if ( strncmp(clientName, "lib", 3) == 0 )
573 clientName = &clientName[3];
574 // up to first dot
575 const char* firstDot = strchr(clientName, '.');
576 if ( firstDot != NULL )
577 clientNameLen = firstDot - clientName;
578 // up to first underscore
579 const char* firstUnderscore = strchr(clientName, '_');
580 if ( (firstUnderscore != NULL) && ((firstUnderscore - clientName) < clientNameLen) )
581 clientNameLen = firstUnderscore - clientName;
582 }
583
584 // Use clientName to check if this dylib is able to link against the allowable clients.
585 for (std::vector<const char*>::const_iterator it = clients->begin(); it != clients->end(); it++) {
586 if ( strncmp(*it, clientName, clientNameLen) == 0 )
587 isAllowableClient = true;
588 }
589 }
590
591 if ( !isParent && !isSibling && !isAllowableClient ) {
592 if ( dylibParentName != NULL ) {
593 throwf("cannot link directly with %s. Link against the umbrella framework '%s.framework' instead.",
594 dylib->path(), dylibParentName);
595 }
596 else {
597 throwf("cannot link directly with %s", dylib->path());
598 }
599 }
600 }
601}
602
603
604void InputFiles::inferArchitecture(Options& opts, const char** archName)
605{
606 _inferredArch = true;
607 // scan all input files, looking for a thin .o file.
608 // the first one found is presumably the architecture to link
609 uint8_t buffer[sizeof(mach_header_64)];
610 const std::vector<Options::FileInfo>& files = opts.getInputFiles();
611 for (std::vector<Options::FileInfo>::const_iterator it = files.begin(); it != files.end(); ++it) {
612 int fd = ::open(it->path, O_RDONLY, 0);
613 if ( fd != -1 ) {
614 ssize_t amount = read(fd, buffer, sizeof(buffer));
615 ::close(fd);
616 if ( amount >= (ssize_t)sizeof(buffer) ) {
617 cpu_type_t type;
618 cpu_subtype_t subtype;
619 if ( mach_o::relocatable::isObjectFile(buffer, &type, &subtype) ) {
620 opts.setArchitecture(type, subtype);
621 *archName = opts.architectureName();
622 return;
623 }
624 }
625 }
626 }
627
628 // no thin .o files found, so default to same architecture this tool was built as
629 warning("-arch not specified");
630#if __i386__
631 opts.setArchitecture(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL);
632#elif __x86_64__
633 opts.setArchitecture(CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL);
634#elif __arm__
635 opts.setArchitecture(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6);
636#else
637 #error unknown default architecture
638#endif
639 *archName = opts.architectureName();
640}
641
642
643InputFiles::InputFiles(Options& opts, const char** archName)
644 : _totalObjectSize(0), _totalArchiveSize(0),
645 _totalObjectLoaded(0), _totalArchivesLoaded(0), _totalDylibsLoaded(0),
646 _options(opts), _bundleLoader(NULL), _nextInputOrdinal(1),
647 _allDirectDylibsLoaded(false), _inferredArch(false)
648{
649// fStartCreateReadersTime = mach_absolute_time();
650 if ( opts.architecture() == 0 ) {
651 // command line missing -arch, so guess arch
652 inferArchitecture(opts, archName);
653 }
654
655 const std::vector<Options::FileInfo>& files = opts.getInputFiles();
656 if ( files.size() == 0 )
657 throw "no object files specified";
658 // add all direct object, archives, and dylibs
659 _inputFiles.reserve(files.size());
660 for (std::vector<Options::FileInfo>::const_iterator it = files.begin(); it != files.end(); ++it) {
661 const Options::FileInfo& entry = *it;
662 try {
663 _inputFiles.push_back(this->makeFile(entry, false));
664 }
665 catch (const char* msg) {
666 if ( (strstr(msg, "architecture") != NULL) && !_options.errorOnOtherArchFiles() ) {
667 if ( opts.ignoreOtherArchInputFiles() ) {
668 // ignore, because this is about an architecture not in use
669 }
670 else {
671 warning("ignoring file %s, %s", entry.path, msg);
672 }
673 }
674 else {
675 throwf("in %s, %s", entry.path, msg);
676 }
677 }
678 }
679
680 this->createIndirectDylibs();
681 this->createOpaqueFileSections();
682}
683
684
685
686ld::File* InputFiles::addArchive(ld::File* reader, const Options::FileInfo& info, uint64_t mappedLen)
687{
688 // bump ordinal
689 _nextInputOrdinal += reader->subFileCount();
690
691 // update stats
692 _totalArchiveSize += mappedLen;
693 _totalArchivesLoaded++;
694 return reader;
695}
696
697
698ld::File* InputFiles::addObject(ld::relocatable::File* file, const Options::FileInfo& info, uint64_t mappedLen)
699{
700 // bump ordinal
701 _nextInputOrdinal++;
702
703 // update stats
704 _totalObjectSize += mappedLen;
705 _totalObjectLoaded++;
706 return file;
707}
708
709
710ld::File* InputFiles::addDylib(ld::dylib::File* reader, const Options::FileInfo& info, uint64_t mappedLen)
711{
712 _allDylibs.insert(reader);
713
714 if ( (reader->installPath() == NULL) && !info.options.fBundleLoader ) {
715 // this is a "blank" stub
716 // silently ignore it
717 return reader;
718 }
719 // store options about how dylib will be used in dylib itself
720 if ( info.options.fWeakImport )
721 reader->setForcedWeakLinked();
722 if ( info.options.fReExport )
723 reader->setWillBeReExported();
724 if ( info.options.fUpward ) {
725 if ( _options.outputKind() == Options::kDynamicLibrary )
726 reader->setWillBeUpwardDylib();
727 else
728 warning("ignoring upward dylib option for %s\n", info.path);
729 }
730 if ( info.options.fLazyLoad )
731 reader->setWillBeLazyLoadedDylb();
732
733 // add to map of loaded dylibs
734 const char* installPath = reader->installPath();
735 if ( installPath != NULL ) {
736 InstallNameToDylib::iterator pos = _installPathToDylibs.find(installPath);
737 if ( pos == _installPathToDylibs.end() ) {
738 _installPathToDylibs[strdup(installPath)] = reader;
739 }
740 else {
741 bool dylibOnCommandLineTwice = ( strcmp(pos->second->path(), reader->path()) == 0 );
742 bool isSymlink = false;
743 // ignore if this is a symlink to a dylib we've already loaded
744 if ( !dylibOnCommandLineTwice ) {
745 char existingDylibPath[PATH_MAX];
746 if ( realpath(pos->second->path(), existingDylibPath) != NULL ) {
747 char newDylibPath[PATH_MAX];
748 if ( realpath(reader->path(), newDylibPath) != NULL ) {
749 isSymlink = ( strcmp(existingDylibPath, newDylibPath) == 0 );
750 }
751 }
752 }
753 if ( !dylibOnCommandLineTwice && !isSymlink )
754 warning("dylibs with same install name: %s and %s", pos->second->path(), reader->path());
755 }
756 }
757 else if ( info.options.fBundleLoader )
758 _bundleLoader = reader;
759
760 // log direct readers
761 if ( !_allDirectDylibsLoaded )
762 this->logDylib(reader, false);
763
764 // bump ordinal
765 _nextInputOrdinal++;
766
767 // update stats
768 _totalDylibsLoaded++;
769
770 return reader;
771}
772
773
774bool InputFiles::forEachInitialAtom(ld::File::AtomHandler& handler) const
775{
776 bool didSomething = false;
777 for (std::vector<ld::File*>::const_iterator it=_inputFiles.begin(); it != _inputFiles.end(); ++it) {
778 didSomething |= (*it)->forEachAtom(handler);
779 }
780 if ( didSomething || true ) {
781 switch ( _options.outputKind() ) {
782 case Options::kStaticExecutable:
783 case Options::kDynamicExecutable:
784 // add implicit __dso_handle label
785 handler.doAtom(DSOHandleAtom::_s_atomExecutable);
786 handler.doAtom(DSOHandleAtom::_s_atomAll);
787 if ( _options.pageZeroSize() != 0 )
788 handler.doAtom(*new PageZeroAtom(_options.pageZeroSize()));
789 if ( _options.hasCustomStack() )
790 handler.doAtom(*new CustomStackAtom(_options.customStackSize()));
791 break;
792 case Options::kDynamicLibrary:
793 // add implicit __dso_handle label
794 handler.doAtom(DSOHandleAtom::_s_atomDylib);
795 handler.doAtom(DSOHandleAtom::_s_atomAll);
796 break;
797 case Options::kDynamicBundle:
798 // add implicit __dso_handle label
799 handler.doAtom(DSOHandleAtom::_s_atomBundle);
800 handler.doAtom(DSOHandleAtom::_s_atomAll);
801 break;
802 case Options::kDyld:
803 // add implicit __dso_handle label
804 handler.doAtom(DSOHandleAtom::_s_atomDyld);
805 handler.doAtom(DSOHandleAtom::_s_atomAll);
806 break;
807 case Options::kPreload:
808 // add implicit __mh_preload_header label
809 handler.doAtom(DSOHandleAtom::_s_atomPreload);
810 handler.doAtom(DSOHandleAtom::_s_atomAll);
811 break;
812 case Options::kObjectFile:
813 handler.doAtom(DSOHandleAtom::_s_atomObjectFile);
814 break;
815 case Options::kKextBundle:
816 // add implicit __dso_handle label
817 handler.doAtom(DSOHandleAtom::_s_atomAll);
818 break;
819 }
820 }
821 return didSomething;
822}
823
824
825bool InputFiles::searchLibraries(const char* name, bool searchDylibs, bool searchArchives, bool dataSymbolOnly, ld::File::AtomHandler& handler) const
826{
827 // check each input file
828 for (std::vector<ld::File*>::const_iterator it=_inputFiles.begin(); it != _inputFiles.end(); ++it) {
829 ld::File* file = *it;
830 // if this reader is a static archive that has the symbol we need, pull in all atoms in that module
831 // if this reader is a dylib that exports the symbol we need, have it synthesize an atom for us.
832 ld::dylib::File* dylibFile = dynamic_cast<ld::dylib::File*>(file);
833 ld::archive::File* archiveFile = dynamic_cast<ld::archive::File*>(file);
834 if ( searchDylibs && (dylibFile != NULL) ) {
835 //fprintf(stderr, "searchLibraries(%s), looking in linked %s\n", name, dylibFile->path() );
836 if ( dylibFile->justInTimeforEachAtom(name, handler) ) {
837 // we found a definition in this dylib
838 // done, unless it is a weak definition in which case we keep searching
839 if ( !dylibFile->hasWeakExternals() || !dylibFile->hasWeakDefinition(name))
840 return true;
841 // else continue search for a non-weak definition
842 }
843 }
844 else if ( searchArchives && (archiveFile != NULL) ) {
845 if ( dataSymbolOnly ) {
846 if ( archiveFile->justInTimeDataOnlyforEachAtom(name, handler) ) {
847 if ( _options.traceArchives() )
848 logArchive(file);
849 // found data definition in static library, done
850 return true;
851 }
852 }
853 else {
854 if ( archiveFile->justInTimeforEachAtom(name, handler) ) {
855 if ( _options.traceArchives() )
856 logArchive(file);
857 // found definition in static library, done
858 return true;
859 }
860 }
861 }
862 }
863
864 // search indirect dylibs
865 if ( searchDylibs ) {
866 for (InstallNameToDylib::const_iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); ++it) {
867 ld::dylib::File* dylibFile = it->second;
868 bool searchThisDylib = false;
869 if ( _options.nameSpace() == Options::kTwoLevelNameSpace ) {
870 // for two level namesapce, just check all implicitly linked dylibs
871 searchThisDylib = dylibFile->implicitlyLinked() && !dylibFile->explicitlyLinked();
872 }
873 else {
874 // for flat namespace, check all indirect dylibs
875 searchThisDylib = ! dylibFile->explicitlyLinked();
876 }
877 if ( searchThisDylib ) {
878 //fprintf(stderr, "searchLibraries(%s), looking in implicitly linked %s\n", name, dylibFile->path() );
879 if ( dylibFile->justInTimeforEachAtom(name, handler) ) {
880 // we found a definition in this dylib
881 // done, unless it is a weak definition in which case we keep searching
882 if ( !dylibFile->hasWeakExternals() || !dylibFile->hasWeakDefinition(name))
883 return true;
884 // else continue search for a non-weak definition
885 }
886 }
887 }
888 }
889
890 return false;
891}
892
893
894bool InputFiles::searchWeakDefInDylib(const char* name) const
895{
896 // search all relevant dylibs to see if any of a weak-def with this name
897 for (InstallNameToDylib::const_iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); ++it) {
898 ld::dylib::File* dylibFile = it->second;
899 if ( dylibFile->implicitlyLinked() || dylibFile->explicitlyLinked() ) {
900 if ( dylibFile->hasWeakExternals() && dylibFile->hasWeakDefinition(name) ) {
901 return true;
902 }
903 }
904 }
905 return false;
906}
907
908void InputFiles::dylibs(ld::Internal& state)
909{
910 bool dylibsOK = false;
911 switch ( _options.outputKind() ) {
912 case Options::kDynamicExecutable:
913 case Options::kDynamicLibrary:
914 case Options::kDynamicBundle:
915 dylibsOK = true;
916 break;
917 case Options::kStaticExecutable:
918 case Options::kDyld:
919 case Options::kPreload:
920 case Options::kObjectFile:
921 case Options::kKextBundle:
922 dylibsOK = false;
923 break;
924 }
925
926 // add command line dylibs in order
927 for (std::vector<ld::File*>::const_iterator it=_inputFiles.begin(); it != _inputFiles.end(); ++it) {
928 ld::dylib::File* dylibFile = dynamic_cast<ld::dylib::File*>(*it);
929 // only add dylibs that are not "blank" dylib stubs
930 if ( (dylibFile != NULL) && ((dylibFile->installPath() != NULL) || (dylibFile == _bundleLoader)) ) {
931 if ( dylibsOK )
932 state.dylibs.push_back(dylibFile);
933 else
934 warning("unexpected dylib (%s) on link line", dylibFile->path());
935 }
936 }
937 // add implicitly linked dylibs
938 if ( _options.nameSpace() == Options::kTwoLevelNameSpace ) {
939 for (InstallNameToDylib::const_iterator it=_installPathToDylibs.begin(); it != _installPathToDylibs.end(); ++it) {
940 ld::dylib::File* dylibFile = it->second;
941 if ( dylibFile->implicitlyLinked() && dylibsOK )
942 state.dylibs.push_back(dylibFile);
943 }
944 }
945 // and -bundle_loader
946 state.bundleLoader = _bundleLoader;
947}
948
949
950} // namespace tool
951} // namespace ld
952