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