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