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