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