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