]> git.saurik.com Git - apple/ld64.git/blame - src/ld/Options.cpp
ld64-278.4.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>
0a8dc3df 37#include <tapi/tapi.h>
a645023d 38
6e880c60 39#include <vector>
eaf282aa
A
40#include <map>
41#include <sstream>
c2646906 42
c2646906 43#include "Options.h"
2f2f92e4
A
44#include "Architectures.hpp"
45#include "MachOFileAbstraction.hpp"
ebf6f434 46#include "Snapshot.h"
2f2f92e4 47
eaf282aa
A
48
49// from FunctionNameDemangle.h
50extern "C" size_t fnd_get_demangled_name(const char *mangledName, char *outputBuffer, size_t length);
51
52
a645023d
A
53// upward dependency on lto::version()
54namespace lto {
55 extern const char* version();
56}
2f2f92e4 57
55e3d2f6 58// magic to place command line in crash reports
a645023d 59const int crashreporterBufferSize = 2000;
a645023d 60static char crashreporterBuffer[crashreporterBufferSize];
ebf6f434
A
61#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
62 #include <CrashReporterClient.h>
63 // hack until ld does not need to build on 10.6 anymore
64 struct crashreporter_annotations_t gCRAnnotations
65 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
66 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
67#else
68 extern "C" char* __crashreporter_info__;
69 __attribute__((used))
70 char* __crashreporter_info__ = crashreporterBuffer;
71#endif
72
2f2f92e4
A
73
74static bool sEmitWarnings = true;
b2fa67a8 75static bool sFatalWarnings = false;
2f2f92e4
A
76static const char* sWarningsSideFilePath = NULL;
77static FILE* sWarningsSideFile = NULL;
b2fa67a8 78static int sWarningsCount = 0;
2f2f92e4
A
79
80void warning(const char* format, ...)
81{
b2fa67a8 82 ++sWarningsCount;
2f2f92e4
A
83 if ( sEmitWarnings ) {
84 va_list list;
85 if ( sWarningsSideFilePath != NULL ) {
86 if ( sWarningsSideFile == NULL )
87 sWarningsSideFile = fopen(sWarningsSideFilePath, "a");
88 }
89 va_start(list, format);
55e3d2f6 90 fprintf(stderr, "ld: warning: ");
2f2f92e4
A
91 vfprintf(stderr, format, list);
92 fprintf(stderr, "\n");
93 if ( sWarningsSideFile != NULL ) {
55e3d2f6 94 fprintf(sWarningsSideFile, "ld: warning: ");
2f2f92e4
A
95 vfprintf(sWarningsSideFile, format, list);
96 fprintf(sWarningsSideFile, "\n");
97 fflush(sWarningsSideFile);
98 }
99 va_end(list);
100 }
101}
c2646906 102
d696c285 103void throwf(const char* format, ...)
c2646906
A
104{
105 va_list list;
106 char* p;
107 va_start(list, format);
108 vasprintf(&p, format, list);
109 va_end(list);
d696c285 110
c2646906
A
111 const char* t = p;
112 throw t;
113}
114
f80fe69f
A
115
116bool Options::FileInfo::checkFileExists(const Options& options, const char *p)
ebf6f434
A
117{
118 struct stat statBuffer;
f80fe69f
A
119 if (p == NULL)
120 p = path;
ebf6f434
A
121 if ( stat(p, &statBuffer) == 0 ) {
122 if (p != path) path = strdup(p);
ebf6f434
A
123 modTime = statBuffer.st_mtime;
124 return true;
125 }
f80fe69f
A
126 if ( options.dumpDependencyInfo() )
127 options.dumpDependency(Options::depNotFound, p);
0a8dc3df 128// fprintf(stderr, "not found: %s\n", p);
ebf6f434
A
129 return false;
130}
131
f80fe69f 132
c2646906 133Options::Options(int argc, const char* argv[])
a645023d 134 : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fArchitectureName("unknown"), fOutputKind(kDynamicExecutable),
afe874b1 135 fHasPreferredSubType(false), fArchSupportsThumb2(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
55e3d2f6 136 fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fErrorOnOtherArchFiles(false), fForceSubtypeAll(false),
a645023d 137 fInterposeMode(kInterposeNone), fDeadStrip(false), fNameSpace(kTwoLevelNameSpace),
599556ff 138 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL), fFinalName(NULL), fEntryName(NULL),
a645023d 139 fBaseAddress(0), fMaxAddress(0x7FFFFFFFFFFFFFFFLL),
a61fdf0a 140 fBaseWritableAddress(0), fSplitSegs(false),
a645023d
A
141 fExportMode(kExportDefault), fLibrarySearchMode(kSearchDylibAndArchiveInEachDir),
142 fUndefinedTreatment(kUndefinedError), fMessagesPrefixedWithArchitecture(true),
a61fdf0a
A
143 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchNonWeak),
144 fClientName(NULL),
145 fUmbrellaName(NULL), fInitFunctionName(NULL), fDotOutputFile(NULL), fExecutablePath(NULL),
146 fBundleLoader(NULL), fDtraceScriptName(NULL), fSegAddrTablePath(NULL), fMapPath(NULL),
82b4b32b 147 fDyldInstallPath("/usr/lib/dyld"), fLtoCachePath(NULL), fTempLtoObjectPath(NULL), fOverridePathlibLTO(NULL), fLtoCpu(NULL),
ebf6f434 148 fZeroPageSize(ULLONG_MAX), fStackSize(0), fStackAddr(0), fSourceVersion(0), fSDKVersion(0), fExecutableStack(false),
a645023d 149 fNonExecutableHeap(false), fDisableNonExecutableHeap(false),
55e3d2f6 150 fMinimumHeaderPad(32), fSegmentAlignment(4096),
a61fdf0a
A
151 fCommonsMode(kCommonsIgnoreDylibs), fUUIDMode(kUUIDContent), fLocalSymbolHandling(kLocalSymbolsAll), fWarnCommons(false),
152 fVerbose(false), fKeepRelocations(false), fWarnStabs(false),
69a49097 153 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
eaf282aa 154 fSharedRegionEligible(false), fSharedRegionEligibleForceOff(false), fPrintOrderFileStatistics(false),
a645023d 155 fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fPIEOnCommandLine(false),
d9246299 156 fDisablePositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
ebf6f434 157 fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false), fKextsUseStubs(false),
eaf282aa 158 fUsingLazyDylibLinking(false), fEncryptable(true), fEncryptableForceOn(false), fEncryptableForceOff(false),
4be885f6 159 fOrderData(true), fMarkDeadStrippableDylib(false),
a645023d 160 fMakeCompressedDyldInfo(true), fMakeCompressedDyldInfoForceOff(false), fNoEHLabels(false),
ec29ba20 161 fAllowCpuSubtypeMismatches(false), fEnforceDylibSubtypesMatch(false), fUseSimplifiedDylibReExports(false),
a645023d
A
162 fObjCABIVersion2Override(false), fObjCABIVersion1Override(false), fCanUseUpwardDylib(false),
163 fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false),
164 fLinkingMainExecutable(false), fForFinalLinkedImage(false), fForStatic(false),
165 fForDyld(false), fMakeTentativeDefinitionsReal(false), fWhyLoad(false), fRootSafe(false),
166 fSetuidSafe(false), fImplicitlyLinkPublicDylibs(true), fAddCompactUnwindEncoding(true),
167 fWarnCompactUnwind(false), fRemoveDwarfUnwindIfCompactExists(false),
afe874b1 168 fAutoOrderInitializers(true), fOptimizeZeroFill(true), fMergeZeroFill(false), fLogObjectFiles(false),
0a8dc3df 169 fLogAllFiles(false), fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false), fTraceEmitJSON(false),
a645023d
A
170 fOutputSlidable(false), fWarnWeakExports(false),
171 fObjcGcCompaction(false), fObjCGc(false), fObjCGcOnly(false),
172 fDemangle(false), fTLVSupport(false),
afe874b1
A
173 fVersionLoadCommand(false), fVersionLoadCommandForcedOn(false),
174 fVersionLoadCommandForcedOff(false), fFunctionStartsLoadCommand(false),
175 fFunctionStartsForcedOn(false), fFunctionStartsForcedOff(false),
b1f7435d 176 fDataInCodeInfoLoadCommand(false), fDataInCodeInfoLoadCommandForcedOn(false), fDataInCodeInfoLoadCommandForcedOff(false),
afe874b1 177 fCanReExportSymbols(false), fObjcCategoryMerging(true), fPageAlignDataAtoms(false),
ebf6f434
A
178 fNeedsThreadLoadCommand(false), fEntryPointLoadCommand(false),
179 fEntryPointLoadCommandForceOn(false), fEntryPointLoadCommandForceOff(false),
180 fSourceVersionLoadCommand(false),
181 fSourceVersionLoadCommandForceOn(false), fSourceVersionLoadCommandForceOff(false),
f80fe69f
A
182 fTargetIOSSimulator(false), fExportDynamic(false), fAbsoluteSymbols(false),
183 fAllowSimulatorToLinkWithMacOSX(false), fKeepDwarfUnwind(true),
184 fKeepDwarfUnwindForcedOn(false), fKeepDwarfUnwindForcedOff(false),
9543cb2f 185 fVerboseOptimizationHints(false), fIgnoreOptimizationHints(false),
599556ff 186 fGenerateDtraceDOF(true), fAllowBranchIslands(true), fTraceSymbolLayout(false),
eaf282aa
A
187 fMarkAppExtensionSafe(false), fCheckAppExtensionSafe(false), fForceLoadSwiftLibs(false),
188 fSharedRegionEncodingV2(false), fUseDataConstSegment(false),
0a8dc3df 189 fUseDataConstSegmentForceOn(false), fUseDataConstSegmentForceOff(false), fUseTextExecSegment(false),
dd9e569f 190 fBundleBitcode(false), fHideSymbols(false), fVerifyBitcode(false),
ec29ba20
A
191 fReverseMapUUIDRename(false), fDeDupe(true), fVerboseDeDupe(false),
192 fReverseMapPath(NULL), fLTOCodegenOnly(false),
0a8dc3df 193 fIgnoreAutoLink(false), fAllowDeadDups(false), fAllowWeakImports(true), fBitcodeKind(kBitcodeProcess),
dd9e569f 194 fPlatform(kPlatformUnknown), fDebugInfoStripping(kDebugInfoMinimal), fTraceOutputFile(NULL),
0a8dc3df 195 fMacVersionMin(ld::macVersionUnset), fIOSVersionMin(ld::iOSVersionUnset), fWatchOSVersionMin(ld::wOSVersionUnset),
eaf282aa 196 fSaveTempFiles(false), fSnapshotRequested(false), fPipelineFifo(NULL),
82b4b32b 197 fDependencyInfoPath(NULL), fDependencyFileDescriptor(-1), fTraceFileDescriptor(-1), fMaxDefaultCommonAlign(0)
c2646906 198{
a61fdf0a 199 this->checkForClassic(argc, argv);
c2646906
A
200 this->parsePreCommandLineEnvironmentSettings();
201 this->parse(argc, argv);
202 this->parsePostCommandLineEnvironmentSettings();
69a49097 203 this->reconfigureDefaults();
c2646906 204 this->checkIllegalOptionCombinations();
f80fe69f
A
205
206 if ( this->dumpDependencyInfo() ) {
207 this->dumpDependency(depOutputFile, fOutputFile);
208 if ( fMapPath != NULL )
209 this->dumpDependency(depOutputFile, fMapPath);
210 }
c2646906
A
211}
212
213Options::~Options()
214{
82b4b32b
A
215 if ( fDependencyFileDescriptor != -1 )
216 ::close(fDependencyFileDescriptor);
217
218 if ( fTraceFileDescriptor != -1 )
219 ::close(fTraceFileDescriptor);
c2646906
A
220}
221
b2fa67a8
A
222bool Options::errorBecauseOfWarnings() const
223{
224 return (sFatalWarnings && (sWarningsCount > 0));
225}
c2646906 226
c2646906 227
a645023d 228const char* Options::installPath() const
c2646906 229{
d696c285 230 if ( fDylibInstallName != NULL )
c2646906 231 return fDylibInstallName;
a61fdf0a
A
232 else if ( fFinalName != NULL )
233 return fFinalName;
c2646906
A
234 else
235 return fOutputFile;
236}
237
c2646906 238
a645023d 239bool Options::interposable(const char* name) const
c2646906 240{
2f2f92e4
A
241 switch ( fInterposeMode ) {
242 case kInterposeNone:
243 return false;
244 case kInterposeAllExternal:
245 return true;
246 case kInterposeSome:
247 return fInterposeList.contains(name);
248 }
249 throw "internal error";
c2646906
A
250}
251
c2646906 252
a645023d 253bool Options::printWhyLive(const char* symbolName) const
69a49097 254{
eaf282aa 255 return fWhyLive.contains(symbolName);
69a49097
A
256}
257
d696c285 258
d696c285
A
259const char* Options::dotOutputFile()
260{
261 return fDotOutputFile;
262}
263
c2646906 264
a645023d 265bool Options::hasWildCardExportRestrictList() const
2f2f92e4 266{
a645023d
A
267 // has -exported_symbols_list which contains some wildcards
268 return ((fExportMode == kExportSome) && fExportSymbols.hasWildCards());
2f2f92e4
A
269}
270
a645023d 271bool Options::hasWeakBitTweaks() const
2f2f92e4
A
272{
273 // has -exported_symbols_list which contains some wildcards
a645023d 274 return (!fForceWeakSymbols.empty() || !fForceNotWeakSymbols.empty());
2f2f92e4
A
275}
276
a645023d 277bool Options::allGlobalsAreDeadStripRoots() const
69a49097
A
278{
279 // -exported_symbols_list means globals are not exported by default
a61fdf0a 280 if ( fExportMode == kExportSome )
69a49097
A
281 return false;
282 //
283 switch ( fOutputKind ) {
284 case Options::kDynamicExecutable:
f80fe69f
A
285 // <rdar://problem/12839986> Add the -export_dynamic flag
286 return fExportDynamic;
69a49097 287 case Options::kStaticExecutable:
f80fe69f
A
288 // <rdar://problem/13361218> Support the -export_dynamic flag for xnu
289 return fExportDynamic;
55e3d2f6 290 case Options::kPreload:
69a49097
A
291 // by default unused globals in a main executable are stripped
292 return false;
293 case Options::kDynamicLibrary:
294 case Options::kDynamicBundle:
295 case Options::kObjectFile:
296 case Options::kDyld:
55e3d2f6 297 case Options::kKextBundle:
69a49097
A
298 return true;
299 }
300 return false;
301}
302
a645023d
A
303
304bool Options::keepRelocations()
c2646906 305{
a645023d 306 return fKeepRelocations;
c2646906
A
307}
308
a645023d 309bool Options::warnStabs()
c2646906 310{
a645023d 311 return fWarnStabs;
c2646906
A
312}
313
a645023d 314const char* Options::executablePath()
c2646906 315{
a645023d 316 return fExecutablePath;
c2646906
A
317}
318
a645023d 319uint32_t Options::initialSegProtection(const char* segName) const
c2646906 320{
a645023d
A
321 for(std::vector<Options::SegmentProtect>::const_iterator it = fCustomSegmentProtections.begin(); it != fCustomSegmentProtections.end(); ++it) {
322 if ( strcmp(it->name, segName) == 0 ) {
323 return it->init;
324 }
325 }
0a8dc3df
A
326 if ( strcmp(segName, "__TEXT") == 0 ) {
327 return ( fUseTextExecSegment ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_EXECUTE) );
a645023d 328 }
0a8dc3df 329 else if ( strcmp(segName, "__TEXT_EXEC") == 0 ) {
a645023d
A
330 return VM_PROT_READ | VM_PROT_EXECUTE;
331 }
0a8dc3df
A
332 else if ( strcmp(segName, "__PAGEZERO") == 0 ) {
333 return 0;
334 }
a645023d
A
335 else if ( strcmp(segName, "__LINKEDIT") == 0 ) {
336 return VM_PROT_READ;
337 }
338
339 // all others default to read-write
340 return VM_PROT_READ | VM_PROT_WRITE;
c2646906
A
341}
342
a645023d 343uint32_t Options::maxSegProtection(const char* segName) const
c2646906 344{
a645023d 345 // iPhoneOS always uses same protection for max and initial
b1f7435d 346 // <rdar://problem/11663436> simulator apps need to use MacOSX max-prot
eaf282aa 347 if ( (fPlatform != kPlatformOSX) && !fTargetIOSSimulator )
a645023d
A
348 return initialSegProtection(segName);
349
350 for(std::vector<Options::SegmentProtect>::const_iterator it = fCustomSegmentProtections.begin(); it != fCustomSegmentProtections.end(); ++it) {
351 if ( strcmp(it->name, segName) == 0 ) {
352 return it->max;
353 }
354 }
355 if ( strcmp(segName, "__PAGEZERO") == 0 ) {
356 return 0;
357 }
358 // all others default to all
359 return VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
360}
361
362uint64_t Options::segPageSize(const char* segName) const
363{
364 for(std::vector<SegmentSize>::const_iterator it=fCustomSegmentSizes.begin(); it != fCustomSegmentSizes.end(); ++it) {
365 if ( strcmp(it->name, segName) == 0 )
366 return it->size;
367 }
368 return fSegmentAlignment;
c2646906
A
369}
370
a645023d 371uint64_t Options::customSegmentAddress(const char* segName) const
d696c285 372{
a645023d
A
373 for(std::vector<SegmentStart>::const_iterator it=fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
374 if ( strcmp(it->name, segName) == 0 )
375 return it->address;
376 }
377 // if custom stack in use, model as segment with custom address
378 if ( (fStackSize != 0) && (strcmp("__UNIXSTACK", segName) == 0) )
379 return fStackAddr - fStackSize;
380 return 0;
d696c285
A
381}
382
a645023d 383bool Options::hasCustomSegmentAddress(const char* segName) const
d696c285 384{
a645023d
A
385 for(std::vector<SegmentStart>::const_iterator it=fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
386 if ( strcmp(it->name, segName) == 0 )
387 return true;
388 }
389 // if custom stack in use, model as segment with custom address
390 if ( (fStackSize != 0) && (strcmp("__UNIXSTACK", segName) == 0) )
391 return true;
392 return false;
d696c285
A
393}
394
a645023d 395bool Options::hasCustomSectionAlignment(const char* segName, const char* sectName) const
d696c285 396{
a645023d
A
397 for (std::vector<SectionAlignment>::const_iterator it = fSectionAlignments.begin(); it != fSectionAlignments.end(); ++it) {
398 if ( (strcmp(it->segmentName, segName) == 0) && (strcmp(it->sectionName, sectName) == 0) )
399 return true;
400 }
0a8dc3df
A
401 if ( fEncryptable && (strcmp(sectName, "__oslogstring") == 0) && (strcmp(segName, "__TEXT") == 0) )
402 return true;
403
a645023d 404 return false;
d696c285
A
405}
406
a645023d 407uint8_t Options::customSectionAlignment(const char* segName, const char* sectName) const
d696c285 408{
a645023d
A
409 for (std::vector<SectionAlignment>::const_iterator it = fSectionAlignments.begin(); it != fSectionAlignments.end(); ++it) {
410 if ( (strcmp(it->segmentName, segName) == 0) && (strcmp(it->sectionName, sectName) == 0) )
411 return it->alignment;
412 }
0a8dc3df
A
413 if ( fEncryptable && (strcmp(sectName, "__oslogstring") == 0) && (strcmp(segName, "__TEXT") == 0) )
414 return __builtin_ctz(fSegmentAlignment);
415
a645023d 416 return 0;
d696c285
A
417}
418
eaf282aa
A
419bool Options::segmentOrderAfterFixedAddressSegment(const char* segName) const
420{
421 bool nowPinned = false;
422 for (std::vector<const char*>::const_iterator it=fSegmentOrder.begin(); it != fSegmentOrder.end(); ++it) {
423 if ( strcmp(*it, segName) == 0 )
424 return nowPinned;
425 if ( hasCustomSegmentAddress(*it) )
426 nowPinned = true;
427 }
428 return false;
429}
a645023d 430
55e3d2f6
A
431bool Options::hasExportedSymbolOrder()
432{
433 return (fExportSymbolsOrder.size() > 0);
434}
435
a645023d 436bool Options::exportedSymbolOrder(const char* sym, unsigned int* order) const
55e3d2f6 437{
a645023d 438 NameToOrder::const_iterator pos = fExportSymbolsOrder.find(sym);
55e3d2f6
A
439 if ( pos != fExportSymbolsOrder.end() ) {
440 *order = pos->second;
441 return true;
442 }
443 else {
444 *order = 0xFFFFFFFF;
445 return false;
446 }
447}
448
449void Options::loadSymbolOrderFile(const char* fileOfExports, NameToOrder& orderMapping)
450{
451 // read in whole file
452 int fd = ::open(fileOfExports, O_RDONLY, 0);
453 if ( fd == -1 )
454 throwf("can't open -exported_symbols_order file: %s", fileOfExports);
455 struct stat stat_buf;
456 ::fstat(fd, &stat_buf);
457 char* p = (char*)malloc(stat_buf.st_size);
458 if ( p == NULL )
459 throwf("can't process -exported_symbols_order file: %s", fileOfExports);
460
461 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
462 throwf("can't read -exported_symbols_order file: %s", fileOfExports);
463
464 ::close(fd);
465
d425e388 466 // parse into symbols and add to unordered_set
55e3d2f6
A
467 unsigned int count = 0;
468 char * const end = &p[stat_buf.st_size];
469 enum { lineStart, inSymbol, inComment } state = lineStart;
470 char* symbolStart = NULL;
471 for (char* s = p; s < end; ++s ) {
472 switch ( state ) {
473 case lineStart:
474 if ( *s =='#' ) {
475 state = inComment;
476 }
477 else if ( !isspace(*s) ) {
478 state = inSymbol;
479 symbolStart = s;
480 }
481 break;
482 case inSymbol:
483 if ( (*s == '\n') || (*s == '\r') ) {
484 *s = '\0';
485 // removing any trailing spaces
486 char* last = s-1;
487 while ( isspace(*last) ) {
488 *last = '\0';
489 --last;
490 }
491 orderMapping[symbolStart] = ++count;
492 symbolStart = NULL;
493 state = lineStart;
494 }
495 break;
496 case inComment:
497 if ( (*s == '\n') || (*s == '\r') )
498 state = lineStart;
499 break;
500 }
501 }
502 if ( state == inSymbol ) {
503 warning("missing line-end at end of file \"%s\"", fileOfExports);
504 int len = end-symbolStart+1;
505 char* temp = new char[len];
506 strlcpy(temp, symbolStart, len);
507
508 // remove any trailing spaces
509 char* last = &temp[len-2];
510 while ( isspace(*last) ) {
511 *last = '\0';
512 --last;
513 }
514 orderMapping[temp] = ++count;
515 }
516
517 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
518}
519
a645023d
A
520bool Options::forceWeak(const char* symbolName) const
521{
522 return fForceWeakSymbols.contains(symbolName);
523}
524
525bool Options::forceNotWeak(const char* symbolName) const
526{
527 return fForceNotWeakSymbols.contains(symbolName);
528}
529
530bool Options::forceWeakNonWildCard(const char* symbolName) const
531{
532 return fForceWeakSymbols.containsNonWildcard(symbolName);
533}
534
535bool Options::forceNotWeakNonWildcard(const char* symbolName) const
536{
537 return fForceNotWeakSymbols.containsNonWildcard(symbolName);
538}
539
f80fe69f
A
540bool Options::forceCoalesce(const char* symbolName) const
541{
542 return fForceCoalesceSymbols.contains(symbolName);
543}
544
55e3d2f6 545
a645023d 546bool Options::shouldExport(const char* symbolName) const
c2646906
A
547{
548 switch (fExportMode) {
549 case kExportSome:
a61fdf0a 550 return fExportSymbols.contains(symbolName);
c2646906 551 case kDontExportSome:
a61fdf0a 552 return ! fDontExportSymbols.contains(symbolName);
c2646906
A
553 case kExportDefault:
554 return true;
555 }
556 throw "internal error";
557}
558
a645023d
A
559bool Options::shouldReExport(const char* symbolName) const
560{
561 return fReExportSymbols.contains(symbolName);
562}
563
564bool Options::keepLocalSymbol(const char* symbolName) const
a61fdf0a
A
565{
566 switch (fLocalSymbolHandling) {
567 case kLocalSymbolsAll:
568 return true;
569 case kLocalSymbolsNone:
570 return false;
571 case kLocalSymbolsSelectiveInclude:
572 return fLocalSymbolsIncluded.contains(symbolName);
573 case kLocalSymbolsSelectiveExclude:
574 return ! fLocalSymbolsExcluded.contains(symbolName);
575 }
576 throw "internal error";
577}
578
599556ff
A
579const std::vector<const char*>* Options::sectionOrder(const char* segName) const
580{
581 for (std::vector<SectionOrderList>::const_iterator it=fSectionOrder.begin(); it != fSectionOrder.end(); ++it) {
582 if ( strcmp(it->segmentName, segName) == 0 )
583 return &it->sectionOrder;
584 }
585 return NULL;
586}
587
eaf282aa
A
588uint32_t Options::minOSversion() const
589{
590 switch (fPlatform) {
591 case kPlatformiOS:
592 return iOSVersionMin();
593 case kPlatformOSX:
594 return macosxVersionMin();
595 case kPlatformWatchOS:
596 return watchOSVersionMin();
597#if SUPPORT_APPLE_TV
598 case Options::kPlatform_tvOS:
599 return iOSVersionMin();
600#endif
601 default:
602 break;
603 }
604 return 0;
605}
599556ff 606
eaf282aa 607void Options::setArchitecture(cpu_type_t type, cpu_subtype_t subtype, Options::Platform platform)
c2646906 608{
ebf6f434
A
609 for (const ArchInfo* t=archInfoArray; t->archName != NULL; ++t) {
610 if ( (type == t->cpuType) && (subtype == t->cpuSubType) ) {
611 fArchitecture = type;
612 fSubArchitecture = subtype;
613 fArchitectureName = t->archName;
614 fHasPreferredSubType = t->isSubType;
615 fArchSupportsThumb2 = t->supportsThumb2;
eaf282aa 616 fPlatform = platform;
ebf6f434
A
617 switch ( type ) {
618 case CPU_TYPE_I386:
619 case CPU_TYPE_X86_64:
0a8dc3df 620 if ( (fPlatform == kPlatformOSX) && (fOutputKind != Options::kObjectFile) && (fMacVersionMin == ld::macVersionUnset) ) {
ebf6f434
A
621 #ifdef DEFAULT_MACOSX_MIN_VERSION
622 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
623 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
624 #else
625 warning("-macosx_version_min not specified, assuming 10.6");
626 fMacVersionMin = ld::mac10_6;
627 #endif
628 }
ebf6f434
A
629 break;
630 case CPU_TYPE_ARM:
f80fe69f 631 case CPU_TYPE_ARM64:
0a8dc3df 632 if ( (fMacVersionMin == ld::macVersionUnset) && (fIOSVersionMin == ld::iOSVersionUnset) && (fOutputKind != Options::kObjectFile) ) {
ebf6f434
A
633 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
634 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION);
635 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION);
ebf6f434 636 #else
f80fe69f
A
637 warning("-ios_version_min not specified, assuming 6.0");
638 setIOSVersionMin("6.0");
ebf6f434
A
639 #endif
640 }
ebf6f434 641 break;
afe874b1 642 }
ebf6f434 643 fLinkSnapshot.recordArch(fArchitectureName);
f80fe69f
A
644 // only use compressed LINKEDIT for:
645 // Mac OS X 10.6 or later
646 // iOS 3.1 or later
647 if ( !fMakeCompressedDyldInfo && minOS(ld::mac10_6, ld::iOS_3_1) && !fMakeCompressedDyldInfoForceOff )
648 fMakeCompressedDyldInfo = true;
649 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
650 if ( minOS(ld::mac10_5, ld::iOS_2_0) )
651 fUseSimplifiedDylibReExports = true;
ebf6f434 652 return;
a645023d 653 }
a645023d 654 }
ebf6f434 655 fArchitectureName = "unknown architecture";
a645023d
A
656}
657
ba348e21
A
658bool Options::armUsesZeroCostExceptions() const
659{
660 return ( (fArchitecture == CPU_TYPE_ARM) && (fSubArchitecture == CPU_SUBTYPE_ARM_V7K) );
661}
662
a645023d
A
663void Options::parseArch(const char* arch)
664{
665 if ( arch == NULL )
c2646906 666 throw "-arch must be followed by an architecture string";
ebf6f434
A
667 for (const ArchInfo* t=archInfoArray; t->archName != NULL; ++t) {
668 if ( strcmp(t->archName,arch) == 0 ) {
669 fArchitectureName = arch;
670 fArchitecture = t->cpuType;
671 fSubArchitecture = t->cpuSubType;
672 fHasPreferredSubType = t->isSubType;
673 fArchSupportsThumb2 = t->supportsThumb2;
674 return;
afe874b1 675 }
afe874b1 676 }
ebf6f434 677 throwf("unknown/unsupported architecture name for: -arch %s", arch);
c2646906
A
678}
679
a645023d 680bool Options::checkForFile(const char* format, const char* dir, const char* rootName, FileInfo& result) const
c2646906 681{
d696c285 682 char possiblePath[strlen(dir)+strlen(rootName)+strlen(format)+8];
c2646906 683 sprintf(possiblePath, format, dir, rootName);
f80fe69f 684 bool found = result.checkFileExists(*this, possiblePath);
d696c285
A
685 if ( fTraceDylibSearching )
686 printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), possiblePath);
ebf6f434 687 return found;
d696c285 688}
c2646906
A
689
690
f80fe69f 691Options::FileInfo Options::findLibrary(const char* rootName, bool dylibsOnly) const
c2646906
A
692{
693 FileInfo result;
694 const int rootNameLen = strlen(rootName);
695 // if rootName ends in .o there is no .a vs .dylib choice
696 if ( (rootNameLen > 3) && (strcmp(&rootName[rootNameLen-2], ".o") == 0) ) {
f80fe69f 697 for (std::vector<const char*>::const_iterator it = fLibrarySearchPaths.begin();
d696c285
A
698 it != fLibrarySearchPaths.end();
699 it++) {
c2646906
A
700 const char* dir = *it;
701 if ( checkForFile("%s/%s", dir, rootName, result) )
702 return result;
703 }
704 }
705 else {
9543cb2f
A
706 bool lookForDylibs = false;
707 switch ( fOutputKind ) {
708 case Options::kDynamicExecutable:
709 case Options::kDynamicLibrary:
710 case Options::kDynamicBundle:
711 case Options::kObjectFile: // <rdar://problem/15914513>
712 lookForDylibs = true;
713 break;
714 case Options::kStaticExecutable:
715 case Options::kDyld:
716 case Options::kPreload:
717 case Options::kKextBundle:
718 lookForDylibs = false;
719 break;
720 }
c2646906 721 switch ( fLibrarySearchMode ) {
d696c285 722 case kSearchAllDirsForDylibsThenAllDirsForArchives:
c2646906
A
723 // first look in all directories for just for dylibs
724 if ( lookForDylibs ) {
f80fe69f 725 for (std::vector<const char*>::const_iterator it = fLibrarySearchPaths.begin();
d696c285
A
726 it != fLibrarySearchPaths.end();
727 it++) {
c2646906 728 const char* dir = *it;
ec29ba20
A
729 auto path = std::string(dir) + "/lib" + rootName + ".dylib";
730 if ( findFile(path, {".tbd"}, result) )
c2646906
A
731 return result;
732 }
f80fe69f 733 for (std::vector<const char*>::const_iterator it = fLibrarySearchPaths.begin();
a61fdf0a
A
734 it != fLibrarySearchPaths.end();
735 it++) {
736 const char* dir = *it;
737 if ( checkForFile("%s/lib%s.so", dir, rootName, result) )
738 return result;
739 }
c2646906
A
740 }
741 // next look in all directories for just for archives
2f2f92e4 742 if ( !dylibsOnly ) {
f80fe69f 743 for (std::vector<const char*>::const_iterator it = fLibrarySearchPaths.begin();
2f2f92e4
A
744 it != fLibrarySearchPaths.end();
745 it++) {
746 const char* dir = *it;
747 if ( checkForFile("%s/lib%s.a", dir, rootName, result) )
748 return result;
749 }
c2646906
A
750 }
751 break;
752
753 case kSearchDylibAndArchiveInEachDir:
754 // look in each directory for just for a dylib then for an archive
f80fe69f 755 for (std::vector<const char*>::const_iterator it = fLibrarySearchPaths.begin();
d696c285
A
756 it != fLibrarySearchPaths.end();
757 it++) {
c2646906 758 const char* dir = *it;
ec29ba20
A
759 auto path = std::string(dir) + "/lib" + rootName + ".dylib";
760 if ( lookForDylibs && findFile(path, {".tbd"}, result) )
c2646906 761 return result;
a61fdf0a
A
762 if ( lookForDylibs && checkForFile("%s/lib%s.so", dir, rootName, result) )
763 return result;
2f2f92e4 764 if ( !dylibsOnly && checkForFile("%s/lib%s.a", dir, rootName, result) )
c2646906
A
765 return result;
766 }
767 break;
768 }
769 }
770 throwf("library not found for -l%s", rootName);
771}
772
f80fe69f 773Options::FileInfo Options::findFramework(const char* frameworkName) const
74cfe461
A
774{
775 if ( frameworkName == NULL )
a61fdf0a 776 throw "-framework missing next argument";
74cfe461
A
777 char temp[strlen(frameworkName)+1];
778 strcpy(temp, frameworkName);
779 const char* name = temp;
780 const char* suffix = NULL;
781 char* comma = strchr(temp, ',');
782 if ( comma != NULL ) {
783 *comma = '\0';
784 suffix = &comma[1];
785 }
786 return findFramework(name, suffix);
787}
c2646906 788
f80fe69f 789Options::FileInfo Options::findFramework(const char* rootName, const char* suffix) const
c2646906 790{
eaf282aa
A
791 for (const auto* path : fFrameworkSearchPaths) {
792 auto possiblePath = std::string(path).append("/").append(rootName).append(".framework/").append(rootName);
793 if ( suffix != nullptr ) {
74cfe461
A
794 char realPath[PATH_MAX];
795 // no symlink in framework to suffix variants, so follow main symlink
eaf282aa
A
796 if ( realpath(possiblePath.c_str(), realPath) != nullptr )
797 possiblePath = std::string(realPath).append(suffix);
74cfe461 798 }
ebf6f434 799 FileInfo result;
ec29ba20 800 if ( findFile(possiblePath, {".tbd"}, result) )
c2646906 801 return result;
c2646906 802 }
74cfe461 803 // try without suffix
a61fdf0a 804 if ( suffix != NULL )
74cfe461
A
805 return findFramework(rootName, NULL);
806 else
807 throwf("framework not found %s", rootName);
c2646906
A
808}
809
ec29ba20
A
810static std::string replace_extension(const std::string &path, const std::string &ext)
811{
812 auto result = path;
813 auto lastSlashIdx = result.find_last_of('/');
814 auto lastDotIdx = result.find_last_of('.');
815 if (lastDotIdx != std::string::npos && lastDotIdx > lastSlashIdx)
816 result.erase(lastDotIdx, std::string::npos);
817 if ( ext.size() > 0 && ext[0] == '.' )
818 result.append(ext);
819 else
820 result.append('.' + ext);
821 return result;
822}
823
824bool Options::findFile(const std::string &path, const std::vector<std::string> &tbdExtensions, FileInfo& result) const
825{
826 FileInfo tbdInfo;
827 for ( const auto &ext : tbdExtensions ) {
828 auto newPath = replace_extension(path, ext);
829 bool found = tbdInfo.checkFileExists(*this, newPath.c_str());
830 if ( fTraceDylibSearching )
831 printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), newPath.c_str());
0a8dc3df
A
832 if ( found )
833 break;
ec29ba20
A
834 }
835
836 FileInfo dylibInfo;
837 {
838 bool found = dylibInfo.checkFileExists(*this, path.c_str());
839 if ( fTraceDylibSearching )
840 printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), path.c_str());
ec29ba20
A
841 }
842
82b4b32b
A
843 // There is only a text-based stub file or a dynamic library file.
844 if ( tbdInfo.missing() != dylibInfo.missing() ) {
845 result = tbdInfo.missing() ? dylibInfo : tbdInfo;
ec29ba20 846 }
0a8dc3df
A
847 // There are both - a text-based stub file and a dynamic library file.
848 else if ( !tbdInfo.missing() && !dylibInfo.missing() ) {
82b4b32b
A
849 // Check if we should prefer the text-based stub file (installapi).
850 if (tapi::LinkerInterfaceFile::shouldPreferTextBasedStubFile(tbdInfo.path)) {
851 result = tbdInfo;
852 }
853 // If the files are still in sync we can use and should use the text-based stub file.
854 else if (tapi::LinkerInterfaceFile::areEquivalent(tbdInfo.path, dylibInfo.path)) {
ec29ba20 855 result = tbdInfo;
ec29ba20 856 }
0a8dc3df 857 // Otherwise issue a warning and fall-back to the dynamic library file.
ec29ba20 858 else {
0a8dc3df 859 warning("text-based stub file %s and library file %s are out of sync. Falling back to library file for linking.", tbdInfo.path, dylibInfo.path);
ec29ba20 860 result = dylibInfo;
ec29ba20 861 }
82b4b32b
A
862 } else {
863 return false;
ec29ba20
A
864 }
865
82b4b32b 866 return true;
ec29ba20
A
867}
868
0a8dc3df
A
869static bool startsWith(const std::string& str, const std::string& prefix)
870{
871 return (str.compare(0, prefix.length(), prefix) == 0);
872}
873
874static std::string getDirPath(const std::string& path)
875{
876 std::string::size_type lastSlashPos = path.find_last_of('/');
877 if ( lastSlashPos == std::string::npos )
878 return "./";
879 else
880 return path.substr(0, lastSlashPos+1);
881}
882
883Options::FileInfo Options::findFile(const std::string &path, const ld::dylib::File* fromDylib) const
c2646906 884{
6e880c60 885 FileInfo result;
d696c285 886
eaf282aa
A
887 // if absolute path and not a .o file, then use SDK prefix
888 if ( (path[0] == '/') && (strcmp(&path[path.size()-2], ".o") != 0) ) {
eaf282aa 889 for (const auto* sdkPathDir : fSDKPaths) {
ec29ba20
A
890 auto possiblePath = std::string(sdkPathDir) + path;
891 if ( findFile(possiblePath, {".tbd"}, result) )
6e880c60 892 return result;
6e880c60
A
893 }
894 }
0a8dc3df
A
895
896 // expand @ variables
897 if ( path[0] == '@' ) {
898 if ( startsWith(path, "@executable_path/") && (fExecutablePath != nullptr) ) {
899 std::string exeBasedPath = getDirPath(fExecutablePath) + &path[17];
900 if ( findFile(exeBasedPath, {".tbd"}, result) )
901 return result;
902 }
903 else if ( startsWith(path, "@loader_path/") && (fromDylib != nullptr) ) {
904 char absPath[PATH_MAX];
905 if ( realpath(fromDylib->path(), absPath) != NULL ) {
906 std::string loaderBasedPath = getDirPath(fromDylib->path()) + &path[13];
907 if ( findFile(loaderBasedPath, {".tbd"}, result) )
908 return result;
909 }
910 }
911 else if ( startsWith(path, "@rpath/") ) {
912 // first search any LC_RPATH supplied by dyld that re-exports dylib to be found
913 if ( fromDylib != nullptr ) {
914 for (const char* rp : fromDylib->rpaths() ) {
915 std::string rpath = rp;
916 // handle dylib that has LC_RPATH = @loader_path/blah
917 if ( startsWith(rpath, "@loader_path/") ) {
918 char absPath[PATH_MAX];
919 if ( realpath(fromDylib->path(), absPath) != NULL )
920 rpath = getDirPath(absPath) + &rpath[13];
921 else
922 rpath = getDirPath(fromDylib->path()) + &rpath[13];
923 }
924 std::string rpathBasedPath = rpath + "/" + &path[6];
925 if ( findFile(rpathBasedPath, {".tbd"}, result) )
926 return result;
927 }
928 }
929 }
930 }
931
6e880c60 932 // try raw path
ec29ba20 933 if ( findFile(path, {".tbd"}, result) )
c2646906 934 return result;
eaf282aa 935
6e880c60 936 // not found
eaf282aa 937 throwf("file not found: %s", path.c_str());
c2646906
A
938}
939
0a8dc3df
A
940// search for indirect dylib first using -F and -L paths first
941Options::FileInfo Options::findIndirectDylib(const std::string& installName, const ld::dylib::File* fromDylib) const
a61fdf0a
A
942{
943 FileInfo result;
944
0a8dc3df 945 auto lastSlashPos = installName.find_last_of('/');
eaf282aa 946 auto pos = ( lastSlashPos != std::string::npos ) ? lastSlashPos + 1 : 0;
0a8dc3df 947 auto leafName = installName.substr(pos);
a61fdf0a
A
948
949 // Is this in a framework?
950 // /path/Foo.framework/Foo ==> true (Foo)
951 // /path/Foo.framework/Frameworks/Bar.framework/Bar ==> true (Bar)
952 // /path/Foo.framework/Resources/Bar ==> false
953 bool isFramework = false;
eaf282aa
A
954 if ( lastSlashPos != std::string::npos ) {
955 auto frameworkDir = std::string("/").append(leafName).append(".framework/");
0a8dc3df 956 if ( installName.rfind(frameworkDir) != std::string::npos )
a61fdf0a
A
957 isFramework = true;
958 }
959
960 // These are abbreviated versions of the routines findFramework and findLibrary above
961 // because we already know the final name of the file that we're looking for and so
962 // don't need to try variations, just paths. We do need to add the additional bits
963 // onto the framework path though.
964 if ( isFramework ) {
0a8dc3df
A
965 auto endPos = installName.rfind(".framework");
966 auto beginPos = installName.find_last_of('/', endPos);
967 auto leafPath = installName.substr(beginPos);
eaf282aa
A
968 for (const auto* dir : fFrameworkSearchPaths) {
969 auto possiblePath = dir + leafPath;
ec29ba20 970 if ( findFile(possiblePath, {".tbd"}, result) )
a61fdf0a
A
971 return result;
972 }
eaf282aa 973 } else {
2f2f92e4 974 // if this is a .dylib inside a framework, do not search -L paths
eaf282aa
A
975 // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
976 bool embeddedDylib = ( (leafName.size() > 6)
977 && (leafName.find(".dylib", leafName.size()-6) != std::string::npos)
0a8dc3df 978 && (installName.find(".framework/") != std::string::npos) );
2f2f92e4 979 if ( !embeddedDylib ) {
eaf282aa 980 for (const auto* dir : fLibrarySearchPaths) {
2f2f92e4 981 //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
2a0ed0a3 982 std::string possiblePath = dir + std::string("/") + leafName;
ec29ba20 983 if ( findFile(possiblePath, {".tbd"}, result) )
2f2f92e4
A
984 return result;
985 }
a61fdf0a
A
986 }
987 }
988
989 // If we didn't find it fall back to findFile.
0a8dc3df 990 return findFile(installName, fromDylib);
a61fdf0a 991}
f80fe69f
A
992
993
a61fdf0a 994
a645023d 995void Options::parseSegAddrTable(const char* segAddrPath, const char* installPth)
a61fdf0a
A
996{
997 FILE* file = fopen(segAddrPath, "r");
998 if ( file == NULL ) {
2f2f92e4 999 warning("-seg_addr_table file cannot be read: %s", segAddrPath);
a61fdf0a
A
1000 return;
1001 }
1002
1003 char path[PATH_MAX];
1004 uint64_t firstColumAddress = 0;
1005 uint64_t secondColumAddress = 0;
1006 bool hasSecondColumn = false;
1007 while ( fgets(path, PATH_MAX, file) != NULL ) {
1008 path[PATH_MAX-1] = '\0';
1009 char* eol = strchr(path, '\n');
1010 if ( eol != NULL )
1011 *eol = '\0';
1012 // ignore lines not starting with 0x number
1013 if ( (path[0] == '0') && (path[1] == 'x') ) {
1014 char* p;
1015 firstColumAddress = strtoull(path, &p, 16);
1016 while ( isspace(*p) )
1017 ++p;
1018 // see if second column is a number
1019 if ( (p[0] == '0') && (p[1] == 'x') ) {
1020 secondColumAddress = strtoull(p, &p, 16);
1021 hasSecondColumn = true;
1022 while ( isspace(*p) )
1023 ++p;
1024 }
1025 while ( isspace(*p) )
1026 ++p;
1027 if ( p[0] == '/' ) {
1028 // remove any trailing whitespace
1029 for(char* end = eol-1; (end > p) && isspace(*end); --end)
1030 *end = '\0';
1031 // see if this line is for the dylib being linked
a645023d 1032 if ( strcmp(p, installPth) == 0 ) {
a61fdf0a
A
1033 fBaseAddress = firstColumAddress;
1034 if ( hasSecondColumn ) {
1035 fBaseWritableAddress = secondColumAddress;
1036 fSplitSegs = true;
1037 }
1038 break; // out of while loop
1039 }
1040 }
1041 }
1042 }
1043
1044 fclose(file);
1045}
6e880c60 1046
ebf6f434 1047void Options::loadFileList(const char* fileOfPaths, ld::File::Ordinal baseOrdinal)
c2646906 1048{
69a49097
A
1049 FILE* file;
1050 const char* comma = strrchr(fileOfPaths, ',');
1051 const char* prefix = NULL;
1052 if ( comma != NULL ) {
55e3d2f6
A
1053 // <rdar://problem/5907981> -filelist fails with comma in path
1054 file = fopen(fileOfPaths, "r");
1055 if ( file == NULL ) {
1056 prefix = comma+1;
1057 int realFileOfPathsLen = comma-fileOfPaths;
1058 char realFileOfPaths[realFileOfPathsLen+1];
1059 strncpy(realFileOfPaths,fileOfPaths, realFileOfPathsLen);
1060 realFileOfPaths[realFileOfPathsLen] = '\0';
1061 file = fopen(realFileOfPaths, "r");
1062 if ( file == NULL )
ebf6f434 1063 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", realFileOfPaths, errno, strerror(errno));
f80fe69f
A
1064 if ( this->dumpDependencyInfo() )
1065 this->dumpDependency(Options::depFileList, realFileOfPaths);
55e3d2f6 1066 }
69a49097
A
1067 }
1068 else {
1069 file = fopen(fileOfPaths, "r");
1070 if ( file == NULL )
ebf6f434 1071 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", fileOfPaths, errno, strerror(errno));
f80fe69f
A
1072 if ( this->dumpDependencyInfo() )
1073 this->dumpDependency(Options::depFileList, fileOfPaths);
69a49097 1074 }
d696c285 1075
69a49097 1076 char path[PATH_MAX];
ebf6f434 1077 ld::File::Ordinal previousOrdinal = baseOrdinal;
a61fdf0a 1078 while ( fgets(path, PATH_MAX, file) != NULL ) {
69a49097 1079 path[PATH_MAX-1] = '\0';
c2646906
A
1080 char* eol = strchr(path, '\n');
1081 if ( eol != NULL )
1082 *eol = '\0';
69a49097
A
1083 if ( prefix != NULL ) {
1084 char builtPath[strlen(prefix)+strlen(path)+2];
1085 strcpy(builtPath, prefix);
1086 strcat(builtPath, "/");
1087 strcat(builtPath, path);
ebf6f434
A
1088 if (fPipelineFifo != NULL) {
1089 FileInfo info = FileInfo(builtPath);
1090 info.ordinal = previousOrdinal.nextFileListOrdinal();
1091 previousOrdinal = info.ordinal;
1092 info.fromFileList = true;
1093 fInputFiles.push_back(info);
1094 } else {
1095 FileInfo info = findFile(builtPath);
1096 info.ordinal = previousOrdinal.nextFileListOrdinal();
1097 previousOrdinal = info.ordinal;
1098 info.fromFileList = true;
1099 fInputFiles.push_back(info);
1100 }
69a49097
A
1101 }
1102 else {
ebf6f434
A
1103 if (fPipelineFifo != NULL) {
1104 FileInfo info = FileInfo(path);
1105 info.ordinal = previousOrdinal.nextFileListOrdinal();
1106 previousOrdinal = info.ordinal;
1107 info.fromFileList = true;
1108 fInputFiles.push_back(info);
1109 } else {
1110 FileInfo info = findFile(path);
1111 info.ordinal = previousOrdinal.nextFileListOrdinal();
1112 previousOrdinal = info.ordinal;
1113 info.fromFileList = true;
1114 fInputFiles.push_back(info);
1115 }
69a49097 1116 }
c2646906
A
1117 }
1118 fclose(file);
1119}
1120
a645023d
A
1121
1122void Options::SetWithWildcards::remove(const NameSet& toBeRemoved)
1123{
1124 for(NameSet::const_iterator it=toBeRemoved.begin(); it != toBeRemoved.end(); ++it) {
1125 const char* symbolName = *it;
1126 NameSet::iterator pos = fRegular.find(symbolName);
1127 if ( pos != fRegular.end() )
1128 fRegular.erase(pos);
1129 }
1130}
1131
1132bool Options::SetWithWildcards::hasWildCards(const char* symbol)
a61fdf0a
A
1133{
1134 // an exported symbol name containing *, ?, or [ requires wildcard matching
1135 return ( strpbrk(symbol, "*?[") != NULL );
1136}
1137
1138void Options::SetWithWildcards::insert(const char* symbol)
1139{
1140 if ( hasWildCards(symbol) )
1141 fWildCard.push_back(symbol);
1142 else
1143 fRegular.insert(symbol);
1144}
1145
599556ff 1146bool Options::SetWithWildcards::contains(const char* symbol, bool* matchBecauseOfWildcard) const
a61fdf0a 1147{
599556ff
A
1148 if ( matchBecauseOfWildcard != NULL )
1149 *matchBecauseOfWildcard = false;
a61fdf0a
A
1150 // first look at hash table on non-wildcard symbols
1151 if ( fRegular.find(symbol) != fRegular.end() )
1152 return true;
1153 // next walk list of wild card symbols looking for a match
a645023d 1154 for(std::vector<const char*>::const_iterator it = fWildCard.begin(); it != fWildCard.end(); ++it) {
599556ff
A
1155 if ( wildCardMatch(*it, symbol) ) {
1156 if ( matchBecauseOfWildcard != NULL )
1157 *matchBecauseOfWildcard = true;
a61fdf0a 1158 return true;
599556ff 1159 }
a61fdf0a
A
1160 }
1161 return false;
1162}
1163
599556ff
A
1164// Support "foo.o:_bar" to mean symbol _bar in file foo.o
1165bool Options::SetWithWildcards::containsWithPrefix(const char* symbol, const char* file, bool& wildCardMatch) const
1166{
1167 wildCardMatch = false;
1168 if ( contains(symbol, &wildCardMatch) )
1169 return true;
1170 if ( file == NULL )
1171 return false;
1172 const char* s = strrchr(file, '/');
1173 if ( s != NULL )
1174 file = s+1;
1175 char buff[strlen(file)+strlen(symbol)+2];
1176 sprintf(buff, "%s:%s", file, symbol);
1177 return contains(buff, &wildCardMatch);
1178}
1179
a645023d
A
1180bool Options::SetWithWildcards::containsNonWildcard(const char* symbol) const
1181{
1182 // look at hash table on non-wildcard symbols
1183 return ( fRegular.find(symbol) != fRegular.end() );
1184}
1185
1186
eaf282aa
A
1187std::vector<const char*> Options::exportsData() const
1188{
1189 return fExportSymbols.data();
1190}
1191
1192
1193std::vector<const char*> Options::SetWithWildcards::data() const
1194{
1195 std::vector<const char*> data;
1196 for (NameSet::iterator it=regularBegin(); it != regularEnd(); ++it) {
1197 data.push_back(*it);
1198 }
1199 for (std::vector<const char*>::const_iterator it=fWildCard.begin(); it != fWildCard.end(); ++it) {
1200 data.push_back(*it);
1201 }
1202 return data;
1203}
a61fdf0a 1204
a645023d 1205bool Options::SetWithWildcards::inCharRange(const char*& p, unsigned char c) const
a61fdf0a
A
1206{
1207 ++p; // find end
1208 const char* b = p;
1209 while ( *p != '\0' ) {
1210 if ( *p == ']') {
1211 const char* e = p;
1212 // found beginining [ and ending ]
1213 unsigned char last = '\0';
1214 for ( const char* s = b; s < e; ++s ) {
1215 if ( *s == '-' ) {
1216 unsigned char next = *(++s);
1217 if ( (last <= c) && (c <= next) )
1218 return true;
1219 ++s;
1220 }
1221 else {
1222 if ( *s == c )
1223 return true;
1224 last = *s;
1225 }
1226 }
1227 return false;
1228 }
1229 ++p;
1230 }
1231 return false;
1232}
1233
a645023d 1234bool Options::SetWithWildcards::wildCardMatch(const char* pattern, const char* symbol) const
a61fdf0a
A
1235{
1236 const char* s = symbol;
1237 for (const char* p = pattern; *p != '\0'; ++p) {
1238 switch ( *p ) {
1239 case '*':
1240 if ( p[1] == '\0' )
1241 return true;
1242 for (const char* t = s; *t != '\0'; ++t) {
1243 if ( wildCardMatch(&p[1], t) )
1244 return true;
1245 }
1246 return false;
1247 case '?':
1248 if ( *s == '\0' )
1249 return false;
1250 ++s;
1251 break;
1252 case '[':
1253 if ( ! inCharRange(p, *s) )
1254 return false;
1255 ++s;
1256 break;
1257 default:
1258 if ( *s != *p )
1259 return false;
1260 ++s;
1261 }
1262 }
1263 return (*s == '\0');
1264}
1265
c2646906 1266
a61fdf0a 1267void Options::loadExportFile(const char* fileOfExports, const char* option, SetWithWildcards& set)
c2646906 1268{
a645023d
A
1269 if ( fileOfExports == NULL )
1270 throwf("missing file after %s", option);
c2646906
A
1271 // read in whole file
1272 int fd = ::open(fileOfExports, O_RDONLY, 0);
1273 if ( fd == -1 )
1274 throwf("can't open %s file: %s", option, fileOfExports);
1275 struct stat stat_buf;
1276 ::fstat(fd, &stat_buf);
1277 char* p = (char*)malloc(stat_buf.st_size);
1278 if ( p == NULL )
1279 throwf("can't process %s file: %s", option, fileOfExports);
d696c285 1280
c2646906
A
1281 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1282 throwf("can't read %s file: %s", option, fileOfExports);
d696c285 1283
f80fe69f
A
1284 if ( this->dumpDependencyInfo() )
1285 this->dumpDependency(Options::depMisc, fileOfExports);
1286
c2646906 1287 ::close(fd);
d696c285 1288
d425e388 1289 // parse into symbols and add to unordered_set
c2646906
A
1290 char * const end = &p[stat_buf.st_size];
1291 enum { lineStart, inSymbol, inComment } state = lineStart;
1292 char* symbolStart = NULL;
1293 for (char* s = p; s < end; ++s ) {
1294 switch ( state ) {
d696c285
A
1295 case lineStart:
1296 if ( *s =='#' ) {
1297 state = inComment;
1298 }
1299 else if ( !isspace(*s) ) {
1300 state = inSymbol;
1301 symbolStart = s;
1302 }
1303 break;
1304 case inSymbol:
a61fdf0a 1305 if ( (*s == '\n') || (*s == '\r') ) {
d696c285
A
1306 *s = '\0';
1307 // removing any trailing spaces
1308 char* last = s-1;
1309 while ( isspace(*last) ) {
1310 *last = '\0';
1311 --last;
c2646906 1312 }
d696c285
A
1313 set.insert(symbolStart);
1314 symbolStart = NULL;
1315 state = lineStart;
1316 }
1317 break;
1318 case inComment:
a61fdf0a 1319 if ( (*s == '\n') || (*s == '\r') )
d696c285
A
1320 state = lineStart;
1321 break;
1322 }
1323 }
1324 if ( state == inSymbol ) {
2f2f92e4 1325 warning("missing line-end at end of file \"%s\"", fileOfExports);
d696c285
A
1326 int len = end-symbolStart+1;
1327 char* temp = new char[len];
1328 strlcpy(temp, symbolStart, len);
1329
1330 // remove any trailing spaces
1331 char* last = &temp[len-2];
1332 while ( isspace(*last) ) {
1333 *last = '\0';
1334 --last;
c2646906 1335 }
d696c285 1336 set.insert(temp);
c2646906 1337 }
d696c285 1338
c2646906
A
1339 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
1340}
1341
a61fdf0a
A
1342void Options::parseAliasFile(const char* fileOfAliases)
1343{
1344 // read in whole file
1345 int fd = ::open(fileOfAliases, O_RDONLY, 0);
1346 if ( fd == -1 )
1347 throwf("can't open alias file: %s", fileOfAliases);
1348 struct stat stat_buf;
1349 ::fstat(fd, &stat_buf);
1350 char* p = (char*)malloc(stat_buf.st_size+1);
1351 if ( p == NULL )
1352 throwf("can't process alias file: %s", fileOfAliases);
1353
1354 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1355 throwf("can't read alias file: %s", fileOfAliases);
1356 p[stat_buf.st_size] = '\n';
1357 ::close(fd);
f80fe69f
A
1358 if ( this->dumpDependencyInfo() )
1359 this->dumpDependency(Options::depMisc, fileOfAliases);
a61fdf0a
A
1360
1361 // parse into symbols and add to fAliases
a645023d 1362 AliasPair pair;
a61fdf0a
A
1363 char * const end = &p[stat_buf.st_size+1];
1364 enum { lineStart, inRealName, inBetween, inAliasName, inComment } state = lineStart;
1365 int lineNumber = 1;
1366 for (char* s = p; s < end; ++s ) {
1367 switch ( state ) {
1368 case lineStart:
1369 if ( *s =='#' ) {
1370 state = inComment;
1371 }
1372 else if ( !isspace(*s) ) {
1373 state = inRealName;
1374 pair.realName = s;
1375 }
1376 break;
1377 case inRealName:
1378 if ( *s == '\n' ) {
2f2f92e4 1379 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
a61fdf0a
A
1380 ++lineNumber;
1381 state = lineStart;
1382 }
1383 else if ( isspace(*s) ) {
1384 *s = '\0';
1385 state = inBetween;
1386 }
1387 break;
1388 case inBetween:
1389 if ( *s == '\n' ) {
2f2f92e4 1390 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
a61fdf0a
A
1391 ++lineNumber;
1392 state = lineStart;
1393 }
1394 else if ( ! isspace(*s) ) {
1395 state = inAliasName;
1396 pair.alias = s;
1397 }
1398 break;
1399 case inAliasName:
1400 if ( *s =='#' ) {
1401 *s = '\0';
1402 // removing any trailing spaces
1403 char* last = s-1;
1404 while ( isspace(*last) ) {
1405 *last = '\0';
1406 --last;
1407 }
a645023d 1408 fAliases.push_back(pair);
a61fdf0a
A
1409 state = inComment;
1410 }
1411 else if ( *s == '\n' ) {
1412 *s = '\0';
1413 // removing any trailing spaces
1414 char* last = s-1;
1415 while ( isspace(*last) ) {
1416 *last = '\0';
1417 --last;
1418 }
a645023d 1419 fAliases.push_back(pair);
a61fdf0a
A
1420 state = lineStart;
1421 }
1422 break;
1423 case inComment:
1424 if ( *s == '\n' )
1425 state = lineStart;
1426 break;
1427 }
1428 }
1429
1430 // Note: we do not free() the malloc buffer, because the strings therein are used by fAliases
1431}
1432
1433
1434
c2646906
A
1435void Options::setUndefinedTreatment(const char* treatment)
1436{
d696c285 1437 if ( treatment == NULL )
c2646906
A
1438 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
1439
1440 if ( strcmp(treatment, "warning") == 0 )
1441 fUndefinedTreatment = kUndefinedWarning;
1442 else if ( strcmp(treatment, "error") == 0 )
1443 fUndefinedTreatment = kUndefinedError;
1444 else if ( strcmp(treatment, "suppress") == 0 )
1445 fUndefinedTreatment = kUndefinedSuppress;
1446 else if ( strcmp(treatment, "dynamic_lookup") == 0 )
1447 fUndefinedTreatment = kUndefinedDynamicLookup;
1448 else
1449 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
1450}
1451
d696c285 1452Options::Treatment Options::parseTreatment(const char* treatment)
c2646906 1453{
d696c285
A
1454 if ( treatment == NULL )
1455 return kNULL;
c2646906
A
1456
1457 if ( strcmp(treatment, "warning") == 0 )
d696c285
A
1458 return kWarning;
1459 else if ( strcmp(treatment, "error") == 0 )
1460 return kError;
c2646906 1461 else if ( strcmp(treatment, "suppress") == 0 )
d696c285
A
1462 return kSuppress;
1463 else
1464 return kInvalid;
c2646906
A
1465}
1466
2f2f92e4 1467void Options::setMacOSXVersionMin(const char* version)
d696c285 1468{
ec29ba20
A
1469 uint32_t value;
1470 if ( !parsePackedVersion32(version, value) ) {
1471 throwf("-macosx_version_min value malformed: '%s'", version);
2f2f92e4 1472 }
ec29ba20
A
1473 fMacVersionMin = (ld::MacVersionMin)value;
1474 fPlatform = kPlatformOSX;
2f2f92e4
A
1475}
1476
afe874b1 1477void Options::setIOSVersionMin(const char* version)
2f2f92e4 1478{
ec29ba20
A
1479 uint32_t value;
1480 if ( !parsePackedVersion32(version, value) ) {
1481 throwf("-ios_version_min value malformed: '%s'", version);
1482 }
1483 fIOSVersionMin = (ld::IOSVersionMin)value;
eaf282aa
A
1484 fPlatform = kPlatformiOS;
1485}
1486
1487
1488void Options::setWatchOSVersionMin(const char* version)
1489{
ec29ba20
A
1490 uint32_t value;
1491 if ( !parsePackedVersion32(version, value) ) {
1492 throwf("-watchos_version_min value malformed: '%s'", version);
1493 }
1494 fWatchOSVersionMin = (ld::WatchOSVersionMin)value;
eaf282aa 1495 fPlatform = kPlatformWatchOS;
55e3d2f6
A
1496}
1497
eaf282aa 1498
afe874b1 1499bool Options::minOS(ld::MacVersionMin requiredMacMin, ld::IOSVersionMin requirediPhoneOSMin)
55e3d2f6 1500{
a645023d
A
1501 if ( fMacVersionMin != ld::macVersionUnset ) {
1502 return ( fMacVersionMin >= requiredMacMin );
55e3d2f6 1503 }
eaf282aa
A
1504 else if ( fWatchOSVersionMin != ld::wOSVersionUnset ) {
1505 // Hack until we fully track watch and ios versions seperately
1506 return ( (fWatchOSVersionMin + 0x00070000) >= requirediPhoneOSMin);
1507 }
55e3d2f6 1508 else {
eaf282aa 1509 return ( fIOSVersionMin >= requirediPhoneOSMin );
69a49097 1510 }
c2646906
A
1511}
1512
eaf282aa
A
1513bool Options::min_iOS(ld::IOSVersionMin requirediOSMin)
1514{
1515 if ( fWatchOSVersionMin != ld::wOSVersionUnset ) {
1516 // Hack until we fully track watch and ios versions seperately
1517 return ( (fWatchOSVersionMin + 0x00070000) >= requirediOSMin);
1518 }
1519 else {
1520 return ( fIOSVersionMin >= requirediOSMin );
1521 }
1522}
55e3d2f6 1523
c2646906
A
1524void Options::setWeakReferenceMismatchTreatment(const char* treatment)
1525{
d696c285 1526 if ( treatment == NULL )
c2646906
A
1527 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
1528
1529 if ( strcmp(treatment, "error") == 0 )
1530 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchError;
1531 else if ( strcmp(treatment, "weak") == 0 )
1532 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchWeak;
1533 else if ( strcmp(treatment, "non-weak") == 0 )
1534 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchNonWeak;
1535 else
1536 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
1537}
1538
1539Options::CommonsMode Options::parseCommonsTreatment(const char* mode)
1540{
d696c285 1541 if ( mode == NULL )
c2646906
A
1542 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
1543
1544 if ( strcmp(mode, "ignore_dylibs") == 0 )
1545 return kCommonsIgnoreDylibs;
1546 else if ( strcmp(mode, "use_dylibs") == 0 )
1547 return kCommonsOverriddenByDylibs;
1548 else if ( strcmp(mode, "error") == 0 )
1549 return kCommonsConflictsDylibsError;
1550 else
1551 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
1552}
1553
a61fdf0a 1554void Options::addDylibOverride(const char* paths)
c2646906 1555{
a61fdf0a
A
1556 if ( paths == NULL )
1557 throw "-dylib_file must followed by two colon separated paths";
1558 const char* colon = strchr(paths, ':');
1559 if ( colon == NULL )
1560 throw "-dylib_file must followed by two colon separated paths";
1561 int len = colon-paths;
1562 char* target = new char[len+2];
1563 strncpy(target, paths, len);
1564 target[len] = '\0';
1565 DylibOverride entry;
1566 entry.installName = target;
1567 entry.useInstead = &colon[1];
1568 fDylibOverrides.push_back(entry);
c2646906
A
1569}
1570
c2646906
A
1571uint64_t Options::parseAddress(const char* addr)
1572{
1573 char* endptr;
1574 uint64_t result = strtoull(addr, &endptr, 16);
1575 return result;
1576}
1577
a61fdf0a
A
1578uint32_t Options::parseProtection(const char* prot)
1579{
1580 uint32_t result = 0;
1581 for(const char* p = prot; *p != '\0'; ++p) {
1582 switch(tolower(*p)) {
1583 case 'r':
1584 result |= VM_PROT_READ;
1585 break;
1586 case 'w':
1587 result |= VM_PROT_WRITE;
1588 break;
1589 case 'x':
1590 result |= VM_PROT_EXECUTE;
1591 break;
1592 case '-':
1593 break;
1594 default:
1595 throwf("unknown -segprot lettter in %s", prot);
1596 }
1597 }
1598 return result;
1599}
1600
1601
b2fa67a8
A
1602//
1603// Parses number of form A[.B[.B[.D[.E]]]] into a uint64_t where the bits are a24.b10.c10.d10.e10
1604//
1605uint64_t Options::parseVersionNumber64(const char* versionString)
1606{
1607 uint64_t a = 0;
1608 uint64_t b = 0;
1609 uint64_t c = 0;
1610 uint64_t d = 0;
1611 uint64_t e = 0;
1612 char* end;
1613 a = strtoul(versionString, &end, 10);
1614 if ( *end == '.' ) {
1615 b = strtoul(&end[1], &end, 10);
1616 if ( *end == '.' ) {
1617 c = strtoul(&end[1], &end, 10);
1618 if ( *end == '.' ) {
1619 d = strtoul(&end[1], &end, 10);
1620 if ( *end == '.' ) {
1621 e = strtoul(&end[1], &end, 10);
1622 }
1623 }
1624 }
1625 }
1626 if ( (*end != '\0') || (a > 0xFFFFFF) || (b > 0x3FF) || (c > 0x3FF) || (d > 0x3FF) || (e > 0x3FF) )
1627 throwf("malformed 64-bit a.b.c.d.e version number: %s", versionString);
1628
1629 return (a << 40) | ( b << 30 ) | ( c << 20 ) | ( d << 10 ) | e;
1630}
1631
1632
1633uint32_t Options::currentVersion32() const
1634{
1635 // warn if it does not fit into 32 bit vers number
1636 uint32_t a = (fDylibCurrentVersion >> 40) & 0xFFFF;
1637 uint32_t b = (fDylibCurrentVersion >> 30) & 0xFF;
1638 uint32_t c = (fDylibCurrentVersion >> 20) & 0xFF;
1639 uint64_t rep32 = ((uint64_t)a << 40) | ((uint64_t)b << 30) | ((uint64_t)c << 20);
1640 if ( rep32 != fDylibCurrentVersion ) {
1641 warning("truncating -current_version to fit in 32-bit space used by old mach-o format");
1642 a = (fDylibCurrentVersion >> 40) & 0xFFFFFF;
1643 if ( a > 0xFFFF )
1644 a = 0xFFFF;
1645 b = (fDylibCurrentVersion >> 30) & 0x3FF;
1646 if ( b > 0xFF )
1647 b = 0xFF;
1648 c = (fDylibCurrentVersion >> 20) & 0x3FF;
1649 if ( c > 0xFF )
1650 c = 0xFF;
1651 }
1652 return (a << 16) | ( b << 8 ) | c;
1653}
a61fdf0a 1654
c2646906 1655//
d696c285 1656// Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
c2646906 1657//
b2fa67a8 1658uint32_t Options::parseVersionNumber32(const char* versionString)
c2646906 1659{
b2fa67a8
A
1660 uint32_t x = 0;
1661 uint32_t y = 0;
1662 uint32_t z = 0;
c2646906
A
1663 char* end;
1664 x = strtoul(versionString, &end, 10);
1665 if ( *end == '.' ) {
1666 y = strtoul(&end[1], &end, 10);
1667 if ( *end == '.' ) {
1668 z = strtoul(&end[1], &end, 10);
1669 }
1670 }
1671 if ( (*end != '\0') || (x > 0xffff) || (y > 0xff) || (z > 0xff) )
b2fa67a8 1672 throwf("malformed 32-bit x.y.z version number: %s", versionString);
c2646906
A
1673
1674 return (x << 16) | ( y << 8 ) | z;
1675}
1676
a61fdf0a
A
1677static const char* cstringSymbolName(const char* orderFileString)
1678{
1679 char* result;
1680 asprintf(&result, "cstring=%s", orderFileString);
1681 // convert escaped characters
1682 char* d = result;
1683 for(const char* s=result; *s != '\0'; ++s, ++d) {
1684 if ( *s == '\\' ) {
1685 ++s;
1686 switch ( *s ) {
1687 case 'n':
1688 *d = '\n';
1689 break;
1690 case 't':
1691 *d = '\t';
1692 break;
1693 case 'v':
1694 *d = '\v';
1695 break;
1696 case 'b':
1697 *d = '\b';
1698 break;
1699 case 'r':
1700 *d = '\r';
1701 break;
1702 case 'f':
1703 *d = '\f';
1704 break;
1705 case 'a':
1706 *d = '\a';
1707 break;
1708 case '\\':
1709 *d = '\\';
1710 break;
1711 case '?':
1712 *d = '\?';
1713 break;
1714 case '\'':
1715 *d = '\r';
1716 break;
1717 case '\"':
1718 *d = '\"';
1719 break;
1720 case 'x':
1721 // hexadecimal value of char
1722 {
1723 ++s;
1724 char value = 0;
1725 while ( isxdigit(*s) ) {
1726 value *= 16;
1727 if ( isdigit(*s) )
1728 value += (*s-'0');
1729 else
1730 value += ((toupper(*s)-'A') + 10);
1731 ++s;
1732 }
1733 *d = value;
1734 }
1735 break;
1736 default:
1737 if ( isdigit(*s) ) {
1738 // octal value of char
1739 char value = 0;
1740 while ( isdigit(*s) ) {
1741 value = (value << 3) + (*s-'0');
1742 ++s;
1743 }
1744 *d = value;
1745 }
1746 }
1747 }
1748 else {
1749 *d = *s;
1750 }
1751 }
1752 *d = '\0';
1753 return result;
1754}
1755
1756void Options::parseOrderFile(const char* path, bool cstring)
1757{
55e3d2f6 1758 // order files override auto-ordering
a645023d 1759 fAutoOrderInitializers = false;
55e3d2f6 1760
0a8dc3df
A
1761 // <rdar://problem/24856050> ld64 should prefer OrderFiles from the SDK over the ones in /
1762 for (const char* sdkPath : fSDKPaths) {
1763 char fullPath[PATH_MAX];
1764 strlcpy(fullPath, sdkPath, PATH_MAX);
1765 strlcat(fullPath, "/", PATH_MAX);
1766 strlcat(fullPath, path, PATH_MAX);
1767 struct stat statBuffer;
1768 if ( stat(fullPath, &statBuffer) == 0 ) {
1769 path = strdup(fullPath);
1770 break;
1771 }
1772 }
1773
a61fdf0a
A
1774 // read in whole file
1775 int fd = ::open(path, O_RDONLY, 0);
1776 if ( fd == -1 )
1777 throwf("can't open order file: %s", path);
1778 struct stat stat_buf;
1779 ::fstat(fd, &stat_buf);
1780 char* p = (char*)malloc(stat_buf.st_size+1);
1781 if ( p == NULL )
1782 throwf("can't process order file: %s", path);
1783 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1784 throwf("can't read order file: %s", path);
1785 ::close(fd);
1786 p[stat_buf.st_size] = '\n';
f80fe69f
A
1787 if ( this->dumpDependencyInfo() )
1788 this->dumpDependency(Options::depMisc, path);
a61fdf0a
A
1789
1790 // parse into vector of pairs
1791 char * const end = &p[stat_buf.st_size+1];
1792 enum { lineStart, inSymbol, inComment } state = lineStart;
1793 char* symbolStart = NULL;
1794 for (char* s = p; s < end; ++s ) {
1795 switch ( state ) {
1796 case lineStart:
1797 if ( *s =='#' ) {
1798 state = inComment;
1799 }
1800 else if ( !isspace(*s) || cstring ) {
1801 state = inSymbol;
1802 symbolStart = s;
1803 }
1804 break;
1805 case inSymbol:
1806 if ( (*s == '\n') || (!cstring && (*s == '#')) ) {
1807 bool wasComment = (*s == '#');
1808 *s = '\0';
1809 // removing any trailing spaces
1810 char* last = s-1;
1811 while ( isspace(*last) ) {
1812 *last = '\0';
1813 --last;
1814 }
b2fa67a8 1815 // if there is an architecture prefix, only use this symbol it if matches current arch
a61fdf0a 1816 if ( strncmp(symbolStart, "ppc:", 4) == 0 ) {
b2fa67a8 1817 symbolStart = NULL;
a61fdf0a 1818 }
a61fdf0a 1819 else if ( strncmp(symbolStart, "ppc64:", 6) == 0 ) {
b2fa67a8 1820 symbolStart = NULL;
a61fdf0a
A
1821 }
1822 else if ( strncmp(symbolStart, "i386:", 5) == 0 ) {
1823 if ( fArchitecture == CPU_TYPE_I386 )
1824 symbolStart = &symbolStart[5];
1825 else
1826 symbolStart = NULL;
1827 }
1828 else if ( strncmp(symbolStart, "x86_64:", 7) == 0 ) {
1829 if ( fArchitecture == CPU_TYPE_X86_64 )
1830 symbolStart = &symbolStart[7];
1831 else
1832 symbolStart = NULL;
1833 }
2f2f92e4
A
1834 else if ( strncmp(symbolStart, "arm:", 4) == 0 ) {
1835 if ( fArchitecture == CPU_TYPE_ARM )
1836 symbolStart = &symbolStart[4];
1837 else
1838 symbolStart = NULL;
1839 }
fb9a160c
A
1840 else if ( strncmp(symbolStart, "arm64:", 6) == 0 ) {
1841 if ( fArchitecture == CPU_TYPE_ARM64 )
1842 symbolStart = &symbolStart[6];
1843 else
1844 symbolStart = NULL;
1845 }
a61fdf0a
A
1846 if ( symbolStart != NULL ) {
1847 char* objFileName = NULL;
1848 char* colon = strstr(symbolStart, ".o:");
1849 if ( colon != NULL ) {
1850 colon[2] = '\0';
1851 objFileName = symbolStart;
1852 symbolStart = &colon[3];
1853 }
f80fe69f
A
1854 else {
1855 colon = strstr(symbolStart, ".o):");
1856 if ( colon != NULL ) {
1857 colon[3] = '\0';
1858 objFileName = symbolStart;
1859 symbolStart = &colon[4];
1860 }
1861 }
a61fdf0a
A
1862 // trim leading spaces
1863 while ( isspace(*symbolStart) )
1864 ++symbolStart;
1865 Options::OrderedSymbol pair;
1866 if ( cstring )
1867 pair.symbolName = cstringSymbolName(symbolStart);
1868 else
1869 pair.symbolName = symbolStart;
1870 pair.objectFileName = objFileName;
1871 fOrderedSymbols.push_back(pair);
1872 }
1873 symbolStart = NULL;
1874 if ( wasComment )
1875 state = inComment;
1876 else
1877 state = lineStart;
1878 }
1879 break;
1880 case inComment:
1881 if ( *s == '\n' )
1882 state = lineStart;
1883 break;
1884 }
1885 }
1886 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1887}
1888
c2646906
A
1889void Options::parseSectionOrderFile(const char* segment, const char* section, const char* path)
1890{
a61fdf0a
A
1891 if ( (strcmp(section, "__cstring") == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1892 parseOrderFile(path, true);
1893 }
1894 else if ( (strncmp(section, "__literal",9) == 0) && (strcmp(segment, "__TEXT") == 0) ) {
2f2f92e4 1895 warning("sorting of __literal[4,8,16] sections not supported");
a61fdf0a
A
1896 }
1897 else {
1898 // ignore section information and append all symbol names to global order file
1899 parseOrderFile(path, false);
1900 }
c2646906
A
1901}
1902
1903void Options::addSection(const char* segment, const char* section, const char* path)
1904{
1905 if ( strlen(segment) > 16 )
1906 throw "-seccreate segment name max 16 chars";
d696c285
A
1907 if ( strlen(section) > 16 ) {
1908 char* tmp = strdup(section);
1909 tmp[16] = '\0';
2f2f92e4 1910 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section, tmp);
d696c285
A
1911 section = tmp;
1912 }
c2646906
A
1913
1914 // read in whole file
1915 int fd = ::open(path, O_RDONLY, 0);
1916 if ( fd == -1 )
1917 throwf("can't open -sectcreate file: %s", path);
1918 struct stat stat_buf;
1919 ::fstat(fd, &stat_buf);
1920 char* p = (char*)malloc(stat_buf.st_size);
1921 if ( p == NULL )
1922 throwf("can't process -sectcreate file: %s", path);
1923 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1924 throwf("can't read -sectcreate file: %s", path);
1925 ::close(fd);
d696c285 1926
c2646906 1927 // record section to create
eaf282aa 1928 ExtraSection info = { segment, section, path, (uint8_t*)p, (uint64_t)stat_buf.st_size };
c2646906
A
1929 fExtraSections.push_back(info);
1930}
1931
9543cb2f
A
1932void Options::addSectionRename(const char* srcSegment, const char* srcSection, const char* dstSegment, const char* dstSection)
1933{
1934 if ( strlen(srcSegment) > 16 )
1935 throw "-rename_section segment name max 16 chars";
1936 if ( strlen(srcSection) > 16 )
1937 throw "-rename_section section name max 16 chars";
1938 if ( strlen(dstSegment) > 16 )
1939 throw "-rename_section segment name max 16 chars";
1940 if ( strlen(dstSection) > 16 )
1941 throw "-rename_section section name max 16 chars";
1942
1943 SectionRename info;
1944 info.fromSegment = srcSegment;
1945 info.fromSection = srcSection;
1946 info.toSegment = dstSegment;
1947 info.toSection = dstSection;
1948
1949 fSectionRenames.push_back(info);
1950}
1951
1952
599556ff
A
1953void Options::addSegmentRename(const char* srcSegment, const char* dstSegment)
1954{
1955 if ( strlen(srcSegment) > 16 )
1956 throw "-rename_segment segment name max 16 chars";
1957 if ( strlen(dstSegment) > 16 )
1958 throw "-rename_segment segment name max 16 chars";
1959
1960 SegmentRename info;
1961 info.fromSegment = srcSegment;
1962 info.toSegment = dstSegment;
1963
1964 fSegmentRenames.push_back(info);
1965}
1966
1967
1968
1969void Options::addSymbolMove(const char* dstSegment, const char* symbolList,
1970 std::vector<SymbolsMove>& list, const char* optionName)
1971{
1972 if ( strlen(dstSegment) > 16 )
1973 throwf("%s segment name max 16 chars", optionName);
1974
1975 SymbolsMove tmp;
1976 list.push_back(tmp);
1977 SymbolsMove& info = list.back();
1978 info.toSegment = dstSegment;
1979 loadExportFile(symbolList, optionName, info.symbols);
1980}
1981
1982bool Options::moveRwSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const
1983{
1984 for (std::vector<SymbolsMove>::const_iterator it=fSymbolsMovesData.begin(); it != fSymbolsMovesData.end(); ++it) {
1985 const SymbolsMove& info = *it;
1986 if ( info.symbols.containsWithPrefix(symName, filePath, wildCardMatch)) {
1987 seg = info.toSegment;
1988 return true;
1989 }
1990 }
1991 return false;
1992}
1993
1994bool Options::moveRoSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const
1995{
1996 for (std::vector<SymbolsMove>::const_iterator it=fSymbolsMovesCode.begin(); it != fSymbolsMovesCode.end(); ++it) {
1997 const SymbolsMove& info = *it;
1998 if ( info.symbols.containsWithPrefix(symName, filePath, wildCardMatch)) {
1999 seg = info.toSegment;
2000 return true;
2001 }
2002 }
2003 return false;
2004}
2005
c2646906
A
2006void Options::addSectionAlignment(const char* segment, const char* section, const char* alignmentStr)
2007{
2008 if ( strlen(segment) > 16 )
2009 throw "-sectalign segment name max 16 chars";
2010 if ( strlen(section) > 16 )
2011 throw "-sectalign section name max 16 chars";
2012
d696c285 2013 // argument to -sectalign is a hexadecimal number
c2646906
A
2014 char* endptr;
2015 unsigned long value = strtoul(alignmentStr, &endptr, 16);
2016 if ( *endptr != '\0')
2017 throw "argument for -sectalign is not a hexadecimal number";
2018 if ( value > 0x8000 )
2019 throw "argument for -sectalign must be less than or equal to 0x8000";
d696c285 2020 if ( value == 0 ) {
2f2f92e4 2021 warning("zero is not a valid -sectalign");
d696c285
A
2022 value = 1;
2023 }
a61fdf0a 2024
d696c285 2025 // alignment is power of 2 (e.g. page alignment = 12)
a61fdf0a 2026 uint8_t alignment = (uint8_t)__builtin_ctz(value);
d696c285 2027 if ( (unsigned long)(1 << alignment) != value ) {
2f2f92e4 2028 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
d696c285
A
2029 segment, section, 1 << alignment);
2030 }
c2646906
A
2031
2032 SectionAlignment info = { segment, section, alignment };
2033 fSectionAlignments.push_back(info);
2034}
2035
a61fdf0a
A
2036void Options::addLibrary(const FileInfo& info)
2037{
2038 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
2039 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
2040 if ( strcmp(info.path, fit->path) == 0 ) {
2041 // if dylib is specified again but weak, record that it should be weak
2042 if ( info.options.fWeakImport )
2043 fit->options.fWeakImport = true;
2044 return;
2045 }
2046 }
2047 // add to list
2048 fInputFiles.push_back(info);
2049}
2050
2051void Options::warnObsolete(const char* arg)
2052{
2f2f92e4 2053 warning("option %s is obsolete and being ignored", arg);
a61fdf0a
A
2054}
2055
2056
eaf282aa
A
2057void Options::cannotBeUsedWithBitcode(const char* arg)
2058{
2059 if ( fBundleBitcode )
2060 throwf("%s and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together", arg);
2061}
2062
2063std::string Options::getVersionString32(uint32_t ver) const
2064{
2065 if (ver == 0 || ver >= 0x10000000)
2066 return "0.0.0";
2067
2068 unsigned microVersion = ver & 0xFF;
2069 unsigned minorVersion = (ver >> 8) & 0xFF;
2070 unsigned majorVersion = (ver >> 16) & 0xFF;
2071 std::stringstream versionString;
2072 versionString << majorVersion << "." << minorVersion << "." << microVersion;
2073 return versionString.str();
2074}
2075
2076std::string Options::getVersionString64(uint64_t ver) const
2077{
2078 uint64_t a = (ver >> 40) & 0xFFFFFF;
2079 uint64_t b = (ver >> 30) & 0x3FF;
2080 uint64_t c = (ver >> 20) & 0x3FF;
2081 uint64_t d = (ver >> 10) & 0x3FF;
2082 uint64_t e = ver & 0x3FF;
2083 std::stringstream versionString;
2084 versionString << a << "." << b << "." << c << "." << d << "." << e;
2085 return versionString.str();
2086}
2087
ec29ba20
A
2088// Convert X.Y[.Z] to 32-bit value xxxxyyzz
2089bool Options::parsePackedVersion32(const std::string& versionStr, uint32_t &result)
2090{
2091 result = 0;
2092
2093 if ( versionStr.empty() )
2094 return false;
2095
2096 size_t pos = versionStr.find('.');
2097 if ( pos == std::string::npos )
2098 return false;
2099
2100 std::string majorStr = versionStr.substr(0, pos);
2101 std::string rest = versionStr.substr(pos+1);
2102
2103 try {
2104 size_t majorEnd;
2105 int majorValue = std::stoi(majorStr, &majorEnd);
2106 if ( majorEnd != majorStr.size() )
2107 return false;
2108 if ( majorValue < 0 )
2109 return false;
2110 if ( majorValue > 65535 )
2111 return false;
2112
2113 std::string minorStr;
2114 std::string microStr;
2115 pos = rest.find('.');
2116 if ( pos == std::string::npos ) {
2117 minorStr = rest;
2118 }
2119 else {
2120 minorStr = rest.substr(0, pos);
2121 microStr = rest.substr(pos+1);
2122 }
2123
2124 size_t minorEnd;
2125 int minorValue = std::stoi(minorStr, &minorEnd);
2126 if ( minorEnd != minorStr.size() )
2127 return false;
2128 if ( minorValue < 0 )
2129 return false;
2130 if ( minorValue > 255 )
2131 return false;
2132
2133 int microValue = 0;
2134 if ( !microStr.empty() ) {
2135 size_t microEnd;
2136 microValue = std::stoi(microStr, &microEnd);
2137 if ( microEnd != microStr.size() )
2138 return false;
2139 if ( microValue < 0 )
2140 return false;
2141 if ( microValue > 255 )
2142 return false;
2143 }
2144
2145 result = (majorValue << 16) | (minorValue << 8) | microValue;
2146
2147 return true;
2148 }
2149 catch (...) {
2150 // std::stoi() throws exception on malformed input
2151 return false;
2152 }
2153}
2154
eaf282aa
A
2155std::string Options::getSDKVersionStr() const
2156{
2157 return getVersionString32(fSDKVersion);
2158}
2159
2160std::string Options::getPlatformStr() const
2161{
2162 switch (fPlatform) {
2163 case Options::kPlatformOSX:
2164 return "MacOSX";
2165 case Options::kPlatformiOS:
2166 if (targetIOSSimulator())
2167 return "iPhoneSimulator";
2168 else
2169 return "iPhoneOS";
2170 case Options::kPlatformWatchOS:
2171 if (targetIOSSimulator())
2172 return "watchOS Simulator";
2173 else
2174 return "watchOS";
2175#if SUPPORT_APPLE_TV
2176 case Options::kPlatform_tvOS:
2177 if (targetIOSSimulator())
2178 return "AppleTVSimulator";
2179 else
2180 return "AppleTVOS";
2181 break;
2182#endif
2183 case Options::kPlatformUnknown:
2184 return "Unknown";
2185 }
2186}
2187
2188std::vector<std::string> Options::writeBitcodeLinkOptions() const
2189{
2190 std::vector<std::string> linkCommand;
2191 switch ( fOutputKind ) {
2192 case Options::kDynamicLibrary:
2193 linkCommand.push_back("-dylib");
2194 linkCommand.push_back("-compatibility_version");
2195 if ( fDylibCompatVersion != 0 ) {
2196 linkCommand.push_back(getVersionString32(fDylibCompatVersion));
2197 } else {
2198 linkCommand.push_back(getVersionString32(currentVersion32()));
2199 }
2200 if ( fDylibCurrentVersion != 0 ) {
2201 linkCommand.push_back("-current_version");
2202 linkCommand.push_back(getVersionString64(fDylibCurrentVersion));
2203 }
2204 linkCommand.push_back("-install_name");
2205 linkCommand.push_back(installPath());
2206 break;
2207 case Options::kDynamicExecutable:
2208 linkCommand.push_back("-execute");
2209 break;
2210 case Options::kObjectFile:
2211 linkCommand.push_back("-r");
2212 break;
2213 default:
2214 throwf("could not write bitcode options file output kind\n");
2215 }
a61fdf0a 2216
eaf282aa
A
2217 if (!fImplicitlyLinkPublicDylibs)
2218 linkCommand.push_back("-no_implicit_dylibs");
2219
2220 // Add deployment target.
2221 // Platform is allowed to be unknown for "ld -r".
2222 switch (fPlatform) {
2223 case Options::kPlatformOSX:
2224 linkCommand.push_back("-macosx_version_min");
2225 linkCommand.push_back(getVersionString32((unsigned)fMacVersionMin));
2226 break;
2227 case Options::kPlatformiOS:
2228 if (targetIOSSimulator())
2229 linkCommand.push_back("-ios_simulator_version_min");
2230 else
2231 linkCommand.push_back("-ios_version_min");
2232 linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
2233 break;
2234 case Options::kPlatformWatchOS:
2235 if (targetIOSSimulator())
2236 linkCommand.push_back("-watchos_simulator_version_min");
2237 else
2238 linkCommand.push_back("-watchos_version_min");
2239 linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
2240 break;
2241#if SUPPORT_APPLE_TV
2242 case Options::kPlatform_tvOS:
2243 if (targetIOSSimulator())
2244 linkCommand.push_back("-tvos_simulator_version_min");
2245 else
2246 linkCommand.push_back("-tvos_version_min");
2247 linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
2248 break;
2249#endif
2250 case Options::kPlatformUnknown:
2251 if ( fOutputKind != Options::kObjectFile ) {
2252 throwf("platform is unknown for final bitcode bundle,"
2253 "deployment target and min version is required for -bitcode_bundle");
2254 }
2255 break;
2256 }
2257
2258
2259 // entry name
2260 if ( fEntryName ) {
2261 linkCommand.push_back("-e");
2262 linkCommand.push_back(fEntryName);
2263 }
2264
2265 // Write rpaths
2266 if (!fRPaths.empty()) {
2267 for (std::vector<const char*>::const_iterator it=fRPaths.begin(); it != fRPaths.end(); ++it) {
2268 linkCommand.push_back("-rpath");
2269 linkCommand.push_back(*it);
2270 }
2271 }
2272
2273 // Other bitcode compatiable options
2274 if ( fObjCABIVersion1Override ) {
2275 linkCommand.push_back("-objc_abi_version");
2276 linkCommand.push_back("1");
2277 } else if ( fObjCABIVersion2Override ) {
2278 linkCommand.push_back("-objc_abi_version");
2279 linkCommand.push_back("2");
2280 }
2281 if ( fExecutablePath ) {
2282 linkCommand.push_back("-executable_path");
2283 linkCommand.push_back(fExecutablePath);
2284 }
2285 if ( fDeadStrip )
2286 linkCommand.push_back("-dead_strip");
2287 if ( fExportDynamic )
2288 linkCommand.push_back("-export_dynamic");
2289 if ( fMarkAppExtensionSafe && fCheckAppExtensionSafe )
2290 linkCommand.push_back("-application_extension");
2291
2292 if ( fSourceVersionLoadCommandForceOn )
2293 linkCommand.push_back("-add_source_version");
2294 if ( fSourceVersion != 0 ) {
2295 linkCommand.push_back("-source_version");
2296 linkCommand.push_back(getVersionString64(fSourceVersion));
2297 }
2298
2299 // linker flag added by swift driver
2300 // rdar://problem/20108072
2301 if ( !fObjcCategoryMerging )
2302 linkCommand.push_back("-no_objc_category_merging");
2303
2304 return linkCommand;
2305}
a61fdf0a 2306
d696c285
A
2307//
2308// Process all command line arguments.
2309//
2310// The only error checking done here is that each option is valid and if it has arguments
2311// that they too are valid.
2312//
2313// The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
2314// whichever was last on the command line is used.
2315//
2316// Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
2317//
c2646906
A
2318void Options::parse(int argc, const char* argv[])
2319{
ebf6f434
A
2320 // Store the original args in the link snapshot.
2321 fLinkSnapshot.recordRawArgs(argc, argv);
2322
c2646906
A
2323 // pass one builds search list from -L and -F options
2324 this->buildSearchPaths(argc, argv);
d696c285
A
2325
2326 // reduce re-allocations
2327 fInputFiles.reserve(32);
2328
c2646906
A
2329 // pass two parse all other options
2330 for(int i=1; i < argc; ++i) {
2331 const char* arg = argv[i];
d696c285 2332
c2646906 2333 if ( arg[0] == '-' ) {
ebf6f434
A
2334 // by default, copy one arg to the snapshot link command, and do no file copying
2335 int snapshotArgIndex = i;
2336 int snapshotArgCount = -1; // -1 means compute count based on change in index
2337 int snapshotFileArgIndex = -1; // -1 means no data file parameter to arg
d696c285
A
2338
2339 // Since we don't care about the files passed, just the option names, we do this here.
2340 if (fPrintOptions)
2341 fprintf (stderr, "[Logging ld64 options]\t%s\n", arg);
2342
c2646906 2343 if ( (arg[1] == 'L') || (arg[1] == 'F') ) {
ebf6f434 2344 snapshotArgCount = 0; // stripped out of link snapshot
a645023d
A
2345 if (arg[2] == '\0')
2346 ++i;
6e880c60 2347 // previously handled by buildSearchPaths()
c2646906 2348 }
a61fdf0a
A
2349 // The one gnu style option we have to keep compatibility
2350 // with gcc. Might as well have the single hyphen one as well.
2351 else if ( (strcmp(arg, "--help") == 0)
2352 || (strcmp(arg, "-help") == 0)) {
2353 fprintf (stdout, "ld64: For information on command line options please use 'man ld'.\n");
2354 exit (0);
2355 }
c2646906
A
2356 else if ( strcmp(arg, "-arch") == 0 ) {
2357 parseArch(argv[++i]);
2358 }
2359 else if ( strcmp(arg, "-dynamic") == 0 ) {
2360 // default
2361 }
2362 else if ( strcmp(arg, "-static") == 0 ) {
a645023d
A
2363 fForStatic = true;
2364 if ( (fOutputKind != kObjectFile) && (fOutputKind != kKextBundle) ) {
55e3d2f6
A
2365 fOutputKind = kStaticExecutable;
2366 }
eaf282aa 2367 cannotBeUsedWithBitcode(arg);
c2646906
A
2368 }
2369 else if ( strcmp(arg, "-dylib") == 0 ) {
2370 fOutputKind = kDynamicLibrary;
2371 }
2372 else if ( strcmp(arg, "-bundle") == 0 ) {
2373 fOutputKind = kDynamicBundle;
eaf282aa 2374 cannotBeUsedWithBitcode(arg);
c2646906
A
2375 }
2376 else if ( strcmp(arg, "-dylinker") == 0 ) {
2377 fOutputKind = kDyld;
eaf282aa 2378 cannotBeUsedWithBitcode(arg);
c2646906
A
2379 }
2380 else if ( strcmp(arg, "-execute") == 0 ) {
2381 if ( fOutputKind != kStaticExecutable )
2382 fOutputKind = kDynamicExecutable;
2383 }
55e3d2f6
A
2384 else if ( strcmp(arg, "-preload") == 0 ) {
2385 fOutputKind = kPreload;
eaf282aa 2386 cannotBeUsedWithBitcode(arg);
55e3d2f6 2387 }
c2646906
A
2388 else if ( strcmp(arg, "-r") == 0 ) {
2389 fOutputKind = kObjectFile;
2390 }
55e3d2f6
A
2391 else if ( strcmp(arg, "-kext") == 0 ) {
2392 fOutputKind = kKextBundle;
eaf282aa 2393 cannotBeUsedWithBitcode(arg);
55e3d2f6 2394 }
c2646906 2395 else if ( strcmp(arg, "-o") == 0 ) {
ebf6f434 2396 snapshotArgCount = 0;
c2646906 2397 fOutputFile = argv[++i];
ebf6f434 2398 fLinkSnapshot.setSnapshotName(fOutputFile);
c2646906 2399 }
a645023d 2400 else if ( strncmp(arg, "-lazy-l", 7) == 0 ) {
ebf6f434 2401 snapshotArgCount = 0;
a645023d
A
2402 FileInfo info = findLibrary(&arg[7], true);
2403 info.options.fLazyLoad = true;
ebf6f434 2404 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a645023d
A
2405 addLibrary(info);
2406 fUsingLazyDylibLinking = true;
eaf282aa 2407 cannotBeUsedWithBitcode(arg);
a645023d 2408 }
ebf6f434
A
2409 else if ( strcmp(arg, "-lto_library") == 0 ) {
2410 snapshotFileArgIndex = 1;
2411 fOverridePathlibLTO = argv[++i];
2412 if ( fOverridePathlibLTO == NULL )
2413 throw "missing argument to -lto_library";
2414 }
0a8dc3df
A
2415 else if ( strcmp(arg, "-cache_path_lto") == 0 ) {
2416 fLtoCachePath = argv[++i];
2417 if ( fLtoCachePath == NULL )
2418 throw "missing argument to -cache_path_lto";
2419 }
2420 else if ( strcmp(arg, "-prune_interval_lto") == 0 ) {
2421 const char* value = argv[++i];
2422 if ( value == NULL )
2423 throw "missing argument to -prune_interval_lto";
2424 char* endptr;
2425 fLtoPruneInterval = strtoul(value, &endptr, 10);
2426 if ( *endptr != '\0')
2427 throw "invalid argument for -prune_interval_lto";
2428 }
2429 else if ( strcmp(arg, "-prune_after_lto") == 0 ) {
2430 const char* value = argv[++i];
2431 if ( value == NULL )
2432 throw "missing argument to -prune_after_lto";
2433 char* endptr;
2434 fLtoPruneAfter = strtoul(value, &endptr, 10);
2435 if ( *endptr != '\0')
2436 throw "invalid argument for -prune_after_lto";
2437 }
2438 else if ( strcmp(arg, "-max_relative_cache_size_lto") == 0 ) {
2439 const char* value = argv[++i];
2440 if ( value == NULL )
2441 throw "missing argument to -max_relative_cache_size_lto";
2442 char* endptr;
2443 fLtoMaxCacheSize = strtoul(value, &endptr, 10);
2444 if ( *endptr != '\0')
2445 throw "invalid argument for -max_relative_cache_size_lto";
2446 if (fLtoMaxCacheSize > 100)
2447 throw "Expect a value between 0 and 100 for -max_relative_cache_size_lto";
2448 }
2f2f92e4 2449 else if ( (arg[1] == 'l') && (strncmp(arg,"-lazy_",6) !=0) ) {
ebf6f434
A
2450 snapshotArgCount = 0;
2451 FileInfo info = findLibrary(&arg[2]);
2452 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2453 addLibrary(info);
c2646906 2454 }
d696c285
A
2455 // This causes a dylib to be weakly bound at
2456 // link time. This corresponds to weak_import.
2457 else if ( strncmp(arg, "-weak-l", 7) == 0 ) {
ebf6f434
A
2458 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2459 snapshotArgCount = 0;
d696c285 2460 FileInfo info = findLibrary(&arg[7]);
c2646906 2461 info.options.fWeakImport = true;
ebf6f434 2462 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a 2463 addLibrary(info);
c2646906 2464 }
d696c285 2465 // Avoid lazy binding.
c2646906
A
2466 else if ( strcmp(arg, "-bind_at_load") == 0 ) {
2467 fBindAtLoad = true;
eaf282aa 2468 cannotBeUsedWithBitcode(arg);
c2646906
A
2469 }
2470 else if ( strcmp(arg, "-twolevel_namespace") == 0 ) {
2471 fNameSpace = kTwoLevelNameSpace;
2472 }
2473 else if ( strcmp(arg, "-flat_namespace") == 0 ) {
2474 fNameSpace = kFlatNameSpace;
eaf282aa 2475 cannotBeUsedWithBitcode(arg);
c2646906 2476 }
d696c285
A
2477 // Also sets a bit to ensure dyld causes everything
2478 // in the namespace to be flat.
2479 // ??? Deprecate
c2646906
A
2480 else if ( strcmp(arg, "-force_flat_namespace") == 0 ) {
2481 fNameSpace = kForceFlatNameSpace;
eaf282aa 2482 cannotBeUsedWithBitcode(arg);
c2646906 2483 }
d696c285 2484 // Similar to --whole-archive.
c2646906 2485 else if ( strcmp(arg, "-all_load") == 0 ) {
a645023d 2486 fFullyLoadArchives = true;
c2646906 2487 }
a61fdf0a
A
2488 else if ( strcmp(arg, "-noall_load") == 0) {
2489 warnObsolete(arg);
2490 }
2491 // Similar to -all_load
c2646906 2492 else if ( strcmp(arg, "-ObjC") == 0 ) {
a645023d 2493 fLoadAllObjcObjectsFromArchives = true;
c2646906 2494 }
55e3d2f6
A
2495 // Similar to -all_load, but for the following archive only.
2496 else if ( strcmp(arg, "-force_load") == 0 ) {
2497 FileInfo info = findFile(argv[++i]);
2498 info.options.fForceLoad = true;
ebf6f434 2499 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
55e3d2f6
A
2500 addLibrary(info);
2501 }
d696c285 2502 // Library versioning.
a61fdf0a
A
2503 else if ( (strcmp(arg, "-dylib_compatibility_version") == 0)
2504 || (strcmp(arg, "-compatibility_version") == 0)) {
2505 const char* vers = argv[++i];
2506 if ( vers == NULL )
2507 throw "-dylib_compatibility_version missing <version>";
b2fa67a8 2508 fDylibCompatVersion = parseVersionNumber32(vers);
a61fdf0a
A
2509 }
2510 else if ( (strcmp(arg, "-dylib_current_version") == 0)
2511 || (strcmp(arg, "-current_version") == 0)) {
2512 const char* vers = argv[++i];
2513 if ( vers == NULL )
2514 throw "-dylib_current_version missing <version>";
b2fa67a8 2515 fDylibCurrentVersion = parseVersionNumber64(vers);
c2646906
A
2516 }
2517 else if ( strcmp(arg, "-sectorder") == 0 ) {
a61fdf0a
A
2518 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2519 throw "-sectorder missing <segment> <section> <file-path>";
ebf6f434 2520 snapshotFileArgIndex = 3;
c2646906
A
2521 parseSectionOrderFile(argv[i+1], argv[i+2], argv[i+3]);
2522 i += 3;
eaf282aa 2523 cannotBeUsedWithBitcode(arg);
c2646906 2524 }
a61fdf0a 2525 else if ( strcmp(arg, "-order_file") == 0 ) {
ebf6f434 2526 snapshotFileArgIndex = 1;
a61fdf0a
A
2527 parseOrderFile(argv[++i], false);
2528 }
2529 else if ( strcmp(arg, "-order_file_statistics") == 0 ) {
2530 fPrintOrderFileStatistics = true;
eaf282aa 2531 cannotBeUsedWithBitcode(arg);
a61fdf0a 2532 }
d696c285
A
2533 // ??? Deprecate segcreate.
2534 // -sectcreate puts whole files into a section in the output.
c2646906 2535 else if ( (strcmp(arg, "-sectcreate") == 0) || (strcmp(arg, "-segcreate") == 0) ) {
a61fdf0a
A
2536 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2537 throw "-sectcreate missing <segment> <section> <file-path>";
ebf6f434 2538 snapshotFileArgIndex = 3;
c2646906
A
2539 addSection(argv[i+1], argv[i+2], argv[i+3]);
2540 i += 3;
2541 }
d696c285 2542 // Since we have a full path in binary/library names we need to be able to override it.
a61fdf0a
A
2543 else if ( (strcmp(arg, "-dylib_install_name") == 0)
2544 || (strcmp(arg, "-dylinker_install_name") == 0)
2545 || (strcmp(arg, "-install_name") == 0)) {
c2646906 2546 fDylibInstallName = argv[++i];
ebf6f434 2547 if ( fDylibInstallName == NULL )
a61fdf0a 2548 throw "-install_name missing <path>";
c2646906 2549 }
d696c285 2550 // Sets the base address of the output.
69a49097 2551 else if ( (strcmp(arg, "-seg1addr") == 0) || (strcmp(arg, "-image_base") == 0) ) {
a61fdf0a
A
2552 const char* address = argv[++i];
2553 if ( address == NULL )
2554 throwf("%s missing <address>", arg);
2555 fBaseAddress = parseAddress(address);
55e3d2f6 2556 uint64_t temp = ((fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment));
2f2f92e4 2557 if ( fBaseAddress != temp ) {
55e3d2f6 2558 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment);
2f2f92e4
A
2559 fBaseAddress = temp;
2560 }
eaf282aa 2561 cannotBeUsedWithBitcode(arg);
c2646906
A
2562 }
2563 else if ( strcmp(arg, "-e") == 0 ) {
2564 fEntryName = argv[++i];
2565 }
d696c285 2566 // Same as -@ from the FSF linker.
c2646906 2567 else if ( strcmp(arg, "-filelist") == 0 ) {
ebf6f434 2568 snapshotArgCount = 0;
a61fdf0a
A
2569 const char* path = argv[++i];
2570 if ( (path == NULL) || (path[0] == '-') )
2571 throw "-filelist missing <path>";
ebf6f434
A
2572 ld::File::Ordinal baseOrdinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2573 loadFileList(path, baseOrdinal);
c2646906
A
2574 }
2575 else if ( strcmp(arg, "-keep_private_externs") == 0 ) {
eaf282aa
A
2576 cannotBeUsedWithBitcode(arg);
2577 fKeepPrivateExterns = true;
c2646906
A
2578 }
2579 else if ( strcmp(arg, "-final_output") == 0 ) {
a61fdf0a 2580 fFinalName = argv[++i];
c2646906 2581 }
d696c285
A
2582 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
2583 // just ensures that this happens for cross object file boundaries.
c2646906 2584 else if ( (strcmp(arg, "-interposable") == 0) || (strcmp(arg, "-multi_module") == 0)) {
2f2f92e4
A
2585 switch ( fInterposeMode ) {
2586 case kInterposeNone:
2587 case kInterposeAllExternal:
2588 fInterposeMode = kInterposeAllExternal;
2589 break;
2590 case kInterposeSome:
2591 // do nothing, -interposable_list overrides -interposable"
2592 break;
2593 }
eaf282aa 2594 cannotBeUsedWithBitcode(arg);
2f2f92e4
A
2595 }
2596 else if ( strcmp(arg, "-interposable_list") == 0 ) {
ebf6f434 2597 snapshotFileArgIndex = 1;
2f2f92e4
A
2598 fInterposeMode = kInterposeSome;
2599 loadExportFile(argv[++i], "-interposable_list", fInterposeList);
eaf282aa 2600 cannotBeUsedWithBitcode(arg);
c2646906 2601 }
d696c285 2602 // Default for -interposable/-multi_module/-single_module.
c2646906 2603 else if ( strcmp(arg, "-single_module") == 0 ) {
2f2f92e4 2604 fInterposeMode = kInterposeNone;
c2646906
A
2605 }
2606 else if ( strcmp(arg, "-exported_symbols_list") == 0 ) {
ebf6f434 2607 snapshotFileArgIndex = 1;
c2646906
A
2608 if ( fExportMode == kDontExportSome )
2609 throw "can't use -exported_symbols_list and -unexported_symbols_list";
2610 fExportMode = kExportSome;
2611 loadExportFile(argv[++i], "-exported_symbols_list", fExportSymbols);
2612 }
2613 else if ( strcmp(arg, "-unexported_symbols_list") == 0 ) {
ebf6f434 2614 snapshotFileArgIndex = 1;
c2646906 2615 if ( fExportMode == kExportSome )
a61fdf0a 2616 throw "can't use -unexported_symbols_list and -exported_symbols_list";
c2646906
A
2617 fExportMode = kDontExportSome;
2618 loadExportFile(argv[++i], "-unexported_symbols_list", fDontExportSymbols);
2619 }
a61fdf0a
A
2620 else if ( strcmp(arg, "-exported_symbol") == 0 ) {
2621 if ( fExportMode == kDontExportSome )
2622 throw "can't use -exported_symbol and -unexported_symbols";
2623 fExportMode = kExportSome;
2624 fExportSymbols.insert(argv[++i]);
2625 }
2626 else if ( strcmp(arg, "-unexported_symbol") == 0 ) {
2627 if ( fExportMode == kExportSome )
2628 throw "can't use -unexported_symbol and -exported_symbol";
2629 fExportMode = kDontExportSome;
2630 fDontExportSymbols.insert(argv[++i]);
2631 }
2632 else if ( strcmp(arg, "-non_global_symbols_no_strip_list") == 0 ) {
ebf6f434 2633 snapshotFileArgIndex = 1;
a61fdf0a
A
2634 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveExclude )
2635 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2636 fLocalSymbolHandling = kLocalSymbolsSelectiveInclude;
2637 loadExportFile(argv[++i], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded);
eaf282aa 2638 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
2639 }
2640 else if ( strcmp(arg, "-non_global_symbols_strip_list") == 0 ) {
ebf6f434 2641 snapshotFileArgIndex = 1;
a61fdf0a
A
2642 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveInclude )
2643 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2644 fLocalSymbolHandling = kLocalSymbolsSelectiveExclude;
2645 loadExportFile(argv[++i], "-non_global_symbols_strip_list", fLocalSymbolsExcluded);
eaf282aa 2646 cannotBeUsedWithBitcode(arg);
a61fdf0a 2647 }
d696c285 2648 // ??? Deprecate
c2646906
A
2649 else if ( strcmp(arg, "-no_arch_warnings") == 0 ) {
2650 fIgnoreOtherArchFiles = true;
2651 }
2652 else if ( strcmp(arg, "-force_cpusubtype_ALL") == 0 ) {
afe874b1
A
2653 fForceSubtypeAll = true;
2654 fAllowCpuSubtypeMismatches = true;
eaf282aa 2655 cannotBeUsedWithBitcode(arg);
c2646906 2656 }
d696c285 2657 // Similar to -weak-l but uses the absolute path name to the library.
c2646906 2658 else if ( strcmp(arg, "-weak_library") == 0 ) {
ebf6f434
A
2659 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2660 snapshotArgCount = 0;
6e880c60 2661 FileInfo info = findFile(argv[++i]);
c2646906 2662 info.options.fWeakImport = true;
ebf6f434 2663 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a 2664 addLibrary(info);
eaf282aa 2665 cannotBeUsedWithBitcode(arg);
c2646906 2666 }
2f2f92e4 2667 else if ( strcmp(arg, "-lazy_library") == 0 ) {
ebf6f434
A
2668 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2669 snapshotArgCount = 0;
2f2f92e4
A
2670 FileInfo info = findFile(argv[++i]);
2671 info.options.fLazyLoad = true;
ebf6f434 2672 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2f2f92e4
A
2673 addLibrary(info);
2674 fUsingLazyDylibLinking = true;
eaf282aa 2675 cannotBeUsedWithBitcode(arg);
2f2f92e4 2676 }
c2646906 2677 else if ( strcmp(arg, "-framework") == 0 ) {
ebf6f434
A
2678 snapshotArgCount = 0;
2679 FileInfo info = findFramework(argv[++i]);
2680 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2681 addLibrary(info);
c2646906
A
2682 }
2683 else if ( strcmp(arg, "-weak_framework") == 0 ) {
ebf6f434
A
2684 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2685 snapshotArgCount = 0;
c2646906
A
2686 FileInfo info = findFramework(argv[++i]);
2687 info.options.fWeakImport = true;
ebf6f434 2688 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a 2689 addLibrary(info);
c2646906 2690 }
2f2f92e4 2691 else if ( strcmp(arg, "-lazy_framework") == 0 ) {
ebf6f434
A
2692 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2693 snapshotArgCount = 0;
2f2f92e4
A
2694 FileInfo info = findFramework(argv[++i]);
2695 info.options.fLazyLoad = true;
ebf6f434 2696 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2f2f92e4
A
2697 addLibrary(info);
2698 fUsingLazyDylibLinking = true;
eaf282aa 2699 cannotBeUsedWithBitcode(arg);
2f2f92e4 2700 }
c2646906 2701 else if ( strcmp(arg, "-search_paths_first") == 0 ) {
a61fdf0a 2702 // previously handled by buildSearchPaths()
c2646906 2703 }
a645023d
A
2704 else if ( strcmp(arg, "-search_dylibs_first") == 0 ) {
2705 // previously handled by buildSearchPaths()
2706 }
c2646906 2707 else if ( strcmp(arg, "-undefined") == 0 ) {
ebf6f434 2708 setUndefinedTreatment(argv[++i]);
eaf282aa 2709 cannotBeUsedWithBitcode(arg);
c2646906 2710 }
d696c285 2711 // Debugging output flag.
c2646906
A
2712 else if ( strcmp(arg, "-arch_multiple") == 0 ) {
2713 fMessagesPrefixedWithArchitecture = true;
2714 }
d696c285
A
2715 // Specify what to do with relocations in read only
2716 // sections like .text. Could be errors, warnings,
2717 // or suppressed. Currently we do nothing with the
2718 // flag.
c2646906 2719 else if ( strcmp(arg, "-read_only_relocs") == 0 ) {
2f2f92e4
A
2720 switch ( parseTreatment(argv[++i]) ) {
2721 case kNULL:
2722 case kInvalid:
2723 throw "-read_only_relocs missing [ warning | error | suppress ]";
2724 case kWarning:
2725 fWarnTextRelocs = true;
2726 fAllowTextRelocs = true;
eaf282aa 2727 cannotBeUsedWithBitcode(arg);
2f2f92e4
A
2728 break;
2729 case kSuppress:
2730 fWarnTextRelocs = false;
2731 fAllowTextRelocs = true;
eaf282aa 2732 cannotBeUsedWithBitcode(arg);
2f2f92e4
A
2733 break;
2734 case kError:
2735 fWarnTextRelocs = false;
2736 fAllowTextRelocs = false;
2737 break;
2738 }
c2646906
A
2739 }
2740 else if ( strcmp(arg, "-sect_diff_relocs") == 0 ) {
a61fdf0a
A
2741 warnObsolete(arg);
2742 ++i;
c2646906 2743 }
d696c285
A
2744 // Warn, error or make strong a mismatch between weak
2745 // and non-weak references.
c2646906 2746 else if ( strcmp(arg, "-weak_reference_mismatches") == 0 ) {
ebf6f434 2747 setWeakReferenceMismatchTreatment(argv[++i]);
c2646906 2748 }
d696c285
A
2749 // For a deployment target of 10.3 and earlier ld64 will
2750 // prebind an executable with 0s in all addresses that
2751 // are prebound. This can then be fixed up by update_prebinding
2752 // later. Prebinding is less useful on 10.4 and greater.
c2646906 2753 else if ( strcmp(arg, "-prebind") == 0 ) {
d696c285 2754 fPrebind = true;
eaf282aa 2755 cannotBeUsedWithBitcode(arg);
c2646906
A
2756 }
2757 else if ( strcmp(arg, "-noprebind") == 0 ) {
a61fdf0a 2758 warnObsolete(arg);
d696c285 2759 fPrebind = false;
c2646906
A
2760 }
2761 else if ( strcmp(arg, "-prebind_allow_overlap") == 0 ) {
a61fdf0a 2762 warnObsolete(arg);
c2646906
A
2763 }
2764 else if ( strcmp(arg, "-prebind_all_twolevel_modules") == 0 ) {
a61fdf0a 2765 warnObsolete(arg);
c2646906
A
2766 }
2767 else if ( strcmp(arg, "-noprebind_all_twolevel_modules") == 0 ) {
a61fdf0a 2768 warnObsolete(arg);
c2646906
A
2769 }
2770 else if ( strcmp(arg, "-nofixprebinding") == 0 ) {
a61fdf0a 2771 warnObsolete(arg);
c2646906 2772 }
d696c285
A
2773 // This should probably be deprecated when we respect -L and -F
2774 // when searching for libraries.
c2646906 2775 else if ( strcmp(arg, "-dylib_file") == 0 ) {
ebf6f434
A
2776 // ignore for snapshot because a stub dylib will be created in the snapshot
2777 snapshotArgCount = 0;
a61fdf0a 2778 addDylibOverride(argv[++i]);
eaf282aa 2779 cannotBeUsedWithBitcode(arg);
c2646906 2780 }
a61fdf0a 2781 // What to expand @executable_path to if found in dependent dylibs
c2646906 2782 else if ( strcmp(arg, "-executable_path") == 0 ) {
d696c285
A
2783 fExecutablePath = argv[++i];
2784 if ( (fExecutablePath == NULL) || (fExecutablePath[0] == '-') )
2785 throw "-executable_path missing <path>";
a61fdf0a
A
2786 // if a directory was passed, add / to end
2787 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2788 struct stat statBuffer;
2789 if ( stat(fExecutablePath, &statBuffer) == 0 ) {
2790 if ( (statBuffer.st_mode & S_IFMT) == S_IFDIR ) {
2791 char* pathWithSlash = new char[strlen(fExecutablePath)+2];
2792 strcpy(pathWithSlash, fExecutablePath);
2793 strcat(pathWithSlash, "/");
2794 fExecutablePath = pathWithSlash;
2795 }
2796 }
c2646906 2797 }
d696c285 2798 // Aligns all segments to the power of 2 boundary specified.
c2646906 2799 else if ( strcmp(arg, "-segalign") == 0 ) {
55e3d2f6
A
2800 const char* size = argv[++i];
2801 if ( size == NULL )
2802 throw "-segalign missing <size>";
2803 fSegmentAlignment = parseAddress(size);
2804 uint8_t alignment = (uint8_t)__builtin_ctz(fSegmentAlignment);
2805 uint32_t p2aligned = (1 << alignment);
2806 if ( p2aligned != fSegmentAlignment ) {
2807 warning("alignment for -segalign %s is not a power of two, using 0x%X", size, p2aligned);
2808 fSegmentAlignment = p2aligned;
2809 }
eaf282aa 2810 cannotBeUsedWithBitcode(arg);
c2646906 2811 }
d696c285
A
2812 // Puts a specified segment at a particular address that must
2813 // be a multiple of the segment alignment.
c2646906 2814 else if ( strcmp(arg, "-segaddr") == 0 ) {
a61fdf0a
A
2815 SegmentStart seg;
2816 seg.name = argv[++i];
2817 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
2818 throw "-segaddr missing segName Adddress";
2819 seg.address = parseAddress(argv[++i]);
b2fa67a8
A
2820 uint64_t temp = ((seg.address+fSegmentAlignment-1) & (-fSegmentAlignment));
2821 if ( seg.address != temp )
2822 warning("-segaddr %s not %lld byte aligned", seg.name, fSegmentAlignment);
a61fdf0a 2823 fCustomSegmentAddresses.push_back(seg);
eaf282aa 2824 cannotBeUsedWithBitcode(arg);
c2646906 2825 }
d696c285 2826 // ??? Deprecate when we deprecate split-seg.
c2646906 2827 else if ( strcmp(arg, "-segs_read_only_addr") == 0 ) {
a61fdf0a 2828 fBaseAddress = parseAddress(argv[++i]);
eaf282aa 2829 cannotBeUsedWithBitcode(arg);
c2646906 2830 }
d696c285 2831 // ??? Deprecate when we deprecate split-seg.
c2646906 2832 else if ( strcmp(arg, "-segs_read_write_addr") == 0 ) {
a61fdf0a
A
2833 fBaseWritableAddress = parseAddress(argv[++i]);
2834 fSplitSegs = true;
eaf282aa 2835 cannotBeUsedWithBitcode(arg);
c2646906 2836 }
d696c285 2837 // ??? Deprecate when we get rid of basing at build time.
c2646906 2838 else if ( strcmp(arg, "-seg_addr_table") == 0 ) {
ebf6f434 2839 snapshotFileArgIndex = 1;
a61fdf0a
A
2840 const char* name = argv[++i];
2841 if ( name == NULL )
2842 throw "-seg_addr_table missing argument";
2843 fSegAddrTablePath = name;
eaf282aa 2844 cannotBeUsedWithBitcode(arg);
c2646906
A
2845 }
2846 else if ( strcmp(arg, "-seg_addr_table_filename") == 0 ) {
a61fdf0a 2847 warnObsolete(arg);
d696c285 2848 ++i;
c2646906
A
2849 }
2850 else if ( strcmp(arg, "-segprot") == 0 ) {
a61fdf0a
A
2851 SegmentProtect seg;
2852 seg.name = argv[++i];
2853 if ( (seg.name == NULL) || (argv[i+1] == NULL) || (argv[i+2] == NULL) )
2854 throw "-segprot missing segName max-prot init-prot";
2855 seg.max = parseProtection(argv[++i]);
2856 seg.init = parseProtection(argv[++i]);
ec29ba20
A
2857 if ( strcmp(seg.name, "__LINKEDIT") == 0 )
2858 warning("-segprot cannot be used to modify __LINKEDIT protections");
2859 else
2860 fCustomSegmentProtections.push_back(seg);
eaf282aa 2861 cannotBeUsedWithBitcode(arg);
c2646906
A
2862 }
2863 else if ( strcmp(arg, "-pagezero_size") == 0 ) {
a61fdf0a
A
2864 const char* size = argv[++i];
2865 if ( size == NULL )
2866 throw "-pagezero_size missing <size>";
2867 fZeroPageSize = parseAddress(size);
69a49097 2868 uint64_t temp = fZeroPageSize & (-4096); // page align
2f2f92e4
A
2869 if ( (fZeroPageSize != temp) )
2870 warning("-pagezero_size not page aligned, rounding down");
69a49097 2871 fZeroPageSize = temp;
eaf282aa 2872 cannotBeUsedWithBitcode(arg);
c2646906
A
2873 }
2874 else if ( strcmp(arg, "-stack_addr") == 0 ) {
a61fdf0a
A
2875 const char* address = argv[++i];
2876 if ( address == NULL )
2877 throw "-stack_addr missing <address>";
2878 fStackAddr = parseAddress(address);
eaf282aa 2879 cannotBeUsedWithBitcode(arg);
c2646906
A
2880 }
2881 else if ( strcmp(arg, "-stack_size") == 0 ) {
a61fdf0a
A
2882 const char* size = argv[++i];
2883 if ( size == NULL )
2884 throw "-stack_size missing <address>";
2885 fStackSize = parseAddress(size);
c2646906 2886 }
d696c285
A
2887 else if ( strcmp(arg, "-allow_stack_execute") == 0 ) {
2888 fExecutableStack = true;
eaf282aa 2889 cannotBeUsedWithBitcode(arg);
d696c285 2890 }
a645023d
A
2891 else if ( strcmp(arg, "-allow_heap_execute") == 0 ) {
2892 fDisableNonExecutableHeap = true;
eaf282aa 2893 cannotBeUsedWithBitcode(arg);
a645023d 2894 }
c2646906 2895 else if ( strcmp(arg, "-sectalign") == 0 ) {
a61fdf0a
A
2896 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2897 throw "-sectalign missing <segment> <section> <file-path>";
c2646906
A
2898 addSectionAlignment(argv[i+1], argv[i+2], argv[i+3]);
2899 i += 3;
eaf282aa 2900 cannotBeUsedWithBitcode(arg);
c2646906
A
2901 }
2902 else if ( strcmp(arg, "-sectorder_detail") == 0 ) {
a61fdf0a 2903 warnObsolete(arg);
c2646906
A
2904 }
2905 else if ( strcmp(arg, "-sectobjectsymbols") == 0 ) {
a61fdf0a 2906 warnObsolete(arg);
c2646906
A
2907 i += 2;
2908 }
2909 else if ( strcmp(arg, "-bundle_loader") == 0 ) {
ebf6f434 2910 snapshotFileArgIndex = 1;
69a49097
A
2911 fBundleLoader = argv[++i];
2912 if ( (fBundleLoader == NULL) || (fBundleLoader[0] == '-') )
2913 throw "-bundle_loader missing <path>";
2914 FileInfo info = findFile(fBundleLoader);
ebf6f434 2915 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
69a49097
A
2916 info.options.fBundleLoader = true;
2917 fInputFiles.push_back(info);
c2646906
A
2918 }
2919 else if ( strcmp(arg, "-private_bundle") == 0 ) {
a61fdf0a 2920 warnObsolete(arg);
c2646906
A
2921 }
2922 else if ( strcmp(arg, "-twolevel_namespace_hints") == 0 ) {
2923 // FIX FIX
2924 }
d696c285 2925 // Use this flag to set default behavior for deployement targets.
c7f24d34 2926 else if ( strcmp(arg, "-macosx_version_min") == 0 ) {
f80fe69f 2927 const char* macVers = argv[++i];
ec29ba20
A
2928 if ( macVers == NULL )
2929 throw "-macosx_version_min missing version argument";
f80fe69f
A
2930 const char* envMacVers = getenv("MACOSX_DEPLOYMENT_TARGET");
2931 const char* enviPhoneVers = getenv("IPHONEOS_DEPLOYMENT_TARGET");
2932 if ( (envMacVers != NULL) && (enviPhoneVers != NULL) ) {
2933 // <rdar://problem/13774329> when conflicting deployments set, break tie by looking at syslibroot
2934 warning("both MACOSX_DEPLOYMENT_TARGET and IPHONEOS_DEPLOYMENT_TARGET are set");
2935 if ( !fSDKPaths.empty() ) {
2936 const char* sysrootPath = fSDKPaths.back();
2937 const char* lastSlash = strrchr(sysrootPath, '/');
2938 if ( strstr(lastSlash, "Simulator") != NULL )
2939 setIOSVersionMin(enviPhoneVers);
2940 else
2941 setMacOSXVersionMin(macVers);
2942 }
2943 else {
2944 setMacOSXVersionMin(macVers);
2945 }
2946 }
2947 else {
2948 setMacOSXVersionMin(macVers);
2949 }
2f2f92e4 2950 }
afe874b1 2951 else if ( (strcmp(arg, "-ios_version_min") == 0) || (strcmp(arg, "-iphoneos_version_min") == 0) ) {
ec29ba20
A
2952 const char* vers = argv[++i];
2953 if ( vers == NULL )
2954 throw "-ios_version_min missing version argument";
2955 setIOSVersionMin(vers);
afe874b1
A
2956 }
2957 else if ( strcmp(arg, "-ios_simulator_version_min") == 0 ) {
ec29ba20
A
2958 const char* vers = argv[++i];
2959 if ( vers == NULL )
2960 throw "-ios_simulator_version_min missing version argument";
2961 setIOSVersionMin(vers);
f80fe69f 2962 fTargetIOSSimulator = true;
c7f24d34 2963 }
eaf282aa 2964 else if ( strcmp(arg, "-watchos_version_min") == 0 ) {
ec29ba20
A
2965 const char* vers = argv[++i];
2966 if ( vers == NULL )
2967 throw "-watchos_version_min missing version argument";
2968 setWatchOSVersionMin(vers);
eaf282aa
A
2969 }
2970 else if ( strcmp(arg, "-watchos_simulator_version_min") == 0 ) {
ec29ba20
A
2971 const char* vers = argv[++i];
2972 if ( vers == NULL )
2973 throw "-watchos_simulator_version_min missing version argument";
2974 setWatchOSVersionMin(vers);
eaf282aa
A
2975 fTargetIOSSimulator = true;
2976 }
2977 #if SUPPORT_APPLE_TV
2978 else if ( strcmp(arg, "-tvos_version_min") == 0 ) {
ec29ba20
A
2979 const char* vers = argv[++i];
2980 if ( vers == NULL )
2981 throw "-tvos_version_min missing version argument";
2982 setIOSVersionMin(vers);
eaf282aa
A
2983 fPlatform = kPlatform_tvOS;
2984 }
2985 else if ( strcmp(arg, "-tvos_simulator_version_min") == 0 ) {
ec29ba20
A
2986 const char* vers = argv[++i];
2987 if ( vers == NULL )
2988 throw "-tvos_simulator_version_min missing version argument";
2989 setIOSVersionMin(vers);
eaf282aa
A
2990 fPlatform = kPlatform_tvOS;
2991 fTargetIOSSimulator = true;
2992 }
2993 #endif
c2646906 2994 else if ( strcmp(arg, "-multiply_defined") == 0 ) {
a61fdf0a
A
2995 //warnObsolete(arg);
2996 ++i;
c2646906
A
2997 }
2998 else if ( strcmp(arg, "-multiply_defined_unused") == 0 ) {
a61fdf0a
A
2999 warnObsolete(arg);
3000 ++i;
c2646906
A
3001 }
3002 else if ( strcmp(arg, "-nomultidefs") == 0 ) {
a61fdf0a 3003 warnObsolete(arg);
c2646906 3004 }
d696c285
A
3005 // Display each file in which the argument symbol appears and whether
3006 // the file defines or references it. This option takes an argument
3007 // as -y<symbol> note that there is no space.
3008 else if ( strncmp(arg, "-y", 2) == 0 ) {
a61fdf0a 3009 warnObsolete("-y");
c2646906 3010 }
d696c285 3011 // Same output as -y, but output <arg> number of undefined symbols only.
c2646906 3012 else if ( strcmp(arg, "-Y") == 0 ) {
a61fdf0a
A
3013 //warnObsolete(arg);
3014 ++i;
c2646906 3015 }
d696c285 3016 // This option affects all objects linked into the final result.
c2646906 3017 else if ( strcmp(arg, "-m") == 0 ) {
a61fdf0a 3018 warnObsolete(arg);
c2646906 3019 }
69a49097 3020 else if ( (strcmp(arg, "-why_load") == 0) || (strcmp(arg, "-whyload") == 0) ) {
a645023d 3021 fWhyLoad = true;
69a49097
A
3022 }
3023 else if ( strcmp(arg, "-why_live") == 0 ) {
3024 const char* name = argv[++i];
3025 if ( name == NULL )
3026 throw "-why_live missing symbol name argument";
3027 fWhyLive.insert(name);
c2646906
A
3028 }
3029 else if ( strcmp(arg, "-u") == 0 ) {
3030 const char* name = argv[++i];
3031 if ( name == NULL )
3032 throw "-u missing argument";
3033 fInitialUndefines.push_back(name);
eaf282aa 3034 cannotBeUsedWithBitcode(arg);
c2646906 3035 }
c2646906 3036 else if ( strcmp(arg, "-U") == 0 ) {
a61fdf0a
A
3037 const char* name = argv[++i];
3038 if ( name == NULL )
3039 throw "-U missing argument";
3040 fAllowedUndefined.insert(name);
eaf282aa 3041 cannotBeUsedWithBitcode(arg);
c2646906
A
3042 }
3043 else if ( strcmp(arg, "-s") == 0 ) {
a61fdf0a
A
3044 warnObsolete(arg);
3045 fLocalSymbolHandling = kLocalSymbolsNone;
a645023d 3046 fDebugInfoStripping = Options::kDebugInfoNone;
c2646906
A
3047 }
3048 else if ( strcmp(arg, "-x") == 0 ) {
a61fdf0a 3049 fLocalSymbolHandling = kLocalSymbolsNone;
c2646906
A
3050 }
3051 else if ( strcmp(arg, "-S") == 0 ) {
a645023d 3052 fDebugInfoStripping = Options::kDebugInfoNone;
c2646906
A
3053 }
3054 else if ( strcmp(arg, "-X") == 0 ) {
a61fdf0a 3055 warnObsolete(arg);
c2646906
A
3056 }
3057 else if ( strcmp(arg, "-Si") == 0 ) {
a61fdf0a 3058 warnObsolete(arg);
a645023d 3059 fDebugInfoStripping = Options::kDebugInfoFull;
c2646906
A
3060 }
3061 else if ( strcmp(arg, "-b") == 0 ) {
a61fdf0a 3062 warnObsolete(arg);
c2646906
A
3063 }
3064 else if ( strcmp(arg, "-Sn") == 0 ) {
a61fdf0a 3065 warnObsolete(arg);
a645023d 3066 fDebugInfoStripping = Options::kDebugInfoFull;
d696c285
A
3067 }
3068 else if ( strcmp(arg, "-Sp") == 0 ) {
a61fdf0a 3069 warnObsolete(arg);
c2646906
A
3070 }
3071 else if ( strcmp(arg, "-dead_strip") == 0 ) {
a645023d 3072 fDeadStrip = true;
d696c285
A
3073 }
3074 else if ( strcmp(arg, "-no_dead_strip_inits_and_terms") == 0 ) {
a645023d 3075 fDeadStrip = true;
c2646906 3076 }
c2646906 3077 else if ( strcmp(arg, "-w") == 0 ) {
a61fdf0a 3078 // previously handled by buildSearchPaths()
c2646906 3079 }
b2fa67a8
A
3080 else if ( strcmp(arg, "-fatal_warnings") == 0 ) {
3081 // previously handled by buildSearchPaths()
3082 }
c2646906 3083 else if ( strcmp(arg, "-arch_errors_fatal") == 0 ) {
55e3d2f6 3084 fErrorOnOtherArchFiles = true;
c2646906
A
3085 }
3086 else if ( strcmp(arg, "-M") == 0 ) {
3087 // FIX FIX
3088 }
c2646906
A
3089 else if ( strcmp(arg, "-headerpad") == 0 ) {
3090 const char* size = argv[++i];
3091 if ( size == NULL )
3092 throw "-headerpad missing argument";
3093 fMinimumHeaderPad = parseAddress(size);
eaf282aa 3094 cannotBeUsedWithBitcode(arg);
c2646906
A
3095 }
3096 else if ( strcmp(arg, "-headerpad_max_install_names") == 0 ) {
eaf282aa
A
3097 // ignore -headerpad_max_install_names when compiling with bitcode
3098 // rdar://problem/20748962
3099 if ( fBundleBitcode )
3100 warning("-headerpad_max_install_names is ignored when used with -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES)");
3101 else
3102 fMaxMinimumHeaderPad = true;
c2646906
A
3103 }
3104 else if ( strcmp(arg, "-t") == 0 ) {
a645023d 3105 fLogAllFiles = true;
a61fdf0a
A
3106 }
3107 else if ( strcmp(arg, "-whatsloaded") == 0 ) {
a645023d 3108 fLogObjectFiles = true;
c2646906
A
3109 }
3110 else if ( strcmp(arg, "-A") == 0 ) {
a61fdf0a 3111 warnObsolete(arg);
d696c285 3112 ++i;
c2646906
A
3113 }
3114 else if ( strcmp(arg, "-umbrella") == 0 ) {
3115 const char* name = argv[++i];
3116 if ( name == NULL )
3117 throw "-umbrella missing argument";
3118 fUmbrellaName = name;
eaf282aa 3119 cannotBeUsedWithBitcode(arg);
c2646906
A
3120 }
3121 else if ( strcmp(arg, "-allowable_client") == 0 ) {
d696c285
A
3122 const char* name = argv[++i];
3123
3124 if ( name == NULL )
3125 throw "-allowable_client missing argument";
3126
3127 fAllowableClients.push_back(name);
eaf282aa 3128 cannotBeUsedWithBitcode(arg);
c2646906
A
3129 }
3130 else if ( strcmp(arg, "-client_name") == 0 ) {
d696c285
A
3131 const char* name = argv[++i];
3132
3133 if ( name == NULL )
3134 throw "-client_name missing argument";
3135
3136 fClientName = name;
eaf282aa 3137 cannotBeUsedWithBitcode(arg);
c2646906
A
3138 }
3139 else if ( strcmp(arg, "-sub_umbrella") == 0 ) {
3140 const char* name = argv[++i];
3141 if ( name == NULL )
3142 throw "-sub_umbrella missing argument";
3143 fSubUmbellas.push_back(name);
eaf282aa 3144 cannotBeUsedWithBitcode(arg);
c2646906
A
3145 }
3146 else if ( strcmp(arg, "-sub_library") == 0 ) {
3147 const char* name = argv[++i];
3148 if ( name == NULL )
3149 throw "-sub_library missing argument";
3150 fSubLibraries.push_back(name);
eaf282aa 3151 cannotBeUsedWithBitcode(arg);
c2646906
A
3152 }
3153 else if ( strcmp(arg, "-init") == 0 ) {
3154 const char* name = argv[++i];
3155 if ( name == NULL )
3156 throw "-init missing argument";
3157 fInitFunctionName = name;
eaf282aa 3158 cannotBeUsedWithBitcode(arg);
c2646906 3159 }
d696c285
A
3160 else if ( strcmp(arg, "-dot") == 0 ) {
3161 const char* name = argv[++i];
3162 if ( name == NULL )
3163 throw "-dot missing argument";
3164 fDotOutputFile = name;
eaf282aa 3165 cannotBeUsedWithBitcode(arg);
d696c285 3166 }
c2646906
A
3167 else if ( strcmp(arg, "-warn_commons") == 0 ) {
3168 fWarnCommons = true;
3169 }
3170 else if ( strcmp(arg, "-commons") == 0 ) {
3171 fCommonsMode = parseCommonsTreatment(argv[++i]);
3172 }
d696c285
A
3173 else if ( strcmp(arg, "-keep_relocs") == 0 ) {
3174 fKeepRelocations = true;
3175 }
3176 else if ( strcmp(arg, "-warn_stabs") == 0 ) {
3177 fWarnStabs = true;
3178 }
3179 else if ( strcmp(arg, "-pause") == 0 ) {
3180 fPause = true;
3181 }
3182 else if ( strcmp(arg, "-print_statistics") == 0 ) {
3183 fStatistics = true;
3184 }
69a49097 3185 else if ( strcmp(arg, "-d") == 0 ) {
a645023d 3186 fMakeTentativeDefinitionsReal = true;
69a49097 3187 }
6e880c60
A
3188 else if ( strcmp(arg, "-v") == 0 ) {
3189 // previously handled by buildSearchPaths()
3190 }
3191 else if ( strcmp(arg, "-Z") == 0 ) {
3192 // previously handled by buildSearchPaths()
3193 }
3194 else if ( strcmp(arg, "-syslibroot") == 0 ) {
ebf6f434 3195 snapshotArgCount = 0;
6e880c60
A
3196 ++i;
3197 // previously handled by buildSearchPaths()
3198 }
eaf282aa
A
3199 else if ( strcmp(arg, "-bitcode_bundle") == 0 ) {
3200 snapshotArgCount = 0;
3201 // previously handled by buildSearchPaths()
3202 }
d696c285 3203 else if ( strcmp(arg, "-no_uuid") == 0 ) {
a61fdf0a 3204 fUUIDMode = kUUIDNone;
eaf282aa 3205 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
3206 }
3207 else if ( strcmp(arg, "-random_uuid") == 0 ) {
3208 fUUIDMode = kUUIDRandom;
eaf282aa 3209 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
3210 }
3211 else if ( strcmp(arg, "-dtrace") == 0 ) {
ebf6f434 3212 snapshotFileArgIndex = 1;
a61fdf0a
A
3213 const char* name = argv[++i];
3214 if ( name == NULL )
3215 throw "-dtrace missing argument";
3216 fDtraceScriptName = name;
eaf282aa 3217 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
3218 }
3219 else if ( strcmp(arg, "-root_safe") == 0 ) {
a645023d 3220 fRootSafe = true;
a61fdf0a
A
3221 }
3222 else if ( strcmp(arg, "-setuid_safe") == 0 ) {
a645023d 3223 fSetuidSafe = true;
a61fdf0a
A
3224 }
3225 else if ( strcmp(arg, "-alias") == 0 ) {
a645023d 3226 Options::AliasPair pair;
a61fdf0a
A
3227 pair.realName = argv[++i];
3228 if ( pair.realName == NULL )
3229 throw "missing argument to -alias";
3230 pair.alias = argv[++i];
3231 if ( pair.alias == NULL )
3232 throw "missing argument to -alias";
a645023d 3233 fAliases.push_back(pair);
eaf282aa 3234 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
3235 }
3236 else if ( strcmp(arg, "-alias_list") == 0 ) {
ebf6f434 3237 snapshotFileArgIndex = 1;
a61fdf0a 3238 parseAliasFile(argv[++i]);
eaf282aa 3239 cannotBeUsedWithBitcode(arg);
d696c285 3240 }
a61fdf0a
A
3241 else if ( strcmp(arg, "-save-temps") == 0 ) {
3242 fSaveTempFiles = true;
3243 }
eaf282aa
A
3244 else if ( strcmp(arg, "-bitcode_hide_symbols") == 0 ) {
3245 fHideSymbols = true;
eaf282aa 3246 }
dd9e569f
A
3247 else if ( strcmp(arg, "-bitcode_verify") == 0 ) {
3248 fVerifyBitcode = true;
dd9e569f 3249 }
eaf282aa
A
3250 else if ( strcmp(arg, "-bitcode_symbol_map") == 0) {
3251 fReverseMapPath = argv[++i];
3252 if ( fReverseMapPath == NULL )
3253 throw "missing argument to -bitcode_symbol_map";
3254 struct stat statbuf;
3255 ::stat(fReverseMapPath, &statbuf);
3256 if (S_ISDIR(statbuf.st_mode)) {
3257 char tempPath[PATH_MAX];
3258 sprintf(tempPath, "%s/XXXXXX", fReverseMapPath);
3259 int tempFile = ::mkstemp(tempPath);
3260 if (tempFile == -1)
3261 throwf("could not write file to symbol map directory: %s", fReverseMapPath);
3262 ::close(tempFile);
3263 fReverseMapTempPath = std::string(tempPath);
3264 fReverseMapUUIDRename = true;
3265 } else
3266 fReverseMapTempPath = std::string(fReverseMapPath);
3267 }
3268 else if ( strcmp(argv[i], "-flto-codegen-only") == 0) {
3269 fLTOCodegenOnly = true;
3270 }
3271 else if ( strcmp(argv[i], "-ignore_auto_link") == 0) {
3272 fIgnoreAutoLink = true;
3273 }
dd9e569f
A
3274 else if ( strcmp(argv[i], "-allow_dead_duplicates") == 0) {
3275 fAllowDeadDups = true;
3276 }
3277 else if ( strcmp(argv[i], "-bitcode_process_mode") == 0 ) {
3278 const char* bitcode_type = argv[++i];
3279 if ( bitcode_type == NULL )
3280 throw "missing argument to -bitcode_process_mode";
3281 else if ( strcmp(bitcode_type, "strip") == 0 )
3282 fBitcodeKind = kBitcodeStrip;
3283 else if ( strcmp(bitcode_type, "marker") == 0 )
3284 fBitcodeKind = kBitcodeMarker;
3285 else if ( strcmp(bitcode_type, "data") == 0 )
3286 fBitcodeKind = kBitcodeAsData;
3287 else if ( strcmp(bitcode_type, "bitcode") == 0 )
3288 fBitcodeKind = kBitcodeProcess;
3289 else
3290 throw "unknown argument to -bitcode_process_mode {strip,marker,data,bitcode}";
3291 }
a61fdf0a
A
3292 else if ( strcmp(arg, "-rpath") == 0 ) {
3293 const char* path = argv[++i];
3294 if ( path == NULL )
3295 throw "missing argument to -rpath";
3296 fRPaths.push_back(path);
3297 }
3298 else if ( strcmp(arg, "-read_only_stubs") == 0 ) {
3299 fReadOnlyx86Stubs = true;
3300 }
2f2f92e4 3301 else if ( strcmp(arg, "-slow_stubs") == 0 ) {
55e3d2f6 3302 warnObsolete(arg);
2f2f92e4 3303 }
a61fdf0a
A
3304 else if ( strcmp(arg, "-map") == 0 ) {
3305 fMapPath = argv[++i];
3306 if ( fMapPath == NULL )
3307 throw "missing argument to -map";
3308 }
3309 else if ( strcmp(arg, "-pie") == 0 ) {
3310 fPositionIndependentExecutable = true;
a645023d 3311 fPIEOnCommandLine = true;
a61fdf0a 3312 }
d9246299
A
3313 else if ( strcmp(arg, "-no_pie") == 0 ) {
3314 fDisablePositionIndependentExecutable = true;
eaf282aa 3315 cannotBeUsedWithBitcode(arg);
d9246299 3316 }
a61fdf0a 3317 else if ( strncmp(arg, "-reexport-l", 11) == 0 ) {
ebf6f434
A
3318 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3319 snapshotArgCount = 0;
2f2f92e4 3320 FileInfo info = findLibrary(&arg[11], true);
a61fdf0a 3321 info.options.fReExport = true;
ebf6f434 3322 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a 3323 addLibrary(info);
eaf282aa 3324 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
3325 }
3326 else if ( strcmp(arg, "-reexport_library") == 0 ) {
ebf6f434
A
3327 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3328 snapshotArgCount = 0;
a61fdf0a
A
3329 FileInfo info = findFile(argv[++i]);
3330 info.options.fReExport = true;
ebf6f434 3331 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a 3332 addLibrary(info);
eaf282aa 3333 cannotBeUsedWithBitcode(arg);
a61fdf0a
A
3334 }
3335 else if ( strcmp(arg, "-reexport_framework") == 0 ) {
ebf6f434
A
3336 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3337 snapshotArgCount = 0;
a61fdf0a
A
3338 FileInfo info = findFramework(argv[++i]);
3339 info.options.fReExport = true;
ebf6f434 3340 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a 3341 addLibrary(info);
eaf282aa 3342 cannotBeUsedWithBitcode(arg);
a61fdf0a 3343 }
a645023d 3344 else if ( strncmp(arg, "-upward-l", 9) == 0 ) {
ebf6f434
A
3345 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3346 snapshotArgCount = 0;
a645023d
A
3347 FileInfo info = findLibrary(&arg[9], true);
3348 info.options.fUpward = true;
ebf6f434 3349 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a645023d 3350 addLibrary(info);
eaf282aa 3351 cannotBeUsedWithBitcode(arg);
a645023d
A
3352 }
3353 else if ( strcmp(arg, "-upward_library") == 0 ) {
ebf6f434
A
3354 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3355 snapshotArgCount = 0;
a645023d
A
3356 FileInfo info = findFile(argv[++i]);
3357 info.options.fUpward = true;
ebf6f434 3358 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a645023d 3359 addLibrary(info);
eaf282aa 3360 cannotBeUsedWithBitcode(arg);
a645023d
A
3361 }
3362 else if ( strcmp(arg, "-upward_framework") == 0 ) {
ebf6f434
A
3363 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3364 snapshotArgCount = 0;
a645023d
A
3365 FileInfo info = findFramework(argv[++i]);
3366 info.options.fUpward = true;
ebf6f434 3367 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a645023d 3368 addLibrary(info);
eaf282aa 3369 cannotBeUsedWithBitcode(arg);
a645023d 3370 }
a61fdf0a
A
3371 else if ( strcmp(arg, "-dead_strip_dylibs") == 0 ) {
3372 fDeadStripDylibs = true;
eaf282aa 3373 cannotBeUsedWithBitcode(arg);
a61fdf0a 3374 }
2f2f92e4 3375 else if ( strcmp(arg, "-no_implicit_dylibs") == 0 ) {
a645023d 3376 fImplicitlyLinkPublicDylibs = false;
2f2f92e4 3377 }
a61fdf0a
A
3378 else if ( strcmp(arg, "-new_linker") == 0 ) {
3379 // ignore
d696c285 3380 }
2f2f92e4 3381 else if ( strcmp(arg, "-no_encryption") == 0 ) {
eaf282aa
A
3382 fEncryptableForceOff = true;
3383 cannotBeUsedWithBitcode(arg);
3384 }
3385 else if ( strcmp(arg, "-encryptable") == 0 ) {
3386 fEncryptableForceOn = true;
3387 cannotBeUsedWithBitcode(arg);
2f2f92e4 3388 }
55e3d2f6 3389 else if ( strcmp(arg, "-no_compact_unwind") == 0 ) {
a645023d 3390 fAddCompactUnwindEncoding = false;
eaf282aa 3391 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3392 }
3393 else if ( strcmp(arg, "-mllvm") == 0 ) {
3394 const char* opts = argv[++i];
3395 if ( opts == NULL )
3396 throw "missing argument to -mllvm";
3397 fLLVMOptions.push_back(opts);
eaf282aa 3398 cannotBeUsedWithBitcode(arg);
55e3d2f6 3399 }
f80fe69f
A
3400 else if ( strcmp(arg, "-mcpu") == 0 ) {
3401 const char* cpu = argv[++i];
3402 if ( cpu == NULL )
3403 throw "missing argument to -mcpu";
3404 fLtoCpu = cpu;
eaf282aa 3405 cannotBeUsedWithBitcode(arg);
f80fe69f 3406 }
55e3d2f6 3407 else if ( strcmp(arg, "-no_order_inits") == 0 ) {
a645023d 3408 fAutoOrderInitializers = false;
eaf282aa 3409 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3410 }
3411 else if ( strcmp(arg, "-no_order_data") == 0 ) {
3412 fOrderData = false;
eaf282aa 3413 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3414 }
3415 else if ( strcmp(arg, "-seg_page_size") == 0 ) {
3416 SegmentSize seg;
3417 seg.name = argv[++i];
3418 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
3419 throw "-seg_page_size missing segName Adddress";
3420 seg.size = parseAddress(argv[++i]);
3421 uint64_t temp = seg.size & (-4096); // page align
3422 if ( (seg.size != temp) )
3423 warning("-seg_page_size %s not 4K aligned, rounding down", seg.name);
3424 fCustomSegmentSizes.push_back(seg);
eaf282aa 3425 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3426 }
3427 else if ( strcmp(arg, "-mark_dead_strippable_dylib") == 0 ) {
3428 fMarkDeadStrippableDylib = true;
eaf282aa 3429 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3430 }
3431 else if ( strcmp(arg, "-exported_symbols_order") == 0 ) {
ebf6f434 3432 snapshotFileArgIndex = 1;
55e3d2f6 3433 loadSymbolOrderFile(argv[++i], fExportSymbolsOrder);
eaf282aa 3434 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3435 }
3436 else if ( strcmp(arg, "-no_compact_linkedit") == 0 ) {
afe874b1 3437 warnObsolete("-no_compact_linkedit");
55e3d2f6
A
3438 }
3439 else if ( strcmp(arg, "-no_eh_labels") == 0 ) {
a645023d 3440 fNoEHLabels = true;
eaf282aa 3441 cannotBeUsedWithBitcode(arg);
55e3d2f6
A
3442 }
3443 else if ( strcmp(arg, "-warn_compact_unwind") == 0 ) {
a645023d 3444 fWarnCompactUnwind = true;
55e3d2f6
A
3445 }
3446 else if ( strcmp(arg, "-allow_sub_type_mismatches") == 0 ) {
3447 fAllowCpuSubtypeMismatches = true;
eaf282aa 3448 cannotBeUsedWithBitcode(arg);
55e3d2f6 3449 }
4be885f6 3450 else if ( strcmp(arg, "-no_zero_fill_sections") == 0 ) {
a645023d 3451 fOptimizeZeroFill = false;
eaf282aa 3452 cannotBeUsedWithBitcode(arg);
4be885f6 3453 }
afe874b1
A
3454 else if ( strcmp(arg, "-merge_zero_fill_sections") == 0 ) {
3455 fMergeZeroFill = true;
eaf282aa 3456 cannotBeUsedWithBitcode(arg);
afe874b1 3457 }
d9246299
A
3458 else if ( strcmp(arg, "-objc_abi_version") == 0 ) {
3459 const char* version = argv[++i];
3460 if ( version == NULL )
3461 throw "-objc_abi_version missing version number";
a645023d
A
3462 if ( strcmp(version, "2") == 0 ) {
3463 fObjCABIVersion1Override = false;
3464 fObjCABIVersion2Override = true;
3465 }
3466 else if ( strcmp(version, "1") == 0 ) {
3467 fObjCABIVersion1Override = true;
3468 fObjCABIVersion2Override = false;
3469 }
d9246299
A
3470 else
3471 warning("ignoring unrecognized argument (%s) to -objc_abi_version", version);
3472 }
a645023d
A
3473 else if ( strcmp(arg, "-warn_weak_exports") == 0 ) {
3474 fWarnWeakExports = true;
3475 }
3476 else if ( strcmp(arg, "-objc_gc_compaction") == 0 ) {
3477 fObjcGcCompaction = true;
eaf282aa 3478 cannotBeUsedWithBitcode(arg);
a645023d
A
3479 }
3480 else if ( strcmp(arg, "-objc_gc") == 0 ) {
3481 fObjCGc = true;
3482 if ( fObjCGcOnly ) {
3483 warning("-objc_gc overriding -objc_gc_only");
3484 fObjCGcOnly = false;
3485 }
eaf282aa 3486 cannotBeUsedWithBitcode(arg);
a645023d
A
3487 }
3488 else if ( strcmp(arg, "-objc_gc_only") == 0 ) {
3489 fObjCGcOnly = true;
3490 if ( fObjCGc ) {
3491 warning("-objc_gc_only overriding -objc_gc");
3492 fObjCGc = false;
3493 }
eaf282aa 3494 cannotBeUsedWithBitcode(arg);
a645023d 3495 }
07feaf2c 3496 else if ( strcmp(arg, "-demangle") == 0 ) {
a645023d
A
3497 fDemangle = true;
3498 }
3499 else if ( strcmp(arg, "-version_load_command") == 0 ) {
afe874b1
A
3500 fVersionLoadCommandForcedOn = true;
3501 fVersionLoadCommandForcedOff = false;
a645023d
A
3502 }
3503 else if ( strcmp(arg, "-no_version_load_command") == 0 ) {
afe874b1
A
3504 fVersionLoadCommandForcedOff = true;
3505 fVersionLoadCommandForcedOn = false;
eaf282aa 3506 cannotBeUsedWithBitcode(arg);
a645023d
A
3507 }
3508 else if ( strcmp(arg, "-function_starts") == 0 ) {
afe874b1
A
3509 fFunctionStartsForcedOn = true;
3510 fFunctionStartsForcedOff = false;
a645023d
A
3511 }
3512 else if ( strcmp(arg, "-no_function_starts") == 0 ) {
afe874b1
A
3513 fFunctionStartsForcedOff = true;
3514 fFunctionStartsForcedOn = false;
eaf282aa 3515 cannotBeUsedWithBitcode(arg);
a645023d 3516 }
ebf6f434 3517 else if ( strcmp(arg, "-no_data_in_code_info") == 0 ) {
b1f7435d
A
3518 fDataInCodeInfoLoadCommandForcedOff = true;
3519 fDataInCodeInfoLoadCommandForcedOn = false;
eaf282aa 3520 cannotBeUsedWithBitcode(arg);
ebf6f434
A
3521 }
3522 else if ( strcmp(arg, "-data_in_code_info") == 0 ) {
b1f7435d
A
3523 fDataInCodeInfoLoadCommandForcedOn = true;
3524 fDataInCodeInfoLoadCommandForcedOff = false;
ebf6f434 3525 }
a645023d
A
3526 else if ( strcmp(arg, "-object_path_lto") == 0 ) {
3527 fTempLtoObjectPath = argv[++i];
3528 if ( fTempLtoObjectPath == NULL )
3529 throw "missing argument to -object_path_lto";
3530 }
3531 else if ( strcmp(arg, "-no_objc_category_merging") == 0 ) {
3532 fObjcCategoryMerging = false;
3533 }
3534 else if ( strcmp(arg, "-force_symbols_weak_list") == 0 ) {
ebf6f434 3535 snapshotFileArgIndex = 1;
a645023d 3536 loadExportFile(argv[++i], "-force_symbols_weak_list", fForceWeakSymbols);
eaf282aa 3537 cannotBeUsedWithBitcode(arg);
a645023d
A
3538 }
3539 else if ( strcmp(arg, "-force_symbols_not_weak_list") == 0 ) {
ebf6f434 3540 snapshotFileArgIndex = 1;
a645023d 3541 loadExportFile(argv[++i], "-force_symbols_not_weak_list", fForceNotWeakSymbols);
eaf282aa 3542 cannotBeUsedWithBitcode(arg);
a645023d
A
3543 }
3544 else if ( strcmp(arg, "-force_symbol_weak") == 0 ) {
3545 const char* symbol = argv[++i];
3546 if ( symbol == NULL )
3547 throw "-force_symbol_weak missing <symbol>";
3548 fForceWeakSymbols.insert(symbol);
eaf282aa 3549 cannotBeUsedWithBitcode(arg);
a645023d
A
3550 }
3551 else if ( strcmp(arg, "-force_symbol_not_weak") == 0 ) {
3552 const char* symbol = argv[++i];
3553 if ( symbol == NULL )
3554 throw "-force_symbol_not_weak missing <symbol>";
3555 fForceNotWeakSymbols.insert(symbol);
eaf282aa 3556 cannotBeUsedWithBitcode(arg);
a645023d
A
3557 }
3558 else if ( strcmp(arg, "-reexported_symbols_list") == 0 ) {
ebf6f434 3559 snapshotFileArgIndex = 1;
a645023d
A
3560 if ( fExportMode == kExportSome )
3561 throw "can't use -exported_symbols_list and -reexported_symbols_list";
3562 loadExportFile(argv[++i], "-reexported_symbols_list", fReExportSymbols);
3563 }
3564 else if ( strcmp(arg, "-dyld_env") == 0 ) {
3565 const char* envarg = argv[++i];
3566 if ( envarg == NULL )
3567 throw "-dyld_env missing ENV=VALUE";
3568 if ( strchr(envarg, '=') == NULL )
3569 throw "-dyld_env missing ENV=VALUE";
3570 fDyldEnvironExtras.push_back(envarg);
eaf282aa 3571 cannotBeUsedWithBitcode(arg);
07feaf2c 3572 }
afe874b1
A
3573 else if ( strcmp(arg, "-page_align_data_atoms") == 0 ) {
3574 fPageAlignDataAtoms = true;
eaf282aa 3575 cannotBeUsedWithBitcode(arg);
ebf6f434
A
3576 }
3577 else if (strcmp(arg, "-debug_snapshot") == 0) {
3578 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
3579 fSnapshotRequested = true;
eaf282aa 3580 cannotBeUsedWithBitcode(arg);
f80fe69f
A
3581 }
3582 else if (strcmp(arg, "-snapshot_dir") == 0) {
3583 const char* path = argv[++i];
3584 if ( path == NULL )
3585 throw "-snapshot_dir missing path";
3586 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
3587 fLinkSnapshot.setSnapshotPath(path);
3588 fSnapshotRequested = true;
eaf282aa 3589 cannotBeUsedWithBitcode(arg);
ebf6f434
A
3590 }
3591 else if ( strcmp(arg, "-new_main") == 0 ) {
3592 fEntryPointLoadCommandForceOn = true;
eaf282aa 3593 cannotBeUsedWithBitcode(arg);
ebf6f434
A
3594 }
3595 else if ( strcmp(arg, "-no_new_main") == 0 ) {
3596 fEntryPointLoadCommandForceOff = true;
eaf282aa 3597 cannotBeUsedWithBitcode(arg);
ebf6f434
A
3598 }
3599 else if ( strcmp(arg, "-source_version") == 0 ) {
3600 const char* vers = argv[++i];
3601 if ( vers == NULL )
3602 throw "-source_version missing <version>";
3603 fSourceVersion = parseVersionNumber64(vers);
3604 }
3605 else if ( strcmp(arg, "-add_source_version") == 0 ) {
3606 fSourceVersionLoadCommandForceOn = true;
3607 }
3608 else if ( strcmp(arg, "-no_source_version") == 0 ) {
3609 fSourceVersionLoadCommandForceOff = true;
eaf282aa 3610 cannotBeUsedWithBitcode(arg);
ebf6f434
A
3611 }
3612 else if ( strcmp(arg, "-sdk_version") == 0 ) {
3613 const char* vers = argv[++i];
3614 if ( vers == NULL )
3615 throw "-sdk_version missing <version>";
3616 fSDKVersion = parseVersionNumber32(vers);
3617 }
3618 else if ( strcmp(arg, "-dependent_dr_info") == 0 ) {
eaf282aa 3619 warnObsolete(arg);
ebf6f434
A
3620 }
3621 else if ( strcmp(arg, "-no_dependent_dr_info") == 0 ) {
eaf282aa 3622 warnObsolete(arg);
ebf6f434
A
3623 }
3624 else if ( strcmp(arg, "-kexts_use_stubs") == 0 ) {
3625 fKextsUseStubs = true;
eaf282aa 3626 cannotBeUsedWithBitcode(arg);
afe874b1 3627 }
f80fe69f 3628 else if ( strcmp(argv[i], "-dependency_info") == 0 ) {
599556ff 3629 snapshotArgCount = 0;
f80fe69f
A
3630 ++i;
3631 // previously handled by buildSearchPaths()
3632 }
3633 else if ( strcmp(arg, "-export_dynamic") == 0 ) {
3634 fExportDynamic = true;
3635 }
3636 else if ( strcmp(arg, "-force_symbols_coalesce_list") == 0 ) {
3637 snapshotFileArgIndex = 1;
3638 loadExportFile(argv[++i], "-force_symbols_coalesce_list", fForceCoalesceSymbols);
3639 }
3640 else if ( strcmp(arg, "-add_linker_option") == 0 ) {
3641 // ex: -add_linker_option '-framework Foundation'
3642 const char* optString = argv[++i];
3643 if ( optString == NULL )
3644 throw "-add_linker_option missing <option>";
3645 // break up into list of tokens at whitespace
3646 std::vector<const char*> opts;
3647 char* buffer = strdup(optString);
3648 char* start = buffer;
3649 for (char* s = buffer; ; ++s) {
3650 if ( isspace(*s) ) {
3651 *s = '\0';
3652 opts.push_back(start);
3653 start = s+1;
3654 }
3655 else if ( *s == '\0' ) {
3656 opts.push_back(start);
3657 break;
3658 }
3659 }
3660 fLinkerOptions.push_back(opts);
eaf282aa 3661 cannotBeUsedWithBitcode(arg);
f80fe69f
A
3662 }
3663 else if ( strcmp(arg, "-allow_simulator_linking_to_macosx_dylibs") == 0 ) {
3664 fAllowSimulatorToLinkWithMacOSX = true;
eaf282aa 3665 cannotBeUsedWithBitcode(arg);
f80fe69f
A
3666 }
3667 else if ( strcmp(arg, "-keep_dwarf_unwind") == 0 ) {
3668 fKeepDwarfUnwindForcedOn = true;
3669 fKeepDwarfUnwindForcedOff = false;
eaf282aa 3670 cannotBeUsedWithBitcode(arg);
f80fe69f
A
3671 }
3672 else if ( strcmp(arg, "-no_keep_dwarf_unwind") == 0 ) {
3673 fKeepDwarfUnwindForcedOn = false;
3674 fKeepDwarfUnwindForcedOff = true;
eaf282aa 3675 cannotBeUsedWithBitcode(arg);
f80fe69f 3676 }
9543cb2f
A
3677 else if ( strcmp(arg, "-verbose_optimization_hints") == 0 ) {
3678 fVerboseOptimizationHints = true;
3679 }
3680 else if ( strcmp(arg, "-ignore_optimization_hints") == 0 ) {
3681 fIgnoreOptimizationHints = true;
eaf282aa 3682 cannotBeUsedWithBitcode(arg);
9543cb2f 3683 }
f80fe69f
A
3684 else if ( strcmp(arg, "-no_dtrace_dof") == 0 ) {
3685 fGenerateDtraceDOF = false;
3686 }
9543cb2f
A
3687 else if ( strcmp(arg, "-rename_section") == 0 ) {
3688 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) || (argv[i+4]==NULL) )
3689 throw "-rename_section missing <segment> <section> <segment> <section>";
3690 addSectionRename(argv[i+1], argv[i+2], argv[i+3], argv[i+4]);
3691 i += 4;
eaf282aa 3692 cannotBeUsedWithBitcode(arg);
9543cb2f 3693 }
599556ff
A
3694 else if ( strcmp(arg, "-rename_segment") == 0 ) {
3695 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3696 throw "-rename_segment missing <existing-segment> <new-segment>";
3697 addSegmentRename(argv[i+1], argv[i+2]);
3698 i += 2;
eaf282aa 3699 cannotBeUsedWithBitcode(arg);
599556ff
A
3700 }
3701 else if ( strcmp(arg, "-move_to_ro_segment") == 0 ) {
3702 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3703 throw "-move_to_ro_segment missing <segment> <symbol-list-file>";
3704 addSymbolMove(argv[i+1], argv[i+2], fSymbolsMovesCode, "-move_to_ro_segment");
3705 i += 2;
eaf282aa 3706 cannotBeUsedWithBitcode(arg);
599556ff
A
3707 }
3708 else if ( strcmp(arg, "-move_to_rw_segment") == 0 ) {
3709 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3710 throw "-move_to_rw_segment missing <segment> <symbol-list-file>";
3711 addSymbolMove(argv[i+1], argv[i+2], fSymbolsMovesData, "-move_to_rw_segment");
3712 i += 2;
eaf282aa 3713 cannotBeUsedWithBitcode(arg);
599556ff
A
3714 }
3715 else if ( strcmp(arg, "-trace_symbol_layout") == 0 ) {
3716 fTraceSymbolLayout = true;
3717 }
9543cb2f
A
3718 else if ( strcmp(arg, "-no_branch_islands") == 0 ) {
3719 fAllowBranchIslands = false;
eaf282aa 3720 cannotBeUsedWithBitcode(arg);
9543cb2f 3721 }
599556ff
A
3722 else if ( strcmp(arg, "-segment_order") == 0 ) {
3723 // ex: -segment_order __TEXT:__DATA:__JUNK
3724 const char* optString = argv[++i];
3725 if ( optString == NULL )
3726 throw "-segment_order missing colon separated <segment-list>";
3727 if ( !fSegmentOrder.empty() )
3728 throw "-segment_order used more than once";
3729 // break up into list of tokens at colon
3730 char* buffer = strdup(optString);
3731 char* start = buffer;
3732 for (char* s = buffer; ; ++s) {
3733 if ( *s == ':' ) {
3734 *s = '\0';
3735 fSegmentOrder.push_back(start);
3736 start = s+1;
3737 }
3738 else if ( *s == '\0' ) {
3739 fSegmentOrder.push_back(start);
3740 break;
3741 }
3742 }
eaf282aa 3743 cannotBeUsedWithBitcode(arg);
599556ff
A
3744 }
3745 else if ( strcmp(arg, "-section_order") == 0 ) {
3746 // ex: -section_order __DATA __data:__const:__nl_pointers
3747 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3748 throw "-section_order missing <segment> <section-list>";
3749 const char* segName = argv[++i];
3750 const char* optString = argv[++i];
3751 if ( sectionOrder(segName) != NULL )
3752 throwf("-section_order %s ... used more than once", segName);
3753 SectionOrderList dummy;
3754 fSectionOrder.push_back(dummy);
3755 SectionOrderList& entry = fSectionOrder.back();
3756 entry.segmentName = segName;
3757 // break up into list of tokens at colon
3758 char* buffer = strdup(optString);
3759 char* start = buffer;
3760 for (char* s = buffer; ; ++s) {
3761 if ( *s == ':' ) {
3762 *s = '\0';
3763 entry.sectionOrder.push_back(start);
3764 start = s+1;
3765 }
3766 else if ( *s == '\0' ) {
3767 entry.sectionOrder.push_back(start);
3768 break;
3769 }
3770 }
eaf282aa 3771 cannotBeUsedWithBitcode(arg);
599556ff
A
3772 }
3773 else if ( strcmp(arg, "-application_extension") == 0 ) {
3774 fMarkAppExtensionSafe = true;
3775 fCheckAppExtensionSafe = true;
3776 }
3777 else if ( strcmp(arg, "-no_application_extension") == 0 ) {
3778 fMarkAppExtensionSafe = false;
3779 fCheckAppExtensionSafe = false;
3780 }
3781 else if ( strcmp(arg, "-add_ast_path") == 0 ) {
3782 const char* path = argv[++i];
3783 if ( path == NULL )
3784 throw "-add_ast_path missing <option>";
3785 fASTFilePaths.push_back(path);
3786 }
3787 else if ( strcmp(arg, "-force_load_swift_libs") == 0 ) {
3788 fForceLoadSwiftLibs = true;
3789 }
eaf282aa
A
3790 else if ( strcmp(arg, "-not_for_dyld_shared_cache") == 0 ) {
3791 fSharedRegionEligibleForceOff = true;
3792 cannotBeUsedWithBitcode(arg);
3793 }
3794 else if ( strcmp(arg, "-dirty_data_list") == 0 ) {
3795 if ( argv[i+1] == NULL )
3796 throw "-dirty_data_list missing <symbol-list-file>";
3797 addSymbolMove("__DATA_DIRTY", argv[i+1], fSymbolsMovesData, "-dirty_data_list");
3798 ++i;
3799 cannotBeUsedWithBitcode(arg);
3800 }
3801 else if ( strcmp(arg, "-data_const") == 0 ) {
3802 fUseDataConstSegmentForceOn = true;
3803 cannotBeUsedWithBitcode(arg);
3804 }
3805 else if ( strcmp(arg, "-no_data_const") == 0 ) {
3806 fUseDataConstSegmentForceOff = true;
3807 cannotBeUsedWithBitcode(arg);
3808 }
0a8dc3df
A
3809 else if ( strcmp(arg, "-text_exec") == 0 ) {
3810 fUseTextExecSegment = true;
3811 cannotBeUsedWithBitcode(arg);
3812 }
3813 else if ( strcmp(arg, "-add_split_seg_info") == 0) {
3814 fSharedRegionEligible = true;
3815 cannotBeUsedWithBitcode(arg);
3816 }
ec29ba20
A
3817 else if ( strcmp(arg, "-no_deduplicate") == 0 ) {
3818 fDeDupe = false;
3819 }
3820 else if ( strcmp(arg, "-verbose_deduplicate") == 0 ) {
3821 fVerboseDeDupe = true;
3822 }
3823 else if ( strcmp(arg, "-max_default_common_align") == 0 ) {
3824 const char* alignStr = argv[++i];
3825 if ( alignStr == NULL )
3826 throw "-max_default_common_align missing <align-value>";
3827 // argument is a hexadecimal number
3828 char* endptr;
3829 unsigned long value = strtoul(alignStr, &endptr, 16);
3830 if ( *endptr != '\0')
3831 throw "argument for -max_default_common_align is not a hexadecimal number";
3832 if ( value > 0x8000 )
3833 throw "argument for -max_default_common_align must be less than or equal to 0x8000";
3834 if ( value == 0 ) {
3835 warning("zero is not a valid -max_default_common_align");
3836 value = 1;
3837 }
3838 // alignment is power of 2
3839 uint8_t alignment = (uint8_t)__builtin_ctz(value);
3840 if ( (unsigned long)(1 << alignment) != value ) {
3841 warning("alignment for -max_default_common_align is not a power of two, using 0x%X", 1 << alignment);
3842 }
3843 fMaxDefaultCommonAlign = alignment;
3844 }
0a8dc3df
A
3845 else if ( strcmp(argv[i], "-no_weak_imports") == 0 ) {
3846 fAllowWeakImports = false;
ec29ba20 3847 }
9543cb2f
A
3848 // put this last so that it does not interfer with other options starting with 'i'
3849 else if ( strncmp(arg, "-i", 2) == 0 ) {
3850 const char* colon = strchr(arg, ':');
3851 if ( colon == NULL )
3852 throwf("unknown option: %s", arg);
3853 Options::AliasPair pair;
3854 char* temp = new char[colon-arg];
3855 strlcpy(temp, &arg[2], colon-arg-1);
3856 pair.realName = &colon[1];
3857 pair.alias = temp;
3858 fAliases.push_back(pair);
3859 }
c2646906 3860 else {
d696c285 3861 throwf("unknown option: %s", arg);
c2646906 3862 }
ebf6f434
A
3863
3864 if (snapshotArgCount == -1)
3865 snapshotArgCount = i-snapshotArgIndex+1;
3866 if (snapshotArgCount > 0)
3867 fLinkSnapshot.addSnapshotLinkArg(snapshotArgIndex, snapshotArgCount, snapshotFileArgIndex);
c2646906
A
3868 }
3869 else {
a61fdf0a 3870 FileInfo info = findFile(arg);
ebf6f434 3871 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
a61fdf0a
A
3872 if ( strcmp(&info.path[strlen(info.path)-2], ".a") == 0 )
3873 addLibrary(info);
3874 else
3875 fInputFiles.push_back(info);
c2646906
A
3876 }
3877 }
2f2f92e4
A
3878
3879 // if a -lazy option was used, implicitly link in lazydylib1.o
3880 if ( fUsingLazyDylibLinking ) {
ebf6f434
A
3881 FileInfo info = findLibrary("lazydylib1.o");
3882 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)argc);
3883 addLibrary(info);
2f2f92e4 3884 }
ebf6f434
A
3885
3886 if (fSnapshotRequested)
3887 fLinkSnapshot.createSnapshot();
c2646906
A
3888}
3889
69a49097
A
3890
3891
d696c285
A
3892//
3893// -syslibroot <path> is used for SDK support.
6e880c60
A
3894// The rule is that all search paths (both explicit and default) are
3895// checked to see if they exist in the SDK. If so, that path is
3896// replaced with the sdk prefixed path. If not, that search path
3897// is used as is. If multiple -syslibroot options are specified
3898// their directory structures are logically overlayed and files
3899// from sdks specified earlier on the command line used before later ones.
d696c285 3900
c2646906
A
3901void Options::buildSearchPaths(int argc, const char* argv[])
3902{
3903 bool addStandardLibraryDirectories = true;
6e880c60
A
3904 std::vector<const char*> libraryPaths;
3905 std::vector<const char*> frameworkPaths;
d696c285
A
3906 libraryPaths.reserve(10);
3907 frameworkPaths.reserve(10);
6e880c60 3908 // scan through argv looking for -L, -F, -Z, and -syslibroot options
c2646906 3909 for(int i=0; i < argc; ++i) {
c211e7c9
A
3910 if ( (argv[i][0] == '-') && (argv[i][1] == 'L') ) {
3911 const char* libSearchDir = &argv[i][2];
a645023d
A
3912 // Allow either "-L{path}" or "-L {path}".
3913 if (argv[i][2] == '\0') {
3914 // -L {path}. Make sure there is an argument following this.
3915 const char* path = argv[++i];
3916 if ( path == NULL )
3917 throw "-L missing argument";
3918 libSearchDir = path;
3919 }
c211e7c9
A
3920 if ( libSearchDir[0] == '\0' )
3921 throw "-L must be immediately followed by a directory path (no space)";
ec29ba20 3922 libraryPaths.push_back(libSearchDir);
c211e7c9
A
3923 }
3924 else if ( (argv[i][0] == '-') && (argv[i][1] == 'F') ) {
3925 const char* frameworkSearchDir = &argv[i][2];
a645023d
A
3926 // Allow either "-F{path}" or "-F {path}".
3927 if (argv[i][2] == '\0') {
3928 // -F {path}. Make sure there is an argument following this.
3929 const char* path = argv[++i];
3930 if ( path == NULL )
3931 throw "-F missing argument";
3932 frameworkSearchDir = path;
3933 }
c211e7c9
A
3934 if ( frameworkSearchDir[0] == '\0' )
3935 throw "-F must be immediately followed by a directory path (no space)";
ec29ba20 3936 frameworkPaths.push_back(frameworkSearchDir);
c211e7c9 3937 }
c2646906
A
3938 else if ( strcmp(argv[i], "-Z") == 0 )
3939 addStandardLibraryDirectories = false;
6e880c60
A
3940 else if ( strcmp(argv[i], "-v") == 0 ) {
3941 fVerbose = true;
a61fdf0a
A
3942 extern const char ldVersionString[];
3943 fprintf(stderr, "%s", ldVersionString);
ebf6f434 3944 fprintf(stderr, "configured to support archs: %s\n", ALL_SUPPORTED_ARCHS);
6e880c60 3945 // if only -v specified, exit cleanly
2f2f92e4 3946 if ( argc == 2 ) {
a645023d
A
3947 const char* ltoVers = lto::version();
3948 if ( ltoVers != NULL )
ebf6f434 3949 fprintf(stderr, "LTO support using: %s\n", ltoVers);
0a8dc3df 3950 fprintf(stderr, "TAPI support using: %s\n", tapi::Version::getFullVersionAsString().c_str());
6e880c60 3951 exit(0);
2f2f92e4 3952 }
6e880c60
A
3953 }
3954 else if ( strcmp(argv[i], "-syslibroot") == 0 ) {
3955 const char* path = argv[++i];
3956 if ( path == NULL )
3957 throw "-syslibroot missing argument";
3958 fSDKPaths.push_back(path);
3959 }
a61fdf0a 3960 else if ( strcmp(argv[i], "-search_paths_first") == 0 ) {
a61fdf0a
A
3961 fLibrarySearchMode = kSearchDylibAndArchiveInEachDir;
3962 }
a645023d
A
3963 else if ( strcmp(argv[i], "-search_dylibs_first") == 0 ) {
3964 fLibrarySearchMode = kSearchAllDirsForDylibsThenAllDirsForArchives;
3965 }
a61fdf0a 3966 else if ( strcmp(argv[i], "-w") == 0 ) {
2f2f92e4 3967 sEmitWarnings = false;
a61fdf0a 3968 }
b2fa67a8
A
3969 else if ( strcmp(argv[i], "-fatal_warnings") == 0 ) {
3970 sFatalWarnings = true;
3971 }
f80fe69f
A
3972 else if ( strcmp(argv[i], "-dependency_info") == 0 ) {
3973 const char* path = argv[++i];
3974 if ( path == NULL )
3975 throw "-dependency_info missing <path>";
3976 fDependencyInfoPath = path;
3977 }
eaf282aa
A
3978 else if ( strcmp(argv[i], "-bitcode_bundle") == 0 ) {
3979 fBundleBitcode = true;
3980 }
c2646906 3981 }
55e3d2f6
A
3982 int standardLibraryPathsStartIndex = libraryPaths.size();
3983 int standardFrameworkPathsStartIndex = frameworkPaths.size();
c2646906 3984 if ( addStandardLibraryDirectories ) {
6e880c60
A
3985 libraryPaths.push_back("/usr/lib");
3986 libraryPaths.push_back("/usr/local/lib");
d696c285 3987
6e880c60 3988 frameworkPaths.push_back("/Library/Frameworks/");
6e880c60 3989 frameworkPaths.push_back("/System/Library/Frameworks/");
55e3d2f6 3990 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
6e880c60 3991 }
d696c285 3992
77cc3118
A
3993 // <rdar://problem/5829579> Support for configure based hacks
3994 // if last -syslibroot is /, then ignore all syslibroots
3995 if ( fSDKPaths.size() > 0 ) {
3996 if ( strcmp(fSDKPaths.back(), "/") == 0 ) {
3997 fSDKPaths.clear();
3998 }
3999 }
4000
6e880c60 4001 // now merge sdk and library paths to make real search paths
d696c285 4002 fLibrarySearchPaths.reserve(libraryPaths.size()*(fSDKPaths.size()+1));
55e3d2f6
A
4003 int libIndex = 0;
4004 for (std::vector<const char*>::iterator it = libraryPaths.begin(); it != libraryPaths.end(); ++it, ++libIndex) {
6e880c60
A
4005 const char* libDir = *it;
4006 bool sdkOverride = false;
4007 if ( libDir[0] == '/' ) {
4008 char betterLibDir[PATH_MAX];
4009 if ( strstr(libDir, "/..") != NULL ) {
4010 if ( realpath(libDir, betterLibDir) != NULL )
d696c285 4011 libDir = strdup(betterLibDir);
6e880c60
A
4012 }
4013 const int libDirLen = strlen(libDir);
4014 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
4015 const char* sdkDir = *sdkit;
4016 const int sdkDirLen = strlen(sdkDir);
4017 char newPath[libDirLen + sdkDirLen+4];
4018 strcpy(newPath, sdkDir);
4019 if ( newPath[sdkDirLen-1] == '/' )
4020 newPath[sdkDirLen-1] = '\0';
4021 strcat(newPath, libDir);
4022 struct stat statBuffer;
4023 if ( stat(newPath, &statBuffer) == 0 ) {
ec29ba20
A
4024 if ( (statBuffer.st_mode & S_IFDIR) == 0 ) {
4025 warning("-syslibroot and -L combined path '%s' is not a directory", newPath);
4026 }
4027 else {
4028 fLibrarySearchPaths.push_back(strdup(newPath));
4029 sdkOverride = true;
4030 }
6e880c60
A
4031 }
4032 }
4033 }
55e3d2f6
A
4034 if ( !sdkOverride ) {
4035 if ( (libIndex >= standardLibraryPathsStartIndex) && (fSDKPaths.size() == 1) ) {
4036 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
4037 // if one SDK is specified and a standard library path is not in the SDK, don't use it
4038 }
4039 else {
ec29ba20
A
4040 struct stat statBuffer;
4041 if ( stat(libDir, &statBuffer) == 0 ) {
4042 if ( (statBuffer.st_mode & S_IFDIR) == 0 )
4043 warning("-L path '%s' is not a directory", libDir);
4044 else
4045 fLibrarySearchPaths.push_back(libDir);
4046 }
4047 else if ( !addStandardLibraryDirectories || (strcmp(libDir, "/usr/local/lib") != 0) ) {
4048 warning("directory not found for option '-L%s'", libDir);
4049 }
55e3d2f6
A
4050 }
4051 }
6e880c60 4052 }
d696c285 4053
ec29ba20 4054
6e880c60 4055 // now merge sdk and framework paths to make real search paths
d696c285 4056 fFrameworkSearchPaths.reserve(frameworkPaths.size()*(fSDKPaths.size()+1));
55e3d2f6
A
4057 int frameIndex = 0;
4058 for (std::vector<const char*>::iterator it = frameworkPaths.begin(); it != frameworkPaths.end(); ++it, ++frameIndex) {
6e880c60
A
4059 const char* frameworkDir = *it;
4060 bool sdkOverride = false;
4061 if ( frameworkDir[0] == '/' ) {
4062 char betterFrameworkDir[PATH_MAX];
4063 if ( strstr(frameworkDir, "/..") != NULL ) {
4064 if ( realpath(frameworkDir, betterFrameworkDir) != NULL )
d696c285 4065 frameworkDir = strdup(betterFrameworkDir);
6e880c60
A
4066 }
4067 const int frameworkDirLen = strlen(frameworkDir);
4068 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
4069 const char* sdkDir = *sdkit;
4070 const int sdkDirLen = strlen(sdkDir);
4071 char newPath[frameworkDirLen + sdkDirLen+4];
4072 strcpy(newPath, sdkDir);
4073 if ( newPath[sdkDirLen-1] == '/' )
4074 newPath[sdkDirLen-1] = '\0';
4075 strcat(newPath, frameworkDir);
4076 struct stat statBuffer;
4077 if ( stat(newPath, &statBuffer) == 0 ) {
ec29ba20
A
4078 if ( (statBuffer.st_mode & S_IFDIR) == 0 ) {
4079 warning("-syslibroot and -F combined path '%s' is not a directory", newPath);
4080 }
4081 else {
4082 fFrameworkSearchPaths.push_back(strdup(newPath));
4083 sdkOverride = true;
4084 }
6e880c60
A
4085 }
4086 }
4087 }
55e3d2f6
A
4088 if ( !sdkOverride ) {
4089 if ( (frameIndex >= standardFrameworkPathsStartIndex) && (fSDKPaths.size() == 1) ) {
4090 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
4091 // if one SDK is specified and a standard library path is not in the SDK, don't use it
4092 }
4093 else {
ec29ba20
A
4094 struct stat statBuffer;
4095 if ( stat(frameworkDir, &statBuffer) == 0 ) {
4096 if ( (statBuffer.st_mode & S_IFDIR) == 0 )
4097 warning("-F path '%s' is not a directory", frameworkDir);
4098 else
4099 fFrameworkSearchPaths.push_back(frameworkDir);
4100 }
4101 else if ( !addStandardLibraryDirectories || (strcmp(frameworkDir, "/Library/Frameworks/") != 0) ) {
4102 warning("directory not found for option '-F%s'", frameworkDir);
4103 }
55e3d2f6
A
4104 }
4105 }
6e880c60 4106 }
d696c285 4107
6e880c60
A
4108 if ( fVerbose ) {
4109 fprintf(stderr,"Library search paths:\n");
d696c285
A
4110 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
4111 it != fLibrarySearchPaths.end();
4112 it++)
6e880c60
A
4113 fprintf(stderr,"\t%s\n", *it);
4114 fprintf(stderr,"Framework search paths:\n");
d696c285
A
4115 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
4116 it != fFrameworkSearchPaths.end();
4117 it++)
6e880c60 4118 fprintf(stderr,"\t%s\n", *it);
c2646906
A
4119 }
4120}
4121
4122// this is run before the command line is parsed
4123void Options::parsePreCommandLineEnvironmentSettings()
4124{
d696c285
A
4125 if ((getenv("LD_TRACE_ARCHIVES") != NULL)
4126 || (getenv("RC_TRACE_ARCHIVES") != NULL))
a645023d 4127 fTraceArchives = true;
d696c285
A
4128
4129 if ((getenv("LD_TRACE_DYLIBS") != NULL)
4130 || (getenv("RC_TRACE_DYLIBS") != NULL)) {
a645023d
A
4131 fTraceDylibs = true;
4132 fTraceIndirectDylibs = true;
c2646906 4133 }
0a8dc3df
A
4134
4135 if ((getenv("LD_TRACE_DEPENDENTS") != NULL)) {
4136
4137 fTraceEmitJSON = true;
4138 }
d696c285
A
4139
4140 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL) {
4141 fTraceDylibSearching = true;
4142 }
4143
4144 if (getenv("LD_PRINT_OPTIONS") != NULL)
4145 fPrintOptions = true;
4146
0a8dc3df 4147 if (fTraceDylibs || fTraceArchives || fTraceEmitJSON)
a645023d 4148 fTraceOutputFile = getenv("LD_TRACE_FILE");
a61fdf0a
A
4149
4150 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL)
4151 fPrintOrderFileStatistics = true;
2f2f92e4
A
4152
4153 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL)
4154 fSplitSegs = true;
4155
599556ff 4156 if (getenv("LD_NO_ENCRYPT") != NULL) {
2f2f92e4 4157 fEncryptable = false;
599556ff
A
4158 fMarkAppExtensionSafe = true; // temporary
4159 fCheckAppExtensionSafe = false;
4160 }
4161
4162 if (getenv("LD_APPLICATION_EXTENSION_SAFE") != NULL) {
4163 fMarkAppExtensionSafe = true;
4164 fCheckAppExtensionSafe = false;
4165 }
55e3d2f6
A
4166
4167 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL)
4168 fAllowCpuSubtypeMismatches = true;
4169
ec29ba20
A
4170 if (getenv("LD_DYLIB_CPU_SUBTYPES_MUST_MATCH") != NULL)
4171 fEnforceDylibSubtypesMatch = true;
4172
2f2f92e4 4173 sWarningsSideFilePath = getenv("LD_WARN_FILE");
a645023d
A
4174
4175 const char* customDyldPath = getenv("LD_DYLD_PATH");
4176 if ( customDyldPath != NULL )
4177 fDyldInstallPath = customDyldPath;
ebf6f434
A
4178
4179 const char* debugArchivePath = getenv("LD_DEBUG_SNAPSHOT");
4180 if (debugArchivePath != NULL) {
4181 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
4182 if (strlen(debugArchivePath) > 0)
4183 fLinkSnapshot.setSnapshotPath(debugArchivePath);
4184 fSnapshotRequested = true;
4185 }
4186
4187 const char* pipeFdString = getenv("LD_PIPELINE_FIFO");
4188 if (pipeFdString != NULL) {
4189 fPipelineFifo = pipeFdString;
4190 }
c2646906
A
4191}
4192
2f2f92e4 4193
c2646906
A
4194// this is run after the command line is parsed
4195void Options::parsePostCommandLineEnvironmentSettings()
4196{
d696c285
A
4197 // when building a dynamic main executable, default any use of @executable_path to output path
4198 if ( fExecutablePath == NULL && (fOutputKind == kDynamicExecutable) ) {
4199 fExecutablePath = fOutputFile;
4200 }
a61fdf0a
A
4201
4202 // allow build system to set default seg_addr_table
4203 if ( fSegAddrTablePath == NULL )
4204 fSegAddrTablePath = getenv("LD_SEG_ADDR_TABLE");
4205
4206 // allow build system to turn on prebinding
4207 if ( !fPrebind ) {
4208 fPrebind = ( getenv("LD_PREBIND") != NULL );
4209 }
2f2f92e4
A
4210
4211 // allow build system to force on dead-code-stripping
a645023d 4212 if ( !fDeadStrip ) {
2f2f92e4
A
4213 if ( getenv("LD_DEAD_STRIP") != NULL ) {
4214 switch (fOutputKind) {
4215 case Options::kDynamicLibrary:
4216 case Options::kDynamicExecutable:
4217 case Options::kDynamicBundle:
a645023d 4218 fDeadStrip = true;
2f2f92e4 4219 break;
55e3d2f6 4220 case Options::kPreload:
2f2f92e4
A
4221 case Options::kObjectFile:
4222 case Options::kDyld:
4223 case Options::kStaticExecutable:
55e3d2f6 4224 case Options::kKextBundle:
2f2f92e4
A
4225 break;
4226 }
4227 }
4228 }
4229
4230 // allow build system to force on -warn_commons
4231 if ( getenv("LD_WARN_COMMONS") != NULL )
4232 fWarnCommons = true;
ebf6f434
A
4233
4234 // allow B&I to set default -source_version
4235 if ( fSourceVersion == 0 ) {
4236 const char* vers = getenv("RC_ProjectSourceVersion");
4237 if ( vers != NULL )
4238 fSourceVersion = parseVersionNumber64(vers);
4239 }
4be885f6 4240
69a49097
A
4241}
4242
4243void Options::reconfigureDefaults()
4244{
4245 // sync reader options
4246 switch ( fOutputKind ) {
4247 case Options::kObjectFile:
a645023d 4248 fForFinalLinkedImage = false;
69a49097 4249 break;
a61fdf0a 4250 case Options::kDyld:
a645023d
A
4251 fForDyld = true;
4252 fForFinalLinkedImage = true;
4253 fNoEHLabels = true;
a61fdf0a 4254 break;
69a49097
A
4255 case Options::kDynamicLibrary:
4256 case Options::kDynamicBundle:
55e3d2f6 4257 case Options::kKextBundle:
a645023d
A
4258 fForFinalLinkedImage = true;
4259 fNoEHLabels = true;
a61fdf0a
A
4260 break;
4261 case Options::kDynamicExecutable:
4262 case Options::kStaticExecutable:
55e3d2f6 4263 case Options::kPreload:
a645023d
A
4264 fLinkingMainExecutable = true;
4265 fForFinalLinkedImage = true;
4266 fNoEHLabels = true;
69a49097
A
4267 break;
4268 }
4269
4270 // set default min OS version
eaf282aa 4271 if ( (fMacVersionMin == ld::macVersionUnset) && (fIOSVersionMin == ld::iOSVersionUnset) && (fWatchOSVersionMin == ld::wOSVersionUnset) ) {
55e3d2f6
A
4272 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
4273 const char* macVers = getenv("MACOSX_DEPLOYMENT_TARGET");
4274 const char* iPhoneVers = getenv("IPHONEOS_DEPLOYMENT_TARGET");
a645023d 4275 const char* iOSVers = getenv("IOS_DEPLOYMENT_TARGET");
eaf282aa
A
4276 const char* wOSVers = getenv("WATCHOS_DEPLOYMENT_TARGET");
4277 if ( macVers != NULL )
55e3d2f6
A
4278 setMacOSXVersionMin(macVers);
4279 else if ( iPhoneVers != NULL )
afe874b1 4280 setIOSVersionMin(iPhoneVers);
a645023d 4281 else if ( iOSVers != NULL )
afe874b1 4282 setIOSVersionMin(iOSVers);
eaf282aa
A
4283 else if ( wOSVers != NULL )
4284 setWatchOSVersionMin(wOSVers);
55e3d2f6
A
4285 else {
4286 // if still nothing, set default based on architecture
4287 switch ( fArchitecture ) {
4288 case CPU_TYPE_I386:
4289 case CPU_TYPE_X86_64:
a645023d
A
4290 if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
4291 #ifdef DEFAULT_MACOSX_MIN_VERSION
ebf6f434 4292 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
a645023d
A
4293 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
4294 #else
ebf6f434 4295 warning("-macosx_version_min not specified, assuming 10.6");
eaf282aa 4296 setMacOSXVersionMin("10.6");
a645023d
A
4297 #endif
4298 }
55e3d2f6
A
4299 break;
4300 case CPU_TYPE_ARM:
a645023d
A
4301 if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
4302 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
ebf6f434 4303 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION);
afe874b1 4304 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION);
a645023d 4305 #else
eaf282aa
A
4306 if ( fSubArchitecture == CPU_SUBTYPE_ARM_V7K ) {
4307 warning("-watchos_version_min not specified, assuming 2.0");
4308 setWatchOSVersionMin("2.0");
4309 }
4310 else {
4311 warning("-ios_version_min not specified, assuming 6.0");
4312 setIOSVersionMin("6.0");
4313 }
a645023d
A
4314 #endif
4315 }
4316 break;
4317 default:
f80fe69f 4318 // architecture will be infered later by examining .o files
55e3d2f6
A
4319 break;
4320 }
4321 }
69a49097
A
4322 }
4323
55e3d2f6 4324
69a49097
A
4325 // adjust min based on architecture
4326 switch ( fArchitecture ) {
4327 case CPU_TYPE_I386:
eaf282aa 4328 if ( (fPlatform == kPlatformOSX) && (fMacVersionMin < ld::mac10_4) ) {
2f2f92e4 4329 //warning("-macosx_version_min should be 10.4 or later for i386");
a645023d 4330 fMacVersionMin = ld::mac10_4;
69a49097
A
4331 }
4332 break;
69a49097 4333 case CPU_TYPE_X86_64:
eaf282aa 4334 if ( (fPlatform == kPlatformOSX) && (fMacVersionMin < ld::mac10_4) ) {
2f2f92e4 4335 //warning("-macosx_version_min should be 10.4 or later for x86_64");
a645023d 4336 fMacVersionMin = ld::mac10_4;
69a49097
A
4337 }
4338 break;
f80fe69f 4339 case CPU_TYPE_ARM64:
eaf282aa 4340 if ( (fPlatform == kPlatformiOS) && (fIOSVersionMin < ld::iOS_7_0) ) {
f80fe69f
A
4341 //warning("-mios_version_min should be 7.0 or later for arm64");
4342 fIOSVersionMin = ld::iOS_7_0;
4343 }
4344 break;
69a49097 4345 }
55e3d2f6 4346
d425e388
A
4347 // default to adding functions start for dynamic code, static code must opt-in
4348 switch ( fOutputKind ) {
4349 case Options::kPreload:
4350 case Options::kStaticExecutable:
4351 case Options::kKextBundle:
4352 if ( fDataInCodeInfoLoadCommandForcedOn )
4353 fDataInCodeInfoLoadCommand = true;
4354 if ( fFunctionStartsForcedOn )
4355 fFunctionStartsLoadCommand = true;
4356 break;
4357 case Options::kObjectFile:
9543cb2f
A
4358 if ( !fDataInCodeInfoLoadCommandForcedOff )
4359 fDataInCodeInfoLoadCommand = true;
4360 if ( fFunctionStartsForcedOn )
4361 fFunctionStartsLoadCommand = true;
4362 break;
d425e388
A
4363 case Options::kDynamicExecutable:
4364 case Options::kDyld:
4365 case Options::kDynamicLibrary:
4366 case Options::kDynamicBundle:
4367 if ( !fDataInCodeInfoLoadCommandForcedOff )
4368 fDataInCodeInfoLoadCommand = true;
4369 if ( !fFunctionStartsForcedOff )
4370 fFunctionStartsLoadCommand = true;
4371 break;
4372 }
4373
55e3d2f6
A
4374 // adjust kext type based on architecture
4375 if ( fOutputKind == kKextBundle ) {
4376 switch ( fArchitecture ) {
4377 case CPU_TYPE_X86_64:
4378 // x86_64 uses new MH_KEXT_BUNDLE type
55e3d2f6 4379 fMakeCompressedDyldInfo = false;
a645023d 4380 fMakeCompressedDyldInfoForceOff = true;
55e3d2f6
A
4381 fAllowTextRelocs = true;
4382 fUndefinedTreatment = kUndefinedDynamicLookup;
4383 break;
f80fe69f
A
4384 case CPU_TYPE_ARM64:
4385 // arm64 uses new MH_KEXT_BUNDLE type
4386 fMakeCompressedDyldInfo = false;
4387 fMakeCompressedDyldInfoForceOff = true;
4388 fAllowTextRelocs = false;
4389 fKextsUseStubs = true;
4390 fUndefinedTreatment = kUndefinedDynamicLookup;
4391 break;
afe874b1 4392 case CPU_TYPE_ARM:
eaf282aa 4393 if ( min_iOS(ld::iOS_5_0) ) {
afe874b1
A
4394 // iOS 5.0 and later use new MH_KEXT_BUNDLE type
4395 fMakeCompressedDyldInfo = false;
4396 fMakeCompressedDyldInfoForceOff = true;
b1f7435d 4397 // kexts are PIC in iOS 6.0 and later
eaf282aa 4398 fAllowTextRelocs = !min_iOS(ld::iOS_6_0);
ebf6f434 4399 fKextsUseStubs = !fAllowTextRelocs;
afe874b1
A
4400 fUndefinedTreatment = kUndefinedDynamicLookup;
4401 break;
4402 }
4403 // else use object file
55e3d2f6 4404 case CPU_TYPE_I386:
55e3d2f6
A
4405 // use .o files
4406 fOutputKind = kObjectFile;
4407 break;
4408 }
4409 }
a61fdf0a 4410
55e3d2f6 4411 // disable implicit dylibs when targeting 10.3
2f2f92e4 4412 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
afe874b1 4413 if ( !minOS(ld::mac10_4, ld::iOS_2_0) )
a645023d 4414 fImplicitlyLinkPublicDylibs = false;
2f2f92e4
A
4415
4416
55e3d2f6
A
4417 // allow build system to force linker to ignore -prebind
4418 if ( getenv("LD_FORCE_NO_PREBIND") != NULL )
4419 fPrebind = false;
a61fdf0a 4420
55e3d2f6 4421 // allow build system to force linker to ignore -seg_addr_table
a61fdf0a
A
4422 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL )
4423 fSegAddrTablePath = NULL;
4424
4425 // check for base address specified externally
2f2f92e4 4426 if ( (fSegAddrTablePath != NULL) && (fOutputKind == Options::kDynamicLibrary) ) {
a61fdf0a 4427 parseSegAddrTable(fSegAddrTablePath, this->installPath());
2f2f92e4
A
4428 // HACK to support seg_addr_table entries that are physical paths instead of install paths
4429 if ( fBaseAddress == 0 ) {
55e3d2f6 4430 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
2f2f92e4 4431 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.4.dylib");
55e3d2f6
A
4432 if ( fBaseAddress == 0 )
4433 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.9.dylib");
4434 }
2f2f92e4
A
4435
4436 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
4437 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libz.1.2.3.dylib");
4438
4439 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
4440 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libutil1.0.dylib");
4441 }
4442 }
a61fdf0a 4443
a61fdf0a
A
4444 // split segs only allowed for dylibs
4445 if ( fSplitSegs ) {
b2fa67a8 4446 // split seg only supported for i386, and arm.
2f2f92e4 4447 switch ( fArchitecture ) {
2f2f92e4
A
4448 case CPU_TYPE_I386:
4449 if ( fOutputKind != Options::kDynamicLibrary )
4450 fSplitSegs = false;
4451 // make sure read and write segments are proper distance apart
4452 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x10000000) )
4453 fBaseWritableAddress = fBaseAddress + 0x10000000;
4454 break;
4455 case CPU_TYPE_ARM:
4456 if ( fOutputKind != Options::kDynamicLibrary ) {
4457 fSplitSegs = false;
4458 }
4459 else {
4460 // make sure read and write segments are proper distance apart
4461 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x08000000) )
4462 fBaseWritableAddress = fBaseAddress + 0x08000000;
4463 }
4464 break;
4465 default:
4466 fSplitSegs = false;
4467 fBaseAddress = 0;
4468 fBaseWritableAddress = 0;
a61fdf0a
A
4469 }
4470 }
4471
a645023d
A
4472 // set too-large size
4473 switch ( fArchitecture ) {
a645023d
A
4474 case CPU_TYPE_I386:
4475 fMaxAddress = 0xFFFFFFFF;
4476 break;
a645023d
A
4477 case CPU_TYPE_X86_64:
4478 break;
4479 case CPU_TYPE_ARM:
4480 switch ( fOutputKind ) {
4481 case Options::kDynamicExecutable:
4482 case Options::kDynamicLibrary:
4483 case Options::kDynamicBundle:
4484 // user land code is limited to low 1GB
4485 fMaxAddress = 0x2FFFFFFF;
4486 break;
4487 case Options::kStaticExecutable:
4488 case Options::kObjectFile:
4489 case Options::kDyld:
4490 case Options::kPreload:
4491 case Options::kKextBundle:
4492 fMaxAddress = 0xFFFFFFFF;
4493 break;
4494 }
4495 // range check -seg1addr for ARM
4496 if ( fBaseAddress > fMaxAddress ) {
4497 warning("ignoring -seg1addr 0x%08llX. Address out of range.", fBaseAddress);
4498 fBaseAddress = 0;
4499 }
4500 break;
4501 }
4502
55e3d2f6
A
4503 // <rdar://problem/6138961> -r implies no prebinding for all architectures
4504 if ( fOutputKind == Options::kObjectFile )
4505 fPrebind = false;
4506
a61fdf0a
A
4507 // disable prebinding depending on arch and min OS version
4508 if ( fPrebind ) {
4509 switch ( fArchitecture ) {
a61fdf0a 4510 case CPU_TYPE_I386:
a645023d 4511 if ( fMacVersionMin == ld::mac10_4 ) {
2f2f92e4 4512 // in 10.4 only split seg dylibs are prebound
a61fdf0a
A
4513 if ( (fOutputKind != Options::kDynamicLibrary) || ! fSplitSegs )
4514 fPrebind = false;
4515 }
a645023d 4516 else if ( fMacVersionMin >= ld::mac10_5 ) {
2f2f92e4
A
4517 // in 10.5 nothing is prebound
4518 fPrebind = false;
4519 }
afe874b1
A
4520 else if ( fIOSVersionMin != ld::iOSVersionUnset ) {
4521 // nothing in simulator is prebound
4522 fPrebind = false;
4523 }
2f2f92e4
A
4524 else {
4525 // in 10.3 and earlier only dylibs and main executables could be prebound
4526 switch ( fOutputKind ) {
4527 case Options::kDynamicExecutable:
4528 case Options::kDynamicLibrary:
4529 // only main executables and dylibs can be prebound
4530 break;
4531 case Options::kStaticExecutable:
4532 case Options::kDynamicBundle:
4533 case Options::kObjectFile:
4534 case Options::kDyld:
55e3d2f6
A
4535 case Options::kPreload:
4536 case Options::kKextBundle:
2f2f92e4
A
4537 // disable prebinding for everything else
4538 fPrebind = false;
4539 break;
4540 }
4541 }
a61fdf0a 4542 break;
a61fdf0a
A
4543 case CPU_TYPE_X86_64:
4544 fPrebind = false;
4545 break;
2f2f92e4
A
4546 case CPU_TYPE_ARM:
4547 switch ( fOutputKind ) {
4548 case Options::kDynamicExecutable:
4549 case Options::kDynamicLibrary:
4550 // only main executables and dylibs can be prebound
4551 break;
4552 case Options::kStaticExecutable:
4553 case Options::kDynamicBundle:
4554 case Options::kObjectFile:
4555 case Options::kDyld:
55e3d2f6
A
4556 case Options::kPreload:
4557 case Options::kKextBundle:
2f2f92e4
A
4558 // disable prebinding for everything else
4559 fPrebind = false;
4560 break;
4561 }
4562 break;
a61fdf0a
A
4563 }
4564 }
4565
2f2f92e4
A
4566 // only prebound images can be split-seg
4567 if ( fSplitSegs && !fPrebind )
4568 fSplitSegs = false;
a61fdf0a 4569
55e3d2f6
A
4570 // determine if info for shared region should be added
4571 if ( fOutputKind == Options::kDynamicLibrary ) {
0a8dc3df 4572 if ( minOS(ld::mac10_5, ld::iOS_3_1) && !fTargetIOSSimulator )
eaf282aa 4573 if ( !fPrebind && !fSharedRegionEligibleForceOff )
55e3d2f6
A
4574 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
4575 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
4576 fSharedRegionEligible = true;
4577 }
b2fa67a8
A
4578 else if ( fOutputKind == Options::kDyld ) {
4579 // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
4580 fSharedRegionEligible = true;
4581 }
eaf282aa
A
4582
4583 // <rdar://problem/18719327> warn if -rpath is used with OS dylibs
4584 if ( fSharedRegionEligible && !fRPaths.empty() )
4585 warning("-rpath cannot be used with dylibs that will be in the dyld shared cache");
4586
4587 // automatically use __DATA_CONST in iOS dylibs
4588 if ( fSharedRegionEligible && minOS(ld::mac10_Future, ld::iOS_9_0) && !fUseDataConstSegmentForceOff ) {
4589 fUseDataConstSegment = true;
4590 }
4591 if ( fUseDataConstSegmentForceOn ) {
4592 fUseDataConstSegment = true;
4593 }
0a8dc3df
A
4594 // A -kext for iOS 10 ==> -data_const, -text_exec, -add_split_seg_info
4595 if ( (fOutputKind == Options::kKextBundle) && minOS(ld::mac10_Future, ld::iOS_10_0) && (fArchitecture == CPU_TYPE_ARM64) ) {
4596 fUseDataConstSegment = true;
4597 fUseTextExecSegment = true;
4598 fSharedRegionEligible = true;
4599 }
eaf282aa
A
4600 if ( fUseDataConstSegment ) {
4601 addSectionRename("__DATA", "__got", "__DATA_CONST", "__got");
4602 addSectionRename("__DATA", "__la_symbol_ptr", "__DATA_CONST", "__la_symbol_ptr");
4603 addSectionRename("__DATA", "__nl_symbol_ptr", "__DATA_CONST", "__nl_symbol_ptr");
4604 addSectionRename("__DATA", "__const", "__DATA_CONST", "__const");
4605 addSectionRename("__DATA", "__cfstring", "__DATA_CONST", "__cfstring");
4606 addSectionRename("__DATA", "__mod_init_func", "__DATA_CONST", "__mod_init_func");
4607 addSectionRename("__DATA", "__mod_term_func", "__DATA_CONST", "__mod_term_func");
4608 addSectionRename("__DATA", "__objc_classlist", "__DATA_CONST", "__objc_classlist");
4609 addSectionRename("__DATA", "__objc_nlclslist", "__DATA_CONST", "__objc_nlclslist");
4610 addSectionRename("__DATA", "__objc_catlist", "__DATA_CONST", "__objc_catlist");
4611 addSectionRename("__DATA", "__objc_nlcatlist", "__DATA_CONST", "__objc_nlcatlist");
4612 addSectionRename("__DATA", "__objc_protolist", "__DATA_CONST", "__objc_protolist");
4613 addSectionRename("__DATA", "__objc_imageinfo", "__DATA_CONST", "__objc_imageinfo");
4614 addSectionRename("__DATA", "__objc_const", "__DATA_CONST", "__objc_const");
4615 }
0a8dc3df
A
4616 if ( fUseTextExecSegment ) {
4617 addSectionRename("__TEXT", "__text", "__TEXT_EXEC", "__text");
4618 addSectionRename("__TEXT", "__stubs", "__TEXT_EXEC", "__stubs");
4619 }
eaf282aa
A
4620
4621 // Use V2 shared cache info when targetting newer OSs
0a8dc3df 4622 if ( fSharedRegionEligible && minOS(ld::mac10_12, ld::iOS_9_0)) {
eaf282aa 4623 fSharedRegionEncodingV2 = true;
0a8dc3df
A
4624 // <rdar://problem/24772435> only use v2 for Swift dylibs on Mac OS X
4625 if ( (fPlatform == kPlatformOSX) && (strncmp(this->installPath(), "/System/Library/PrivateFrameworks/Swift/", 40) != 0) )
4626 fSharedRegionEncodingV2 = false;
eaf282aa
A
4627 fIgnoreOptimizationHints = true;
4628 }
4629
a61fdf0a
A
4630 // figure out if module table is needed for compatibility with old ld/dyld
4631 if ( fOutputKind == Options::kDynamicLibrary ) {
4632 switch ( fArchitecture ) {
afe874b1
A
4633 case CPU_TYPE_I386:
4634 if ( fIOSVersionMin != ld::iOSVersionUnset ) // simulator never needs modules
4635 break;
2f2f92e4 4636 case CPU_TYPE_ARM:
55e3d2f6
A
4637 if ( fPrebind )
4638 fNeedsModuleTable = true; // redo_prebinding requires a module table
2f2f92e4 4639 break;
a61fdf0a
A
4640 }
4641 }
4642
2f2f92e4
A
4643 // <rdar://problem/5366363> -r -x implies -S
4644 if ( (fOutputKind == Options::kObjectFile) && (fLocalSymbolHandling == kLocalSymbolsNone) )
a645023d 4645 fDebugInfoStripping = Options::kDebugInfoNone;
9543cb2f
A
4646
4647 // <rdar://problem/15252891> -r implies -no_uuid
4648 if ( fOutputKind == Options::kObjectFile )
4649 fUUIDMode = kUUIDNone;
4650
55e3d2f6
A
4651 // choose how to process unwind info
4652 switch ( fArchitecture ) {
4653 case CPU_TYPE_I386:
4654 case CPU_TYPE_X86_64:
f80fe69f 4655 case CPU_TYPE_ARM64:
55e3d2f6
A
4656 switch ( fOutputKind ) {
4657 case Options::kObjectFile:
4658 case Options::kStaticExecutable:
4659 case Options::kPreload:
4660 case Options::kKextBundle:
a645023d 4661 fAddCompactUnwindEncoding = false;
55e3d2f6
A
4662 break;
4663 case Options::kDyld:
4664 case Options::kDynamicLibrary:
4665 case Options::kDynamicBundle:
4666 case Options::kDynamicExecutable:
a645023d
A
4667 //if ( fAddCompactUnwindEncoding && (fVersionMin >= ld::mac10_6) )
4668 // fRemoveDwarfUnwindIfCompactExists = true;
55e3d2f6
A
4669 break;
4670 }
4671 break;
55e3d2f6 4672 case CPU_TYPE_ARM:
ba348e21
A
4673 if ( armUsesZeroCostExceptions() ) {
4674 switch ( fOutputKind ) {
4675 case Options::kObjectFile:
4676 case Options::kStaticExecutable:
4677 case Options::kPreload:
4678 case Options::kKextBundle:
4679 fAddCompactUnwindEncoding = false;
4680 break;
4681 case Options::kDyld:
4682 case Options::kDynamicLibrary:
4683 case Options::kDynamicBundle:
4684 case Options::kDynamicExecutable:
4685 fAddCompactUnwindEncoding = true;
4686 break;
4687 }
4688 }
4689 else {
4690 fAddCompactUnwindEncoding = false;
4691 fRemoveDwarfUnwindIfCompactExists = false;
4692 }
55e3d2f6
A
4693 break;
4694 case 0:
4695 // if -arch is missing, assume we don't want compact unwind info
a645023d 4696 fAddCompactUnwindEncoding = false;
55e3d2f6
A
4697 break;
4698 }
4699
599556ff
A
4700 // only iOS executables should be encryptable
4701 switch ( fOutputKind ) {
4702 case Options::kObjectFile:
4703 case Options::kDyld:
4704 case Options::kStaticExecutable:
4705 case Options::kPreload:
4706 case Options::kKextBundle:
4707 fEncryptable = false;
4708 break;
4709 case Options::kDynamicExecutable:
4710 break;
4711 case Options::kDynamicLibrary:
4712 case Options::kDynamicBundle:
4713 // <rdar://problem/16293398> Add LC_ENCRYPTION_INFO load command to bundled frameworks
eaf282aa 4714 if ( !min_iOS(ld::iOS_7_0) )
599556ff
A
4715 fEncryptable = false;
4716 break;
4717 }
0a8dc3df
A
4718 if ( (fArchitecture != CPU_TYPE_ARM) && (fArchitecture != CPU_TYPE_ARM64)
4719 )
2f2f92e4 4720 fEncryptable = false;
eaf282aa
A
4721 if ( fEncryptableForceOn )
4722 fEncryptable = true;
4723 else if ( fEncryptableForceOff )
4724 fEncryptable = false;
4be885f6 4725
55e3d2f6
A
4726 // don't move inits in dyld because dyld wants certain
4727 // entries point at stable locations at the start of __text
4728 if ( fOutputKind == Options::kDyld )
a645023d 4729 fAutoOrderInitializers = false;
55e3d2f6
A
4730
4731
4732 // disable __data ordering for some output kinds
4733 switch ( fOutputKind ) {
4734 case Options::kObjectFile:
4735 case Options::kDyld:
4736 case Options::kStaticExecutable:
4737 case Options::kPreload:
4738 case Options::kKextBundle:
4739 fOrderData = false;
4740 break;
4741 case Options::kDynamicExecutable:
4742 case Options::kDynamicLibrary:
4743 case Options::kDynamicBundle:
4744 break;
4745 }
4746
a645023d
A
4747 // only use compressed LINKEDIT for final linked images
4748 switch ( fOutputKind ) {
4749 case Options::kDynamicExecutable:
4750 case Options::kDynamicLibrary:
4751 case Options::kDynamicBundle:
4752 break;
4753 case Options::kPreload:
4754 case Options::kStaticExecutable:
4755 case Options::kObjectFile:
4756 case Options::kDyld:
4757 case Options::kKextBundle:
4758 fMakeCompressedDyldInfoForceOff = true;
4759 break;
4760 }
4761 if ( fMakeCompressedDyldInfoForceOff )
4762 fMakeCompressedDyldInfo = false;
4763
4764
fb24a050 4765 // only use compressed LINKEDIT for:
ebf6f434
A
4766 // Mac OS X 10.6 or later
4767 // iOS 3.1 or later
55e3d2f6 4768 if ( fMakeCompressedDyldInfo ) {
ebf6f434
A
4769 if ( !minOS(ld::mac10_6, ld::iOS_3_1) )
4770 fMakeCompressedDyldInfo = false;
55e3d2f6
A
4771 }
4772
9543cb2f
A
4773 // only ARM and x86_64 enforces that cpu-sub-types must match
4774 switch ( fArchitecture ) {
4775 case CPU_TYPE_ARM:
ec29ba20 4776 break;
9543cb2f 4777 case CPU_TYPE_X86_64:
ec29ba20 4778 fEnforceDylibSubtypesMatch = false;
9543cb2f
A
4779 break;
4780 case CPU_TYPE_I386:
4781 case CPU_TYPE_ARM64:
ec29ba20 4782 fEnforceDylibSubtypesMatch = false;
9543cb2f
A
4783 break;
4784 }
4785
4be885f6
A
4786
4787 // only final linked images can not optimize zero fill sections
4788 if ( fOutputKind == Options::kObjectFile )
a645023d
A
4789 fOptimizeZeroFill = true;
4790
4791 // all undefines in -r mode
4792// if ( fOutputKind == Options::kObjectFile )
4793// fUndefinedTreatment = kUndefinedSuppress;
fb24a050
A
4794
4795 // only dynamic final linked images should warn about use of commmons
4796 if ( fWarnCommons ) {
4797 switch ( fOutputKind ) {
4798 case Options::kDynamicExecutable:
4799 case Options::kDynamicLibrary:
4800 case Options::kDynamicBundle:
4801 break;
4802 case Options::kPreload:
4803 case Options::kStaticExecutable:
4804 case Options::kObjectFile:
4805 case Options::kDyld:
4806 case Options::kKextBundle:
4807 fWarnCommons = false;
4808 break;
4809 }
4810 }
4811
4812 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
afe874b1 4813 if ( minOS(ld::mac10_5, ld::iOS_2_0) )
fb24a050 4814 fUseSimplifiedDylibReExports = true;
a645023d
A
4815
4816 // Mac OS X 10.7 and iOS 4.2 support LC_LOAD_UPWARD_DYLIB
afe874b1 4817 if ( minOS(ld::mac10_7, ld::iOS_4_2) && (fOutputKind == kDynamicLibrary) )
a645023d 4818 fCanUseUpwardDylib = true;
d9246299 4819
afe874b1 4820 // MacOSX 10.7 defaults to PIE
0a8dc3df 4821 if ( (fArchitecture == CPU_TYPE_I386)
60ce07c1
A
4822 && (fOutputKind == kDynamicExecutable)
4823 && (fMacVersionMin >= ld::mac10_7) ) {
4824 fPositionIndependentExecutable = true;
d9246299 4825 }
a645023d
A
4826
4827 // armv7 for iOS4.3 defaults to PIE
4828 if ( (fArchitecture == CPU_TYPE_ARM)
afe874b1 4829 && fArchSupportsThumb2
a645023d 4830 && (fOutputKind == kDynamicExecutable)
eaf282aa 4831 && min_iOS(ld::iOS_4_3) ) {
a645023d
A
4832 fPositionIndependentExecutable = true;
4833 }
4834
0a8dc3df
A
4835 // <rdar://problem/24535196> x86_64 defaults PIE (regardless of minOS version)
4836 if ( (fArchitecture == CPU_TYPE_X86_64) && (fOutputKind == kDynamicExecutable) && (fMacVersionMin >= ld::mac10_6) )
4837 fPositionIndependentExecutable = true;
4838
599556ff
A
4839 // Simulator defaults to PIE
4840 if ( fTargetIOSSimulator && (fOutputKind == kDynamicExecutable) )
4841 fPositionIndependentExecutable = true;
4842
a645023d
A
4843 // -no_pie anywhere on command line disable PIE
4844 if ( fDisablePositionIndependentExecutable )
4845 fPositionIndependentExecutable = false;
4846
f80fe69f 4847 // arm64 is always PIE
0a8dc3df
A
4848 if ( ((fArchitecture == CPU_TYPE_ARM64)
4849 )
4850 && (fOutputKind == kDynamicExecutable) ) {
f80fe69f 4851 fPositionIndependentExecutable = true;
0a8dc3df
A
4852 if ( fDisablePositionIndependentExecutable )
4853 warning("-no_pie ignored for arm64");
f80fe69f
A
4854 }
4855
a645023d
A
4856 // set fOutputSlidable
4857 switch ( fOutputKind ) {
4858 case Options::kObjectFile:
a645023d
A
4859 fOutputSlidable = false;
4860 break;
ebf6f434 4861 case Options::kStaticExecutable:
a645023d
A
4862 case Options::kDynamicExecutable:
4863 fOutputSlidable = fPositionIndependentExecutable;
4864 break;
4865 case Options::kPreload:
4866 fOutputSlidable = fPIEOnCommandLine;
4867 break;
4868 case Options::kDyld:
4869 case Options::kDynamicLibrary:
4870 case Options::kDynamicBundle:
4871 case Options::kKextBundle:
4872 fOutputSlidable = true;
4873 break;
4874 }
4875
4876 // let linker know if thread local variables are supported
4877 if ( fMacVersionMin >= ld::mac10_7 ) {
4878 fTLVSupport = true;
4879 }
0a8dc3df
A
4880 else if ( ((fArchitecture == CPU_TYPE_ARM64)
4881 )
4882 && min_iOS(ld::iOS_8_0) ) {
eaf282aa
A
4883 fTLVSupport = true;
4884 }
4885 else if ( (fArchitecture == CPU_TYPE_ARM) && min_iOS(ld::iOS_9_0) ) {
9543cb2f
A
4886 fTLVSupport = true;
4887 }
ec29ba20
A
4888 else if ( fTargetIOSSimulator && (fArchitecture == CPU_TYPE_X86_64) && min_iOS(ld::iOS_8_0) ) {
4889 fTLVSupport = true;
4890 }
4891 else if ( fTargetIOSSimulator && (fArchitecture == CPU_TYPE_I386) && min_iOS(ld::iOS_9_0) ) {
4892 fTLVSupport = true;
4893 }
9543cb2f 4894
afe874b1 4895 // default to adding version load command for dynamic code, static code must opt-in
a645023d
A
4896 switch ( fOutputKind ) {
4897 case Options::kObjectFile:
afe874b1
A
4898 fVersionLoadCommand = false;
4899 break;
a645023d
A
4900 case Options::kStaticExecutable:
4901 case Options::kPreload:
4902 case Options::kKextBundle:
afe874b1
A
4903 if ( fVersionLoadCommandForcedOn )
4904 fVersionLoadCommand = true;
a645023d
A
4905 break;
4906 case Options::kDynamicExecutable:
4907 case Options::kDyld:
4908 case Options::kDynamicLibrary:
4909 case Options::kDynamicBundle:
afe874b1
A
4910 if ( !fVersionLoadCommandForcedOff )
4911 fVersionLoadCommand = true;
a645023d
A
4912 break;
4913 }
4914
4915 // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
afe874b1 4916 if ( (fOutputKind == kDynamicLibrary) && minOS(ld::mac10_7, ld::iOS_4_2) )
a645023d
A
4917 fCanReExportSymbols = true;
4918
4919 // ObjC optimization is only in dynamic final linked images
4920 switch ( fOutputKind ) {
4921 case Options::kObjectFile:
4922 case Options::kStaticExecutable:
4923 case Options::kPreload:
4924 case Options::kKextBundle:
4925 case Options::kDyld:
4926 fObjcCategoryMerging = false;
4927 break;
4928 case Options::kDynamicExecutable:
4929 case Options::kDynamicLibrary:
4930 case Options::kDynamicBundle:
4931 break;
4932 }
4933
4934 // i386 main executables linked on Mac OS X 10.7 default to NX heap
4935 // regardless of target unless overriden with -allow_heap_execute anywhere
4936 // on the command line
4937 if ( (fArchitecture == CPU_TYPE_I386) && (fOutputKind == kDynamicExecutable) && !fDisableNonExecutableHeap)
4938 fNonExecutableHeap = true;
ebf6f434
A
4939
4940 // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
4941 switch ( fOutputKind ) {
4942 case Options::kDynamicExecutable:
4943 if ( fEntryPointLoadCommandForceOn ) {
4944 fEntryPointLoadCommand = true;
599556ff
A
4945 if ( fEntryName == NULL )
4946 fEntryName = "_main";
ebf6f434
A
4947 }
4948 else if ( fEntryPointLoadCommandForceOff ) {
4949 fNeedsThreadLoadCommand = true;
599556ff
A
4950 if ( fEntryName == NULL )
4951 fEntryName = "start";
ebf6f434
A
4952 }
4953 else {
599556ff
A
4954 // <rdar://problem/16310363> Linker should look for "_main" not "start" when building for sim regardless of min OS
4955 if ( minOS(ld::mac10_8, ld::iOS_6_0) || fTargetIOSSimulator ) {
ebf6f434 4956 fEntryPointLoadCommand = true;
599556ff
A
4957 if ( fEntryName == NULL )
4958 fEntryName = "_main";
4959 if ( strcmp(fEntryName, "start") == 0 ) {
4960 warning("Ignoring '-e start' because entry point 'start' is not used for the targeted OS version");
4961 fEntryName = "_main";
4962 }
4963 }
4964 else {
ebf6f434 4965 fNeedsThreadLoadCommand = true;
599556ff
A
4966 if ( fEntryName == NULL )
4967 fEntryName = "start";
4968 }
ebf6f434
A
4969 }
4970 break;
4971 case Options::kObjectFile:
4972 case Options::kKextBundle:
4973 case Options::kDynamicLibrary:
4974 case Options::kDynamicBundle:
4975 break;
4976
4977 case Options::kStaticExecutable:
4978 case Options::kPreload:
4979 case Options::kDyld:
4980 fNeedsThreadLoadCommand = true;
599556ff
A
4981 if ( fEntryName == NULL )
4982 fEntryName = "start"; // Perhaps these should have no default and require -e
ebf6f434
A
4983 break;
4984 }
4985
4986 // add LC_SOURCE_VERSION
4987 switch ( fOutputKind ) {
4988 case Options::kDynamicExecutable:
4989 case Options::kKextBundle:
4990 case Options::kDynamicLibrary:
4991 case Options::kDynamicBundle:
4992 case Options::kDyld:
4993 case Options::kStaticExecutable:
4994 if ( fSourceVersionLoadCommandForceOn ) {
4995 fSourceVersionLoadCommand = true;
4996 }
4997 else if ( fSourceVersionLoadCommandForceOff ) {
4998 fSourceVersionLoadCommand = false;
4999 }
5000 else {
b1f7435d 5001 if ( minOS(ld::mac10_8, ld::iOS_6_0) ) {
ebf6f434
A
5002 fSourceVersionLoadCommand = true;
5003 }
5004 else
5005 fSourceVersionLoadCommand = false;
5006 }
5007 break;
5008 case Options::kObjectFile:
5009 case Options::kPreload:
5010 fSourceVersionLoadCommand = false;
5011 break;
5012 }
eaf282aa 5013
ebf6f434
A
5014 // if -sdk_version not on command line, infer from -syslibroot
5015 if ( (fSDKVersion == 0) && (fSDKPaths.size() > 0) ) {
5016 const char* sdkPath = fSDKPaths.front();
5017 const char* end = &sdkPath[strlen(sdkPath)-1];
5018 while ( !isdigit(*end) && (end > sdkPath) )
5019 --end;
5020 const char* start = end-1;
5021 while ( (isdigit(*start) || (*start == '.')) && (start > sdkPath))
5022 --start;
5023 char sdkVersionStr[32];
5024 int len = end-start+1;
5025 if ( len > 2 ) {
5026 strlcpy(sdkVersionStr, start+1, len);
5027 fSDKVersion = parseVersionNumber32(sdkVersionStr);
5028 }
5029 }
5030
5031 // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
5032 if ( (fSDKVersion == 0) && (fMacVersionMin != ld::macVersionUnset) ) {
5033 // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
5034 if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
5035 fSDKVersion = fMacVersionMin;
5036 }
5037 else {
5038 int mib[2] = { CTL_KERN, KERN_OSRELEASE };
5039 char kernVersStr[100];
5040 size_t strlen = sizeof(kernVersStr);
5041 if ( sysctl(mib, 2, kernVersStr, &strlen, NULL, 0) != -1 ) {
5042 uint32_t kernVers = parseVersionNumber32(kernVersStr);
5043 int minor = (kernVers >> 16) - 4; // kernel major version is 4 ahead of x in 10.x
5044 fSDKVersion = 0x000A0000 + (minor << 8);
5045 }
5046 }
5047 }
5048
f80fe69f
A
5049 // allow trie based absolute symbols if targeting new enough OS
5050 if ( fMakeCompressedDyldInfo ) {
5051 if ( minOS(ld::mac10_9, ld::iOS_7_0) ) {
eaf282aa 5052 fAbsoluteSymbols = true;
f80fe69f
A
5053 }
5054 }
5055
5056 // <rdar://problem/12959510> iOS main executables now default to 16KB page size
5057 if ( (fIOSVersionMin != ld::iOSVersionUnset) && (fOutputKind == Options::kDynamicExecutable) ) {
5058 // <rdar://problem/13070042> Only third party apps should have 16KB page segments by default
5059 if ( fEncryptable ) {
5060 if ( fSegmentAlignment == 4096 )
5061 fSegmentAlignment = 4096*4;
5062 }
5063 }
5064
5065 // <rdar://problem/12258065> ARM64 needs 16KB page size for user land code
599556ff
A
5066 // <rdar://problem/15974532> make armv7[s] use 16KB pages in user land code for iOS 8 or later
5067 if ( fSegmentAlignment == 4096 ) {
ba348e21
A
5068 switch ( fOutputKind ) {
5069 case Options::kDynamicExecutable:
5070 case Options::kDynamicLibrary:
5071 case Options::kDynamicBundle:
5072 case Options::kDyld:
0a8dc3df
A
5073 if ( ((fArchitecture == CPU_TYPE_ARM64)
5074 )
eaf282aa 5075 || ((fArchitecture == CPU_TYPE_ARM) && min_iOS(ld::iOS_7_0)) ) {
f80fe69f 5076 fSegmentAlignment = 4096*4;
ba348e21
A
5077 }
5078 break;
5079 case Options::kStaticExecutable:
5080 case Options::kKextBundle:
5081 // <rdar://problem/14676611> 16KB segments for arm64 kexts
0a8dc3df
A
5082 if ( ((fArchitecture == CPU_TYPE_ARM64)
5083 )
5084 && min_iOS(ld::iOS_9_0) ) {
ba348e21
A
5085 fSegmentAlignment = 4096*4;
5086 }
5087 break;
5088 case Options::kObjectFile:
5089 case Options::kPreload:
5090 break;
f80fe69f
A
5091 }
5092 }
599556ff 5093
ba348e21
A
5094
5095
f80fe69f
A
5096 // <rdar://problem/13624134> linker should not convert dwarf unwind if .o file has compact unwind section
5097 switch ( fOutputKind ) {
5098 case Options::kDynamicExecutable:
5099 case Options::kDynamicLibrary:
5100 case Options::kDynamicBundle:
5101 case Options::kDyld:
5102 if ( fKeepDwarfUnwindForcedOn ) {
5103 fKeepDwarfUnwind = true;
5104 }
5105 else if ( fKeepDwarfUnwindForcedOff ) {
5106 fKeepDwarfUnwind = false;
5107 }
5108 else {
5109 if ( minOS(ld::mac10_9, ld::iOS_7_0) )
5110 fKeepDwarfUnwind = false;
5111 else
5112 fKeepDwarfUnwind = true;
5113 }
5114 break;
5115 case Options::kKextBundle:
5116 case Options::kStaticExecutable:
5117 case Options::kObjectFile:
5118 case Options::kPreload:
5119 fKeepDwarfUnwind = true;
5120 break;
5121 }
5122
ba348e21
A
5123 // Make sure -image_base matches alignment
5124 uint64_t alignedBaseAddress = (fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment);
5125 if ( alignedBaseAddress != fBaseAddress ) {
5126 warning("base address 0x%llX is not properly aligned. Changing it to 0x%llX", fBaseAddress, alignedBaseAddress);
5127 fBaseAddress = alignedBaseAddress;
5128 }
5129
eaf282aa
A
5130 // If -dirty_data_list not specified, look in $SDKROOT/AppleInternal/DirtyDataFiles/<dylib>.dirty for dirty data list
5131 if ( fSymbolsMovesData.empty() && fUseDataConstSegment && ( fDylibInstallName != NULL) && !fSDKPaths.empty() ) {
5132 const char* dylibLeaf = strrchr(fDylibInstallName, '/');
5133 if ( dylibLeaf ) {
5134 char path[PATH_MAX];
5135 strlcpy(path , fSDKPaths.front(), sizeof(path));
5136 strlcat(path , "/AppleInternal/DirtyDataFiles", sizeof(path));
5137 strlcat(path , dylibLeaf, sizeof(path));
5138 strlcat(path , ".dirty", sizeof(path));
5139 FileInfo info;
5140 if ( info.checkFileExists(*this, path) )
5141 addSymbolMove("__DATA_DIRTY", path, fSymbolsMovesData, "-dirty_data_list");
5142 }
5143 }
5144
ec29ba20
A
5145 // <rdar://problem/20503811> Reduce the default alignment of structures/arrays to save memory in embedded systems
5146 if ( fMaxDefaultCommonAlign == 0 ) {
5147 if ( fOutputKind == Options::kPreload )
5148 fMaxDefaultCommonAlign = 8;
5149 else
5150 fMaxDefaultCommonAlign = 15;
5151 }
c2646906
A
5152}
5153
5154void Options::checkIllegalOptionCombinations()
5155{
5156 // check -undefined setting
5157 switch ( fUndefinedTreatment ) {
5158 case kUndefinedError:
c2646906
A
5159 // always legal
5160 break;
ec29ba20
A
5161 case kUndefinedDynamicLookup:
5162 switch (fPlatform) {
5163 case kPlatformOSX:
5164 break;
5165 case kPlatformiOS:
5166 case kPlatformWatchOS:
5167 #if SUPPORT_APPLE_TV
5168 case kPlatform_tvOS:
5169 #endif
5170 if ( fOutputKind != kKextBundle )
5171 warning("-undefined dynamic_lookup is deprecated on %s", platformName(fPlatform));
5172 break;
5173 default:
5174 break;
5175 }
5176 break;
c2646906
A
5177 case kUndefinedWarning:
5178 case kUndefinedSuppress:
5179 // requires flat namespace
5180 if ( fNameSpace == kTwoLevelNameSpace )
5181 throw "can't use -undefined warning or suppress with -twolevel_namespace";
5182 break;
5183 }
d696c285 5184
c2646906
A
5185 // unify -sub_umbrella with dylibs
5186 for (std::vector<const char*>::iterator it = fSubUmbellas.begin(); it != fSubUmbellas.end(); it++) {
5187 const char* subUmbrella = *it;
5188 bool found = false;
5189 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
5190 Options::FileInfo& info = *fit;
5191 const char* lastSlash = strrchr(info.path, '/');
5192 if ( lastSlash == NULL )
5193 lastSlash = info.path - 1;
ec29ba20
A
5194 std::string path(&lastSlash[1]);
5195 auto idx = path.find(".tbd", path.size() - 4);
5196 if (idx != std::string::npos)
5197 path.erase(idx);
5198 if ( path == subUmbrella ) {
c2646906
A
5199 info.options.fReExport = true;
5200 found = true;
ebf6f434 5201 fLinkSnapshot.recordSubUmbrella(info.path);
c2646906
A
5202 break;
5203 }
5204 }
2f2f92e4
A
5205 if ( ! found )
5206 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella);
c2646906 5207 }
d696c285 5208
c2646906
A
5209 // unify -sub_library with dylibs
5210 for (std::vector<const char*>::iterator it = fSubLibraries.begin(); it != fSubLibraries.end(); it++) {
5211 const char* subLibrary = *it;
5212 bool found = false;
5213 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
5214 Options::FileInfo& info = *fit;
5215 const char* lastSlash = strrchr(info.path, '/');
5216 if ( lastSlash == NULL )
5217 lastSlash = info.path - 1;
69a49097 5218 const char* dot = strchr(&lastSlash[1], '.');
c2646906
A
5219 if ( dot == NULL )
5220 dot = &lastSlash[strlen(lastSlash)];
5221 if ( strncmp(&lastSlash[1], subLibrary, dot-lastSlash-1) == 0 ) {
5222 info.options.fReExport = true;
5223 found = true;
ebf6f434 5224 fLinkSnapshot.recordSubLibrary(info.path);
c2646906
A
5225 break;
5226 }
5227 }
2f2f92e4
A
5228 if ( ! found )
5229 warning("-sub_library %s does not match a supplied dylib", subLibrary);
c2646906 5230 }
d696c285 5231
c2646906 5232 // sync reader options
ec29ba20 5233 if ( fNameSpace != kTwoLevelNameSpace ) {
a645023d 5234 fFlatNamespace = true;
ec29ba20
A
5235 switch (fPlatform) {
5236 case kPlatformOSX:
5237 break;
5238 case kPlatformiOS:
5239 case kPlatformWatchOS:
5240 #if SUPPORT_APPLE_TV
5241 case Options::kPlatform_tvOS:
5242 #endif
5243 warning("-flat_namespace is deprecated on %s", platformName(fPlatform));
5244 break;
5245 default:
5246 break;
5247 }
5248 }
5249
c2646906
A
5250
5251 // check -stack_addr
d696c285 5252 if ( fStackAddr != 0 ) {
c2646906
A
5253 switch (fArchitecture) {
5254 case CPU_TYPE_I386:
2f2f92e4 5255 case CPU_TYPE_ARM:
d696c285 5256 if ( fStackAddr > 0xFFFFFFFF )
c2646906
A
5257 throw "-stack_addr must be < 4G for 32-bit processes";
5258 break;
69a49097 5259 case CPU_TYPE_X86_64:
f80fe69f 5260 case CPU_TYPE_ARM64:
c2646906
A
5261 break;
5262 }
5263 if ( (fStackAddr & -4096) != fStackAddr )
5264 throw "-stack_addr must be multiples of 4K";
5265 if ( fStackSize == 0 )
5266 throw "-stack_addr must be used with -stack_size";
5267 }
d696c285 5268
c2646906 5269 // check -stack_size
d696c285 5270 if ( fStackSize != 0 ) {
c2646906
A
5271 switch (fArchitecture) {
5272 case CPU_TYPE_I386:
ec29ba20
A
5273 if ( fPlatform == kPlatformOSX ) {
5274 if ( fStackSize > 0xFFFFFFFF )
5275 throw "-stack_size must be < 4GB for 32-bit processes";
5276 if ( fStackAddr == 0 )
5277 fStackAddr = 0xC0000000;
5278 if ( (fStackAddr > 0xB0000000) && ((fStackAddr-fStackSize) < 0xB0000000) )
5279 warning("custom stack placement overlaps and will disable shared region");
5280 }
5281 else {
5282 if ( fStackSize > 0x1F000000 )
5283 throw "-stack_size must be < 496MB";
5284 if ( fStackAddr == 0 )
5285 fStackAddr = 0xC0000000;
c2646906
A
5286 }
5287 break;
2f2f92e4 5288 case CPU_TYPE_ARM:
ec29ba20
A
5289 if ( fStackSize > 0x1F000000 )
5290 throw "-stack_size must be < 496MB";
2f2f92e4 5291 if ( fStackAddr == 0 )
ec29ba20
A
5292 fStackAddr = 0x1F000000;
5293 if ( fStackAddr > 0x20000000)
5294 throw "-stack_addr must be < 0x20000000 for arm";
f80fe69f 5295 break;
69a49097 5296 case CPU_TYPE_X86_64:
ec29ba20
A
5297 if ( fPlatform == kPlatformOSX ) {
5298 if ( fStackSize > 0x10000000000 )
5299 throw "-stack_size must be <= 1TB";
5300 if ( fStackAddr == 0 ) {
5301 fStackAddr = 0x00007FFF5C000000LL;
5302 }
5303 }
5304 else {
5305 if ( fStackSize > 0x20000000 )
5306 throw "-stack_size must be <= 512MB";
5307 if ( fStackAddr == 0 ) {
5308 fStackAddr = 0x120000000;
c2646906
A
5309 }
5310 break;
f80fe69f
A
5311 case CPU_TYPE_ARM64:
5312 if ( fStackSize > 0x20000000 )
ec29ba20
A
5313 throw "-stack_size must be <= 512MB";
5314 if ( fStackAddr == 0 )
f80fe69f
A
5315 fStackAddr = 0x120000000;
5316 }
5317 break;
c2646906 5318 }
ec29ba20
A
5319 if ( (fStackSize & (-fSegmentAlignment)) != fStackSize )
5320 throwf("-stack_size must be multiple of segment alignment (%lldKB)", fSegmentAlignment/1024);
c2646906
A
5321 switch ( fOutputKind ) {
5322 case Options::kDynamicExecutable:
5323 case Options::kStaticExecutable:
d696c285 5324 // custom stack size only legal when building main executable
c2646906
A
5325 break;
5326 case Options::kDynamicLibrary:
5327 case Options::kDynamicBundle:
5328 case Options::kObjectFile:
5329 case Options::kDyld:
55e3d2f6
A
5330 case Options::kPreload:
5331 case Options::kKextBundle:
c2646906
A
5332 throw "-stack_size option can only be used when linking a main executable";
5333 }
a645023d
A
5334 if ( fStackSize > fStackAddr )
5335 throwf("-stack_size (0x%08llX) must be smaller than -stack_addr (0x%08llX)", fStackSize, fStackAddr);
c2646906 5336 }
d696c285
A
5337
5338 // check that -allow_stack_execute is only used with main executables
5339 if ( fExecutableStack ) {
5340 switch ( fOutputKind ) {
5341 case Options::kDynamicExecutable:
5342 case Options::kStaticExecutable:
5343 // -allow_stack_execute size only legal when building main executable
5344 break;
5345 case Options::kDynamicLibrary:
5346 case Options::kDynamicBundle:
5347 case Options::kObjectFile:
5348 case Options::kDyld:
55e3d2f6
A
5349 case Options::kPreload:
5350 case Options::kKextBundle:
d696c285
A
5351 throw "-allow_stack_execute option can only be used when linking a main executable";
5352 }
5353 }
5354
a645023d
A
5355 // check that -allow_heap_execute is only used with i386 main executables
5356 if ( fDisableNonExecutableHeap ) {
5357 if ( fArchitecture != CPU_TYPE_I386 )
5358 throw "-allow_heap_execute option can only be used when linking for i386";
5359 switch ( fOutputKind ) {
5360 case Options::kDynamicExecutable:
5361 // -allow_heap_execute only legal when building main executable
5362 break;
5363 case Options::kStaticExecutable:
5364 case Options::kDynamicLibrary:
5365 case Options::kDynamicBundle:
5366 case Options::kObjectFile:
5367 case Options::kDyld:
5368 case Options::kPreload:
5369 case Options::kKextBundle:
5370 throw "-allow_heap_execute option can only be used when linking a main executable";
5371 }
5372 }
5373
a61fdf0a
A
5374 // check -client_name is only used when making a bundle or main executable
5375 if ( fClientName != NULL ) {
5376 switch ( fOutputKind ) {
5377 case Options::kDynamicExecutable:
5378 case Options::kDynamicBundle:
5379 break;
5380 case Options::kStaticExecutable:
5381 case Options::kDynamicLibrary:
5382 case Options::kObjectFile:
5383 case Options::kDyld:
55e3d2f6
A
5384 case Options::kPreload:
5385 case Options::kKextBundle:
a61fdf0a
A
5386 throw "-client_name can only be used with -bundle";
5387 }
5388 }
5389
c2646906
A
5390 // check -init is only used when building a dylib
5391 if ( (fInitFunctionName != NULL) && (fOutputKind != Options::kDynamicLibrary) )
5392 throw "-init can only be used with -dynamiclib";
c2646906 5393
69a49097
A
5394 // check -bundle_loader only used with -bundle
5395 if ( (fBundleLoader != NULL) && (fOutputKind != Options::kDynamicBundle) )
5396 throw "-bundle_loader can only be used with -bundle";
5397
a61fdf0a
A
5398 // check -dtrace not used with -r
5399 if ( (fDtraceScriptName != NULL) && (fOutputKind == Options::kObjectFile) )
5400 throw "-dtrace can only be used when creating final linked images";
5401
69a49097 5402 // check -d can only be used with -r
a645023d 5403 if ( fMakeTentativeDefinitionsReal && (fOutputKind != Options::kObjectFile) )
69a49097 5404 throw "-d can only be used with -r";
a61fdf0a
A
5405
5406 // check that -root_safe is not used with -r
a645023d 5407 if ( fRootSafe && (fOutputKind == Options::kObjectFile) )
a61fdf0a
A
5408 throw "-root_safe cannot be used with -r";
5409
5410 // check that -setuid_safe is not used with -r
a645023d 5411 if ( fSetuidSafe && (fOutputKind == Options::kObjectFile) )
a61fdf0a
A
5412 throw "-setuid_safe cannot be used with -r";
5413
f80fe69f
A
5414 // <rdar://problem/12781832> compiler driver no longer uses -objc_abi_version, it uses -ios_simulator_version_min instead
5415 if ( !fObjCABIVersion1Override && !fObjCABIVersion2Override && fTargetIOSSimulator )
5416 fObjCABIVersion2Override = true;
5417
a645023d
A
5418 // rdar://problem/4718189 map ObjC class names to new runtime names
5419 bool alterObjC1ClassNamesToObjC2 = false;
5420 switch (fArchitecture) {
5421 case CPU_TYPE_I386:
5422 // i386 only uses new symbols when using objc2 ABI
5423 if ( fObjCABIVersion2Override )
5424 alterObjC1ClassNamesToObjC2 = true;
5425 break;
a645023d
A
5426 case CPU_TYPE_X86_64:
5427 case CPU_TYPE_ARM:
f80fe69f 5428 case CPU_TYPE_ARM64:
a645023d
A
5429 alterObjC1ClassNamesToObjC2 = true;
5430 break;
5431 }
5432
d696c285 5433 // make sure all required exported symbols exist
a61fdf0a 5434 std::vector<const char*> impliedExports;
a645023d 5435 for (NameSet::iterator it=fExportSymbols.regularBegin(); it != fExportSymbols.regularEnd(); ++it) {
d696c285 5436 const char* name = *it;
a61fdf0a 5437 const int len = strlen(name);
a645023d
A
5438 if ( (strcmp(&name[len-3], ".eh") == 0) || (strncmp(name, ".objc_category_name_", 20) == 0) ) {
5439 // never export .eh symbols
2f2f92e4 5440 warning("ignoring %s in export list", name);
a645023d
A
5441 }
5442 else if ( (fArchitecture == CPU_TYPE_I386) && !fObjCABIVersion2Override && (strncmp(name, "_OBJC_CLASS_$", 13) == 0) ) {
5443 warning("ignoring Objc2 Class symbol %s in i386 export list", name);
5444 fRemovedExports.insert(name);
5445 }
5446 else if ( alterObjC1ClassNamesToObjC2 && (strncmp(name, ".objc_class_name_", 17) == 0) ) {
5447 // linking ObjC2 ABI, but have ObjC1 ABI name in export list. Change it to intended name
5448 fRemovedExports.insert(name);
5449 char* temp;
5450 asprintf(&temp, "_OBJC_CLASS_$_%s", &name[17]);
5451 impliedExports.push_back(temp);
5452 asprintf(&temp, "_OBJC_METACLASS_$_%s", &name[17]);
5453 impliedExports.push_back(temp);
5454 }
5455 else {
d696c285 5456 fInitialUndefines.push_back(name);
a61fdf0a 5457 }
d696c285 5458 }
a645023d
A
5459 fExportSymbols.remove(fRemovedExports);
5460 for (std::vector<const char*>::iterator it=impliedExports.begin(); it != impliedExports.end(); ++it) {
a61fdf0a
A
5461 const char* name = *it;
5462 fExportSymbols.insert(name);
5463 fInitialUndefines.push_back(name);
5464 }
5465
a645023d
A
5466 // make sure all required re-exported symbols exist
5467 for (NameSet::iterator it=fReExportSymbols.regularBegin(); it != fReExportSymbols.regularEnd(); ++it) {
5468 fInitialUndefines.push_back(*it);
5469 }
5470
afe874b1 5471 // make sure that -init symbol exists
69a49097
A
5472 if ( fInitFunctionName != NULL )
5473 fInitialUndefines.push_back(fInitFunctionName);
5474
afe874b1
A
5475 // make sure that entry symbol exists
5476 switch ( fOutputKind ) {
5477 case Options::kDynamicExecutable:
5478 case Options::kStaticExecutable:
5479 case Options::kDyld:
5480 case Options::kPreload:
5481 fInitialUndefines.push_back(fEntryName);
5482 break;
5483 case Options::kDynamicLibrary:
5484 case Options::kDynamicBundle:
5485 case Options::kObjectFile:
5486 case Options::kKextBundle:
5487 break;
5488 }
5489
a645023d
A
5490 // make sure every alias base exists
5491 for (std::vector<AliasPair>::iterator it=fAliases.begin(); it != fAliases.end(); ++it) {
5492 fInitialUndefines.push_back(it->realName);
5493 }
5494
a61fdf0a
A
5495 // check custom segments
5496 if ( fCustomSegmentAddresses.size() != 0 ) {
5497 // verify no segment is in zero page
5498 if ( fZeroPageSize != ULLONG_MAX ) {
5499 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
a645023d 5500 if ( it->address < fZeroPageSize )
fb24a050 5501 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it->name, it->address);
a61fdf0a
A
5502 }
5503 }
5504 // verify no duplicates
5505 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
5506 for (std::vector<SegmentStart>::iterator it2 = fCustomSegmentAddresses.begin(); it2 != fCustomSegmentAddresses.end(); ++it2) {
5507 if ( (it->address == it2->address) && (it != it2) )
5508 throwf("duplicate -segaddr addresses for %s and %s", it->name, it2->name);
5509 }
5510 // a custom segment address of zero will disable the use of a zero page
5511 if ( it->address == 0 )
5512 fZeroPageSize = 0;
5513 }
5514 }
5515
69a49097
A
5516 if ( fZeroPageSize == ULLONG_MAX ) {
5517 // zero page size not specified on command line, set default
5518 switch (fArchitecture) {
5519 case CPU_TYPE_I386:
0a8dc3df 5520 case CPU_TYPE_ARM:
69a49097
A
5521 // first 4KB for 32-bit architectures
5522 fZeroPageSize = 0x1000;
5523 break;
f80fe69f 5524 case CPU_TYPE_ARM64:
69a49097
A
5525 case CPU_TYPE_X86_64:
5526 // first 4GB for x86_64 on all OS's
5527 fZeroPageSize = 0x100000000ULL;
5528 break;
5529 default:
5530 // if -arch not used, default to 4K zero-page
5531 fZeroPageSize = 0x1000;
5532 }
5533 }
5534 else {
5535 switch ( fOutputKind ) {
5536 case Options::kDynamicExecutable:
5537 case Options::kStaticExecutable:
5538 // -pagezero_size size only legal when building main executable
5539 break;
5540 case Options::kDynamicLibrary:
5541 case Options::kDynamicBundle:
5542 case Options::kObjectFile:
5543 case Options::kDyld:
55e3d2f6
A
5544 case Options::kPreload:
5545 case Options::kKextBundle:
a61fdf0a
A
5546 if ( fZeroPageSize != 0 )
5547 throw "-pagezero_size option can only be used when linking a main executable";
5548 }
69a49097
A
5549 }
5550
a645023d
A
5551 // if main executable with custom base address, model zero page as custom segment
5552 if ( (fOutputKind == Options::kDynamicExecutable) && (fBaseAddress != 0) && (fZeroPageSize != 0) ) {
5553 SegmentStart seg;
5554 seg.name = "__PAGEZERO";
5555 seg.address = 0;;
5556 fCustomSegmentAddresses.push_back(seg);
5557 }
5558
69a49097 5559 // -dead_strip and -r are incompatible
a645023d 5560 if ( fDeadStrip && (fOutputKind == Options::kObjectFile) )
2f2f92e4 5561 throw "-r and -dead_strip cannot be used together";
c2646906 5562
a61fdf0a
A
5563 // can't use -rpath unless targeting 10.5 or later
5564 if ( fRPaths.size() > 0 ) {
afe874b1 5565 if ( !minOS(ld::mac10_5, ld::iOS_2_0) )
2f2f92e4 5566 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
a61fdf0a
A
5567 switch ( fOutputKind ) {
5568 case Options::kDynamicExecutable:
5569 case Options::kDynamicLibrary:
5570 case Options::kDynamicBundle:
5571 break;
5572 case Options::kStaticExecutable:
5573 case Options::kObjectFile:
5574 case Options::kDyld:
55e3d2f6
A
5575 case Options::kPreload:
5576 case Options::kKextBundle:
a61fdf0a
A
5577 throw "-rpath can only be used when creating a dynamic final linked image";
5578 }
5579 }
5580
a61fdf0a 5581 if ( fPositionIndependentExecutable ) {
55e3d2f6
A
5582 switch ( fOutputKind ) {
5583 case Options::kDynamicExecutable:
ebf6f434 5584 // check -pie is only used when building a dynamic main executable for 10.5
afe874b1
A
5585 if ( !minOS(ld::mac10_5, ld::iOS_4_2) ) {
5586 if ( fIOSVersionMin == ld::iOSVersionUnset )
a645023d
A
5587 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
5588 else
5589 throw "-pie can only be used when targeting iOS 4.2 or later";
5590 }
d9246299 5591 break;
ebf6f434 5592 case Options::kStaticExecutable:
55e3d2f6 5593 case Options::kPreload:
ebf6f434 5594 // -pie is ok with -static or -preload
55e3d2f6
A
5595 break;
5596 case Options::kDynamicLibrary:
5597 case Options::kDynamicBundle:
5598 warning("-pie being ignored. It is only used when linking a main executable");
a645023d 5599 fPositionIndependentExecutable = false;
55e3d2f6 5600 break;
55e3d2f6
A
5601 case Options::kObjectFile:
5602 case Options::kDyld:
5603 case Options::kKextBundle:
5604 throw "-pie can only be used when linking a main executable";
5605 }
a61fdf0a 5606 }
55e3d2f6
A
5607
5608 // check -read_only_relocs is not used with x86_64
5609 if ( fAllowTextRelocs ) {
5610 if ( (fArchitecture == CPU_TYPE_X86_64) && (fOutputKind != kKextBundle) ) {
5611 warning("-read_only_relocs cannot be used with x86_64");
5612 fAllowTextRelocs = false;
5613 }
5614 }
5615
5616 // check -mark_auto_dead_strip is only used with dylibs
5617 if ( fMarkDeadStrippableDylib ) {
5618 if ( fOutputKind != Options::kDynamicLibrary ) {
5619 warning("-mark_auto_dead_strip can only be used when creating a dylib");
5620 fMarkDeadStrippableDylib = false;
5621 }
5622 }
5623
4be885f6
A
5624 // -force_cpusubtype_ALL is not supported for ARM
5625 if ( fForceSubtypeAll ) {
5626 if ( fArchitecture == CPU_TYPE_ARM ) {
5627 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
5628 }
5629 }
a645023d
A
5630
5631 // -reexported_symbols_list can only be used with -dynamiclib
5632 if ( !fReExportSymbols.empty() ) {
5633 if ( fOutputKind != Options::kDynamicLibrary )
5634 throw "-reexported_symbols_list can only used used when created dynamic libraries";
afe874b1 5635 if ( !minOS(ld::mac10_7, ld::iOS_4_2) )
a645023d
A
5636 throw "targeted OS version does not support -reexported_symbols_list";
5637 }
5638
5639 // -dyld_env can only be used with main executables
5640 if ( (fOutputKind != Options::kDynamicExecutable) && (fDyldEnvironExtras.size() != 0) )
5641 throw "-dyld_env can only used used when created main executables";
9543cb2f 5642
0a8dc3df
A
5643 // -segment_order can only be used with -preload or -static
5644 if ( !fSegmentOrder.empty() && ((fOutputKind != Options::kPreload) && (fOutputKind != kStaticExecutable)) )
599556ff
A
5645 throw "-segment_order can only used used with -preload output";
5646
fb9a160c
A
5647 // warn about bitcode option combinations
5648 if ( !fBundleBitcode ) {
5649 if ( fVerifyBitcode )
5650 warning("-bitcode_verify is ignored without -bitcode_bundle");
5651 else if ( fHideSymbols )
5652 warning("-bitcode_hide_symbols is ignored without -bitcode_bundle");
5653 }
5654 if ( fReverseMapPath != NULL && !fHideSymbols ) {
5655 throw "-bitcode_symbol_map can only be used with -bitcode_hide_symbols";
5656 }
ec29ba20
A
5657 // auto fix up the process type for strip -S.
5658 // when there is only one input and output type is object file, downgrade kBitcodeProcess to kBitcodeAsData.
5659 if ( fOutputKind == Options::kObjectFile && fInputFiles.size() == 1 && fBitcodeKind == Options::kBitcodeProcess )
5660 fBitcodeKind = Options::kBitcodeAsData;
fb9a160c 5661
599556ff 5662 // <rdar://problem/17598404> warn if building an embedded iOS dylib for pre-iOS 8
ec29ba20 5663 // <rdar://problem/18935714> How can we suppress "ld: warning: embedded dylibs/frameworks only run on iOS 8 or later" when building XCTest?
599556ff 5664 if ( (fOutputKind == Options::kDynamicLibrary) && (fIOSVersionMin != ld::iOSVersionUnset) && (fDylibInstallName != NULL) ) {
eaf282aa 5665 if ( !min_iOS(ld::iOS_8_0) && (fDylibInstallName[0] == '@') && !fEncryptableForceOff )
599556ff
A
5666 warning("embedded dylibs/frameworks only run on iOS 8 or later");
5667 }
0a8dc3df
A
5668
5669
5670 // produce nicer error when no input
5671 if ( fInputFiles.empty() ) {
5672 throw "no object files specified";
5673 }
55e3d2f6 5674}
74cfe461
A
5675
5676
a61fdf0a
A
5677void Options::checkForClassic(int argc, const char* argv[])
5678{
5679 // scan options
5680 bool archFound = false;
5681 bool staticFound = false;
5682 bool dtraceFound = false;
55e3d2f6 5683 bool kextFound = false;
a61fdf0a
A
5684 bool rFound = false;
5685 bool creatingMachKernel = false;
5686 bool newLinker = false;
55e3d2f6
A
5687
5688 // build command line buffer in case ld crashes
ebf6f434
A
5689#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
5690 CRSetCrashLogMessage(crashreporterBuffer);
5691#endif
a645023d
A
5692 const char* srcRoot = getenv("SRCROOT");
5693 if ( srcRoot != NULL ) {
5694 strlcpy(crashreporterBuffer, "SRCROOT=", crashreporterBufferSize);
5695 strlcat(crashreporterBuffer, srcRoot, crashreporterBufferSize);
5696 strlcat(crashreporterBuffer, "\n", crashreporterBufferSize);
5697 }
5698#ifdef LD_VERS
5699 strlcat(crashreporterBuffer, LD_VERS, crashreporterBufferSize);
5700 strlcat(crashreporterBuffer, "\n", crashreporterBufferSize);
5701#endif
5702 strlcat(crashreporterBuffer, "ld ", crashreporterBufferSize);
55e3d2f6 5703 for(int i=1; i < argc; ++i) {
a645023d
A
5704 strlcat(crashreporterBuffer, argv[i], crashreporterBufferSize);
5705 strlcat(crashreporterBuffer, " ", crashreporterBufferSize);
55e3d2f6 5706 }
74cfe461 5707
a61fdf0a
A
5708 for(int i=0; i < argc; ++i) {
5709 const char* arg = argv[i];
5710 if ( arg[0] == '-' ) {
5711 if ( strcmp(arg, "-arch") == 0 ) {
5712 parseArch(argv[++i]);
5713 archFound = true;
5714 }
5715 else if ( strcmp(arg, "-static") == 0 ) {
5716 staticFound = true;
5717 }
55e3d2f6
A
5718 else if ( strcmp(arg, "-kext") == 0 ) {
5719 kextFound = true;
5720 }
a61fdf0a
A
5721 else if ( strcmp(arg, "-dtrace") == 0 ) {
5722 dtraceFound = true;
5723 }
5724 else if ( strcmp(arg, "-r") == 0 ) {
5725 rFound = true;
5726 }
5727 else if ( strcmp(arg, "-new_linker") == 0 ) {
5728 newLinker = true;
5729 }
5730 else if ( strcmp(arg, "-classic_linker") == 0 ) {
5731 // ld_classic does not understand this option, so remove it
5732 for(int j=i; j < argc; ++j)
5733 argv[j] = argv[j+1];
b2fa67a8 5734 warning("using ld_classic");
a61fdf0a
A
5735 this->gotoClassicLinker(argc-1, argv);
5736 }
5737 else if ( strcmp(arg, "-o") == 0 ) {
5738 const char* outfile = argv[++i];
5739 if ( (outfile != NULL) && (strstr(outfile, "/mach_kernel") != NULL) )
5740 creatingMachKernel = true;
5741 }
5742 }
5743 }
a61fdf0a
A
5744}
5745
5746void Options::gotoClassicLinker(int argc, const char* argv[])
5747{
5748 argv[0] = "ld_classic";
afe874b1
A
5749 // ld_classic does not support -iphoneos_version_min, so change
5750 for(int j=0; j < argc; ++j) {
5751 if ( (strcmp(argv[j], "-iphoneos_version_min") == 0) || (strcmp(argv[j], "-ios_version_min") == 0) ) {
5752 argv[j] = "-macosx_version_min";
5753 if ( j < argc-1 )
5754 argv[j+1] = "10.5";
5755 break;
5756 }
5757 }
5758 // ld classic does not understand -kext (change to -static -r)
5759 for(int j=0; j < argc; ++j) {
5760 if ( strcmp(argv[j], "-kext") == 0)
5761 argv[j] = "-r";
5762 else if ( strcmp(argv[j], "-dynamic") == 0)
5763 argv[j] = "-static";
5764 }
5765 // ld classic does not understand -demangle
5766 for(int j=0; j < argc; ++j) {
5767 if ( strcmp(argv[j], "-demangle") == 0)
5768 argv[j] = "-noprebind";
5769 }
a645023d
A
5770 // in -v mode, print command line passed to ld_classic
5771 for(int i=0; i < argc; ++i) {
5772 if ( strcmp(argv[i], "-v") == 0 ) {
5773 for(int j=0; j < argc; ++j)
5774 printf("%s ", argv[j]);
5775 printf("\n");
5776 break;
5777 }
5778 }
fb24a050 5779 char rawPath[PATH_MAX];
55e3d2f6
A
5780 char path[PATH_MAX];
5781 uint32_t bufSize = PATH_MAX;
fb24a050
A
5782 if ( _NSGetExecutablePath(rawPath, &bufSize) != -1 ) {
5783 if ( realpath(rawPath, path) != NULL ) {
5784 char* lastSlash = strrchr(path, '/');
5785 if ( lastSlash != NULL ) {
5786 strcpy(lastSlash+1, "ld_classic");
5787 argv[0] = path;
5788 execvp(path, (char**)argv);
5789 }
55e3d2f6
A
5790 }
5791 }
5792 // in case of error in above, try searching for ld_classic via PATH
a61fdf0a
A
5793 execvp(argv[0], (char**)argv);
5794 fprintf(stderr, "can't exec ld_classic\n");
5795 exit(1);
5796}
ebf6f434
A
5797
5798
5799// Note, returned string buffer is own by this function.
5800// It should not be freed
5801// It will be reused, so clients need to strdup() if they want
5802// to use it long term.
5803const char* Options::demangleSymbol(const char* sym) const
5804{
5805 // only try to demangle symbols if -demangle on command line
5806 if ( !fDemangle )
5807 return sym;
5808
eaf282aa
A
5809 static size_t size = 1024;
5810 static char* buff = (char*)malloc(size);
5811
5812#if DEMANGLE_SWIFT
5813 // only try to demangle symbols that look like Swift symbols
5814 if ( strncmp(sym, "__T", 3) == 0 ) {
5815 size_t demangledSize = fnd_get_demangled_name(&sym[1], buff, size);
5816 if ( demangledSize > size ) {
5817 size = demangledSize+2;
5818 buff = (char*)realloc(buff, size);
5819 demangledSize = fnd_get_demangled_name(&sym[1], buff, size);
5820 }
5821 if ( demangledSize != 0 )
5822 return buff;
5823 }
5824#endif
5825
ebf6f434
A
5826 // only try to demangle symbols that look like C++ symbols
5827 if ( strncmp(sym, "__Z", 3) != 0 )
5828 return sym;
5829
ebf6f434 5830 int status;
ebf6f434
A
5831 char* result = abi::__cxa_demangle(&sym[1], buff, &size, &status);
5832 if ( result != NULL ) {
5833 // if demangling successful, keep buffer for next demangle
5834 buff = result;
5835 return buff;
5836 }
5837 return sym;
5838}
5839
f80fe69f
A
5840
5841void Options::dumpDependency(uint8_t opcode, const char* path) const
5842{
5843 if ( !this->dumpDependencyInfo() )
5844 return;
5845
5846 // one time open() of -dependency_info file
5847 if ( fDependencyFileDescriptor == -1 ) {
5848 fDependencyFileDescriptor = open(this->dependencyInfoPath(), O_WRONLY | O_TRUNC | O_CREAT, 0666);
5849 if ( fDependencyFileDescriptor == -1 )
5850 throwf("Could not open or create -dependency_info file: %s", this->dependencyInfoPath());
5851
5852 // write header
5853 uint8_t version = depLinkerVersion;
5854 if ( write(fDependencyFileDescriptor, &version, 1) == -1 )
5855 throwf("write() to -dependency_info failed, errno=%d", errno);
5856 extern const char ldVersionString[];
5857 if ( write(fDependencyFileDescriptor, ldVersionString, strlen(ldVersionString)+1) == -1 )
5858 throwf("write() to -dependency_info failed, errno=%d", errno);
5859 }
5860
5861 char realPath[PATH_MAX];
5862 if ( path[0] != '/' ) {
5863 if ( realpath(path, realPath) != NULL ) {
5864 path = realPath;
5865 }
5866 }
5867
5868 if ( write(fDependencyFileDescriptor, &opcode, 1) == -1 )
5869 throwf("write() to -dependency_info failed, errno=%d", errno);
5870 if ( write(fDependencyFileDescriptor, path, strlen(path)+1) == -1 )
5871 throwf("write() to -dependency_info failed, errno=%d", errno);
5872
5873 //fprintf(stderr, "0x%02X %s\n", opcode, path);
5874}
5875
5876
82b4b32b
A
5877void Options::writeToTraceFile(const char* buffer, size_t len) const
5878{
5879 // one time open() of custom LD_TRACE_FILE
5880 if ( fTraceFileDescriptor == -1 ) {
5881 if ( fTraceOutputFile != NULL ) {
5882 fTraceFileDescriptor = open(fTraceOutputFile, O_WRONLY | O_APPEND | O_CREAT, 0666);
5883 if ( fTraceFileDescriptor == -1 )
5884 throwf("Could not open or create trace file (errno=%d): %s", errno, fTraceOutputFile);
5885 }
5886 else {
5887 fTraceFileDescriptor = fileno(stderr);
5888 }
5889 }
5890
5891 while (len > 0) {
5892 ssize_t amountWritten = write(fTraceFileDescriptor, buffer, len);
5893 if ( amountWritten == -1 )
5894 /* Failure to write shouldn't fail the build. */
5895 return;
5896 buffer += amountWritten;
5897 len -= amountWritten;
5898 }
5899}
5900
f80fe69f 5901