]> git.saurik.com Git - apple/ld64.git/blob - src/ld/Options.cpp
0131911afd722bb5a9363e7187a5c2f888444ca1
[apple/ld64.git] / src / ld / Options.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2005-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 <sys/types.h>
27 #include <sys/stat.h>
28 #include <mach/vm_prot.h>
29 #include <sys/sysctl.h>
30 #include <mach-o/dyld.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <spawn.h>
35 #include <cxxabi.h>
36 #include <Availability.h>
37
38 #include <vector>
39
40 #include "Options.h"
41 #include "Architectures.hpp"
42 #include "MachOFileAbstraction.hpp"
43 #include "Snapshot.h"
44
45 // upward dependency on lto::version()
46 namespace lto {
47 extern const char* version();
48 }
49
50 // magic to place command line in crash reports
51 const int crashreporterBufferSize = 2000;
52 static char crashreporterBuffer[crashreporterBufferSize];
53 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
54 #include <CrashReporterClient.h>
55 // hack until ld does not need to build on 10.6 anymore
56 struct crashreporter_annotations_t gCRAnnotations
57 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
58 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
59 #else
60 extern "C" char* __crashreporter_info__;
61 __attribute__((used))
62 char* __crashreporter_info__ = crashreporterBuffer;
63 #endif
64
65
66 static bool sEmitWarnings = true;
67 static bool sFatalWarnings = false;
68 static const char* sWarningsSideFilePath = NULL;
69 static FILE* sWarningsSideFile = NULL;
70 static int sWarningsCount = 0;
71
72 void warning(const char* format, ...)
73 {
74 ++sWarningsCount;
75 if ( sEmitWarnings ) {
76 va_list list;
77 if ( sWarningsSideFilePath != NULL ) {
78 if ( sWarningsSideFile == NULL )
79 sWarningsSideFile = fopen(sWarningsSideFilePath, "a");
80 }
81 va_start(list, format);
82 fprintf(stderr, "ld: warning: ");
83 vfprintf(stderr, format, list);
84 fprintf(stderr, "\n");
85 if ( sWarningsSideFile != NULL ) {
86 fprintf(sWarningsSideFile, "ld: warning: ");
87 vfprintf(sWarningsSideFile, format, list);
88 fprintf(sWarningsSideFile, "\n");
89 fflush(sWarningsSideFile);
90 }
91 va_end(list);
92 }
93 }
94
95 void throwf(const char* format, ...)
96 {
97 va_list list;
98 char* p;
99 va_start(list, format);
100 vasprintf(&p, format, list);
101 va_end(list);
102
103 const char* t = p;
104 throw t;
105 }
106
107 bool Options::FileInfo::checkFileExists(const char *p)
108 {
109 struct stat statBuffer;
110 if (p == NULL) p = path;
111 if ( stat(p, &statBuffer) == 0 ) {
112 if (p != path) path = strdup(p);
113 fileLen = statBuffer.st_size;
114 modTime = statBuffer.st_mtime;
115 return true;
116 }
117 return false;
118 }
119
120 Options::Options(int argc, const char* argv[])
121 : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fArchitectureName("unknown"), fOutputKind(kDynamicExecutable),
122 fHasPreferredSubType(false), fArchSupportsThumb2(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
123 fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fErrorOnOtherArchFiles(false), fForceSubtypeAll(false),
124 fInterposeMode(kInterposeNone), fDeadStrip(false), fNameSpace(kTwoLevelNameSpace),
125 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL), fFinalName(NULL), fEntryName("start"),
126 fBaseAddress(0), fMaxAddress(0x7FFFFFFFFFFFFFFFLL),
127 fBaseWritableAddress(0), fSplitSegs(false),
128 fExportMode(kExportDefault), fLibrarySearchMode(kSearchDylibAndArchiveInEachDir),
129 fUndefinedTreatment(kUndefinedError), fMessagesPrefixedWithArchitecture(true),
130 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchNonWeak),
131 fClientName(NULL),
132 fUmbrellaName(NULL), fInitFunctionName(NULL), fDotOutputFile(NULL), fExecutablePath(NULL),
133 fBundleLoader(NULL), fDtraceScriptName(NULL), fSegAddrTablePath(NULL), fMapPath(NULL),
134 fDyldInstallPath("/usr/lib/dyld"), fTempLtoObjectPath(NULL), fOverridePathlibLTO(NULL),
135 fZeroPageSize(ULLONG_MAX), fStackSize(0), fStackAddr(0), fSourceVersion(0), fSDKVersion(0), fExecutableStack(false),
136 fNonExecutableHeap(false), fDisableNonExecutableHeap(false),
137 fMinimumHeaderPad(32), fSegmentAlignment(4096),
138 fCommonsMode(kCommonsIgnoreDylibs), fUUIDMode(kUUIDContent), fLocalSymbolHandling(kLocalSymbolsAll), fWarnCommons(false),
139 fVerbose(false), fKeepRelocations(false), fWarnStabs(false),
140 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
141 fSharedRegionEligible(false), fPrintOrderFileStatistics(false),
142 fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fPIEOnCommandLine(false),
143 fDisablePositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
144 fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false), fKextsUseStubs(false),
145 fUsingLazyDylibLinking(false), fEncryptable(true),
146 fOrderData(true), fMarkDeadStrippableDylib(false),
147 fMakeCompressedDyldInfo(true), fMakeCompressedDyldInfoForceOff(false), fNoEHLabels(false),
148 fAllowCpuSubtypeMismatches(false), fUseSimplifiedDylibReExports(false),
149 fObjCABIVersion2Override(false), fObjCABIVersion1Override(false), fCanUseUpwardDylib(false),
150 fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false),
151 fLinkingMainExecutable(false), fForFinalLinkedImage(false), fForStatic(false),
152 fForDyld(false), fMakeTentativeDefinitionsReal(false), fWhyLoad(false), fRootSafe(false),
153 fSetuidSafe(false), fImplicitlyLinkPublicDylibs(true), fAddCompactUnwindEncoding(true),
154 fWarnCompactUnwind(false), fRemoveDwarfUnwindIfCompactExists(false),
155 fAutoOrderInitializers(true), fOptimizeZeroFill(true), fMergeZeroFill(false), fLogObjectFiles(false),
156 fLogAllFiles(false), fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false),
157 fOutputSlidable(false), fWarnWeakExports(false),
158 fObjcGcCompaction(false), fObjCGc(false), fObjCGcOnly(false),
159 fDemangle(false), fTLVSupport(false),
160 fVersionLoadCommand(false), fVersionLoadCommandForcedOn(false),
161 fVersionLoadCommandForcedOff(false), fFunctionStartsLoadCommand(false),
162 fFunctionStartsForcedOn(false), fFunctionStartsForcedOff(false),
163 fDataInCodeInfoLoadCommand(false), fDataInCodeInfoLoadCommandForcedOn(false), fDataInCodeInfoLoadCommandForcedOff(false),
164 fCanReExportSymbols(false), fObjcCategoryMerging(true), fPageAlignDataAtoms(false),
165 fNeedsThreadLoadCommand(false), fEntryPointLoadCommand(false),
166 fEntryPointLoadCommandForceOn(false), fEntryPointLoadCommandForceOff(false),
167 fSourceVersionLoadCommand(false),
168 fSourceVersionLoadCommandForceOn(false), fSourceVersionLoadCommandForceOff(false),
169 fDependentDRInfo(false), fDependentDRInfoForcedOn(false), fDependentDRInfoForcedOff(false),
170 fDebugInfoStripping(kDebugInfoMinimal), fTraceOutputFile(NULL),
171 fMacVersionMin(ld::macVersionUnset), fIOSVersionMin(ld::iOSVersionUnset),
172 fSaveTempFiles(false), fSnapshotRequested(false), fPipelineFifo(NULL)
173 {
174 this->checkForClassic(argc, argv);
175 this->parsePreCommandLineEnvironmentSettings();
176 this->parse(argc, argv);
177 this->parsePostCommandLineEnvironmentSettings();
178 this->reconfigureDefaults();
179 this->checkIllegalOptionCombinations();
180 }
181
182 Options::~Options()
183 {
184 }
185
186 bool Options::errorBecauseOfWarnings() const
187 {
188 return (sFatalWarnings && (sWarningsCount > 0));
189 }
190
191
192 const char* Options::installPath() const
193 {
194 if ( fDylibInstallName != NULL )
195 return fDylibInstallName;
196 else if ( fFinalName != NULL )
197 return fFinalName;
198 else
199 return fOutputFile;
200 }
201
202
203 bool Options::interposable(const char* name) const
204 {
205 switch ( fInterposeMode ) {
206 case kInterposeNone:
207 return false;
208 case kInterposeAllExternal:
209 return true;
210 case kInterposeSome:
211 return fInterposeList.contains(name);
212 }
213 throw "internal error";
214 }
215
216
217 bool Options::printWhyLive(const char* symbolName) const
218 {
219 return ( fWhyLive.find(symbolName) != fWhyLive.end() );
220 }
221
222
223 const char* Options::dotOutputFile()
224 {
225 return fDotOutputFile;
226 }
227
228
229 bool Options::hasWildCardExportRestrictList() const
230 {
231 // has -exported_symbols_list which contains some wildcards
232 return ((fExportMode == kExportSome) && fExportSymbols.hasWildCards());
233 }
234
235 bool Options::hasWeakBitTweaks() const
236 {
237 // has -exported_symbols_list which contains some wildcards
238 return (!fForceWeakSymbols.empty() || !fForceNotWeakSymbols.empty());
239 }
240
241 bool Options::allGlobalsAreDeadStripRoots() const
242 {
243 // -exported_symbols_list means globals are not exported by default
244 if ( fExportMode == kExportSome )
245 return false;
246 //
247 switch ( fOutputKind ) {
248 case Options::kDynamicExecutable:
249 case Options::kStaticExecutable:
250 case Options::kPreload:
251 // by default unused globals in a main executable are stripped
252 return false;
253 case Options::kDynamicLibrary:
254 case Options::kDynamicBundle:
255 case Options::kObjectFile:
256 case Options::kDyld:
257 case Options::kKextBundle:
258 return true;
259 }
260 return false;
261 }
262
263
264 bool Options::keepRelocations()
265 {
266 return fKeepRelocations;
267 }
268
269 bool Options::warnStabs()
270 {
271 return fWarnStabs;
272 }
273
274 const char* Options::executablePath()
275 {
276 return fExecutablePath;
277 }
278
279
280 uint32_t Options::initialSegProtection(const char* segName) const
281 {
282 for(std::vector<Options::SegmentProtect>::const_iterator it = fCustomSegmentProtections.begin(); it != fCustomSegmentProtections.end(); ++it) {
283 if ( strcmp(it->name, segName) == 0 ) {
284 return it->init;
285 }
286 }
287 if ( strcmp(segName, "__PAGEZERO") == 0 ) {
288 return 0;
289 }
290 else if ( strcmp(segName, "__TEXT") == 0 ) {
291 return VM_PROT_READ | VM_PROT_EXECUTE;
292 }
293 else if ( strcmp(segName, "__LINKEDIT") == 0 ) {
294 return VM_PROT_READ;
295 }
296
297 // all others default to read-write
298 return VM_PROT_READ | VM_PROT_WRITE;
299 }
300
301 uint32_t Options::maxSegProtection(const char* segName) const
302 {
303 // iPhoneOS always uses same protection for max and initial
304 // <rdar://problem/11663436> simulator apps need to use MacOSX max-prot
305 if ( (fIOSVersionMin != ld::iOSVersionUnset) && (fArchitecture != CPU_TYPE_I386) )
306 return initialSegProtection(segName);
307
308 for(std::vector<Options::SegmentProtect>::const_iterator it = fCustomSegmentProtections.begin(); it != fCustomSegmentProtections.end(); ++it) {
309 if ( strcmp(it->name, segName) == 0 ) {
310 return it->max;
311 }
312 }
313 if ( strcmp(segName, "__PAGEZERO") == 0 ) {
314 return 0;
315 }
316 // all others default to all
317 return VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
318 }
319
320 uint64_t Options::segPageSize(const char* segName) const
321 {
322 for(std::vector<SegmentSize>::const_iterator it=fCustomSegmentSizes.begin(); it != fCustomSegmentSizes.end(); ++it) {
323 if ( strcmp(it->name, segName) == 0 )
324 return it->size;
325 }
326 return fSegmentAlignment;
327 }
328
329 uint64_t Options::customSegmentAddress(const char* segName) const
330 {
331 for(std::vector<SegmentStart>::const_iterator it=fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
332 if ( strcmp(it->name, segName) == 0 )
333 return it->address;
334 }
335 // if custom stack in use, model as segment with custom address
336 if ( (fStackSize != 0) && (strcmp("__UNIXSTACK", segName) == 0) )
337 return fStackAddr - fStackSize;
338 return 0;
339 }
340
341 bool Options::hasCustomSegmentAddress(const char* segName) const
342 {
343 for(std::vector<SegmentStart>::const_iterator it=fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
344 if ( strcmp(it->name, segName) == 0 )
345 return true;
346 }
347 // if custom stack in use, model as segment with custom address
348 if ( (fStackSize != 0) && (strcmp("__UNIXSTACK", segName) == 0) )
349 return true;
350 return false;
351 }
352
353 bool Options::hasCustomSectionAlignment(const char* segName, const char* sectName) const
354 {
355 for (std::vector<SectionAlignment>::const_iterator it = fSectionAlignments.begin(); it != fSectionAlignments.end(); ++it) {
356 if ( (strcmp(it->segmentName, segName) == 0) && (strcmp(it->sectionName, sectName) == 0) )
357 return true;
358 }
359 return false;
360 }
361
362 uint8_t Options::customSectionAlignment(const char* segName, const char* sectName) const
363 {
364 for (std::vector<SectionAlignment>::const_iterator it = fSectionAlignments.begin(); it != fSectionAlignments.end(); ++it) {
365 if ( (strcmp(it->segmentName, segName) == 0) && (strcmp(it->sectionName, sectName) == 0) )
366 return it->alignment;
367 }
368 return 0;
369 }
370
371
372 bool Options::hasExportedSymbolOrder()
373 {
374 return (fExportSymbolsOrder.size() > 0);
375 }
376
377 bool Options::exportedSymbolOrder(const char* sym, unsigned int* order) const
378 {
379 NameToOrder::const_iterator pos = fExportSymbolsOrder.find(sym);
380 if ( pos != fExportSymbolsOrder.end() ) {
381 *order = pos->second;
382 return true;
383 }
384 else {
385 *order = 0xFFFFFFFF;
386 return false;
387 }
388 }
389
390 void Options::loadSymbolOrderFile(const char* fileOfExports, NameToOrder& orderMapping)
391 {
392 // read in whole file
393 int fd = ::open(fileOfExports, O_RDONLY, 0);
394 if ( fd == -1 )
395 throwf("can't open -exported_symbols_order file: %s", fileOfExports);
396 struct stat stat_buf;
397 ::fstat(fd, &stat_buf);
398 char* p = (char*)malloc(stat_buf.st_size);
399 if ( p == NULL )
400 throwf("can't process -exported_symbols_order file: %s", fileOfExports);
401
402 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
403 throwf("can't read -exported_symbols_order file: %s", fileOfExports);
404
405 ::close(fd);
406
407 // parse into symbols and add to unordered_set
408 unsigned int count = 0;
409 char * const end = &p[stat_buf.st_size];
410 enum { lineStart, inSymbol, inComment } state = lineStart;
411 char* symbolStart = NULL;
412 for (char* s = p; s < end; ++s ) {
413 switch ( state ) {
414 case lineStart:
415 if ( *s =='#' ) {
416 state = inComment;
417 }
418 else if ( !isspace(*s) ) {
419 state = inSymbol;
420 symbolStart = s;
421 }
422 break;
423 case inSymbol:
424 if ( (*s == '\n') || (*s == '\r') ) {
425 *s = '\0';
426 // removing any trailing spaces
427 char* last = s-1;
428 while ( isspace(*last) ) {
429 *last = '\0';
430 --last;
431 }
432 orderMapping[symbolStart] = ++count;
433 symbolStart = NULL;
434 state = lineStart;
435 }
436 break;
437 case inComment:
438 if ( (*s == '\n') || (*s == '\r') )
439 state = lineStart;
440 break;
441 }
442 }
443 if ( state == inSymbol ) {
444 warning("missing line-end at end of file \"%s\"", fileOfExports);
445 int len = end-symbolStart+1;
446 char* temp = new char[len];
447 strlcpy(temp, symbolStart, len);
448
449 // remove any trailing spaces
450 char* last = &temp[len-2];
451 while ( isspace(*last) ) {
452 *last = '\0';
453 --last;
454 }
455 orderMapping[temp] = ++count;
456 }
457
458 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
459 }
460
461 bool Options::forceWeak(const char* symbolName) const
462 {
463 return fForceWeakSymbols.contains(symbolName);
464 }
465
466 bool Options::forceNotWeak(const char* symbolName) const
467 {
468 return fForceNotWeakSymbols.contains(symbolName);
469 }
470
471 bool Options::forceWeakNonWildCard(const char* symbolName) const
472 {
473 return fForceWeakSymbols.containsNonWildcard(symbolName);
474 }
475
476 bool Options::forceNotWeakNonWildcard(const char* symbolName) const
477 {
478 return fForceNotWeakSymbols.containsNonWildcard(symbolName);
479 }
480
481
482 bool Options::shouldExport(const char* symbolName) const
483 {
484 switch (fExportMode) {
485 case kExportSome:
486 return fExportSymbols.contains(symbolName);
487 case kDontExportSome:
488 return ! fDontExportSymbols.contains(symbolName);
489 case kExportDefault:
490 return true;
491 }
492 throw "internal error";
493 }
494
495 bool Options::shouldReExport(const char* symbolName) const
496 {
497 return fReExportSymbols.contains(symbolName);
498 }
499
500 bool Options::keepLocalSymbol(const char* symbolName) const
501 {
502 switch (fLocalSymbolHandling) {
503 case kLocalSymbolsAll:
504 return true;
505 case kLocalSymbolsNone:
506 return false;
507 case kLocalSymbolsSelectiveInclude:
508 return fLocalSymbolsIncluded.contains(symbolName);
509 case kLocalSymbolsSelectiveExclude:
510 return ! fLocalSymbolsExcluded.contains(symbolName);
511 }
512 throw "internal error";
513 }
514
515 void Options::setArchitecture(cpu_type_t type, cpu_subtype_t subtype)
516 {
517 for (const ArchInfo* t=archInfoArray; t->archName != NULL; ++t) {
518 if ( (type == t->cpuType) && (subtype == t->cpuSubType) ) {
519 fArchitecture = type;
520 fSubArchitecture = subtype;
521 fArchitectureName = t->archName;
522 fHasPreferredSubType = t->isSubType;
523 fArchSupportsThumb2 = t->supportsThumb2;
524 switch ( type ) {
525 case CPU_TYPE_I386:
526 case CPU_TYPE_X86_64:
527 if ( (fMacVersionMin == ld::macVersionUnset) && (fIOSVersionMin == ld::iOSVersionUnset) && (fOutputKind != Options::kObjectFile) ) {
528 #ifdef DEFAULT_MACOSX_MIN_VERSION
529 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
530 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
531 #else
532 warning("-macosx_version_min not specified, assuming 10.6");
533 fMacVersionMin = ld::mac10_6;
534 #endif
535 }
536 if ( !fMakeCompressedDyldInfo && minOS(ld::mac10_6, ld::iOS_3_1) && !fMakeCompressedDyldInfoForceOff )
537 fMakeCompressedDyldInfo = true;
538 break;
539 case CPU_TYPE_ARM:
540 if ( (fMacVersionMin == ld::macVersionUnset) && (fIOSVersionMin == ld::iOSVersionUnset) && (fOutputKind != Options::kObjectFile) ) {
541 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
542 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION);
543 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION);
544 #elif defined(DEFAULT_MACOSX_MIN_VERSION)
545 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
546 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
547 #else
548 warning("-macosx_version_min not specified, assuming 10.6");
549 fMacVersionMin = ld::mac10_6;
550 #endif
551 }
552 if ( !fMakeCompressedDyldInfo && minOS(ld::mac10_6, ld::iOS_3_1) && !fMakeCompressedDyldInfoForceOff )
553 fMakeCompressedDyldInfo = true;
554 break;
555 }
556 fLinkSnapshot.recordArch(fArchitectureName);
557 return;
558 }
559 }
560 fArchitectureName = "unknown architecture";
561 }
562
563 void Options::parseArch(const char* arch)
564 {
565 if ( arch == NULL )
566 throw "-arch must be followed by an architecture string";
567 for (const ArchInfo* t=archInfoArray; t->archName != NULL; ++t) {
568 if ( strcmp(t->archName,arch) == 0 ) {
569 fArchitectureName = arch;
570 fArchitecture = t->cpuType;
571 fSubArchitecture = t->cpuSubType;
572 fHasPreferredSubType = t->isSubType;
573 fArchSupportsThumb2 = t->supportsThumb2;
574 return;
575 }
576 }
577 throwf("unknown/unsupported architecture name for: -arch %s", arch);
578 }
579
580 bool Options::checkForFile(const char* format, const char* dir, const char* rootName, FileInfo& result) const
581 {
582 char possiblePath[strlen(dir)+strlen(rootName)+strlen(format)+8];
583 sprintf(possiblePath, format, dir, rootName);
584 bool found = result.checkFileExists(possiblePath);
585 if ( fTraceDylibSearching )
586 printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), possiblePath);
587 return found;
588 }
589
590
591 Options::FileInfo Options::findLibrary(const char* rootName, bool dylibsOnly)
592 {
593 FileInfo result;
594 const int rootNameLen = strlen(rootName);
595 // if rootName ends in .o there is no .a vs .dylib choice
596 if ( (rootNameLen > 3) && (strcmp(&rootName[rootNameLen-2], ".o") == 0) ) {
597 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
598 it != fLibrarySearchPaths.end();
599 it++) {
600 const char* dir = *it;
601 if ( checkForFile("%s/%s", dir, rootName, result) )
602 return result;
603 }
604 }
605 else {
606 bool lookForDylibs = ( fOutputKind != Options::kDyld);
607 switch ( fLibrarySearchMode ) {
608 case kSearchAllDirsForDylibsThenAllDirsForArchives:
609 // first look in all directories for just for dylibs
610 if ( lookForDylibs ) {
611 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
612 it != fLibrarySearchPaths.end();
613 it++) {
614 const char* dir = *it;
615 if ( checkForFile("%s/lib%s.dylib", dir, rootName, result) )
616 return result;
617 }
618 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
619 it != fLibrarySearchPaths.end();
620 it++) {
621 const char* dir = *it;
622 if ( checkForFile("%s/lib%s.so", dir, rootName, result) )
623 return result;
624 }
625 }
626 // next look in all directories for just for archives
627 if ( !dylibsOnly ) {
628 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
629 it != fLibrarySearchPaths.end();
630 it++) {
631 const char* dir = *it;
632 if ( checkForFile("%s/lib%s.a", dir, rootName, result) )
633 return result;
634 }
635 }
636 break;
637
638 case kSearchDylibAndArchiveInEachDir:
639 // look in each directory for just for a dylib then for an archive
640 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
641 it != fLibrarySearchPaths.end();
642 it++) {
643 const char* dir = *it;
644 if ( lookForDylibs && checkForFile("%s/lib%s.dylib", dir, rootName, result) )
645 return result;
646 if ( lookForDylibs && checkForFile("%s/lib%s.so", dir, rootName, result) )
647 return result;
648 if ( !dylibsOnly && checkForFile("%s/lib%s.a", dir, rootName, result) )
649 return result;
650 }
651 break;
652 }
653 }
654 throwf("library not found for -l%s", rootName);
655 }
656
657 Options::FileInfo Options::findFramework(const char* frameworkName)
658 {
659 if ( frameworkName == NULL )
660 throw "-framework missing next argument";
661 char temp[strlen(frameworkName)+1];
662 strcpy(temp, frameworkName);
663 const char* name = temp;
664 const char* suffix = NULL;
665 char* comma = strchr(temp, ',');
666 if ( comma != NULL ) {
667 *comma = '\0';
668 suffix = &comma[1];
669 }
670 return findFramework(name, suffix);
671 }
672
673 Options::FileInfo Options::findFramework(const char* rootName, const char* suffix)
674 {
675 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
676 it != fFrameworkSearchPaths.end();
677 it++) {
678 // ??? Shouldn't we be using String here and just initializing it?
679 // ??? Use str.c_str () to pull out the string for the stat call.
680 const char* dir = *it;
681 char possiblePath[PATH_MAX];
682 strcpy(possiblePath, dir);
683 strcat(possiblePath, "/");
684 strcat(possiblePath, rootName);
685 strcat(possiblePath, ".framework/");
686 strcat(possiblePath, rootName);
687 if ( suffix != NULL ) {
688 char realPath[PATH_MAX];
689 // no symlink in framework to suffix variants, so follow main symlink
690 if ( realpath(possiblePath, realPath) != NULL ) {
691 strcpy(possiblePath, realPath);
692 strcat(possiblePath, suffix);
693 }
694 }
695 FileInfo result;
696 bool found = result.checkFileExists(possiblePath);
697 if ( fTraceDylibSearching )
698 printf("[Logging for XBS]%sfound framework: '%s'\n",
699 (found ? " " : " not "), possiblePath);
700 if ( found ) {
701 return result;
702 }
703 }
704 // try without suffix
705 if ( suffix != NULL )
706 return findFramework(rootName, NULL);
707 else
708 throwf("framework not found %s", rootName);
709 }
710
711 Options::FileInfo Options::findFile(const char* path) const
712 {
713 FileInfo result;
714
715 // if absolute path and not a .o file, the use SDK prefix
716 if ( (path[0] == '/') && (strcmp(&path[strlen(path)-2], ".o") != 0) ) {
717 const int pathLen = strlen(path);
718 for (std::vector<const char*>::const_iterator it = fSDKPaths.begin(); it != fSDKPaths.end(); it++) {
719 // ??? Shouldn't we be using String here?
720 const char* sdkPathDir = *it;
721 const int sdkPathDirLen = strlen(sdkPathDir);
722 char possiblePath[sdkPathDirLen+pathLen+4];
723 strcpy(possiblePath, sdkPathDir);
724 if ( possiblePath[sdkPathDirLen-1] == '/' )
725 possiblePath[sdkPathDirLen-1] = '\0';
726 strcat(possiblePath, path);
727 if ( result.checkFileExists(possiblePath) ) {
728 return result;
729 }
730 }
731 }
732 // try raw path
733 if ( result.checkFileExists(path) ) {
734 return result;
735 }
736
737 // try @executable_path substitution
738 if ( (strncmp(path, "@executable_path/", 17) == 0) && (fExecutablePath != NULL) ) {
739 char newPath[strlen(fExecutablePath) + strlen(path)];
740 strcpy(newPath, fExecutablePath);
741 char* addPoint = strrchr(newPath,'/');
742 if ( addPoint != NULL )
743 strcpy(&addPoint[1], &path[17]);
744 else
745 strcpy(newPath, &path[17]);
746 if ( result.checkFileExists(newPath) ) {
747 return result;
748 }
749 }
750
751 // not found
752 throwf("file not found: %s", path);
753 }
754
755 Options::FileInfo Options::findFileUsingPaths(const char* path) const
756 {
757 FileInfo result;
758
759 const char* lastSlash = strrchr(path, '/');
760 const char* leafName = (lastSlash == NULL) ? path : &lastSlash[1];
761
762 // Is this in a framework?
763 // /path/Foo.framework/Foo ==> true (Foo)
764 // /path/Foo.framework/Frameworks/Bar.framework/Bar ==> true (Bar)
765 // /path/Foo.framework/Resources/Bar ==> false
766 bool isFramework = false;
767 if ( lastSlash != NULL ) {
768 char frameworkDir[strlen(leafName) + 20];
769 strcpy(frameworkDir, "/");
770 strcat(frameworkDir, leafName);
771 strcat(frameworkDir, ".framework/");
772 if ( strstr(path, frameworkDir) != NULL )
773 isFramework = true;
774 }
775
776 // These are abbreviated versions of the routines findFramework and findLibrary above
777 // because we already know the final name of the file that we're looking for and so
778 // don't need to try variations, just paths. We do need to add the additional bits
779 // onto the framework path though.
780 if ( isFramework ) {
781 for (std::vector<const char*>::const_iterator it = fFrameworkSearchPaths.begin();
782 it != fFrameworkSearchPaths.end();
783 it++) {
784 const char* dir = *it;
785 char possiblePath[PATH_MAX];
786 strcpy(possiblePath, dir);
787 strcat(possiblePath, "/");
788 strcat(possiblePath, leafName);
789 strcat(possiblePath, ".framework");
790
791 //fprintf(stderr,"Finding Framework: %s/%s, leafName=%s\n", possiblePath, leafName, leafName);
792 if ( checkForFile("%s/%s", possiblePath, leafName, result) )
793 return result;
794 }
795 }
796 else {
797 // if this is a .dylib inside a framework, do not search -L paths
798 // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
799 int leafLen = strlen(leafName);
800 bool embeddedDylib = ( (leafLen > 6)
801 && (strcmp(&leafName[leafLen-6], ".dylib") == 0)
802 && (strstr(path, ".framework/") != NULL) );
803 if ( !embeddedDylib ) {
804 for (std::vector<const char*>::const_iterator it = fLibrarySearchPaths.begin();
805 it != fLibrarySearchPaths.end();
806 it++) {
807 const char* dir = *it;
808 //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
809 if ( checkForFile("%s/%s", dir, leafName, result) )
810 return result;
811 }
812 }
813 }
814
815 // If we didn't find it fall back to findFile.
816 return findFile(path);
817 }
818
819
820 void Options::parseSegAddrTable(const char* segAddrPath, const char* installPth)
821 {
822 FILE* file = fopen(segAddrPath, "r");
823 if ( file == NULL ) {
824 warning("-seg_addr_table file cannot be read: %s", segAddrPath);
825 return;
826 }
827
828 char path[PATH_MAX];
829 uint64_t firstColumAddress = 0;
830 uint64_t secondColumAddress = 0;
831 bool hasSecondColumn = false;
832 while ( fgets(path, PATH_MAX, file) != NULL ) {
833 path[PATH_MAX-1] = '\0';
834 char* eol = strchr(path, '\n');
835 if ( eol != NULL )
836 *eol = '\0';
837 // ignore lines not starting with 0x number
838 if ( (path[0] == '0') && (path[1] == 'x') ) {
839 char* p;
840 firstColumAddress = strtoull(path, &p, 16);
841 while ( isspace(*p) )
842 ++p;
843 // see if second column is a number
844 if ( (p[0] == '0') && (p[1] == 'x') ) {
845 secondColumAddress = strtoull(p, &p, 16);
846 hasSecondColumn = true;
847 while ( isspace(*p) )
848 ++p;
849 }
850 while ( isspace(*p) )
851 ++p;
852 if ( p[0] == '/' ) {
853 // remove any trailing whitespace
854 for(char* end = eol-1; (end > p) && isspace(*end); --end)
855 *end = '\0';
856 // see if this line is for the dylib being linked
857 if ( strcmp(p, installPth) == 0 ) {
858 fBaseAddress = firstColumAddress;
859 if ( hasSecondColumn ) {
860 fBaseWritableAddress = secondColumAddress;
861 fSplitSegs = true;
862 }
863 break; // out of while loop
864 }
865 }
866 }
867 }
868
869 fclose(file);
870 }
871
872 void Options::loadFileList(const char* fileOfPaths, ld::File::Ordinal baseOrdinal)
873 {
874 FILE* file;
875 const char* comma = strrchr(fileOfPaths, ',');
876 const char* prefix = NULL;
877 if ( comma != NULL ) {
878 // <rdar://problem/5907981> -filelist fails with comma in path
879 file = fopen(fileOfPaths, "r");
880 if ( file == NULL ) {
881 prefix = comma+1;
882 int realFileOfPathsLen = comma-fileOfPaths;
883 char realFileOfPaths[realFileOfPathsLen+1];
884 strncpy(realFileOfPaths,fileOfPaths, realFileOfPathsLen);
885 realFileOfPaths[realFileOfPathsLen] = '\0';
886 file = fopen(realFileOfPaths, "r");
887 if ( file == NULL )
888 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", realFileOfPaths, errno, strerror(errno));
889 }
890 }
891 else {
892 file = fopen(fileOfPaths, "r");
893 if ( file == NULL )
894 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", fileOfPaths, errno, strerror(errno));
895 }
896
897 char path[PATH_MAX];
898 ld::File::Ordinal previousOrdinal = baseOrdinal;
899 while ( fgets(path, PATH_MAX, file) != NULL ) {
900 path[PATH_MAX-1] = '\0';
901 char* eol = strchr(path, '\n');
902 if ( eol != NULL )
903 *eol = '\0';
904 if ( prefix != NULL ) {
905 char builtPath[strlen(prefix)+strlen(path)+2];
906 strcpy(builtPath, prefix);
907 strcat(builtPath, "/");
908 strcat(builtPath, path);
909 if (fPipelineFifo != NULL) {
910 FileInfo info = FileInfo(builtPath);
911 info.ordinal = previousOrdinal.nextFileListOrdinal();
912 previousOrdinal = info.ordinal;
913 info.fromFileList = true;
914 fInputFiles.push_back(info);
915 } else {
916 FileInfo info = findFile(builtPath);
917 info.ordinal = previousOrdinal.nextFileListOrdinal();
918 previousOrdinal = info.ordinal;
919 info.fromFileList = true;
920 fInputFiles.push_back(info);
921 }
922 }
923 else {
924 if (fPipelineFifo != NULL) {
925 FileInfo info = FileInfo(path);
926 info.ordinal = previousOrdinal.nextFileListOrdinal();
927 previousOrdinal = info.ordinal;
928 info.fromFileList = true;
929 fInputFiles.push_back(info);
930 } else {
931 FileInfo info = findFile(path);
932 info.ordinal = previousOrdinal.nextFileListOrdinal();
933 previousOrdinal = info.ordinal;
934 info.fromFileList = true;
935 fInputFiles.push_back(info);
936 }
937 }
938 }
939 fclose(file);
940 }
941
942
943 void Options::SetWithWildcards::remove(const NameSet& toBeRemoved)
944 {
945 for(NameSet::const_iterator it=toBeRemoved.begin(); it != toBeRemoved.end(); ++it) {
946 const char* symbolName = *it;
947 NameSet::iterator pos = fRegular.find(symbolName);
948 if ( pos != fRegular.end() )
949 fRegular.erase(pos);
950 }
951 }
952
953 bool Options::SetWithWildcards::hasWildCards(const char* symbol)
954 {
955 // an exported symbol name containing *, ?, or [ requires wildcard matching
956 return ( strpbrk(symbol, "*?[") != NULL );
957 }
958
959 void Options::SetWithWildcards::insert(const char* symbol)
960 {
961 if ( hasWildCards(symbol) )
962 fWildCard.push_back(symbol);
963 else
964 fRegular.insert(symbol);
965 }
966
967 bool Options::SetWithWildcards::contains(const char* symbol) const
968 {
969 // first look at hash table on non-wildcard symbols
970 if ( fRegular.find(symbol) != fRegular.end() )
971 return true;
972 // next walk list of wild card symbols looking for a match
973 for(std::vector<const char*>::const_iterator it = fWildCard.begin(); it != fWildCard.end(); ++it) {
974 if ( wildCardMatch(*it, symbol) )
975 return true;
976 }
977 return false;
978 }
979
980 bool Options::SetWithWildcards::containsNonWildcard(const char* symbol) const
981 {
982 // look at hash table on non-wildcard symbols
983 return ( fRegular.find(symbol) != fRegular.end() );
984 }
985
986
987
988 bool Options::SetWithWildcards::inCharRange(const char*& p, unsigned char c) const
989 {
990 ++p; // find end
991 const char* b = p;
992 while ( *p != '\0' ) {
993 if ( *p == ']') {
994 const char* e = p;
995 // found beginining [ and ending ]
996 unsigned char last = '\0';
997 for ( const char* s = b; s < e; ++s ) {
998 if ( *s == '-' ) {
999 unsigned char next = *(++s);
1000 if ( (last <= c) && (c <= next) )
1001 return true;
1002 ++s;
1003 }
1004 else {
1005 if ( *s == c )
1006 return true;
1007 last = *s;
1008 }
1009 }
1010 return false;
1011 }
1012 ++p;
1013 }
1014 return false;
1015 }
1016
1017 bool Options::SetWithWildcards::wildCardMatch(const char* pattern, const char* symbol) const
1018 {
1019 const char* s = symbol;
1020 for (const char* p = pattern; *p != '\0'; ++p) {
1021 switch ( *p ) {
1022 case '*':
1023 if ( p[1] == '\0' )
1024 return true;
1025 for (const char* t = s; *t != '\0'; ++t) {
1026 if ( wildCardMatch(&p[1], t) )
1027 return true;
1028 }
1029 return false;
1030 case '?':
1031 if ( *s == '\0' )
1032 return false;
1033 ++s;
1034 break;
1035 case '[':
1036 if ( ! inCharRange(p, *s) )
1037 return false;
1038 ++s;
1039 break;
1040 default:
1041 if ( *s != *p )
1042 return false;
1043 ++s;
1044 }
1045 }
1046 return (*s == '\0');
1047 }
1048
1049
1050 void Options::loadExportFile(const char* fileOfExports, const char* option, SetWithWildcards& set)
1051 {
1052 if ( fileOfExports == NULL )
1053 throwf("missing file after %s", option);
1054 // read in whole file
1055 int fd = ::open(fileOfExports, O_RDONLY, 0);
1056 if ( fd == -1 )
1057 throwf("can't open %s file: %s", option, fileOfExports);
1058 struct stat stat_buf;
1059 ::fstat(fd, &stat_buf);
1060 char* p = (char*)malloc(stat_buf.st_size);
1061 if ( p == NULL )
1062 throwf("can't process %s file: %s", option, fileOfExports);
1063
1064 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1065 throwf("can't read %s file: %s", option, fileOfExports);
1066
1067 ::close(fd);
1068
1069 // parse into symbols and add to unordered_set
1070 char * const end = &p[stat_buf.st_size];
1071 enum { lineStart, inSymbol, inComment } state = lineStart;
1072 char* symbolStart = NULL;
1073 for (char* s = p; s < end; ++s ) {
1074 switch ( state ) {
1075 case lineStart:
1076 if ( *s =='#' ) {
1077 state = inComment;
1078 }
1079 else if ( !isspace(*s) ) {
1080 state = inSymbol;
1081 symbolStart = s;
1082 }
1083 break;
1084 case inSymbol:
1085 if ( (*s == '\n') || (*s == '\r') ) {
1086 *s = '\0';
1087 // removing any trailing spaces
1088 char* last = s-1;
1089 while ( isspace(*last) ) {
1090 *last = '\0';
1091 --last;
1092 }
1093 set.insert(symbolStart);
1094 symbolStart = NULL;
1095 state = lineStart;
1096 }
1097 break;
1098 case inComment:
1099 if ( (*s == '\n') || (*s == '\r') )
1100 state = lineStart;
1101 break;
1102 }
1103 }
1104 if ( state == inSymbol ) {
1105 warning("missing line-end at end of file \"%s\"", fileOfExports);
1106 int len = end-symbolStart+1;
1107 char* temp = new char[len];
1108 strlcpy(temp, symbolStart, len);
1109
1110 // remove any trailing spaces
1111 char* last = &temp[len-2];
1112 while ( isspace(*last) ) {
1113 *last = '\0';
1114 --last;
1115 }
1116 set.insert(temp);
1117 }
1118
1119 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
1120 }
1121
1122 void Options::parseAliasFile(const char* fileOfAliases)
1123 {
1124 // read in whole file
1125 int fd = ::open(fileOfAliases, O_RDONLY, 0);
1126 if ( fd == -1 )
1127 throwf("can't open alias file: %s", fileOfAliases);
1128 struct stat stat_buf;
1129 ::fstat(fd, &stat_buf);
1130 char* p = (char*)malloc(stat_buf.st_size+1);
1131 if ( p == NULL )
1132 throwf("can't process alias file: %s", fileOfAliases);
1133
1134 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1135 throwf("can't read alias file: %s", fileOfAliases);
1136 p[stat_buf.st_size] = '\n';
1137 ::close(fd);
1138
1139 // parse into symbols and add to fAliases
1140 AliasPair pair;
1141 char * const end = &p[stat_buf.st_size+1];
1142 enum { lineStart, inRealName, inBetween, inAliasName, inComment } state = lineStart;
1143 int lineNumber = 1;
1144 for (char* s = p; s < end; ++s ) {
1145 switch ( state ) {
1146 case lineStart:
1147 if ( *s =='#' ) {
1148 state = inComment;
1149 }
1150 else if ( !isspace(*s) ) {
1151 state = inRealName;
1152 pair.realName = s;
1153 }
1154 break;
1155 case inRealName:
1156 if ( *s == '\n' ) {
1157 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
1158 ++lineNumber;
1159 state = lineStart;
1160 }
1161 else if ( isspace(*s) ) {
1162 *s = '\0';
1163 state = inBetween;
1164 }
1165 break;
1166 case inBetween:
1167 if ( *s == '\n' ) {
1168 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
1169 ++lineNumber;
1170 state = lineStart;
1171 }
1172 else if ( ! isspace(*s) ) {
1173 state = inAliasName;
1174 pair.alias = s;
1175 }
1176 break;
1177 case inAliasName:
1178 if ( *s =='#' ) {
1179 *s = '\0';
1180 // removing any trailing spaces
1181 char* last = s-1;
1182 while ( isspace(*last) ) {
1183 *last = '\0';
1184 --last;
1185 }
1186 fAliases.push_back(pair);
1187 state = inComment;
1188 }
1189 else if ( *s == '\n' ) {
1190 *s = '\0';
1191 // removing any trailing spaces
1192 char* last = s-1;
1193 while ( isspace(*last) ) {
1194 *last = '\0';
1195 --last;
1196 }
1197 fAliases.push_back(pair);
1198 state = lineStart;
1199 }
1200 break;
1201 case inComment:
1202 if ( *s == '\n' )
1203 state = lineStart;
1204 break;
1205 }
1206 }
1207
1208 // Note: we do not free() the malloc buffer, because the strings therein are used by fAliases
1209 }
1210
1211
1212
1213 void Options::setUndefinedTreatment(const char* treatment)
1214 {
1215 if ( treatment == NULL )
1216 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
1217
1218 if ( strcmp(treatment, "warning") == 0 )
1219 fUndefinedTreatment = kUndefinedWarning;
1220 else if ( strcmp(treatment, "error") == 0 )
1221 fUndefinedTreatment = kUndefinedError;
1222 else if ( strcmp(treatment, "suppress") == 0 )
1223 fUndefinedTreatment = kUndefinedSuppress;
1224 else if ( strcmp(treatment, "dynamic_lookup") == 0 )
1225 fUndefinedTreatment = kUndefinedDynamicLookup;
1226 else
1227 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
1228 }
1229
1230 Options::Treatment Options::parseTreatment(const char* treatment)
1231 {
1232 if ( treatment == NULL )
1233 return kNULL;
1234
1235 if ( strcmp(treatment, "warning") == 0 )
1236 return kWarning;
1237 else if ( strcmp(treatment, "error") == 0 )
1238 return kError;
1239 else if ( strcmp(treatment, "suppress") == 0 )
1240 return kSuppress;
1241 else
1242 return kInvalid;
1243 }
1244
1245 void Options::setMacOSXVersionMin(const char* version)
1246 {
1247 if ( version == NULL )
1248 throw "-macosx_version_min argument missing";
1249
1250 if ( (strncmp(version, "10.", 3) == 0) && isdigit(version[3]) ) {
1251 unsigned int minorVersion = version[3] - '0';
1252 fMacVersionMin = (ld::MacVersionMin)(0x000A0000 | (minorVersion << 8));
1253 }
1254 else {
1255 warning("unknown option to -macosx_version_min, not 10.x");
1256 }
1257 }
1258
1259 void Options::setIOSVersionMin(const char* version)
1260 {
1261 if ( version == NULL )
1262 throw "-ios_version_min argument missing";
1263 if ( ! isdigit(version[0]) )
1264 throw "-ios_version_min argument is not a number";
1265 if ( version[1] != '.' )
1266 throw "-ios_version_min argument is missing period as second character";
1267 if ( ! isdigit(version[2]) )
1268 throw "-ios_version_min argument is not a number";
1269
1270 unsigned int majorVersion = version[0] - '0';
1271 unsigned int minorVersion = version[2] - '0';
1272 fIOSVersionMin = (ld::IOSVersionMin)((majorVersion << 16) | (minorVersion << 8));
1273 }
1274
1275 bool Options::minOS(ld::MacVersionMin requiredMacMin, ld::IOSVersionMin requirediPhoneOSMin)
1276 {
1277 if ( fMacVersionMin != ld::macVersionUnset ) {
1278 return ( fMacVersionMin >= requiredMacMin );
1279 }
1280 else {
1281 return ( fIOSVersionMin >= requirediPhoneOSMin);
1282 }
1283 }
1284
1285
1286 void Options::setWeakReferenceMismatchTreatment(const char* treatment)
1287 {
1288 if ( treatment == NULL )
1289 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
1290
1291 if ( strcmp(treatment, "error") == 0 )
1292 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchError;
1293 else if ( strcmp(treatment, "weak") == 0 )
1294 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchWeak;
1295 else if ( strcmp(treatment, "non-weak") == 0 )
1296 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchNonWeak;
1297 else
1298 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
1299 }
1300
1301 Options::CommonsMode Options::parseCommonsTreatment(const char* mode)
1302 {
1303 if ( mode == NULL )
1304 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
1305
1306 if ( strcmp(mode, "ignore_dylibs") == 0 )
1307 return kCommonsIgnoreDylibs;
1308 else if ( strcmp(mode, "use_dylibs") == 0 )
1309 return kCommonsOverriddenByDylibs;
1310 else if ( strcmp(mode, "error") == 0 )
1311 return kCommonsConflictsDylibsError;
1312 else
1313 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
1314 }
1315
1316 void Options::addDylibOverride(const char* paths)
1317 {
1318 if ( paths == NULL )
1319 throw "-dylib_file must followed by two colon separated paths";
1320 const char* colon = strchr(paths, ':');
1321 if ( colon == NULL )
1322 throw "-dylib_file must followed by two colon separated paths";
1323 int len = colon-paths;
1324 char* target = new char[len+2];
1325 strncpy(target, paths, len);
1326 target[len] = '\0';
1327 DylibOverride entry;
1328 entry.installName = target;
1329 entry.useInstead = &colon[1];
1330 fDylibOverrides.push_back(entry);
1331 }
1332
1333 uint64_t Options::parseAddress(const char* addr)
1334 {
1335 char* endptr;
1336 uint64_t result = strtoull(addr, &endptr, 16);
1337 return result;
1338 }
1339
1340 uint32_t Options::parseProtection(const char* prot)
1341 {
1342 uint32_t result = 0;
1343 for(const char* p = prot; *p != '\0'; ++p) {
1344 switch(tolower(*p)) {
1345 case 'r':
1346 result |= VM_PROT_READ;
1347 break;
1348 case 'w':
1349 result |= VM_PROT_WRITE;
1350 break;
1351 case 'x':
1352 result |= VM_PROT_EXECUTE;
1353 break;
1354 case '-':
1355 break;
1356 default:
1357 throwf("unknown -segprot lettter in %s", prot);
1358 }
1359 }
1360 return result;
1361 }
1362
1363
1364 //
1365 // Parses number of form A[.B[.B[.D[.E]]]] into a uint64_t where the bits are a24.b10.c10.d10.e10
1366 //
1367 uint64_t Options::parseVersionNumber64(const char* versionString)
1368 {
1369 uint64_t a = 0;
1370 uint64_t b = 0;
1371 uint64_t c = 0;
1372 uint64_t d = 0;
1373 uint64_t e = 0;
1374 char* end;
1375 a = strtoul(versionString, &end, 10);
1376 if ( *end == '.' ) {
1377 b = strtoul(&end[1], &end, 10);
1378 if ( *end == '.' ) {
1379 c = strtoul(&end[1], &end, 10);
1380 if ( *end == '.' ) {
1381 d = strtoul(&end[1], &end, 10);
1382 if ( *end == '.' ) {
1383 e = strtoul(&end[1], &end, 10);
1384 }
1385 }
1386 }
1387 }
1388 if ( (*end != '\0') || (a > 0xFFFFFF) || (b > 0x3FF) || (c > 0x3FF) || (d > 0x3FF) || (e > 0x3FF) )
1389 throwf("malformed 64-bit a.b.c.d.e version number: %s", versionString);
1390
1391 return (a << 40) | ( b << 30 ) | ( c << 20 ) | ( d << 10 ) | e;
1392 }
1393
1394
1395 uint32_t Options::currentVersion32() const
1396 {
1397 // warn if it does not fit into 32 bit vers number
1398 uint32_t a = (fDylibCurrentVersion >> 40) & 0xFFFF;
1399 uint32_t b = (fDylibCurrentVersion >> 30) & 0xFF;
1400 uint32_t c = (fDylibCurrentVersion >> 20) & 0xFF;
1401 uint64_t rep32 = ((uint64_t)a << 40) | ((uint64_t)b << 30) | ((uint64_t)c << 20);
1402 if ( rep32 != fDylibCurrentVersion ) {
1403 warning("truncating -current_version to fit in 32-bit space used by old mach-o format");
1404 a = (fDylibCurrentVersion >> 40) & 0xFFFFFF;
1405 if ( a > 0xFFFF )
1406 a = 0xFFFF;
1407 b = (fDylibCurrentVersion >> 30) & 0x3FF;
1408 if ( b > 0xFF )
1409 b = 0xFF;
1410 c = (fDylibCurrentVersion >> 20) & 0x3FF;
1411 if ( c > 0xFF )
1412 c = 0xFF;
1413 }
1414 return (a << 16) | ( b << 8 ) | c;
1415 }
1416
1417 //
1418 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
1419 //
1420 uint32_t Options::parseVersionNumber32(const char* versionString)
1421 {
1422 uint32_t x = 0;
1423 uint32_t y = 0;
1424 uint32_t z = 0;
1425 char* end;
1426 x = strtoul(versionString, &end, 10);
1427 if ( *end == '.' ) {
1428 y = strtoul(&end[1], &end, 10);
1429 if ( *end == '.' ) {
1430 z = strtoul(&end[1], &end, 10);
1431 }
1432 }
1433 if ( (*end != '\0') || (x > 0xffff) || (y > 0xff) || (z > 0xff) )
1434 throwf("malformed 32-bit x.y.z version number: %s", versionString);
1435
1436 return (x << 16) | ( y << 8 ) | z;
1437 }
1438
1439 static const char* cstringSymbolName(const char* orderFileString)
1440 {
1441 char* result;
1442 asprintf(&result, "cstring=%s", orderFileString);
1443 // convert escaped characters
1444 char* d = result;
1445 for(const char* s=result; *s != '\0'; ++s, ++d) {
1446 if ( *s == '\\' ) {
1447 ++s;
1448 switch ( *s ) {
1449 case 'n':
1450 *d = '\n';
1451 break;
1452 case 't':
1453 *d = '\t';
1454 break;
1455 case 'v':
1456 *d = '\v';
1457 break;
1458 case 'b':
1459 *d = '\b';
1460 break;
1461 case 'r':
1462 *d = '\r';
1463 break;
1464 case 'f':
1465 *d = '\f';
1466 break;
1467 case 'a':
1468 *d = '\a';
1469 break;
1470 case '\\':
1471 *d = '\\';
1472 break;
1473 case '?':
1474 *d = '\?';
1475 break;
1476 case '\'':
1477 *d = '\r';
1478 break;
1479 case '\"':
1480 *d = '\"';
1481 break;
1482 case 'x':
1483 // hexadecimal value of char
1484 {
1485 ++s;
1486 char value = 0;
1487 while ( isxdigit(*s) ) {
1488 value *= 16;
1489 if ( isdigit(*s) )
1490 value += (*s-'0');
1491 else
1492 value += ((toupper(*s)-'A') + 10);
1493 ++s;
1494 }
1495 *d = value;
1496 }
1497 break;
1498 default:
1499 if ( isdigit(*s) ) {
1500 // octal value of char
1501 char value = 0;
1502 while ( isdigit(*s) ) {
1503 value = (value << 3) + (*s-'0');
1504 ++s;
1505 }
1506 *d = value;
1507 }
1508 }
1509 }
1510 else {
1511 *d = *s;
1512 }
1513 }
1514 *d = '\0';
1515 return result;
1516 }
1517
1518 void Options::parseOrderFile(const char* path, bool cstring)
1519 {
1520 // order files override auto-ordering
1521 fAutoOrderInitializers = false;
1522
1523 // read in whole file
1524 int fd = ::open(path, O_RDONLY, 0);
1525 if ( fd == -1 )
1526 throwf("can't open order file: %s", path);
1527 struct stat stat_buf;
1528 ::fstat(fd, &stat_buf);
1529 char* p = (char*)malloc(stat_buf.st_size+1);
1530 if ( p == NULL )
1531 throwf("can't process order file: %s", path);
1532 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1533 throwf("can't read order file: %s", path);
1534 ::close(fd);
1535 p[stat_buf.st_size] = '\n';
1536
1537 // parse into vector of pairs
1538 char * const end = &p[stat_buf.st_size+1];
1539 enum { lineStart, inSymbol, inComment } state = lineStart;
1540 char* symbolStart = NULL;
1541 for (char* s = p; s < end; ++s ) {
1542 switch ( state ) {
1543 case lineStart:
1544 if ( *s =='#' ) {
1545 state = inComment;
1546 }
1547 else if ( !isspace(*s) || cstring ) {
1548 state = inSymbol;
1549 symbolStart = s;
1550 }
1551 break;
1552 case inSymbol:
1553 if ( (*s == '\n') || (!cstring && (*s == '#')) ) {
1554 bool wasComment = (*s == '#');
1555 *s = '\0';
1556 // removing any trailing spaces
1557 char* last = s-1;
1558 while ( isspace(*last) ) {
1559 *last = '\0';
1560 --last;
1561 }
1562 // if there is an architecture prefix, only use this symbol it if matches current arch
1563 if ( strncmp(symbolStart, "ppc:", 4) == 0 ) {
1564 symbolStart = NULL;
1565 }
1566 else if ( strncmp(symbolStart, "ppc64:", 6) == 0 ) {
1567 symbolStart = NULL;
1568 }
1569 else if ( strncmp(symbolStart, "i386:", 5) == 0 ) {
1570 if ( fArchitecture == CPU_TYPE_I386 )
1571 symbolStart = &symbolStart[5];
1572 else
1573 symbolStart = NULL;
1574 }
1575 else if ( strncmp(symbolStart, "x86_64:", 7) == 0 ) {
1576 if ( fArchitecture == CPU_TYPE_X86_64 )
1577 symbolStart = &symbolStart[7];
1578 else
1579 symbolStart = NULL;
1580 }
1581 else if ( strncmp(symbolStart, "arm:", 4) == 0 ) {
1582 if ( fArchitecture == CPU_TYPE_ARM )
1583 symbolStart = &symbolStart[4];
1584 else
1585 symbolStart = NULL;
1586 }
1587 if ( symbolStart != NULL ) {
1588 char* objFileName = NULL;
1589 char* colon = strstr(symbolStart, ".o:");
1590 if ( colon != NULL ) {
1591 colon[2] = '\0';
1592 objFileName = symbolStart;
1593 symbolStart = &colon[3];
1594 }
1595 // trim leading spaces
1596 while ( isspace(*symbolStart) )
1597 ++symbolStart;
1598 Options::OrderedSymbol pair;
1599 if ( cstring )
1600 pair.symbolName = cstringSymbolName(symbolStart);
1601 else
1602 pair.symbolName = symbolStart;
1603 pair.objectFileName = objFileName;
1604 fOrderedSymbols.push_back(pair);
1605 }
1606 symbolStart = NULL;
1607 if ( wasComment )
1608 state = inComment;
1609 else
1610 state = lineStart;
1611 }
1612 break;
1613 case inComment:
1614 if ( *s == '\n' )
1615 state = lineStart;
1616 break;
1617 }
1618 }
1619 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1620 }
1621
1622 void Options::parseSectionOrderFile(const char* segment, const char* section, const char* path)
1623 {
1624 if ( (strcmp(section, "__cstring") == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1625 parseOrderFile(path, true);
1626 }
1627 else if ( (strncmp(section, "__literal",9) == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1628 warning("sorting of __literal[4,8,16] sections not supported");
1629 }
1630 else {
1631 // ignore section information and append all symbol names to global order file
1632 parseOrderFile(path, false);
1633 }
1634 }
1635
1636 void Options::addSection(const char* segment, const char* section, const char* path)
1637 {
1638 if ( strlen(segment) > 16 )
1639 throw "-seccreate segment name max 16 chars";
1640 if ( strlen(section) > 16 ) {
1641 char* tmp = strdup(section);
1642 tmp[16] = '\0';
1643 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section, tmp);
1644 section = tmp;
1645 }
1646
1647 // read in whole file
1648 int fd = ::open(path, O_RDONLY, 0);
1649 if ( fd == -1 )
1650 throwf("can't open -sectcreate file: %s", path);
1651 struct stat stat_buf;
1652 ::fstat(fd, &stat_buf);
1653 char* p = (char*)malloc(stat_buf.st_size);
1654 if ( p == NULL )
1655 throwf("can't process -sectcreate file: %s", path);
1656 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1657 throwf("can't read -sectcreate file: %s", path);
1658 ::close(fd);
1659
1660 // record section to create
1661 ExtraSection info = { segment, section, path, (uint8_t*)p, stat_buf.st_size };
1662 fExtraSections.push_back(info);
1663 }
1664
1665 void Options::addSectionAlignment(const char* segment, const char* section, const char* alignmentStr)
1666 {
1667 if ( strlen(segment) > 16 )
1668 throw "-sectalign segment name max 16 chars";
1669 if ( strlen(section) > 16 )
1670 throw "-sectalign section name max 16 chars";
1671
1672 // argument to -sectalign is a hexadecimal number
1673 char* endptr;
1674 unsigned long value = strtoul(alignmentStr, &endptr, 16);
1675 if ( *endptr != '\0')
1676 throw "argument for -sectalign is not a hexadecimal number";
1677 if ( value > 0x8000 )
1678 throw "argument for -sectalign must be less than or equal to 0x8000";
1679 if ( value == 0 ) {
1680 warning("zero is not a valid -sectalign");
1681 value = 1;
1682 }
1683
1684 // alignment is power of 2 (e.g. page alignment = 12)
1685 uint8_t alignment = (uint8_t)__builtin_ctz(value);
1686 if ( (unsigned long)(1 << alignment) != value ) {
1687 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1688 segment, section, 1 << alignment);
1689 }
1690
1691 SectionAlignment info = { segment, section, alignment };
1692 fSectionAlignments.push_back(info);
1693 }
1694
1695 void Options::addLibrary(const FileInfo& info)
1696 {
1697 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1698 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
1699 if ( strcmp(info.path, fit->path) == 0 ) {
1700 // if dylib is specified again but weak, record that it should be weak
1701 if ( info.options.fWeakImport )
1702 fit->options.fWeakImport = true;
1703 return;
1704 }
1705 }
1706 // add to list
1707 fInputFiles.push_back(info);
1708 }
1709
1710 void Options::warnObsolete(const char* arg)
1711 {
1712 warning("option %s is obsolete and being ignored", arg);
1713 }
1714
1715
1716
1717
1718 //
1719 // Process all command line arguments.
1720 //
1721 // The only error checking done here is that each option is valid and if it has arguments
1722 // that they too are valid.
1723 //
1724 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
1725 // whichever was last on the command line is used.
1726 //
1727 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
1728 //
1729 void Options::parse(int argc, const char* argv[])
1730 {
1731 // Store the original args in the link snapshot.
1732 fLinkSnapshot.recordRawArgs(argc, argv);
1733
1734 // pass one builds search list from -L and -F options
1735 this->buildSearchPaths(argc, argv);
1736
1737 // reduce re-allocations
1738 fInputFiles.reserve(32);
1739
1740 // pass two parse all other options
1741 for(int i=1; i < argc; ++i) {
1742 const char* arg = argv[i];
1743
1744 if ( arg[0] == '-' ) {
1745 // by default, copy one arg to the snapshot link command, and do no file copying
1746 int snapshotArgIndex = i;
1747 int snapshotArgCount = -1; // -1 means compute count based on change in index
1748 int snapshotFileArgIndex = -1; // -1 means no data file parameter to arg
1749
1750 // Since we don't care about the files passed, just the option names, we do this here.
1751 if (fPrintOptions)
1752 fprintf (stderr, "[Logging ld64 options]\t%s\n", arg);
1753
1754 if ( (arg[1] == 'L') || (arg[1] == 'F') ) {
1755 snapshotArgCount = 0; // stripped out of link snapshot
1756 if (arg[2] == '\0')
1757 ++i;
1758 // previously handled by buildSearchPaths()
1759 }
1760 // The one gnu style option we have to keep compatibility
1761 // with gcc. Might as well have the single hyphen one as well.
1762 else if ( (strcmp(arg, "--help") == 0)
1763 || (strcmp(arg, "-help") == 0)) {
1764 fprintf (stdout, "ld64: For information on command line options please use 'man ld'.\n");
1765 exit (0);
1766 }
1767 else if ( strcmp(arg, "-arch") == 0 ) {
1768 parseArch(argv[++i]);
1769 }
1770 else if ( strcmp(arg, "-dynamic") == 0 ) {
1771 // default
1772 }
1773 else if ( strcmp(arg, "-static") == 0 ) {
1774 fForStatic = true;
1775 if ( (fOutputKind != kObjectFile) && (fOutputKind != kKextBundle) ) {
1776 fOutputKind = kStaticExecutable;
1777 }
1778 }
1779 else if ( strcmp(arg, "-dylib") == 0 ) {
1780 fOutputKind = kDynamicLibrary;
1781 }
1782 else if ( strcmp(arg, "-bundle") == 0 ) {
1783 fOutputKind = kDynamicBundle;
1784 }
1785 else if ( strcmp(arg, "-dylinker") == 0 ) {
1786 fOutputKind = kDyld;
1787 }
1788 else if ( strcmp(arg, "-execute") == 0 ) {
1789 if ( fOutputKind != kStaticExecutable )
1790 fOutputKind = kDynamicExecutable;
1791 }
1792 else if ( strcmp(arg, "-preload") == 0 ) {
1793 fOutputKind = kPreload;
1794 }
1795 else if ( strcmp(arg, "-r") == 0 ) {
1796 fOutputKind = kObjectFile;
1797 }
1798 else if ( strcmp(arg, "-kext") == 0 ) {
1799 fOutputKind = kKextBundle;
1800 }
1801 else if ( strcmp(arg, "-o") == 0 ) {
1802 snapshotArgCount = 0;
1803 fOutputFile = argv[++i];
1804 fLinkSnapshot.setSnapshotName(fOutputFile);
1805 }
1806 else if ( strncmp(arg, "-lazy-l", 7) == 0 ) {
1807 snapshotArgCount = 0;
1808 FileInfo info = findLibrary(&arg[7], true);
1809 info.options.fLazyLoad = true;
1810 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
1811 addLibrary(info);
1812 fUsingLazyDylibLinking = true;
1813 }
1814 else if ( strcmp(arg, "-lto_library") == 0 ) {
1815 snapshotFileArgIndex = 1;
1816 fOverridePathlibLTO = argv[++i];
1817 if ( fOverridePathlibLTO == NULL )
1818 throw "missing argument to -lto_library";
1819 }
1820 else if ( (arg[1] == 'l') && (strncmp(arg,"-lazy_",6) !=0) ) {
1821 snapshotArgCount = 0;
1822 FileInfo info = findLibrary(&arg[2]);
1823 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
1824 addLibrary(info);
1825 }
1826 // This causes a dylib to be weakly bound at
1827 // link time. This corresponds to weak_import.
1828 else if ( strncmp(arg, "-weak-l", 7) == 0 ) {
1829 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
1830 snapshotArgCount = 0;
1831 FileInfo info = findLibrary(&arg[7]);
1832 info.options.fWeakImport = true;
1833 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
1834 addLibrary(info);
1835 }
1836 // Avoid lazy binding.
1837 else if ( strcmp(arg, "-bind_at_load") == 0 ) {
1838 fBindAtLoad = true;
1839 }
1840 else if ( strcmp(arg, "-twolevel_namespace") == 0 ) {
1841 fNameSpace = kTwoLevelNameSpace;
1842 }
1843 else if ( strcmp(arg, "-flat_namespace") == 0 ) {
1844 fNameSpace = kFlatNameSpace;
1845 }
1846 // Also sets a bit to ensure dyld causes everything
1847 // in the namespace to be flat.
1848 // ??? Deprecate
1849 else if ( strcmp(arg, "-force_flat_namespace") == 0 ) {
1850 fNameSpace = kForceFlatNameSpace;
1851 }
1852 // Similar to --whole-archive.
1853 else if ( strcmp(arg, "-all_load") == 0 ) {
1854 fFullyLoadArchives = true;
1855 }
1856 else if ( strcmp(arg, "-noall_load") == 0) {
1857 warnObsolete(arg);
1858 }
1859 // Similar to -all_load
1860 else if ( strcmp(arg, "-ObjC") == 0 ) {
1861 fLoadAllObjcObjectsFromArchives = true;
1862 }
1863 // Similar to -all_load, but for the following archive only.
1864 else if ( strcmp(arg, "-force_load") == 0 ) {
1865 FileInfo info = findFile(argv[++i]);
1866 info.options.fForceLoad = true;
1867 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
1868 addLibrary(info);
1869 }
1870 // Library versioning.
1871 else if ( (strcmp(arg, "-dylib_compatibility_version") == 0)
1872 || (strcmp(arg, "-compatibility_version") == 0)) {
1873 const char* vers = argv[++i];
1874 if ( vers == NULL )
1875 throw "-dylib_compatibility_version missing <version>";
1876 fDylibCompatVersion = parseVersionNumber32(vers);
1877 }
1878 else if ( (strcmp(arg, "-dylib_current_version") == 0)
1879 || (strcmp(arg, "-current_version") == 0)) {
1880 const char* vers = argv[++i];
1881 if ( vers == NULL )
1882 throw "-dylib_current_version missing <version>";
1883 fDylibCurrentVersion = parseVersionNumber64(vers);
1884 }
1885 else if ( strcmp(arg, "-sectorder") == 0 ) {
1886 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
1887 throw "-sectorder missing <segment> <section> <file-path>";
1888 snapshotFileArgIndex = 3;
1889 parseSectionOrderFile(argv[i+1], argv[i+2], argv[i+3]);
1890 i += 3;
1891 }
1892 else if ( strcmp(arg, "-order_file") == 0 ) {
1893 snapshotFileArgIndex = 1;
1894 parseOrderFile(argv[++i], false);
1895 }
1896 else if ( strcmp(arg, "-order_file_statistics") == 0 ) {
1897 fPrintOrderFileStatistics = true;
1898 }
1899 // ??? Deprecate segcreate.
1900 // -sectcreate puts whole files into a section in the output.
1901 else if ( (strcmp(arg, "-sectcreate") == 0) || (strcmp(arg, "-segcreate") == 0) ) {
1902 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
1903 throw "-sectcreate missing <segment> <section> <file-path>";
1904 snapshotFileArgIndex = 3;
1905 addSection(argv[i+1], argv[i+2], argv[i+3]);
1906 i += 3;
1907 }
1908 // Since we have a full path in binary/library names we need to be able to override it.
1909 else if ( (strcmp(arg, "-dylib_install_name") == 0)
1910 || (strcmp(arg, "-dylinker_install_name") == 0)
1911 || (strcmp(arg, "-install_name") == 0)) {
1912 fDylibInstallName = argv[++i];
1913 if ( fDylibInstallName == NULL )
1914 throw "-install_name missing <path>";
1915 }
1916 // Sets the base address of the output.
1917 else if ( (strcmp(arg, "-seg1addr") == 0) || (strcmp(arg, "-image_base") == 0) ) {
1918 const char* address = argv[++i];
1919 if ( address == NULL )
1920 throwf("%s missing <address>", arg);
1921 fBaseAddress = parseAddress(address);
1922 uint64_t temp = ((fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment));
1923 if ( fBaseAddress != temp ) {
1924 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment);
1925 fBaseAddress = temp;
1926 }
1927 }
1928 else if ( strcmp(arg, "-e") == 0 ) {
1929 fEntryName = argv[++i];
1930 }
1931 // Same as -@ from the FSF linker.
1932 else if ( strcmp(arg, "-filelist") == 0 ) {
1933 snapshotArgCount = 0;
1934 const char* path = argv[++i];
1935 if ( (path == NULL) || (path[0] == '-') )
1936 throw "-filelist missing <path>";
1937 ld::File::Ordinal baseOrdinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
1938 loadFileList(path, baseOrdinal);
1939 }
1940 else if ( strcmp(arg, "-keep_private_externs") == 0 ) {
1941 fKeepPrivateExterns = true;
1942 }
1943 else if ( strcmp(arg, "-final_output") == 0 ) {
1944 fFinalName = argv[++i];
1945 }
1946 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
1947 // just ensures that this happens for cross object file boundaries.
1948 else if ( (strcmp(arg, "-interposable") == 0) || (strcmp(arg, "-multi_module") == 0)) {
1949 switch ( fInterposeMode ) {
1950 case kInterposeNone:
1951 case kInterposeAllExternal:
1952 fInterposeMode = kInterposeAllExternal;
1953 break;
1954 case kInterposeSome:
1955 // do nothing, -interposable_list overrides -interposable"
1956 break;
1957 }
1958 }
1959 else if ( strcmp(arg, "-interposable_list") == 0 ) {
1960 snapshotFileArgIndex = 1;
1961 fInterposeMode = kInterposeSome;
1962 loadExportFile(argv[++i], "-interposable_list", fInterposeList);
1963 }
1964 // Default for -interposable/-multi_module/-single_module.
1965 else if ( strcmp(arg, "-single_module") == 0 ) {
1966 fInterposeMode = kInterposeNone;
1967 }
1968 else if ( strcmp(arg, "-exported_symbols_list") == 0 ) {
1969 snapshotFileArgIndex = 1;
1970 if ( fExportMode == kDontExportSome )
1971 throw "can't use -exported_symbols_list and -unexported_symbols_list";
1972 fExportMode = kExportSome;
1973 loadExportFile(argv[++i], "-exported_symbols_list", fExportSymbols);
1974 }
1975 else if ( strcmp(arg, "-unexported_symbols_list") == 0 ) {
1976 snapshotFileArgIndex = 1;
1977 if ( fExportMode == kExportSome )
1978 throw "can't use -unexported_symbols_list and -exported_symbols_list";
1979 fExportMode = kDontExportSome;
1980 loadExportFile(argv[++i], "-unexported_symbols_list", fDontExportSymbols);
1981 }
1982 else if ( strcmp(arg, "-exported_symbol") == 0 ) {
1983 if ( fExportMode == kDontExportSome )
1984 throw "can't use -exported_symbol and -unexported_symbols";
1985 fExportMode = kExportSome;
1986 fExportSymbols.insert(argv[++i]);
1987 }
1988 else if ( strcmp(arg, "-unexported_symbol") == 0 ) {
1989 if ( fExportMode == kExportSome )
1990 throw "can't use -unexported_symbol and -exported_symbol";
1991 fExportMode = kDontExportSome;
1992 fDontExportSymbols.insert(argv[++i]);
1993 }
1994 else if ( strcmp(arg, "-non_global_symbols_no_strip_list") == 0 ) {
1995 snapshotFileArgIndex = 1;
1996 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveExclude )
1997 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
1998 fLocalSymbolHandling = kLocalSymbolsSelectiveInclude;
1999 loadExportFile(argv[++i], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded);
2000 }
2001 else if ( strcmp(arg, "-non_global_symbols_strip_list") == 0 ) {
2002 snapshotFileArgIndex = 1;
2003 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveInclude )
2004 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2005 fLocalSymbolHandling = kLocalSymbolsSelectiveExclude;
2006 loadExportFile(argv[++i], "-non_global_symbols_strip_list", fLocalSymbolsExcluded);
2007 }
2008 // ??? Deprecate
2009 else if ( strcmp(arg, "-no_arch_warnings") == 0 ) {
2010 fIgnoreOtherArchFiles = true;
2011 }
2012 else if ( strcmp(arg, "-force_cpusubtype_ALL") == 0 ) {
2013 fForceSubtypeAll = true;
2014 fAllowCpuSubtypeMismatches = true;
2015 }
2016 // Similar to -weak-l but uses the absolute path name to the library.
2017 else if ( strcmp(arg, "-weak_library") == 0 ) {
2018 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2019 snapshotArgCount = 0;
2020 FileInfo info = findFile(argv[++i]);
2021 info.options.fWeakImport = true;
2022 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2023 addLibrary(info);
2024 }
2025 else if ( strcmp(arg, "-lazy_library") == 0 ) {
2026 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2027 snapshotArgCount = 0;
2028 FileInfo info = findFile(argv[++i]);
2029 info.options.fLazyLoad = true;
2030 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2031 addLibrary(info);
2032 fUsingLazyDylibLinking = true;
2033 }
2034 else if ( strcmp(arg, "-framework") == 0 ) {
2035 snapshotArgCount = 0;
2036 FileInfo info = findFramework(argv[++i]);
2037 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2038 addLibrary(info);
2039 }
2040 else if ( strcmp(arg, "-weak_framework") == 0 ) {
2041 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2042 snapshotArgCount = 0;
2043 FileInfo info = findFramework(argv[++i]);
2044 info.options.fWeakImport = true;
2045 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2046 addLibrary(info);
2047 }
2048 else if ( strcmp(arg, "-lazy_framework") == 0 ) {
2049 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2050 snapshotArgCount = 0;
2051 FileInfo info = findFramework(argv[++i]);
2052 info.options.fLazyLoad = true;
2053 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2054 addLibrary(info);
2055 fUsingLazyDylibLinking = true;
2056 }
2057 else if ( strcmp(arg, "-search_paths_first") == 0 ) {
2058 // previously handled by buildSearchPaths()
2059 }
2060 else if ( strcmp(arg, "-search_dylibs_first") == 0 ) {
2061 // previously handled by buildSearchPaths()
2062 }
2063 else if ( strcmp(arg, "-undefined") == 0 ) {
2064 setUndefinedTreatment(argv[++i]);
2065 }
2066 // Debugging output flag.
2067 else if ( strcmp(arg, "-arch_multiple") == 0 ) {
2068 fMessagesPrefixedWithArchitecture = true;
2069 }
2070 // Specify what to do with relocations in read only
2071 // sections like .text. Could be errors, warnings,
2072 // or suppressed. Currently we do nothing with the
2073 // flag.
2074 else if ( strcmp(arg, "-read_only_relocs") == 0 ) {
2075 switch ( parseTreatment(argv[++i]) ) {
2076 case kNULL:
2077 case kInvalid:
2078 throw "-read_only_relocs missing [ warning | error | suppress ]";
2079 case kWarning:
2080 fWarnTextRelocs = true;
2081 fAllowTextRelocs = true;
2082 break;
2083 case kSuppress:
2084 fWarnTextRelocs = false;
2085 fAllowTextRelocs = true;
2086 break;
2087 case kError:
2088 fWarnTextRelocs = false;
2089 fAllowTextRelocs = false;
2090 break;
2091 }
2092 }
2093 else if ( strcmp(arg, "-sect_diff_relocs") == 0 ) {
2094 warnObsolete(arg);
2095 ++i;
2096 }
2097 // Warn, error or make strong a mismatch between weak
2098 // and non-weak references.
2099 else if ( strcmp(arg, "-weak_reference_mismatches") == 0 ) {
2100 setWeakReferenceMismatchTreatment(argv[++i]);
2101 }
2102 // For a deployment target of 10.3 and earlier ld64 will
2103 // prebind an executable with 0s in all addresses that
2104 // are prebound. This can then be fixed up by update_prebinding
2105 // later. Prebinding is less useful on 10.4 and greater.
2106 else if ( strcmp(arg, "-prebind") == 0 ) {
2107 fPrebind = true;
2108 }
2109 else if ( strcmp(arg, "-noprebind") == 0 ) {
2110 warnObsolete(arg);
2111 fPrebind = false;
2112 }
2113 else if ( strcmp(arg, "-prebind_allow_overlap") == 0 ) {
2114 warnObsolete(arg);
2115 }
2116 else if ( strcmp(arg, "-prebind_all_twolevel_modules") == 0 ) {
2117 warnObsolete(arg);
2118 }
2119 else if ( strcmp(arg, "-noprebind_all_twolevel_modules") == 0 ) {
2120 warnObsolete(arg);
2121 }
2122 else if ( strcmp(arg, "-nofixprebinding") == 0 ) {
2123 warnObsolete(arg);
2124 }
2125 // This should probably be deprecated when we respect -L and -F
2126 // when searching for libraries.
2127 else if ( strcmp(arg, "-dylib_file") == 0 ) {
2128 // ignore for snapshot because a stub dylib will be created in the snapshot
2129 snapshotArgCount = 0;
2130 addDylibOverride(argv[++i]);
2131 }
2132 // What to expand @executable_path to if found in dependent dylibs
2133 else if ( strcmp(arg, "-executable_path") == 0 ) {
2134 fExecutablePath = argv[++i];
2135 if ( (fExecutablePath == NULL) || (fExecutablePath[0] == '-') )
2136 throw "-executable_path missing <path>";
2137 // if a directory was passed, add / to end
2138 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2139 struct stat statBuffer;
2140 if ( stat(fExecutablePath, &statBuffer) == 0 ) {
2141 if ( (statBuffer.st_mode & S_IFMT) == S_IFDIR ) {
2142 char* pathWithSlash = new char[strlen(fExecutablePath)+2];
2143 strcpy(pathWithSlash, fExecutablePath);
2144 strcat(pathWithSlash, "/");
2145 fExecutablePath = pathWithSlash;
2146 }
2147 }
2148 }
2149 // Aligns all segments to the power of 2 boundary specified.
2150 else if ( strcmp(arg, "-segalign") == 0 ) {
2151 const char* size = argv[++i];
2152 if ( size == NULL )
2153 throw "-segalign missing <size>";
2154 fSegmentAlignment = parseAddress(size);
2155 uint8_t alignment = (uint8_t)__builtin_ctz(fSegmentAlignment);
2156 uint32_t p2aligned = (1 << alignment);
2157 if ( p2aligned != fSegmentAlignment ) {
2158 warning("alignment for -segalign %s is not a power of two, using 0x%X", size, p2aligned);
2159 fSegmentAlignment = p2aligned;
2160 }
2161 }
2162 // Puts a specified segment at a particular address that must
2163 // be a multiple of the segment alignment.
2164 else if ( strcmp(arg, "-segaddr") == 0 ) {
2165 SegmentStart seg;
2166 seg.name = argv[++i];
2167 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
2168 throw "-segaddr missing segName Adddress";
2169 seg.address = parseAddress(argv[++i]);
2170 uint64_t temp = ((seg.address+fSegmentAlignment-1) & (-fSegmentAlignment));
2171 if ( seg.address != temp )
2172 warning("-segaddr %s not %lld byte aligned", seg.name, fSegmentAlignment);
2173 fCustomSegmentAddresses.push_back(seg);
2174 }
2175 // ??? Deprecate when we deprecate split-seg.
2176 else if ( strcmp(arg, "-segs_read_only_addr") == 0 ) {
2177 fBaseAddress = parseAddress(argv[++i]);
2178 }
2179 // ??? Deprecate when we deprecate split-seg.
2180 else if ( strcmp(arg, "-segs_read_write_addr") == 0 ) {
2181 fBaseWritableAddress = parseAddress(argv[++i]);
2182 fSplitSegs = true;
2183 }
2184 // ??? Deprecate when we get rid of basing at build time.
2185 else if ( strcmp(arg, "-seg_addr_table") == 0 ) {
2186 snapshotFileArgIndex = 1;
2187 const char* name = argv[++i];
2188 if ( name == NULL )
2189 throw "-seg_addr_table missing argument";
2190 fSegAddrTablePath = name;
2191 }
2192 else if ( strcmp(arg, "-seg_addr_table_filename") == 0 ) {
2193 warnObsolete(arg);
2194 ++i;
2195 }
2196 else if ( strcmp(arg, "-segprot") == 0 ) {
2197 SegmentProtect seg;
2198 seg.name = argv[++i];
2199 if ( (seg.name == NULL) || (argv[i+1] == NULL) || (argv[i+2] == NULL) )
2200 throw "-segprot missing segName max-prot init-prot";
2201 seg.max = parseProtection(argv[++i]);
2202 seg.init = parseProtection(argv[++i]);
2203 fCustomSegmentProtections.push_back(seg);
2204 }
2205 else if ( strcmp(arg, "-pagezero_size") == 0 ) {
2206 const char* size = argv[++i];
2207 if ( size == NULL )
2208 throw "-pagezero_size missing <size>";
2209 fZeroPageSize = parseAddress(size);
2210 uint64_t temp = fZeroPageSize & (-4096); // page align
2211 if ( (fZeroPageSize != temp) )
2212 warning("-pagezero_size not page aligned, rounding down");
2213 fZeroPageSize = temp;
2214 }
2215 else if ( strcmp(arg, "-stack_addr") == 0 ) {
2216 const char* address = argv[++i];
2217 if ( address == NULL )
2218 throw "-stack_addr missing <address>";
2219 fStackAddr = parseAddress(address);
2220 }
2221 else if ( strcmp(arg, "-stack_size") == 0 ) {
2222 const char* size = argv[++i];
2223 if ( size == NULL )
2224 throw "-stack_size missing <address>";
2225 fStackSize = parseAddress(size);
2226 uint64_t temp = fStackSize & (-4096); // page align
2227 if ( (fStackSize != temp) )
2228 warning("-stack_size not page aligned, rounding down");
2229 }
2230 else if ( strcmp(arg, "-allow_stack_execute") == 0 ) {
2231 fExecutableStack = true;
2232 }
2233 else if ( strcmp(arg, "-allow_heap_execute") == 0 ) {
2234 fDisableNonExecutableHeap = true;
2235 }
2236 else if ( strcmp(arg, "-sectalign") == 0 ) {
2237 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2238 throw "-sectalign missing <segment> <section> <file-path>";
2239 addSectionAlignment(argv[i+1], argv[i+2], argv[i+3]);
2240 i += 3;
2241 }
2242 else if ( strcmp(arg, "-sectorder_detail") == 0 ) {
2243 warnObsolete(arg);
2244 }
2245 else if ( strcmp(arg, "-sectobjectsymbols") == 0 ) {
2246 warnObsolete(arg);
2247 i += 2;
2248 }
2249 else if ( strcmp(arg, "-bundle_loader") == 0 ) {
2250 snapshotFileArgIndex = 1;
2251 fBundleLoader = argv[++i];
2252 if ( (fBundleLoader == NULL) || (fBundleLoader[0] == '-') )
2253 throw "-bundle_loader missing <path>";
2254 FileInfo info = findFile(fBundleLoader);
2255 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2256 info.options.fBundleLoader = true;
2257 fInputFiles.push_back(info);
2258 }
2259 else if ( strcmp(arg, "-private_bundle") == 0 ) {
2260 warnObsolete(arg);
2261 }
2262 else if ( strcmp(arg, "-twolevel_namespace_hints") == 0 ) {
2263 // FIX FIX
2264 }
2265 // Use this flag to set default behavior for deployement targets.
2266 else if ( strcmp(arg, "-macosx_version_min") == 0 ) {
2267 setMacOSXVersionMin(argv[++i]);
2268 }
2269 else if ( (strcmp(arg, "-ios_version_min") == 0) || (strcmp(arg, "-iphoneos_version_min") == 0) ) {
2270 setIOSVersionMin(argv[++i]);
2271 }
2272 else if ( strcmp(arg, "-ios_simulator_version_min") == 0 ) {
2273 setIOSVersionMin(argv[++i]);
2274 }
2275 else if ( strcmp(arg, "-multiply_defined") == 0 ) {
2276 //warnObsolete(arg);
2277 ++i;
2278 }
2279 else if ( strcmp(arg, "-multiply_defined_unused") == 0 ) {
2280 warnObsolete(arg);
2281 ++i;
2282 }
2283 else if ( strcmp(arg, "-nomultidefs") == 0 ) {
2284 warnObsolete(arg);
2285 }
2286 // Display each file in which the argument symbol appears and whether
2287 // the file defines or references it. This option takes an argument
2288 // as -y<symbol> note that there is no space.
2289 else if ( strncmp(arg, "-y", 2) == 0 ) {
2290 warnObsolete("-y");
2291 }
2292 // Same output as -y, but output <arg> number of undefined symbols only.
2293 else if ( strcmp(arg, "-Y") == 0 ) {
2294 //warnObsolete(arg);
2295 ++i;
2296 }
2297 // This option affects all objects linked into the final result.
2298 else if ( strcmp(arg, "-m") == 0 ) {
2299 warnObsolete(arg);
2300 }
2301 else if ( (strcmp(arg, "-why_load") == 0) || (strcmp(arg, "-whyload") == 0) ) {
2302 fWhyLoad = true;
2303 }
2304 else if ( strcmp(arg, "-why_live") == 0 ) {
2305 const char* name = argv[++i];
2306 if ( name == NULL )
2307 throw "-why_live missing symbol name argument";
2308 fWhyLive.insert(name);
2309 }
2310 else if ( strcmp(arg, "-u") == 0 ) {
2311 const char* name = argv[++i];
2312 if ( name == NULL )
2313 throw "-u missing argument";
2314 fInitialUndefines.push_back(name);
2315 }
2316 else if ( strcmp(arg, "-U") == 0 ) {
2317 const char* name = argv[++i];
2318 if ( name == NULL )
2319 throw "-U missing argument";
2320 fAllowedUndefined.insert(name);
2321 }
2322 else if ( strcmp(arg, "-s") == 0 ) {
2323 warnObsolete(arg);
2324 fLocalSymbolHandling = kLocalSymbolsNone;
2325 fDebugInfoStripping = Options::kDebugInfoNone;
2326 }
2327 else if ( strcmp(arg, "-x") == 0 ) {
2328 fLocalSymbolHandling = kLocalSymbolsNone;
2329 }
2330 else if ( strcmp(arg, "-S") == 0 ) {
2331 fDebugInfoStripping = Options::kDebugInfoNone;
2332 }
2333 else if ( strcmp(arg, "-X") == 0 ) {
2334 warnObsolete(arg);
2335 }
2336 else if ( strcmp(arg, "-Si") == 0 ) {
2337 warnObsolete(arg);
2338 fDebugInfoStripping = Options::kDebugInfoFull;
2339 }
2340 else if ( strcmp(arg, "-b") == 0 ) {
2341 warnObsolete(arg);
2342 }
2343 else if ( strcmp(arg, "-Sn") == 0 ) {
2344 warnObsolete(arg);
2345 fDebugInfoStripping = Options::kDebugInfoFull;
2346 }
2347 else if ( strcmp(arg, "-Sp") == 0 ) {
2348 warnObsolete(arg);
2349 }
2350 else if ( strcmp(arg, "-dead_strip") == 0 ) {
2351 fDeadStrip = true;
2352 }
2353 else if ( strcmp(arg, "-no_dead_strip_inits_and_terms") == 0 ) {
2354 fDeadStrip = true;
2355 }
2356 else if ( strcmp(arg, "-w") == 0 ) {
2357 // previously handled by buildSearchPaths()
2358 }
2359 else if ( strcmp(arg, "-fatal_warnings") == 0 ) {
2360 // previously handled by buildSearchPaths()
2361 }
2362 else if ( strcmp(arg, "-arch_errors_fatal") == 0 ) {
2363 fErrorOnOtherArchFiles = true;
2364 }
2365 else if ( strcmp(arg, "-M") == 0 ) {
2366 // FIX FIX
2367 }
2368 else if ( strcmp(arg, "-headerpad") == 0 ) {
2369 const char* size = argv[++i];
2370 if ( size == NULL )
2371 throw "-headerpad missing argument";
2372 fMinimumHeaderPad = parseAddress(size);
2373 }
2374 else if ( strcmp(arg, "-headerpad_max_install_names") == 0 ) {
2375 fMaxMinimumHeaderPad = true;
2376 }
2377 else if ( strcmp(arg, "-t") == 0 ) {
2378 fLogAllFiles = true;
2379 }
2380 else if ( strcmp(arg, "-whatsloaded") == 0 ) {
2381 fLogObjectFiles = true;
2382 }
2383 else if ( strcmp(arg, "-A") == 0 ) {
2384 warnObsolete(arg);
2385 ++i;
2386 }
2387 else if ( strcmp(arg, "-umbrella") == 0 ) {
2388 const char* name = argv[++i];
2389 if ( name == NULL )
2390 throw "-umbrella missing argument";
2391 fUmbrellaName = name;
2392 }
2393 else if ( strcmp(arg, "-allowable_client") == 0 ) {
2394 const char* name = argv[++i];
2395
2396 if ( name == NULL )
2397 throw "-allowable_client missing argument";
2398
2399 fAllowableClients.push_back(name);
2400 }
2401 else if ( strcmp(arg, "-client_name") == 0 ) {
2402 const char* name = argv[++i];
2403
2404 if ( name == NULL )
2405 throw "-client_name missing argument";
2406
2407 fClientName = name;
2408 }
2409 else if ( strcmp(arg, "-sub_umbrella") == 0 ) {
2410 const char* name = argv[++i];
2411 if ( name == NULL )
2412 throw "-sub_umbrella missing argument";
2413 fSubUmbellas.push_back(name);
2414 }
2415 else if ( strcmp(arg, "-sub_library") == 0 ) {
2416 const char* name = argv[++i];
2417 if ( name == NULL )
2418 throw "-sub_library missing argument";
2419 fSubLibraries.push_back(name);
2420 }
2421 else if ( strcmp(arg, "-init") == 0 ) {
2422 const char* name = argv[++i];
2423 if ( name == NULL )
2424 throw "-init missing argument";
2425 fInitFunctionName = name;
2426 }
2427 else if ( strcmp(arg, "-dot") == 0 ) {
2428 const char* name = argv[++i];
2429 if ( name == NULL )
2430 throw "-dot missing argument";
2431 fDotOutputFile = name;
2432 }
2433 else if ( strcmp(arg, "-warn_commons") == 0 ) {
2434 fWarnCommons = true;
2435 }
2436 else if ( strcmp(arg, "-commons") == 0 ) {
2437 fCommonsMode = parseCommonsTreatment(argv[++i]);
2438 }
2439 else if ( strcmp(arg, "-keep_relocs") == 0 ) {
2440 fKeepRelocations = true;
2441 }
2442 else if ( strcmp(arg, "-warn_stabs") == 0 ) {
2443 fWarnStabs = true;
2444 }
2445 else if ( strcmp(arg, "-pause") == 0 ) {
2446 fPause = true;
2447 }
2448 else if ( strcmp(arg, "-print_statistics") == 0 ) {
2449 fStatistics = true;
2450 }
2451 else if ( strcmp(arg, "-d") == 0 ) {
2452 fMakeTentativeDefinitionsReal = true;
2453 }
2454 else if ( strcmp(arg, "-v") == 0 ) {
2455 // previously handled by buildSearchPaths()
2456 }
2457 else if ( strcmp(arg, "-Z") == 0 ) {
2458 // previously handled by buildSearchPaths()
2459 }
2460 else if ( strcmp(arg, "-syslibroot") == 0 ) {
2461 snapshotArgCount = 0;
2462 ++i;
2463 // previously handled by buildSearchPaths()
2464 }
2465 else if ( strcmp(arg, "-no_uuid") == 0 ) {
2466 fUUIDMode = kUUIDNone;
2467 }
2468 else if ( strcmp(arg, "-random_uuid") == 0 ) {
2469 fUUIDMode = kUUIDRandom;
2470 }
2471 else if ( strcmp(arg, "-dtrace") == 0 ) {
2472 snapshotFileArgIndex = 1;
2473 const char* name = argv[++i];
2474 if ( name == NULL )
2475 throw "-dtrace missing argument";
2476 fDtraceScriptName = name;
2477 }
2478 else if ( strcmp(arg, "-root_safe") == 0 ) {
2479 fRootSafe = true;
2480 }
2481 else if ( strcmp(arg, "-setuid_safe") == 0 ) {
2482 fSetuidSafe = true;
2483 }
2484 else if ( strcmp(arg, "-alias") == 0 ) {
2485 Options::AliasPair pair;
2486 pair.realName = argv[++i];
2487 if ( pair.realName == NULL )
2488 throw "missing argument to -alias";
2489 pair.alias = argv[++i];
2490 if ( pair.alias == NULL )
2491 throw "missing argument to -alias";
2492 fAliases.push_back(pair);
2493 }
2494 else if ( strcmp(arg, "-alias_list") == 0 ) {
2495 snapshotFileArgIndex = 1;
2496 parseAliasFile(argv[++i]);
2497 }
2498 // put this last so that it does not interfer with other options starting with 'i'
2499 else if ( strncmp(arg, "-i", 2) == 0 ) {
2500 const char* colon = strchr(arg, ':');
2501 if ( colon == NULL )
2502 throwf("unknown option: %s", arg);
2503 Options::AliasPair pair;
2504 char* temp = new char[colon-arg];
2505 strlcpy(temp, &arg[2], colon-arg-1);
2506 pair.realName = &colon[1];
2507 pair.alias = temp;
2508 fAliases.push_back(pair);
2509 }
2510 else if ( strcmp(arg, "-save-temps") == 0 ) {
2511 fSaveTempFiles = true;
2512 }
2513 else if ( strcmp(arg, "-rpath") == 0 ) {
2514 const char* path = argv[++i];
2515 if ( path == NULL )
2516 throw "missing argument to -rpath";
2517 fRPaths.push_back(path);
2518 }
2519 else if ( strcmp(arg, "-read_only_stubs") == 0 ) {
2520 fReadOnlyx86Stubs = true;
2521 }
2522 else if ( strcmp(arg, "-slow_stubs") == 0 ) {
2523 warnObsolete(arg);
2524 }
2525 else if ( strcmp(arg, "-map") == 0 ) {
2526 fMapPath = argv[++i];
2527 if ( fMapPath == NULL )
2528 throw "missing argument to -map";
2529 }
2530 else if ( strcmp(arg, "-pie") == 0 ) {
2531 fPositionIndependentExecutable = true;
2532 fPIEOnCommandLine = true;
2533 }
2534 else if ( strcmp(arg, "-no_pie") == 0 ) {
2535 fDisablePositionIndependentExecutable = true;
2536 }
2537 else if ( strncmp(arg, "-reexport-l", 11) == 0 ) {
2538 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2539 snapshotArgCount = 0;
2540 FileInfo info = findLibrary(&arg[11], true);
2541 info.options.fReExport = true;
2542 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2543 addLibrary(info);
2544 }
2545 else if ( strcmp(arg, "-reexport_library") == 0 ) {
2546 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2547 snapshotArgCount = 0;
2548 FileInfo info = findFile(argv[++i]);
2549 info.options.fReExport = true;
2550 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2551 addLibrary(info);
2552 }
2553 else if ( strcmp(arg, "-reexport_framework") == 0 ) {
2554 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2555 snapshotArgCount = 0;
2556 FileInfo info = findFramework(argv[++i]);
2557 info.options.fReExport = true;
2558 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2559 addLibrary(info);
2560 }
2561 else if ( strncmp(arg, "-upward-l", 9) == 0 ) {
2562 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2563 snapshotArgCount = 0;
2564 FileInfo info = findLibrary(&arg[9], true);
2565 info.options.fUpward = true;
2566 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2567 addLibrary(info);
2568 }
2569 else if ( strcmp(arg, "-upward_library") == 0 ) {
2570 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2571 snapshotArgCount = 0;
2572 FileInfo info = findFile(argv[++i]);
2573 info.options.fUpward = true;
2574 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2575 addLibrary(info);
2576 }
2577 else if ( strcmp(arg, "-upward_framework") == 0 ) {
2578 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2579 snapshotArgCount = 0;
2580 FileInfo info = findFramework(argv[++i]);
2581 info.options.fUpward = true;
2582 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2583 addLibrary(info);
2584 }
2585 else if ( strcmp(arg, "-dead_strip_dylibs") == 0 ) {
2586 fDeadStripDylibs = true;
2587 }
2588 else if ( strcmp(arg, "-no_implicit_dylibs") == 0 ) {
2589 fImplicitlyLinkPublicDylibs = false;
2590 }
2591 else if ( strcmp(arg, "-new_linker") == 0 ) {
2592 // ignore
2593 }
2594 else if ( strcmp(arg, "-no_encryption") == 0 ) {
2595 fEncryptable = false;
2596 }
2597 else if ( strcmp(arg, "-no_compact_unwind") == 0 ) {
2598 fAddCompactUnwindEncoding = false;
2599 }
2600 else if ( strcmp(arg, "-mllvm") == 0 ) {
2601 const char* opts = argv[++i];
2602 if ( opts == NULL )
2603 throw "missing argument to -mllvm";
2604 fLLVMOptions.push_back(opts);
2605 }
2606 else if ( strcmp(arg, "-no_order_inits") == 0 ) {
2607 fAutoOrderInitializers = false;
2608 }
2609 else if ( strcmp(arg, "-no_order_data") == 0 ) {
2610 fOrderData = false;
2611 }
2612 else if ( strcmp(arg, "-seg_page_size") == 0 ) {
2613 SegmentSize seg;
2614 seg.name = argv[++i];
2615 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
2616 throw "-seg_page_size missing segName Adddress";
2617 seg.size = parseAddress(argv[++i]);
2618 uint64_t temp = seg.size & (-4096); // page align
2619 if ( (seg.size != temp) )
2620 warning("-seg_page_size %s not 4K aligned, rounding down", seg.name);
2621 fCustomSegmentSizes.push_back(seg);
2622 }
2623 else if ( strcmp(arg, "-mark_dead_strippable_dylib") == 0 ) {
2624 fMarkDeadStrippableDylib = true;
2625 }
2626 else if ( strcmp(arg, "-exported_symbols_order") == 0 ) {
2627 snapshotFileArgIndex = 1;
2628 loadSymbolOrderFile(argv[++i], fExportSymbolsOrder);
2629 }
2630 else if ( strcmp(arg, "-no_compact_linkedit") == 0 ) {
2631 warnObsolete("-no_compact_linkedit");
2632 }
2633 else if ( strcmp(arg, "-no_eh_labels") == 0 ) {
2634 fNoEHLabels = true;
2635 }
2636 else if ( strcmp(arg, "-warn_compact_unwind") == 0 ) {
2637 fWarnCompactUnwind = true;
2638 }
2639 else if ( strcmp(arg, "-allow_sub_type_mismatches") == 0 ) {
2640 fAllowCpuSubtypeMismatches = true;
2641 }
2642 else if ( strcmp(arg, "-no_zero_fill_sections") == 0 ) {
2643 fOptimizeZeroFill = false;
2644 }
2645 else if ( strcmp(arg, "-merge_zero_fill_sections") == 0 ) {
2646 fMergeZeroFill = true;
2647 }
2648 else if ( strcmp(arg, "-objc_abi_version") == 0 ) {
2649 const char* version = argv[++i];
2650 if ( version == NULL )
2651 throw "-objc_abi_version missing version number";
2652 if ( strcmp(version, "2") == 0 ) {
2653 fObjCABIVersion1Override = false;
2654 fObjCABIVersion2Override = true;
2655 }
2656 else if ( strcmp(version, "1") == 0 ) {
2657 fObjCABIVersion1Override = true;
2658 fObjCABIVersion2Override = false;
2659 }
2660 else
2661 warning("ignoring unrecognized argument (%s) to -objc_abi_version", version);
2662 }
2663 else if ( strcmp(arg, "-warn_weak_exports") == 0 ) {
2664 fWarnWeakExports = true;
2665 }
2666 else if ( strcmp(arg, "-objc_gc_compaction") == 0 ) {
2667 fObjcGcCompaction = true;
2668 }
2669 else if ( strcmp(arg, "-objc_gc") == 0 ) {
2670 fObjCGc = true;
2671 if ( fObjCGcOnly ) {
2672 warning("-objc_gc overriding -objc_gc_only");
2673 fObjCGcOnly = false;
2674 }
2675 }
2676 else if ( strcmp(arg, "-objc_gc_only") == 0 ) {
2677 fObjCGcOnly = true;
2678 if ( fObjCGc ) {
2679 warning("-objc_gc_only overriding -objc_gc");
2680 fObjCGc = false;
2681 }
2682 }
2683 else if ( strcmp(arg, "-demangle") == 0 ) {
2684 fDemangle = true;
2685 }
2686 else if ( strcmp(arg, "-version_load_command") == 0 ) {
2687 fVersionLoadCommandForcedOn = true;
2688 fVersionLoadCommandForcedOff = false;
2689 }
2690 else if ( strcmp(arg, "-no_version_load_command") == 0 ) {
2691 fVersionLoadCommandForcedOff = true;
2692 fVersionLoadCommandForcedOn = false;
2693 }
2694 else if ( strcmp(arg, "-function_starts") == 0 ) {
2695 fFunctionStartsForcedOn = true;
2696 fFunctionStartsForcedOff = false;
2697 }
2698 else if ( strcmp(arg, "-no_function_starts") == 0 ) {
2699 fFunctionStartsForcedOff = true;
2700 fFunctionStartsForcedOn = false;
2701 }
2702 else if ( strcmp(arg, "-no_data_in_code_info") == 0 ) {
2703 fDataInCodeInfoLoadCommandForcedOff = true;
2704 fDataInCodeInfoLoadCommandForcedOn = false;
2705 }
2706 else if ( strcmp(arg, "-data_in_code_info") == 0 ) {
2707 fDataInCodeInfoLoadCommandForcedOn = true;
2708 fDataInCodeInfoLoadCommandForcedOff = false;
2709 }
2710 else if ( strcmp(arg, "-object_path_lto") == 0 ) {
2711 fTempLtoObjectPath = argv[++i];
2712 if ( fTempLtoObjectPath == NULL )
2713 throw "missing argument to -object_path_lto";
2714 }
2715 else if ( strcmp(arg, "-no_objc_category_merging") == 0 ) {
2716 fObjcCategoryMerging = false;
2717 }
2718 else if ( strcmp(arg, "-force_symbols_weak_list") == 0 ) {
2719 snapshotFileArgIndex = 1;
2720 loadExportFile(argv[++i], "-force_symbols_weak_list", fForceWeakSymbols);
2721 }
2722 else if ( strcmp(arg, "-force_symbols_not_weak_list") == 0 ) {
2723 snapshotFileArgIndex = 1;
2724 loadExportFile(argv[++i], "-force_symbols_not_weak_list", fForceNotWeakSymbols);
2725 }
2726 else if ( strcmp(arg, "-force_symbol_weak") == 0 ) {
2727 const char* symbol = argv[++i];
2728 if ( symbol == NULL )
2729 throw "-force_symbol_weak missing <symbol>";
2730 fForceWeakSymbols.insert(symbol);
2731 }
2732 else if ( strcmp(arg, "-force_symbol_not_weak") == 0 ) {
2733 const char* symbol = argv[++i];
2734 if ( symbol == NULL )
2735 throw "-force_symbol_not_weak missing <symbol>";
2736 fForceNotWeakSymbols.insert(symbol);
2737 }
2738 else if ( strcmp(arg, "-reexported_symbols_list") == 0 ) {
2739 snapshotFileArgIndex = 1;
2740 if ( fExportMode == kExportSome )
2741 throw "can't use -exported_symbols_list and -reexported_symbols_list";
2742 loadExportFile(argv[++i], "-reexported_symbols_list", fReExportSymbols);
2743 }
2744 else if ( strcmp(arg, "-dyld_env") == 0 ) {
2745 const char* envarg = argv[++i];
2746 if ( envarg == NULL )
2747 throw "-dyld_env missing ENV=VALUE";
2748 if ( strchr(envarg, '=') == NULL )
2749 throw "-dyld_env missing ENV=VALUE";
2750 fDyldEnvironExtras.push_back(envarg);
2751 }
2752 else if ( strcmp(arg, "-page_align_data_atoms") == 0 ) {
2753 fPageAlignDataAtoms = true;
2754 }
2755 else if (strcmp(arg, "-debug_snapshot") == 0) {
2756 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
2757 fSnapshotRequested = true;
2758 }
2759 else if ( strcmp(arg, "-new_main") == 0 ) {
2760 fEntryPointLoadCommandForceOn = true;
2761 }
2762 else if ( strcmp(arg, "-no_new_main") == 0 ) {
2763 fEntryPointLoadCommandForceOff = true;
2764 }
2765 else if ( strcmp(arg, "-source_version") == 0 ) {
2766 const char* vers = argv[++i];
2767 if ( vers == NULL )
2768 throw "-source_version missing <version>";
2769 fSourceVersion = parseVersionNumber64(vers);
2770 }
2771 else if ( strcmp(arg, "-add_source_version") == 0 ) {
2772 fSourceVersionLoadCommandForceOn = true;
2773 }
2774 else if ( strcmp(arg, "-no_source_version") == 0 ) {
2775 fSourceVersionLoadCommandForceOff = true;
2776 }
2777 else if ( strcmp(arg, "-sdk_version") == 0 ) {
2778 const char* vers = argv[++i];
2779 if ( vers == NULL )
2780 throw "-sdk_version missing <version>";
2781 fSDKVersion = parseVersionNumber32(vers);
2782 }
2783 else if ( strcmp(arg, "-dependent_dr_info") == 0 ) {
2784 fDependentDRInfoForcedOn = true;
2785 }
2786 else if ( strcmp(arg, "-no_dependent_dr_info") == 0 ) {
2787 fDependentDRInfoForcedOff = true;
2788 }
2789 else if ( strcmp(arg, "-kexts_use_stubs") == 0 ) {
2790 fKextsUseStubs = true;
2791 }
2792 else {
2793 throwf("unknown option: %s", arg);
2794 }
2795
2796 if (snapshotArgCount == -1)
2797 snapshotArgCount = i-snapshotArgIndex+1;
2798 if (snapshotArgCount > 0)
2799 fLinkSnapshot.addSnapshotLinkArg(snapshotArgIndex, snapshotArgCount, snapshotFileArgIndex);
2800 }
2801 else {
2802 FileInfo info = findFile(arg);
2803 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2804 if ( strcmp(&info.path[strlen(info.path)-2], ".a") == 0 )
2805 addLibrary(info);
2806 else
2807 fInputFiles.push_back(info);
2808 }
2809 }
2810
2811 // if a -lazy option was used, implicitly link in lazydylib1.o
2812 if ( fUsingLazyDylibLinking ) {
2813 FileInfo info = findLibrary("lazydylib1.o");
2814 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)argc);
2815 addLibrary(info);
2816 }
2817
2818 if (fSnapshotRequested)
2819 fLinkSnapshot.createSnapshot();
2820 }
2821
2822
2823
2824 //
2825 // -syslibroot <path> is used for SDK support.
2826 // The rule is that all search paths (both explicit and default) are
2827 // checked to see if they exist in the SDK. If so, that path is
2828 // replaced with the sdk prefixed path. If not, that search path
2829 // is used as is. If multiple -syslibroot options are specified
2830 // their directory structures are logically overlayed and files
2831 // from sdks specified earlier on the command line used before later ones.
2832
2833 void Options::buildSearchPaths(int argc, const char* argv[])
2834 {
2835 bool addStandardLibraryDirectories = true;
2836 std::vector<const char*> libraryPaths;
2837 std::vector<const char*> frameworkPaths;
2838 libraryPaths.reserve(10);
2839 frameworkPaths.reserve(10);
2840 // scan through argv looking for -L, -F, -Z, and -syslibroot options
2841 for(int i=0; i < argc; ++i) {
2842 if ( (argv[i][0] == '-') && (argv[i][1] == 'L') ) {
2843 const char* libSearchDir = &argv[i][2];
2844 // Allow either "-L{path}" or "-L {path}".
2845 if (argv[i][2] == '\0') {
2846 // -L {path}. Make sure there is an argument following this.
2847 const char* path = argv[++i];
2848 if ( path == NULL )
2849 throw "-L missing argument";
2850 libSearchDir = path;
2851 }
2852 if ( libSearchDir[0] == '\0' )
2853 throw "-L must be immediately followed by a directory path (no space)";
2854 struct stat statbuf;
2855 if ( stat(libSearchDir, &statbuf) == 0 ) {
2856 if ( statbuf.st_mode & S_IFDIR )
2857 libraryPaths.push_back(libSearchDir);
2858 else
2859 warning("path '%s' following -L not a directory", libSearchDir);
2860 }
2861 else {
2862 warning("directory not found for option '-L%s'", libSearchDir);
2863 }
2864 }
2865 else if ( (argv[i][0] == '-') && (argv[i][1] == 'F') ) {
2866 const char* frameworkSearchDir = &argv[i][2];
2867 // Allow either "-F{path}" or "-F {path}".
2868 if (argv[i][2] == '\0') {
2869 // -F {path}. Make sure there is an argument following this.
2870 const char* path = argv[++i];
2871 if ( path == NULL )
2872 throw "-F missing argument";
2873 frameworkSearchDir = path;
2874 }
2875 if ( frameworkSearchDir[0] == '\0' )
2876 throw "-F must be immediately followed by a directory path (no space)";
2877 struct stat statbuf;
2878 if ( stat(frameworkSearchDir, &statbuf) == 0 ) {
2879 if ( statbuf.st_mode & S_IFDIR )
2880 frameworkPaths.push_back(frameworkSearchDir);
2881 else
2882 warning("path '%s' following -F not a directory", frameworkSearchDir);
2883 }
2884 else {
2885 warning("directory not found for option '-F%s'", frameworkSearchDir);
2886 }
2887 }
2888 else if ( strcmp(argv[i], "-Z") == 0 )
2889 addStandardLibraryDirectories = false;
2890 else if ( strcmp(argv[i], "-v") == 0 ) {
2891 fVerbose = true;
2892 extern const char ldVersionString[];
2893 fprintf(stderr, "%s", ldVersionString);
2894 fprintf(stderr, "configured to support archs: %s\n", ALL_SUPPORTED_ARCHS);
2895 // if only -v specified, exit cleanly
2896 if ( argc == 2 ) {
2897 const char* ltoVers = lto::version();
2898 if ( ltoVers != NULL )
2899 fprintf(stderr, "LTO support using: %s\n", ltoVers);
2900 exit(0);
2901 }
2902 }
2903 else if ( strcmp(argv[i], "-syslibroot") == 0 ) {
2904 const char* path = argv[++i];
2905 if ( path == NULL )
2906 throw "-syslibroot missing argument";
2907 fSDKPaths.push_back(path);
2908 }
2909 else if ( strcmp(argv[i], "-search_paths_first") == 0 ) {
2910 fLibrarySearchMode = kSearchDylibAndArchiveInEachDir;
2911 }
2912 else if ( strcmp(argv[i], "-search_dylibs_first") == 0 ) {
2913 fLibrarySearchMode = kSearchAllDirsForDylibsThenAllDirsForArchives;
2914 }
2915 else if ( strcmp(argv[i], "-w") == 0 ) {
2916 sEmitWarnings = false;
2917 }
2918 else if ( strcmp(argv[i], "-fatal_warnings") == 0 ) {
2919 sFatalWarnings = true;
2920 }
2921 }
2922 int standardLibraryPathsStartIndex = libraryPaths.size();
2923 int standardFrameworkPathsStartIndex = frameworkPaths.size();
2924 if ( addStandardLibraryDirectories ) {
2925 libraryPaths.push_back("/usr/lib");
2926 libraryPaths.push_back("/usr/local/lib");
2927
2928 frameworkPaths.push_back("/Library/Frameworks/");
2929 frameworkPaths.push_back("/System/Library/Frameworks/");
2930 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
2931 }
2932
2933 // <rdar://problem/5829579> Support for configure based hacks
2934 // if last -syslibroot is /, then ignore all syslibroots
2935 if ( fSDKPaths.size() > 0 ) {
2936 if ( strcmp(fSDKPaths.back(), "/") == 0 ) {
2937 fSDKPaths.clear();
2938 }
2939 }
2940
2941 // now merge sdk and library paths to make real search paths
2942 fLibrarySearchPaths.reserve(libraryPaths.size()*(fSDKPaths.size()+1));
2943 int libIndex = 0;
2944 for (std::vector<const char*>::iterator it = libraryPaths.begin(); it != libraryPaths.end(); ++it, ++libIndex) {
2945 const char* libDir = *it;
2946 bool sdkOverride = false;
2947 if ( libDir[0] == '/' ) {
2948 char betterLibDir[PATH_MAX];
2949 if ( strstr(libDir, "/..") != NULL ) {
2950 if ( realpath(libDir, betterLibDir) != NULL )
2951 libDir = strdup(betterLibDir);
2952 }
2953 const int libDirLen = strlen(libDir);
2954 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
2955 const char* sdkDir = *sdkit;
2956 const int sdkDirLen = strlen(sdkDir);
2957 char newPath[libDirLen + sdkDirLen+4];
2958 strcpy(newPath, sdkDir);
2959 if ( newPath[sdkDirLen-1] == '/' )
2960 newPath[sdkDirLen-1] = '\0';
2961 strcat(newPath, libDir);
2962 struct stat statBuffer;
2963 if ( stat(newPath, &statBuffer) == 0 ) {
2964 fLibrarySearchPaths.push_back(strdup(newPath));
2965 sdkOverride = true;
2966 }
2967 }
2968 }
2969 if ( !sdkOverride ) {
2970 if ( (libIndex >= standardLibraryPathsStartIndex) && (fSDKPaths.size() == 1) ) {
2971 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
2972 // if one SDK is specified and a standard library path is not in the SDK, don't use it
2973 }
2974 else {
2975 fLibrarySearchPaths.push_back(libDir);
2976 }
2977 }
2978 }
2979
2980 // now merge sdk and framework paths to make real search paths
2981 fFrameworkSearchPaths.reserve(frameworkPaths.size()*(fSDKPaths.size()+1));
2982 int frameIndex = 0;
2983 for (std::vector<const char*>::iterator it = frameworkPaths.begin(); it != frameworkPaths.end(); ++it, ++frameIndex) {
2984 const char* frameworkDir = *it;
2985 bool sdkOverride = false;
2986 if ( frameworkDir[0] == '/' ) {
2987 char betterFrameworkDir[PATH_MAX];
2988 if ( strstr(frameworkDir, "/..") != NULL ) {
2989 if ( realpath(frameworkDir, betterFrameworkDir) != NULL )
2990 frameworkDir = strdup(betterFrameworkDir);
2991 }
2992 const int frameworkDirLen = strlen(frameworkDir);
2993 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
2994 const char* sdkDir = *sdkit;
2995 const int sdkDirLen = strlen(sdkDir);
2996 char newPath[frameworkDirLen + sdkDirLen+4];
2997 strcpy(newPath, sdkDir);
2998 if ( newPath[sdkDirLen-1] == '/' )
2999 newPath[sdkDirLen-1] = '\0';
3000 strcat(newPath, frameworkDir);
3001 struct stat statBuffer;
3002 if ( stat(newPath, &statBuffer) == 0 ) {
3003 fFrameworkSearchPaths.push_back(strdup(newPath));
3004 sdkOverride = true;
3005 }
3006 }
3007 }
3008 if ( !sdkOverride ) {
3009 if ( (frameIndex >= standardFrameworkPathsStartIndex) && (fSDKPaths.size() == 1) ) {
3010 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3011 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3012 }
3013 else {
3014 fFrameworkSearchPaths.push_back(frameworkDir);
3015 }
3016 }
3017 }
3018
3019 if ( fVerbose ) {
3020 fprintf(stderr,"Library search paths:\n");
3021 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
3022 it != fLibrarySearchPaths.end();
3023 it++)
3024 fprintf(stderr,"\t%s\n", *it);
3025 fprintf(stderr,"Framework search paths:\n");
3026 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
3027 it != fFrameworkSearchPaths.end();
3028 it++)
3029 fprintf(stderr,"\t%s\n", *it);
3030 }
3031 }
3032
3033 // this is run before the command line is parsed
3034 void Options::parsePreCommandLineEnvironmentSettings()
3035 {
3036 if ((getenv("LD_TRACE_ARCHIVES") != NULL)
3037 || (getenv("RC_TRACE_ARCHIVES") != NULL))
3038 fTraceArchives = true;
3039
3040 if ((getenv("LD_TRACE_DYLIBS") != NULL)
3041 || (getenv("RC_TRACE_DYLIBS") != NULL)) {
3042 fTraceDylibs = true;
3043 fTraceIndirectDylibs = true;
3044 }
3045
3046 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL) {
3047 fTraceDylibSearching = true;
3048 }
3049
3050 if (getenv("LD_PRINT_OPTIONS") != NULL)
3051 fPrintOptions = true;
3052
3053 if (fTraceDylibs || fTraceArchives)
3054 fTraceOutputFile = getenv("LD_TRACE_FILE");
3055
3056 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL)
3057 fPrintOrderFileStatistics = true;
3058
3059 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL)
3060 fSplitSegs = true;
3061
3062 if (getenv("LD_NO_ENCRYPT") != NULL)
3063 fEncryptable = false;
3064
3065 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL)
3066 fAllowCpuSubtypeMismatches = true;
3067
3068 sWarningsSideFilePath = getenv("LD_WARN_FILE");
3069
3070 const char* customDyldPath = getenv("LD_DYLD_PATH");
3071 if ( customDyldPath != NULL )
3072 fDyldInstallPath = customDyldPath;
3073
3074 const char* debugArchivePath = getenv("LD_DEBUG_SNAPSHOT");
3075 if (debugArchivePath != NULL) {
3076 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
3077 if (strlen(debugArchivePath) > 0)
3078 fLinkSnapshot.setSnapshotPath(debugArchivePath);
3079 fSnapshotRequested = true;
3080 }
3081
3082 const char* pipeFdString = getenv("LD_PIPELINE_FIFO");
3083 if (pipeFdString != NULL) {
3084 fPipelineFifo = pipeFdString;
3085 }
3086 }
3087
3088
3089 // this is run after the command line is parsed
3090 void Options::parsePostCommandLineEnvironmentSettings()
3091 {
3092 // when building a dynamic main executable, default any use of @executable_path to output path
3093 if ( fExecutablePath == NULL && (fOutputKind == kDynamicExecutable) ) {
3094 fExecutablePath = fOutputFile;
3095 }
3096
3097 // allow build system to set default seg_addr_table
3098 if ( fSegAddrTablePath == NULL )
3099 fSegAddrTablePath = getenv("LD_SEG_ADDR_TABLE");
3100
3101 // allow build system to turn on prebinding
3102 if ( !fPrebind ) {
3103 fPrebind = ( getenv("LD_PREBIND") != NULL );
3104 }
3105
3106 // allow build system to force on dead-code-stripping
3107 if ( !fDeadStrip ) {
3108 if ( getenv("LD_DEAD_STRIP") != NULL ) {
3109 switch (fOutputKind) {
3110 case Options::kDynamicLibrary:
3111 case Options::kDynamicExecutable:
3112 case Options::kDynamicBundle:
3113 fDeadStrip = true;
3114 break;
3115 case Options::kPreload:
3116 case Options::kObjectFile:
3117 case Options::kDyld:
3118 case Options::kStaticExecutable:
3119 case Options::kKextBundle:
3120 break;
3121 }
3122 }
3123 }
3124
3125 // allow build system to force on -warn_commons
3126 if ( getenv("LD_WARN_COMMONS") != NULL )
3127 fWarnCommons = true;
3128
3129 // allow B&I to set default -source_version
3130 if ( fSourceVersion == 0 ) {
3131 const char* vers = getenv("RC_ProjectSourceVersion");
3132 if ( vers != NULL )
3133 fSourceVersion = parseVersionNumber64(vers);
3134 }
3135
3136 }
3137
3138 void Options::reconfigureDefaults()
3139 {
3140 // sync reader options
3141 switch ( fOutputKind ) {
3142 case Options::kObjectFile:
3143 fForFinalLinkedImage = false;
3144 break;
3145 case Options::kDyld:
3146 fForDyld = true;
3147 fForFinalLinkedImage = true;
3148 fNoEHLabels = true;
3149 break;
3150 case Options::kDynamicLibrary:
3151 case Options::kDynamicBundle:
3152 case Options::kKextBundle:
3153 fForFinalLinkedImage = true;
3154 fNoEHLabels = true;
3155 break;
3156 case Options::kDynamicExecutable:
3157 case Options::kStaticExecutable:
3158 case Options::kPreload:
3159 fLinkingMainExecutable = true;
3160 fForFinalLinkedImage = true;
3161 fNoEHLabels = true;
3162 break;
3163 }
3164
3165 // set default min OS version
3166 if ( (fMacVersionMin == ld::macVersionUnset)
3167 && (fIOSVersionMin == ld::iOSVersionUnset) ) {
3168 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
3169 const char* macVers = getenv("MACOSX_DEPLOYMENT_TARGET");
3170 const char* iPhoneVers = getenv("IPHONEOS_DEPLOYMENT_TARGET");
3171 const char* iOSVers = getenv("IOS_DEPLOYMENT_TARGET");
3172 const char* iOSSimulatorVers = getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET");
3173 if ( macVers != NULL )
3174 setMacOSXVersionMin(macVers);
3175 else if ( iPhoneVers != NULL )
3176 setIOSVersionMin(iPhoneVers);
3177 else if ( iOSVers != NULL )
3178 setIOSVersionMin(iOSVers);
3179 else if ( iOSSimulatorVers != NULL )
3180 setIOSVersionMin(iOSSimulatorVers);
3181 else {
3182 // if still nothing, set default based on architecture
3183 switch ( fArchitecture ) {
3184 case CPU_TYPE_I386:
3185 case CPU_TYPE_X86_64:
3186 if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
3187 #ifdef DEFAULT_MACOSX_MIN_VERSION
3188 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
3189 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
3190 #else
3191 warning("-macosx_version_min not specified, assuming 10.6");
3192 fMacVersionMin = ld::mac10_6;
3193 #endif
3194 }
3195 break;
3196 case CPU_TYPE_ARM:
3197 if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
3198 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
3199 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION);
3200 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION);
3201 #elif defined(DEFAULT_MACOSX_MIN_VERSION)
3202 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
3203 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
3204 #else
3205 warning("-macosx_version_min not specified, assuming 10.6");
3206 fMacVersionMin = ld::mac10_6;
3207 #endif
3208 }
3209 break;
3210 default:
3211 // architecture will be infered ;ater by examining .o files
3212 break;
3213 }
3214 }
3215 }
3216
3217
3218 // adjust min based on architecture
3219 switch ( fArchitecture ) {
3220 case CPU_TYPE_I386:
3221 if ( (fMacVersionMin < ld::mac10_4) && (fIOSVersionMin == ld::iOSVersionUnset) ) {
3222 //warning("-macosx_version_min should be 10.4 or later for i386");
3223 fMacVersionMin = ld::mac10_4;
3224 }
3225 break;
3226 case CPU_TYPE_X86_64:
3227 if ( (fMacVersionMin < ld::mac10_4) && (fIOSVersionMin == ld::iOSVersionUnset) ) {
3228 //warning("-macosx_version_min should be 10.4 or later for x86_64");
3229 fMacVersionMin = ld::mac10_4;
3230 }
3231 break;
3232 }
3233
3234 // default to adding functions start for dynamic code, static code must opt-in
3235 switch ( fOutputKind ) {
3236 case Options::kPreload:
3237 case Options::kStaticExecutable:
3238 case Options::kKextBundle:
3239 if ( fDataInCodeInfoLoadCommandForcedOn )
3240 fDataInCodeInfoLoadCommand = true;
3241 if ( fFunctionStartsForcedOn )
3242 fFunctionStartsLoadCommand = true;
3243 break;
3244 case Options::kObjectFile:
3245 case Options::kDynamicExecutable:
3246 case Options::kDyld:
3247 case Options::kDynamicLibrary:
3248 case Options::kDynamicBundle:
3249 if ( !fDataInCodeInfoLoadCommandForcedOff )
3250 fDataInCodeInfoLoadCommand = true;
3251 if ( !fFunctionStartsForcedOff )
3252 fFunctionStartsLoadCommand = true;
3253 break;
3254 }
3255
3256 // adjust kext type based on architecture
3257 if ( fOutputKind == kKextBundle ) {
3258 switch ( fArchitecture ) {
3259 case CPU_TYPE_X86_64:
3260 // x86_64 uses new MH_KEXT_BUNDLE type
3261 fMakeCompressedDyldInfo = false;
3262 fMakeCompressedDyldInfoForceOff = true;
3263 fAllowTextRelocs = true;
3264 fUndefinedTreatment = kUndefinedDynamicLookup;
3265 break;
3266 case CPU_TYPE_ARM:
3267 if ( fIOSVersionMin >= ld::iOS_5_0 ) {
3268 // iOS 5.0 and later use new MH_KEXT_BUNDLE type
3269 fMakeCompressedDyldInfo = false;
3270 fMakeCompressedDyldInfoForceOff = true;
3271 // kexts are PIC in iOS 6.0 and later
3272 fAllowTextRelocs = (fIOSVersionMin < ld::iOS_6_0);
3273 fKextsUseStubs = !fAllowTextRelocs;
3274 fUndefinedTreatment = kUndefinedDynamicLookup;
3275 break;
3276 }
3277 // else use object file
3278 case CPU_TYPE_I386:
3279 // use .o files
3280 fOutputKind = kObjectFile;
3281 break;
3282 }
3283 }
3284
3285 // disable implicit dylibs when targeting 10.3
3286 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
3287 if ( !minOS(ld::mac10_4, ld::iOS_2_0) )
3288 fImplicitlyLinkPublicDylibs = false;
3289
3290
3291 // allow build system to force linker to ignore -prebind
3292 if ( getenv("LD_FORCE_NO_PREBIND") != NULL )
3293 fPrebind = false;
3294
3295 // allow build system to force linker to ignore -seg_addr_table
3296 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL )
3297 fSegAddrTablePath = NULL;
3298
3299 // check for base address specified externally
3300 if ( (fSegAddrTablePath != NULL) && (fOutputKind == Options::kDynamicLibrary) ) {
3301 parseSegAddrTable(fSegAddrTablePath, this->installPath());
3302 // HACK to support seg_addr_table entries that are physical paths instead of install paths
3303 if ( fBaseAddress == 0 ) {
3304 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
3305 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.4.dylib");
3306 if ( fBaseAddress == 0 )
3307 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.9.dylib");
3308 }
3309
3310 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
3311 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libz.1.2.3.dylib");
3312
3313 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
3314 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libutil1.0.dylib");
3315 }
3316 }
3317
3318 // split segs only allowed for dylibs
3319 if ( fSplitSegs ) {
3320 // split seg only supported for i386, and arm.
3321 switch ( fArchitecture ) {
3322 case CPU_TYPE_I386:
3323 if ( fOutputKind != Options::kDynamicLibrary )
3324 fSplitSegs = false;
3325 // make sure read and write segments are proper distance apart
3326 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x10000000) )
3327 fBaseWritableAddress = fBaseAddress + 0x10000000;
3328 break;
3329 case CPU_TYPE_ARM:
3330 if ( fOutputKind != Options::kDynamicLibrary ) {
3331 fSplitSegs = false;
3332 }
3333 else {
3334 // make sure read and write segments are proper distance apart
3335 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x08000000) )
3336 fBaseWritableAddress = fBaseAddress + 0x08000000;
3337 }
3338 break;
3339 default:
3340 fSplitSegs = false;
3341 fBaseAddress = 0;
3342 fBaseWritableAddress = 0;
3343 }
3344 }
3345
3346 // set too-large size
3347 switch ( fArchitecture ) {
3348 case CPU_TYPE_I386:
3349 fMaxAddress = 0xFFFFFFFF;
3350 break;
3351 case CPU_TYPE_X86_64:
3352 break;
3353 case CPU_TYPE_ARM:
3354 switch ( fOutputKind ) {
3355 case Options::kDynamicExecutable:
3356 case Options::kDynamicLibrary:
3357 case Options::kDynamicBundle:
3358 // user land code is limited to low 1GB
3359 fMaxAddress = 0x2FFFFFFF;
3360 break;
3361 case Options::kStaticExecutable:
3362 case Options::kObjectFile:
3363 case Options::kDyld:
3364 case Options::kPreload:
3365 case Options::kKextBundle:
3366 fMaxAddress = 0xFFFFFFFF;
3367 break;
3368 }
3369 // range check -seg1addr for ARM
3370 if ( fBaseAddress > fMaxAddress ) {
3371 warning("ignoring -seg1addr 0x%08llX. Address out of range.", fBaseAddress);
3372 fBaseAddress = 0;
3373 }
3374 break;
3375 }
3376
3377 // <rdar://problem/6138961> -r implies no prebinding for all architectures
3378 if ( fOutputKind == Options::kObjectFile )
3379 fPrebind = false;
3380
3381 // disable prebinding depending on arch and min OS version
3382 if ( fPrebind ) {
3383 switch ( fArchitecture ) {
3384 case CPU_TYPE_I386:
3385 if ( fMacVersionMin == ld::mac10_4 ) {
3386 // in 10.4 only split seg dylibs are prebound
3387 if ( (fOutputKind != Options::kDynamicLibrary) || ! fSplitSegs )
3388 fPrebind = false;
3389 }
3390 else if ( fMacVersionMin >= ld::mac10_5 ) {
3391 // in 10.5 nothing is prebound
3392 fPrebind = false;
3393 }
3394 else if ( fIOSVersionMin != ld::iOSVersionUnset ) {
3395 // nothing in simulator is prebound
3396 fPrebind = false;
3397 }
3398 else {
3399 // in 10.3 and earlier only dylibs and main executables could be prebound
3400 switch ( fOutputKind ) {
3401 case Options::kDynamicExecutable:
3402 case Options::kDynamicLibrary:
3403 // only main executables and dylibs can be prebound
3404 break;
3405 case Options::kStaticExecutable:
3406 case Options::kDynamicBundle:
3407 case Options::kObjectFile:
3408 case Options::kDyld:
3409 case Options::kPreload:
3410 case Options::kKextBundle:
3411 // disable prebinding for everything else
3412 fPrebind = false;
3413 break;
3414 }
3415 }
3416 break;
3417 case CPU_TYPE_X86_64:
3418 fPrebind = false;
3419 break;
3420 case CPU_TYPE_ARM:
3421 switch ( fOutputKind ) {
3422 case Options::kDynamicExecutable:
3423 case Options::kDynamicLibrary:
3424 // only main executables and dylibs can be prebound
3425 break;
3426 case Options::kStaticExecutable:
3427 case Options::kDynamicBundle:
3428 case Options::kObjectFile:
3429 case Options::kDyld:
3430 case Options::kPreload:
3431 case Options::kKextBundle:
3432 // disable prebinding for everything else
3433 fPrebind = false;
3434 break;
3435 }
3436 break;
3437 }
3438 }
3439
3440 // only prebound images can be split-seg
3441 if ( fSplitSegs && !fPrebind )
3442 fSplitSegs = false;
3443
3444 // determine if info for shared region should be added
3445 if ( fOutputKind == Options::kDynamicLibrary ) {
3446 if ( minOS(ld::mac10_5, ld::iOS_3_1) )
3447 if ( !fPrebind )
3448 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
3449 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
3450 fSharedRegionEligible = true;
3451 }
3452 else if ( fOutputKind == Options::kDyld ) {
3453 // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
3454 fSharedRegionEligible = true;
3455 }
3456
3457 // figure out if module table is needed for compatibility with old ld/dyld
3458 if ( fOutputKind == Options::kDynamicLibrary ) {
3459 switch ( fArchitecture ) {
3460 case CPU_TYPE_I386:
3461 if ( fIOSVersionMin != ld::iOSVersionUnset ) // simulator never needs modules
3462 break;
3463 case CPU_TYPE_ARM:
3464 if ( fPrebind )
3465 fNeedsModuleTable = true; // redo_prebinding requires a module table
3466 break;
3467 }
3468 }
3469
3470 // <rdar://problem/5366363> -r -x implies -S
3471 if ( (fOutputKind == Options::kObjectFile) && (fLocalSymbolHandling == kLocalSymbolsNone) )
3472 fDebugInfoStripping = Options::kDebugInfoNone;
3473
3474 // choose how to process unwind info
3475 switch ( fArchitecture ) {
3476 case CPU_TYPE_I386:
3477 case CPU_TYPE_X86_64:
3478 switch ( fOutputKind ) {
3479 case Options::kObjectFile:
3480 case Options::kStaticExecutable:
3481 case Options::kPreload:
3482 case Options::kKextBundle:
3483 fAddCompactUnwindEncoding = false;
3484 break;
3485 case Options::kDyld:
3486 case Options::kDynamicLibrary:
3487 case Options::kDynamicBundle:
3488 case Options::kDynamicExecutable:
3489 //if ( fAddCompactUnwindEncoding && (fVersionMin >= ld::mac10_6) )
3490 // fRemoveDwarfUnwindIfCompactExists = true;
3491 break;
3492 }
3493 break;
3494 case CPU_TYPE_ARM:
3495 fAddCompactUnwindEncoding = false;
3496 fRemoveDwarfUnwindIfCompactExists = false;
3497 break;
3498 case 0:
3499 // if -arch is missing, assume we don't want compact unwind info
3500 fAddCompactUnwindEncoding = false;
3501 break;
3502 }
3503
3504 // only ARM main executables can be encrypted
3505 if ( fOutputKind != Options::kDynamicExecutable )
3506 fEncryptable = false;
3507 if ( fArchitecture != CPU_TYPE_ARM )
3508 fEncryptable = false;
3509
3510 // don't move inits in dyld because dyld wants certain
3511 // entries point at stable locations at the start of __text
3512 if ( fOutputKind == Options::kDyld )
3513 fAutoOrderInitializers = false;
3514
3515
3516 // disable __data ordering for some output kinds
3517 switch ( fOutputKind ) {
3518 case Options::kObjectFile:
3519 case Options::kDyld:
3520 case Options::kStaticExecutable:
3521 case Options::kPreload:
3522 case Options::kKextBundle:
3523 fOrderData = false;
3524 break;
3525 case Options::kDynamicExecutable:
3526 case Options::kDynamicLibrary:
3527 case Options::kDynamicBundle:
3528 break;
3529 }
3530
3531 // only use compressed LINKEDIT for final linked images
3532 switch ( fOutputKind ) {
3533 case Options::kDynamicExecutable:
3534 case Options::kDynamicLibrary:
3535 case Options::kDynamicBundle:
3536 break;
3537 case Options::kPreload:
3538 case Options::kStaticExecutable:
3539 case Options::kObjectFile:
3540 case Options::kDyld:
3541 case Options::kKextBundle:
3542 fMakeCompressedDyldInfoForceOff = true;
3543 break;
3544 }
3545 if ( fMakeCompressedDyldInfoForceOff )
3546 fMakeCompressedDyldInfo = false;
3547
3548
3549 // only use compressed LINKEDIT for:
3550 // Mac OS X 10.6 or later
3551 // iOS 3.1 or later
3552 if ( fMakeCompressedDyldInfo ) {
3553 if ( !minOS(ld::mac10_6, ld::iOS_3_1) )
3554 fMakeCompressedDyldInfo = false;
3555 }
3556
3557
3558 // only ARM enforces that cpu-sub-types must match
3559 if ( fArchitecture != CPU_TYPE_ARM )
3560 fAllowCpuSubtypeMismatches = true;
3561
3562 // only final linked images can not optimize zero fill sections
3563 if ( fOutputKind == Options::kObjectFile )
3564 fOptimizeZeroFill = true;
3565
3566 // all undefines in -r mode
3567 // if ( fOutputKind == Options::kObjectFile )
3568 // fUndefinedTreatment = kUndefinedSuppress;
3569
3570 // only dynamic final linked images should warn about use of commmons
3571 if ( fWarnCommons ) {
3572 switch ( fOutputKind ) {
3573 case Options::kDynamicExecutable:
3574 case Options::kDynamicLibrary:
3575 case Options::kDynamicBundle:
3576 break;
3577 case Options::kPreload:
3578 case Options::kStaticExecutable:
3579 case Options::kObjectFile:
3580 case Options::kDyld:
3581 case Options::kKextBundle:
3582 fWarnCommons = false;
3583 break;
3584 }
3585 }
3586
3587 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
3588 if ( minOS(ld::mac10_5, ld::iOS_2_0) )
3589 fUseSimplifiedDylibReExports = true;
3590
3591 // Mac OS X 10.7 and iOS 4.2 support LC_LOAD_UPWARD_DYLIB
3592 if ( minOS(ld::mac10_7, ld::iOS_4_2) && (fOutputKind == kDynamicLibrary) )
3593 fCanUseUpwardDylib = true;
3594
3595 // MacOSX 10.7 defaults to PIE
3596 if ( ((fArchitecture == CPU_TYPE_X86_64) || (fArchitecture == CPU_TYPE_I386))
3597 && (fOutputKind == kDynamicExecutable)
3598 && (fMacVersionMin >= ld::mac10_7) ) {
3599 fPositionIndependentExecutable = true;
3600 }
3601
3602 // armv7 for iOS4.3 defaults to PIE
3603 if ( (fArchitecture == CPU_TYPE_ARM)
3604 && fArchSupportsThumb2
3605 && (fOutputKind == kDynamicExecutable)
3606 && (fIOSVersionMin >= ld::iOS_4_3) ) {
3607 fPositionIndependentExecutable = true;
3608 }
3609
3610 // -no_pie anywhere on command line disable PIE
3611 if ( fDisablePositionIndependentExecutable )
3612 fPositionIndependentExecutable = false;
3613
3614 // set fOutputSlidable
3615 switch ( fOutputKind ) {
3616 case Options::kObjectFile:
3617 fOutputSlidable = false;
3618 break;
3619 case Options::kStaticExecutable:
3620 case Options::kDynamicExecutable:
3621 fOutputSlidable = fPositionIndependentExecutable;
3622 break;
3623 case Options::kPreload:
3624 fOutputSlidable = fPIEOnCommandLine;
3625 break;
3626 case Options::kDyld:
3627 case Options::kDynamicLibrary:
3628 case Options::kDynamicBundle:
3629 case Options::kKextBundle:
3630 fOutputSlidable = true;
3631 break;
3632 }
3633
3634 // let linker know if thread local variables are supported
3635 if ( fMacVersionMin >= ld::mac10_7 ) {
3636 fTLVSupport = true;
3637 }
3638
3639 // default to adding version load command for dynamic code, static code must opt-in
3640 switch ( fOutputKind ) {
3641 case Options::kObjectFile:
3642 fVersionLoadCommand = false;
3643 break;
3644 case Options::kStaticExecutable:
3645 case Options::kPreload:
3646 case Options::kKextBundle:
3647 if ( fVersionLoadCommandForcedOn )
3648 fVersionLoadCommand = true;
3649 break;
3650 case Options::kDynamicExecutable:
3651 case Options::kDyld:
3652 case Options::kDynamicLibrary:
3653 case Options::kDynamicBundle:
3654 if ( !fVersionLoadCommandForcedOff )
3655 fVersionLoadCommand = true;
3656 // <rdar://problem/9945513> for now, don't create version load commands for iOS simulator builds
3657 if ( fVersionLoadCommand && (fArchitecture == CPU_TYPE_I386) ) {
3658 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
3659 if ( strstr(*sdkit, "/iPhoneSimulator.platform/") != NULL )
3660 fVersionLoadCommand = false;
3661 }
3662 }
3663 break;
3664 }
3665
3666 // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
3667 if ( (fOutputKind == kDynamicLibrary) && minOS(ld::mac10_7, ld::iOS_4_2) )
3668 fCanReExportSymbols = true;
3669
3670 // ObjC optimization is only in dynamic final linked images
3671 switch ( fOutputKind ) {
3672 case Options::kObjectFile:
3673 case Options::kStaticExecutable:
3674 case Options::kPreload:
3675 case Options::kKextBundle:
3676 case Options::kDyld:
3677 fObjcCategoryMerging = false;
3678 break;
3679 case Options::kDynamicExecutable:
3680 case Options::kDynamicLibrary:
3681 case Options::kDynamicBundle:
3682 break;
3683 }
3684
3685 // i386 main executables linked on Mac OS X 10.7 default to NX heap
3686 // regardless of target unless overriden with -allow_heap_execute anywhere
3687 // on the command line
3688 if ( (fArchitecture == CPU_TYPE_I386) && (fOutputKind == kDynamicExecutable) && !fDisableNonExecutableHeap)
3689 fNonExecutableHeap = true;
3690
3691 // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
3692 switch ( fOutputKind ) {
3693 case Options::kDynamicExecutable:
3694 if ( fEntryPointLoadCommandForceOn ) {
3695 fEntryPointLoadCommand = true;
3696 fEntryName = "_main";
3697 }
3698 else if ( fEntryPointLoadCommandForceOff ) {
3699 fNeedsThreadLoadCommand = true;
3700 }
3701 else {
3702 if ( (fIOSVersionMin != ld::iOSVersionUnset) && (fArchitecture == CPU_TYPE_I386) ) {
3703 // don't use LC_MAIN for simulator until min host OS is 10.8 for simulator
3704 fNeedsThreadLoadCommand = true;
3705 fEntryPointLoadCommand = false;
3706 }
3707 else if ( minOS(ld::mac10_8, ld::iOS_6_0) ) {
3708 fEntryPointLoadCommand = true;
3709 fEntryName = "_main";
3710 }
3711 else
3712 fNeedsThreadLoadCommand = true;
3713 }
3714 break;
3715 case Options::kObjectFile:
3716 case Options::kKextBundle:
3717 case Options::kDynamicLibrary:
3718 case Options::kDynamicBundle:
3719 break;
3720
3721 case Options::kStaticExecutable:
3722 case Options::kPreload:
3723 case Options::kDyld:
3724 fNeedsThreadLoadCommand = true;
3725 break;
3726 }
3727
3728 // add LC_SOURCE_VERSION
3729 switch ( fOutputKind ) {
3730 case Options::kDynamicExecutable:
3731 case Options::kKextBundle:
3732 case Options::kDynamicLibrary:
3733 case Options::kDynamicBundle:
3734 case Options::kDyld:
3735 case Options::kStaticExecutable:
3736 if ( fSourceVersionLoadCommandForceOn ) {
3737 fSourceVersionLoadCommand = true;
3738 }
3739 else if ( fSourceVersionLoadCommandForceOff ) {
3740 fSourceVersionLoadCommand = false;
3741 }
3742 else {
3743 if ( minOS(ld::mac10_8, ld::iOS_6_0) ) {
3744 fSourceVersionLoadCommand = true;
3745 }
3746 else
3747 fSourceVersionLoadCommand = false;
3748 }
3749 break;
3750 case Options::kObjectFile:
3751 case Options::kPreload:
3752 fSourceVersionLoadCommand = false;
3753 break;
3754 }
3755
3756
3757 // add LC_DYLIB_CODE_SIGN_DRS
3758 switch ( fOutputKind ) {
3759 case Options::kDynamicExecutable:
3760 case Options::kDynamicLibrary:
3761 case Options::kDynamicBundle:
3762 if ( fDependentDRInfoForcedOn ) {
3763 fDependentDRInfo = true;
3764 }
3765 else if ( fDependentDRInfoForcedOff ) {
3766 fDependentDRInfo = false;
3767 }
3768 else {
3769 if ( minOS(ld::mac10_8, ld::iOS_6_0) )
3770 fDependentDRInfo = true;
3771 else
3772 fDependentDRInfo = false;
3773 }
3774 break;
3775 case Options::kKextBundle:
3776 case Options::kDyld:
3777 case Options::kStaticExecutable:
3778 case Options::kObjectFile:
3779 case Options::kPreload:
3780 fDependentDRInfo = false;
3781 break;
3782 }
3783
3784 // if -sdk_version not on command line, infer from -syslibroot
3785 if ( (fSDKVersion == 0) && (fSDKPaths.size() > 0) ) {
3786 const char* sdkPath = fSDKPaths.front();
3787 const char* end = &sdkPath[strlen(sdkPath)-1];
3788 while ( !isdigit(*end) && (end > sdkPath) )
3789 --end;
3790 const char* start = end-1;
3791 while ( (isdigit(*start) || (*start == '.')) && (start > sdkPath))
3792 --start;
3793 char sdkVersionStr[32];
3794 int len = end-start+1;
3795 if ( len > 2 ) {
3796 strlcpy(sdkVersionStr, start+1, len);
3797 fSDKVersion = parseVersionNumber32(sdkVersionStr);
3798 }
3799 }
3800
3801 // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
3802 if ( (fSDKVersion == 0) && (fMacVersionMin != ld::macVersionUnset) ) {
3803 // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
3804 if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
3805 fSDKVersion = fMacVersionMin;
3806 }
3807 else {
3808 int mib[2] = { CTL_KERN, KERN_OSRELEASE };
3809 char kernVersStr[100];
3810 size_t strlen = sizeof(kernVersStr);
3811 if ( sysctl(mib, 2, kernVersStr, &strlen, NULL, 0) != -1 ) {
3812 uint32_t kernVers = parseVersionNumber32(kernVersStr);
3813 int minor = (kernVers >> 16) - 4; // kernel major version is 4 ahead of x in 10.x
3814 fSDKVersion = 0x000A0000 + (minor << 8);
3815 }
3816 }
3817 }
3818
3819 }
3820
3821 void Options::checkIllegalOptionCombinations()
3822 {
3823 // check -undefined setting
3824 switch ( fUndefinedTreatment ) {
3825 case kUndefinedError:
3826 case kUndefinedDynamicLookup:
3827 // always legal
3828 break;
3829 case kUndefinedWarning:
3830 case kUndefinedSuppress:
3831 // requires flat namespace
3832 if ( fNameSpace == kTwoLevelNameSpace )
3833 throw "can't use -undefined warning or suppress with -twolevel_namespace";
3834 break;
3835 }
3836
3837 // unify -sub_umbrella with dylibs
3838 for (std::vector<const char*>::iterator it = fSubUmbellas.begin(); it != fSubUmbellas.end(); it++) {
3839 const char* subUmbrella = *it;
3840 bool found = false;
3841 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
3842 Options::FileInfo& info = *fit;
3843 const char* lastSlash = strrchr(info.path, '/');
3844 if ( lastSlash == NULL )
3845 lastSlash = info.path - 1;
3846 if ( strcmp(&lastSlash[1], subUmbrella) == 0 ) {
3847 info.options.fReExport = true;
3848 found = true;
3849 fLinkSnapshot.recordSubUmbrella(info.path);
3850 break;
3851 }
3852 }
3853 if ( ! found )
3854 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella);
3855 }
3856
3857 // unify -sub_library with dylibs
3858 for (std::vector<const char*>::iterator it = fSubLibraries.begin(); it != fSubLibraries.end(); it++) {
3859 const char* subLibrary = *it;
3860 bool found = false;
3861 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
3862 Options::FileInfo& info = *fit;
3863 const char* lastSlash = strrchr(info.path, '/');
3864 if ( lastSlash == NULL )
3865 lastSlash = info.path - 1;
3866 const char* dot = strchr(&lastSlash[1], '.');
3867 if ( dot == NULL )
3868 dot = &lastSlash[strlen(lastSlash)];
3869 if ( strncmp(&lastSlash[1], subLibrary, dot-lastSlash-1) == 0 ) {
3870 info.options.fReExport = true;
3871 found = true;
3872 fLinkSnapshot.recordSubLibrary(info.path);
3873 break;
3874 }
3875 }
3876 if ( ! found )
3877 warning("-sub_library %s does not match a supplied dylib", subLibrary);
3878 }
3879
3880 // sync reader options
3881 if ( fNameSpace != kTwoLevelNameSpace )
3882 fFlatNamespace = true;
3883
3884 // check -stack_addr
3885 if ( fStackAddr != 0 ) {
3886 switch (fArchitecture) {
3887 case CPU_TYPE_I386:
3888 case CPU_TYPE_ARM:
3889 if ( fStackAddr > 0xFFFFFFFF )
3890 throw "-stack_addr must be < 4G for 32-bit processes";
3891 break;
3892 case CPU_TYPE_X86_64:
3893 break;
3894 }
3895 if ( (fStackAddr & -4096) != fStackAddr )
3896 throw "-stack_addr must be multiples of 4K";
3897 if ( fStackSize == 0 )
3898 throw "-stack_addr must be used with -stack_size";
3899 }
3900
3901 // check -stack_size
3902 if ( fStackSize != 0 ) {
3903 switch (fArchitecture) {
3904 case CPU_TYPE_I386:
3905 if ( fStackSize > 0xFFFFFFFF )
3906 throw "-stack_size must be < 4G for 32-bit processes";
3907 if ( fStackAddr == 0 ) {
3908 fStackAddr = 0xC0000000;
3909 }
3910 if ( (fStackAddr > 0xB0000000) && ((fStackAddr-fStackSize) < 0xB0000000) )
3911 warning("custom stack placement overlaps and will disable shared region");
3912 break;
3913 case CPU_TYPE_ARM:
3914 if ( fStackSize > 0x2F000000 )
3915 throw "-stack_size must be < 752MB";
3916 if ( fStackAddr == 0 )
3917 fStackAddr = 0x2F000000;
3918 if ( fStackAddr > 0x30000000)
3919 throw "-stack_addr must be < 0x30000000 for arm";
3920 case CPU_TYPE_X86_64:
3921 if ( fStackAddr == 0 ) {
3922 fStackAddr = 0x00007FFF5C000000LL;
3923 }
3924 break;
3925 }
3926 if ( (fStackSize & -4096) != fStackSize )
3927 throw "-stack_size must be multiples of 4K";
3928 switch ( fOutputKind ) {
3929 case Options::kDynamicExecutable:
3930 case Options::kStaticExecutable:
3931 // custom stack size only legal when building main executable
3932 break;
3933 case Options::kDynamicLibrary:
3934 case Options::kDynamicBundle:
3935 case Options::kObjectFile:
3936 case Options::kDyld:
3937 case Options::kPreload:
3938 case Options::kKextBundle:
3939 throw "-stack_size option can only be used when linking a main executable";
3940 }
3941 if ( fStackSize > fStackAddr )
3942 throwf("-stack_size (0x%08llX) must be smaller than -stack_addr (0x%08llX)", fStackSize, fStackAddr);
3943 }
3944
3945 // check that -allow_stack_execute is only used with main executables
3946 if ( fExecutableStack ) {
3947 switch ( fOutputKind ) {
3948 case Options::kDynamicExecutable:
3949 case Options::kStaticExecutable:
3950 // -allow_stack_execute size only legal when building main executable
3951 break;
3952 case Options::kDynamicLibrary:
3953 case Options::kDynamicBundle:
3954 case Options::kObjectFile:
3955 case Options::kDyld:
3956 case Options::kPreload:
3957 case Options::kKextBundle:
3958 throw "-allow_stack_execute option can only be used when linking a main executable";
3959 }
3960 }
3961
3962 // check that -allow_heap_execute is only used with i386 main executables
3963 if ( fDisableNonExecutableHeap ) {
3964 if ( fArchitecture != CPU_TYPE_I386 )
3965 throw "-allow_heap_execute option can only be used when linking for i386";
3966 switch ( fOutputKind ) {
3967 case Options::kDynamicExecutable:
3968 // -allow_heap_execute only legal when building main executable
3969 break;
3970 case Options::kStaticExecutable:
3971 case Options::kDynamicLibrary:
3972 case Options::kDynamicBundle:
3973 case Options::kObjectFile:
3974 case Options::kDyld:
3975 case Options::kPreload:
3976 case Options::kKextBundle:
3977 throw "-allow_heap_execute option can only be used when linking a main executable";
3978 }
3979 }
3980
3981 // check -client_name is only used when making a bundle or main executable
3982 if ( fClientName != NULL ) {
3983 switch ( fOutputKind ) {
3984 case Options::kDynamicExecutable:
3985 case Options::kDynamicBundle:
3986 break;
3987 case Options::kStaticExecutable:
3988 case Options::kDynamicLibrary:
3989 case Options::kObjectFile:
3990 case Options::kDyld:
3991 case Options::kPreload:
3992 case Options::kKextBundle:
3993 throw "-client_name can only be used with -bundle";
3994 }
3995 }
3996
3997 // check -init is only used when building a dylib
3998 if ( (fInitFunctionName != NULL) && (fOutputKind != Options::kDynamicLibrary) )
3999 throw "-init can only be used with -dynamiclib";
4000
4001 // check -bundle_loader only used with -bundle
4002 if ( (fBundleLoader != NULL) && (fOutputKind != Options::kDynamicBundle) )
4003 throw "-bundle_loader can only be used with -bundle";
4004
4005 // check -dtrace not used with -r
4006 if ( (fDtraceScriptName != NULL) && (fOutputKind == Options::kObjectFile) )
4007 throw "-dtrace can only be used when creating final linked images";
4008
4009 // check -d can only be used with -r
4010 if ( fMakeTentativeDefinitionsReal && (fOutputKind != Options::kObjectFile) )
4011 throw "-d can only be used with -r";
4012
4013 // check that -root_safe is not used with -r
4014 if ( fRootSafe && (fOutputKind == Options::kObjectFile) )
4015 throw "-root_safe cannot be used with -r";
4016
4017 // check that -setuid_safe is not used with -r
4018 if ( fSetuidSafe && (fOutputKind == Options::kObjectFile) )
4019 throw "-setuid_safe cannot be used with -r";
4020
4021 // rdar://problem/4718189 map ObjC class names to new runtime names
4022 bool alterObjC1ClassNamesToObjC2 = false;
4023 switch (fArchitecture) {
4024 case CPU_TYPE_I386:
4025 // i386 only uses new symbols when using objc2 ABI
4026 if ( fObjCABIVersion2Override )
4027 alterObjC1ClassNamesToObjC2 = true;
4028 break;
4029 case CPU_TYPE_X86_64:
4030 case CPU_TYPE_ARM:
4031 alterObjC1ClassNamesToObjC2 = true;
4032 break;
4033 }
4034
4035 // make sure all required exported symbols exist
4036 std::vector<const char*> impliedExports;
4037 for (NameSet::iterator it=fExportSymbols.regularBegin(); it != fExportSymbols.regularEnd(); ++it) {
4038 const char* name = *it;
4039 const int len = strlen(name);
4040 if ( (strcmp(&name[len-3], ".eh") == 0) || (strncmp(name, ".objc_category_name_", 20) == 0) ) {
4041 // never export .eh symbols
4042 warning("ignoring %s in export list", name);
4043 }
4044 else if ( (fArchitecture == CPU_TYPE_I386) && !fObjCABIVersion2Override && (strncmp(name, "_OBJC_CLASS_$", 13) == 0) ) {
4045 warning("ignoring Objc2 Class symbol %s in i386 export list", name);
4046 fRemovedExports.insert(name);
4047 }
4048 else if ( alterObjC1ClassNamesToObjC2 && (strncmp(name, ".objc_class_name_", 17) == 0) ) {
4049 // linking ObjC2 ABI, but have ObjC1 ABI name in export list. Change it to intended name
4050 fRemovedExports.insert(name);
4051 char* temp;
4052 asprintf(&temp, "_OBJC_CLASS_$_%s", &name[17]);
4053 impliedExports.push_back(temp);
4054 asprintf(&temp, "_OBJC_METACLASS_$_%s", &name[17]);
4055 impliedExports.push_back(temp);
4056 }
4057 else {
4058 fInitialUndefines.push_back(name);
4059 }
4060 }
4061 fExportSymbols.remove(fRemovedExports);
4062 for (std::vector<const char*>::iterator it=impliedExports.begin(); it != impliedExports.end(); ++it) {
4063 const char* name = *it;
4064 fExportSymbols.insert(name);
4065 fInitialUndefines.push_back(name);
4066 }
4067
4068 // make sure all required re-exported symbols exist
4069 for (NameSet::iterator it=fReExportSymbols.regularBegin(); it != fReExportSymbols.regularEnd(); ++it) {
4070 fInitialUndefines.push_back(*it);
4071 }
4072
4073 // make sure that -init symbol exists
4074 if ( fInitFunctionName != NULL )
4075 fInitialUndefines.push_back(fInitFunctionName);
4076
4077 // make sure that entry symbol exists
4078 switch ( fOutputKind ) {
4079 case Options::kDynamicExecutable:
4080 case Options::kStaticExecutable:
4081 case Options::kDyld:
4082 case Options::kPreload:
4083 fInitialUndefines.push_back(fEntryName);
4084 break;
4085 case Options::kDynamicLibrary:
4086 case Options::kDynamicBundle:
4087 case Options::kObjectFile:
4088 case Options::kKextBundle:
4089 break;
4090 }
4091
4092 // make sure every alias base exists
4093 for (std::vector<AliasPair>::iterator it=fAliases.begin(); it != fAliases.end(); ++it) {
4094 fInitialUndefines.push_back(it->realName);
4095 }
4096
4097 // check custom segments
4098 if ( fCustomSegmentAddresses.size() != 0 ) {
4099 // verify no segment is in zero page
4100 if ( fZeroPageSize != ULLONG_MAX ) {
4101 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
4102 if ( it->address < fZeroPageSize )
4103 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it->name, it->address);
4104 }
4105 }
4106 // verify no duplicates
4107 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
4108 for (std::vector<SegmentStart>::iterator it2 = fCustomSegmentAddresses.begin(); it2 != fCustomSegmentAddresses.end(); ++it2) {
4109 if ( (it->address == it2->address) && (it != it2) )
4110 throwf("duplicate -segaddr addresses for %s and %s", it->name, it2->name);
4111 }
4112 // a custom segment address of zero will disable the use of a zero page
4113 if ( it->address == 0 )
4114 fZeroPageSize = 0;
4115 }
4116 }
4117
4118 if ( fZeroPageSize == ULLONG_MAX ) {
4119 // zero page size not specified on command line, set default
4120 switch (fArchitecture) {
4121 case CPU_TYPE_I386:
4122 case CPU_TYPE_ARM:
4123 // first 4KB for 32-bit architectures
4124 fZeroPageSize = 0x1000;
4125 break;
4126 case CPU_TYPE_X86_64:
4127 // first 4GB for x86_64 on all OS's
4128 fZeroPageSize = 0x100000000ULL;
4129 break;
4130 default:
4131 // if -arch not used, default to 4K zero-page
4132 fZeroPageSize = 0x1000;
4133 }
4134 }
4135 else {
4136 switch ( fOutputKind ) {
4137 case Options::kDynamicExecutable:
4138 case Options::kStaticExecutable:
4139 // -pagezero_size size only legal when building main executable
4140 break;
4141 case Options::kDynamicLibrary:
4142 case Options::kDynamicBundle:
4143 case Options::kObjectFile:
4144 case Options::kDyld:
4145 case Options::kPreload:
4146 case Options::kKextBundle:
4147 if ( fZeroPageSize != 0 )
4148 throw "-pagezero_size option can only be used when linking a main executable";
4149 }
4150 }
4151
4152 // if main executable with custom base address, model zero page as custom segment
4153 if ( (fOutputKind == Options::kDynamicExecutable) && (fBaseAddress != 0) && (fZeroPageSize != 0) ) {
4154 SegmentStart seg;
4155 seg.name = "__PAGEZERO";
4156 seg.address = 0;;
4157 fCustomSegmentAddresses.push_back(seg);
4158 }
4159
4160 // -dead_strip and -r are incompatible
4161 if ( fDeadStrip && (fOutputKind == Options::kObjectFile) )
4162 throw "-r and -dead_strip cannot be used together";
4163
4164 // can't use -rpath unless targeting 10.5 or later
4165 if ( fRPaths.size() > 0 ) {
4166 if ( !minOS(ld::mac10_5, ld::iOS_2_0) )
4167 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
4168 switch ( fOutputKind ) {
4169 case Options::kDynamicExecutable:
4170 case Options::kDynamicLibrary:
4171 case Options::kDynamicBundle:
4172 break;
4173 case Options::kStaticExecutable:
4174 case Options::kObjectFile:
4175 case Options::kDyld:
4176 case Options::kPreload:
4177 case Options::kKextBundle:
4178 throw "-rpath can only be used when creating a dynamic final linked image";
4179 }
4180 }
4181
4182 if ( fPositionIndependentExecutable ) {
4183 switch ( fOutputKind ) {
4184 case Options::kDynamicExecutable:
4185 // check -pie is only used when building a dynamic main executable for 10.5
4186 if ( !minOS(ld::mac10_5, ld::iOS_4_2) ) {
4187 if ( fIOSVersionMin == ld::iOSVersionUnset )
4188 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
4189 else
4190 throw "-pie can only be used when targeting iOS 4.2 or later";
4191 }
4192 break;
4193 case Options::kStaticExecutable:
4194 case Options::kPreload:
4195 // -pie is ok with -static or -preload
4196 break;
4197 case Options::kDynamicLibrary:
4198 case Options::kDynamicBundle:
4199 warning("-pie being ignored. It is only used when linking a main executable");
4200 fPositionIndependentExecutable = false;
4201 break;
4202 case Options::kObjectFile:
4203 case Options::kDyld:
4204 case Options::kKextBundle:
4205 throw "-pie can only be used when linking a main executable";
4206 }
4207 }
4208
4209 // check -read_only_relocs is not used with x86_64
4210 if ( fAllowTextRelocs ) {
4211 if ( (fArchitecture == CPU_TYPE_X86_64) && (fOutputKind != kKextBundle) ) {
4212 warning("-read_only_relocs cannot be used with x86_64");
4213 fAllowTextRelocs = false;
4214 }
4215 }
4216
4217 // check -mark_auto_dead_strip is only used with dylibs
4218 if ( fMarkDeadStrippableDylib ) {
4219 if ( fOutputKind != Options::kDynamicLibrary ) {
4220 warning("-mark_auto_dead_strip can only be used when creating a dylib");
4221 fMarkDeadStrippableDylib = false;
4222 }
4223 }
4224
4225 // -force_cpusubtype_ALL is not supported for ARM
4226 if ( fForceSubtypeAll ) {
4227 if ( fArchitecture == CPU_TYPE_ARM ) {
4228 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
4229 }
4230 }
4231
4232 // -reexported_symbols_list can only be used with -dynamiclib
4233 if ( !fReExportSymbols.empty() ) {
4234 if ( fOutputKind != Options::kDynamicLibrary )
4235 throw "-reexported_symbols_list can only used used when created dynamic libraries";
4236 if ( !minOS(ld::mac10_7, ld::iOS_4_2) )
4237 throw "targeted OS version does not support -reexported_symbols_list";
4238 }
4239
4240 // -dyld_env can only be used with main executables
4241 if ( (fOutputKind != Options::kDynamicExecutable) && (fDyldEnvironExtras.size() != 0) )
4242 throw "-dyld_env can only used used when created main executables";
4243 }
4244
4245
4246 void Options::checkForClassic(int argc, const char* argv[])
4247 {
4248 // scan options
4249 bool archFound = false;
4250 bool staticFound = false;
4251 bool dtraceFound = false;
4252 bool kextFound = false;
4253 bool rFound = false;
4254 bool creatingMachKernel = false;
4255 bool newLinker = false;
4256
4257 // build command line buffer in case ld crashes
4258 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
4259 CRSetCrashLogMessage(crashreporterBuffer);
4260 #endif
4261 const char* srcRoot = getenv("SRCROOT");
4262 if ( srcRoot != NULL ) {
4263 strlcpy(crashreporterBuffer, "SRCROOT=", crashreporterBufferSize);
4264 strlcat(crashreporterBuffer, srcRoot, crashreporterBufferSize);
4265 strlcat(crashreporterBuffer, "\n", crashreporterBufferSize);
4266 }
4267 #ifdef LD_VERS
4268 strlcat(crashreporterBuffer, LD_VERS, crashreporterBufferSize);
4269 strlcat(crashreporterBuffer, "\n", crashreporterBufferSize);
4270 #endif
4271 strlcat(crashreporterBuffer, "ld ", crashreporterBufferSize);
4272 for(int i=1; i < argc; ++i) {
4273 strlcat(crashreporterBuffer, argv[i], crashreporterBufferSize);
4274 strlcat(crashreporterBuffer, " ", crashreporterBufferSize);
4275 }
4276
4277 for(int i=0; i < argc; ++i) {
4278 const char* arg = argv[i];
4279 if ( arg[0] == '-' ) {
4280 if ( strcmp(arg, "-arch") == 0 ) {
4281 parseArch(argv[++i]);
4282 archFound = true;
4283 }
4284 else if ( strcmp(arg, "-static") == 0 ) {
4285 staticFound = true;
4286 }
4287 else if ( strcmp(arg, "-kext") == 0 ) {
4288 kextFound = true;
4289 }
4290 else if ( strcmp(arg, "-dtrace") == 0 ) {
4291 dtraceFound = true;
4292 }
4293 else if ( strcmp(arg, "-r") == 0 ) {
4294 rFound = true;
4295 }
4296 else if ( strcmp(arg, "-new_linker") == 0 ) {
4297 newLinker = true;
4298 }
4299 else if ( strcmp(arg, "-classic_linker") == 0 ) {
4300 // ld_classic does not understand this option, so remove it
4301 for(int j=i; j < argc; ++j)
4302 argv[j] = argv[j+1];
4303 warning("using ld_classic");
4304 this->gotoClassicLinker(argc-1, argv);
4305 }
4306 else if ( strcmp(arg, "-o") == 0 ) {
4307 const char* outfile = argv[++i];
4308 if ( (outfile != NULL) && (strstr(outfile, "/mach_kernel") != NULL) )
4309 creatingMachKernel = true;
4310 }
4311 }
4312 }
4313 }
4314
4315 void Options::gotoClassicLinker(int argc, const char* argv[])
4316 {
4317 argv[0] = "ld_classic";
4318 // ld_classic does not support -iphoneos_version_min, so change
4319 for(int j=0; j < argc; ++j) {
4320 if ( (strcmp(argv[j], "-iphoneos_version_min") == 0) || (strcmp(argv[j], "-ios_version_min") == 0) ) {
4321 argv[j] = "-macosx_version_min";
4322 if ( j < argc-1 )
4323 argv[j+1] = "10.5";
4324 break;
4325 }
4326 }
4327 // ld classic does not understand -kext (change to -static -r)
4328 for(int j=0; j < argc; ++j) {
4329 if ( strcmp(argv[j], "-kext") == 0)
4330 argv[j] = "-r";
4331 else if ( strcmp(argv[j], "-dynamic") == 0)
4332 argv[j] = "-static";
4333 }
4334 // ld classic does not understand -demangle
4335 for(int j=0; j < argc; ++j) {
4336 if ( strcmp(argv[j], "-demangle") == 0)
4337 argv[j] = "-noprebind";
4338 }
4339 // in -v mode, print command line passed to ld_classic
4340 for(int i=0; i < argc; ++i) {
4341 if ( strcmp(argv[i], "-v") == 0 ) {
4342 for(int j=0; j < argc; ++j)
4343 printf("%s ", argv[j]);
4344 printf("\n");
4345 break;
4346 }
4347 }
4348 char rawPath[PATH_MAX];
4349 char path[PATH_MAX];
4350 uint32_t bufSize = PATH_MAX;
4351 if ( _NSGetExecutablePath(rawPath, &bufSize) != -1 ) {
4352 if ( realpath(rawPath, path) != NULL ) {
4353 char* lastSlash = strrchr(path, '/');
4354 if ( lastSlash != NULL ) {
4355 strcpy(lastSlash+1, "ld_classic");
4356 argv[0] = path;
4357 execvp(path, (char**)argv);
4358 }
4359 }
4360 }
4361 // in case of error in above, try searching for ld_classic via PATH
4362 execvp(argv[0], (char**)argv);
4363 fprintf(stderr, "can't exec ld_classic\n");
4364 exit(1);
4365 }
4366
4367
4368 // Note, returned string buffer is own by this function.
4369 // It should not be freed
4370 // It will be reused, so clients need to strdup() if they want
4371 // to use it long term.
4372 const char* Options::demangleSymbol(const char* sym) const
4373 {
4374 // only try to demangle symbols if -demangle on command line
4375 if ( !fDemangle )
4376 return sym;
4377
4378 // only try to demangle symbols that look like C++ symbols
4379 if ( strncmp(sym, "__Z", 3) != 0 )
4380 return sym;
4381
4382 static size_t size = 1024;
4383 static char* buff = (char*)malloc(size);
4384 int status;
4385
4386 char* result = abi::__cxa_demangle(&sym[1], buff, &size, &status);
4387 if ( result != NULL ) {
4388 // if demangling successful, keep buffer for next demangle
4389 buff = result;
4390 return buff;
4391 }
4392 return sym;
4393 }
4394