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