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