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