]> git.saurik.com Git - apple/ld64.git/blob - src/ld/Options.cpp
ld64-253.6.tar.gz
[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 if ( symbolStart != NULL ) {
1783 char* objFileName = NULL;
1784 char* colon = strstr(symbolStart, ".o:");
1785 if ( colon != NULL ) {
1786 colon[2] = '\0';
1787 objFileName = symbolStart;
1788 symbolStart = &colon[3];
1789 }
1790 else {
1791 colon = strstr(symbolStart, ".o):");
1792 if ( colon != NULL ) {
1793 colon[3] = '\0';
1794 objFileName = symbolStart;
1795 symbolStart = &colon[4];
1796 }
1797 }
1798 // trim leading spaces
1799 while ( isspace(*symbolStart) )
1800 ++symbolStart;
1801 Options::OrderedSymbol pair;
1802 if ( cstring )
1803 pair.symbolName = cstringSymbolName(symbolStart);
1804 else
1805 pair.symbolName = symbolStart;
1806 pair.objectFileName = objFileName;
1807 fOrderedSymbols.push_back(pair);
1808 }
1809 symbolStart = NULL;
1810 if ( wasComment )
1811 state = inComment;
1812 else
1813 state = lineStart;
1814 }
1815 break;
1816 case inComment:
1817 if ( *s == '\n' )
1818 state = lineStart;
1819 break;
1820 }
1821 }
1822 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1823 }
1824
1825 void Options::parseSectionOrderFile(const char* segment, const char* section, const char* path)
1826 {
1827 if ( (strcmp(section, "__cstring") == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1828 parseOrderFile(path, true);
1829 }
1830 else if ( (strncmp(section, "__literal",9) == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1831 warning("sorting of __literal[4,8,16] sections not supported");
1832 }
1833 else {
1834 // ignore section information and append all symbol names to global order file
1835 parseOrderFile(path, false);
1836 }
1837 }
1838
1839 void Options::addSection(const char* segment, const char* section, const char* path)
1840 {
1841 if ( strlen(segment) > 16 )
1842 throw "-seccreate segment name max 16 chars";
1843 if ( strlen(section) > 16 ) {
1844 char* tmp = strdup(section);
1845 tmp[16] = '\0';
1846 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section, tmp);
1847 section = tmp;
1848 }
1849
1850 // read in whole file
1851 int fd = ::open(path, O_RDONLY, 0);
1852 if ( fd == -1 )
1853 throwf("can't open -sectcreate file: %s", path);
1854 struct stat stat_buf;
1855 ::fstat(fd, &stat_buf);
1856 char* p = (char*)malloc(stat_buf.st_size);
1857 if ( p == NULL )
1858 throwf("can't process -sectcreate file: %s", path);
1859 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1860 throwf("can't read -sectcreate file: %s", path);
1861 ::close(fd);
1862
1863 // record section to create
1864 ExtraSection info = { segment, section, path, (uint8_t*)p, (uint64_t)stat_buf.st_size };
1865 fExtraSections.push_back(info);
1866 }
1867
1868 void Options::addSectionRename(const char* srcSegment, const char* srcSection, const char* dstSegment, const char* dstSection)
1869 {
1870 if ( strlen(srcSegment) > 16 )
1871 throw "-rename_section segment name max 16 chars";
1872 if ( strlen(srcSection) > 16 )
1873 throw "-rename_section section name max 16 chars";
1874 if ( strlen(dstSegment) > 16 )
1875 throw "-rename_section segment name max 16 chars";
1876 if ( strlen(dstSection) > 16 )
1877 throw "-rename_section section name max 16 chars";
1878
1879 SectionRename info;
1880 info.fromSegment = srcSegment;
1881 info.fromSection = srcSection;
1882 info.toSegment = dstSegment;
1883 info.toSection = dstSection;
1884
1885 fSectionRenames.push_back(info);
1886 }
1887
1888
1889 void Options::addSegmentRename(const char* srcSegment, const char* dstSegment)
1890 {
1891 if ( strlen(srcSegment) > 16 )
1892 throw "-rename_segment segment name max 16 chars";
1893 if ( strlen(dstSegment) > 16 )
1894 throw "-rename_segment segment name max 16 chars";
1895
1896 SegmentRename info;
1897 info.fromSegment = srcSegment;
1898 info.toSegment = dstSegment;
1899
1900 fSegmentRenames.push_back(info);
1901 }
1902
1903
1904
1905 void Options::addSymbolMove(const char* dstSegment, const char* symbolList,
1906 std::vector<SymbolsMove>& list, const char* optionName)
1907 {
1908 if ( strlen(dstSegment) > 16 )
1909 throwf("%s segment name max 16 chars", optionName);
1910
1911 SymbolsMove tmp;
1912 list.push_back(tmp);
1913 SymbolsMove& info = list.back();
1914 info.toSegment = dstSegment;
1915 loadExportFile(symbolList, optionName, info.symbols);
1916 }
1917
1918 bool Options::moveRwSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const
1919 {
1920 for (std::vector<SymbolsMove>::const_iterator it=fSymbolsMovesData.begin(); it != fSymbolsMovesData.end(); ++it) {
1921 const SymbolsMove& info = *it;
1922 if ( info.symbols.containsWithPrefix(symName, filePath, wildCardMatch)) {
1923 seg = info.toSegment;
1924 return true;
1925 }
1926 }
1927 return false;
1928 }
1929
1930 bool Options::moveRoSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const
1931 {
1932 for (std::vector<SymbolsMove>::const_iterator it=fSymbolsMovesCode.begin(); it != fSymbolsMovesCode.end(); ++it) {
1933 const SymbolsMove& info = *it;
1934 if ( info.symbols.containsWithPrefix(symName, filePath, wildCardMatch)) {
1935 seg = info.toSegment;
1936 return true;
1937 }
1938 }
1939 return false;
1940 }
1941
1942 void Options::addSectionAlignment(const char* segment, const char* section, const char* alignmentStr)
1943 {
1944 if ( strlen(segment) > 16 )
1945 throw "-sectalign segment name max 16 chars";
1946 if ( strlen(section) > 16 )
1947 throw "-sectalign section name max 16 chars";
1948
1949 // argument to -sectalign is a hexadecimal number
1950 char* endptr;
1951 unsigned long value = strtoul(alignmentStr, &endptr, 16);
1952 if ( *endptr != '\0')
1953 throw "argument for -sectalign is not a hexadecimal number";
1954 if ( value > 0x8000 )
1955 throw "argument for -sectalign must be less than or equal to 0x8000";
1956 if ( value == 0 ) {
1957 warning("zero is not a valid -sectalign");
1958 value = 1;
1959 }
1960
1961 // alignment is power of 2 (e.g. page alignment = 12)
1962 uint8_t alignment = (uint8_t)__builtin_ctz(value);
1963 if ( (unsigned long)(1 << alignment) != value ) {
1964 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1965 segment, section, 1 << alignment);
1966 }
1967
1968 SectionAlignment info = { segment, section, alignment };
1969 fSectionAlignments.push_back(info);
1970 }
1971
1972 void Options::addLibrary(const FileInfo& info)
1973 {
1974 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1975 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
1976 if ( strcmp(info.path, fit->path) == 0 ) {
1977 // if dylib is specified again but weak, record that it should be weak
1978 if ( info.options.fWeakImport )
1979 fit->options.fWeakImport = true;
1980 return;
1981 }
1982 }
1983 // add to list
1984 fInputFiles.push_back(info);
1985 }
1986
1987 void Options::warnObsolete(const char* arg)
1988 {
1989 warning("option %s is obsolete and being ignored", arg);
1990 }
1991
1992
1993 void Options::cannotBeUsedWithBitcode(const char* arg)
1994 {
1995 if ( fBundleBitcode )
1996 throwf("%s and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together", arg);
1997 }
1998
1999 std::string Options::getVersionString32(uint32_t ver) const
2000 {
2001 if (ver == 0 || ver >= 0x10000000)
2002 return "0.0.0";
2003
2004 unsigned microVersion = ver & 0xFF;
2005 unsigned minorVersion = (ver >> 8) & 0xFF;
2006 unsigned majorVersion = (ver >> 16) & 0xFF;
2007 std::stringstream versionString;
2008 versionString << majorVersion << "." << minorVersion << "." << microVersion;
2009 return versionString.str();
2010 }
2011
2012 std::string Options::getVersionString64(uint64_t ver) const
2013 {
2014 uint64_t a = (ver >> 40) & 0xFFFFFF;
2015 uint64_t b = (ver >> 30) & 0x3FF;
2016 uint64_t c = (ver >> 20) & 0x3FF;
2017 uint64_t d = (ver >> 10) & 0x3FF;
2018 uint64_t e = ver & 0x3FF;
2019 std::stringstream versionString;
2020 versionString << a << "." << b << "." << c << "." << d << "." << e;
2021 return versionString.str();
2022 }
2023
2024 std::string Options::getSDKVersionStr() const
2025 {
2026 return getVersionString32(fSDKVersion);
2027 }
2028
2029 std::string Options::getPlatformStr() const
2030 {
2031 switch (fPlatform) {
2032 case Options::kPlatformOSX:
2033 return "MacOSX";
2034 case Options::kPlatformiOS:
2035 if (targetIOSSimulator())
2036 return "iPhoneSimulator";
2037 else
2038 return "iPhoneOS";
2039 case Options::kPlatformWatchOS:
2040 if (targetIOSSimulator())
2041 return "watchOS Simulator";
2042 else
2043 return "watchOS";
2044 #if SUPPORT_APPLE_TV
2045 case Options::kPlatform_tvOS:
2046 if (targetIOSSimulator())
2047 return "AppleTVSimulator";
2048 else
2049 return "AppleTVOS";
2050 break;
2051 #endif
2052 case Options::kPlatformUnknown:
2053 return "Unknown";
2054 }
2055 }
2056
2057 std::vector<std::string> Options::writeBitcodeLinkOptions() const
2058 {
2059 std::vector<std::string> linkCommand;
2060 switch ( fOutputKind ) {
2061 case Options::kDynamicLibrary:
2062 linkCommand.push_back("-dylib");
2063 linkCommand.push_back("-compatibility_version");
2064 if ( fDylibCompatVersion != 0 ) {
2065 linkCommand.push_back(getVersionString32(fDylibCompatVersion));
2066 } else {
2067 linkCommand.push_back(getVersionString32(currentVersion32()));
2068 }
2069 if ( fDylibCurrentVersion != 0 ) {
2070 linkCommand.push_back("-current_version");
2071 linkCommand.push_back(getVersionString64(fDylibCurrentVersion));
2072 }
2073 linkCommand.push_back("-install_name");
2074 linkCommand.push_back(installPath());
2075 break;
2076 case Options::kDynamicExecutable:
2077 linkCommand.push_back("-execute");
2078 break;
2079 case Options::kObjectFile:
2080 linkCommand.push_back("-r");
2081 break;
2082 default:
2083 throwf("could not write bitcode options file output kind\n");
2084 }
2085
2086 if (!fImplicitlyLinkPublicDylibs)
2087 linkCommand.push_back("-no_implicit_dylibs");
2088
2089 // Add deployment target.
2090 // Platform is allowed to be unknown for "ld -r".
2091 switch (fPlatform) {
2092 case Options::kPlatformOSX:
2093 linkCommand.push_back("-macosx_version_min");
2094 linkCommand.push_back(getVersionString32((unsigned)fMacVersionMin));
2095 break;
2096 case Options::kPlatformiOS:
2097 if (targetIOSSimulator())
2098 linkCommand.push_back("-ios_simulator_version_min");
2099 else
2100 linkCommand.push_back("-ios_version_min");
2101 linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
2102 break;
2103 case Options::kPlatformWatchOS:
2104 if (targetIOSSimulator())
2105 linkCommand.push_back("-watchos_simulator_version_min");
2106 else
2107 linkCommand.push_back("-watchos_version_min");
2108 linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
2109 break;
2110 #if SUPPORT_APPLE_TV
2111 case Options::kPlatform_tvOS:
2112 if (targetIOSSimulator())
2113 linkCommand.push_back("-tvos_simulator_version_min");
2114 else
2115 linkCommand.push_back("-tvos_version_min");
2116 linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
2117 break;
2118 #endif
2119 case Options::kPlatformUnknown:
2120 if ( fOutputKind != Options::kObjectFile ) {
2121 throwf("platform is unknown for final bitcode bundle,"
2122 "deployment target and min version is required for -bitcode_bundle");
2123 }
2124 break;
2125 }
2126
2127
2128 // entry name
2129 if ( fEntryName ) {
2130 linkCommand.push_back("-e");
2131 linkCommand.push_back(fEntryName);
2132 }
2133
2134 // Write rpaths
2135 if (!fRPaths.empty()) {
2136 for (std::vector<const char*>::const_iterator it=fRPaths.begin(); it != fRPaths.end(); ++it) {
2137 linkCommand.push_back("-rpath");
2138 linkCommand.push_back(*it);
2139 }
2140 }
2141
2142 // Other bitcode compatiable options
2143 if ( fObjCABIVersion1Override ) {
2144 linkCommand.push_back("-objc_abi_version");
2145 linkCommand.push_back("1");
2146 } else if ( fObjCABIVersion2Override ) {
2147 linkCommand.push_back("-objc_abi_version");
2148 linkCommand.push_back("2");
2149 }
2150 if ( fExecutablePath ) {
2151 linkCommand.push_back("-executable_path");
2152 linkCommand.push_back(fExecutablePath);
2153 }
2154 if ( fDeadStrip )
2155 linkCommand.push_back("-dead_strip");
2156 if ( fExportDynamic )
2157 linkCommand.push_back("-export_dynamic");
2158 if ( fMarkAppExtensionSafe && fCheckAppExtensionSafe )
2159 linkCommand.push_back("-application_extension");
2160
2161 if ( fSourceVersionLoadCommandForceOn )
2162 linkCommand.push_back("-add_source_version");
2163 if ( fSourceVersion != 0 ) {
2164 linkCommand.push_back("-source_version");
2165 linkCommand.push_back(getVersionString64(fSourceVersion));
2166 }
2167
2168 // linker flag added by swift driver
2169 // rdar://problem/20108072
2170 if ( !fObjcCategoryMerging )
2171 linkCommand.push_back("-no_objc_category_merging");
2172
2173 return linkCommand;
2174 }
2175
2176 //
2177 // Process all command line arguments.
2178 //
2179 // The only error checking done here is that each option is valid and if it has arguments
2180 // that they too are valid.
2181 //
2182 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
2183 // whichever was last on the command line is used.
2184 //
2185 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
2186 //
2187 void Options::parse(int argc, const char* argv[])
2188 {
2189 // Store the original args in the link snapshot.
2190 fLinkSnapshot.recordRawArgs(argc, argv);
2191
2192 // pass one builds search list from -L and -F options
2193 this->buildSearchPaths(argc, argv);
2194
2195 // reduce re-allocations
2196 fInputFiles.reserve(32);
2197
2198 // pass two parse all other options
2199 for(int i=1; i < argc; ++i) {
2200 const char* arg = argv[i];
2201
2202 if ( arg[0] == '-' ) {
2203 // by default, copy one arg to the snapshot link command, and do no file copying
2204 int snapshotArgIndex = i;
2205 int snapshotArgCount = -1; // -1 means compute count based on change in index
2206 int snapshotFileArgIndex = -1; // -1 means no data file parameter to arg
2207
2208 // Since we don't care about the files passed, just the option names, we do this here.
2209 if (fPrintOptions)
2210 fprintf (stderr, "[Logging ld64 options]\t%s\n", arg);
2211
2212 if ( (arg[1] == 'L') || (arg[1] == 'F') ) {
2213 snapshotArgCount = 0; // stripped out of link snapshot
2214 if (arg[2] == '\0')
2215 ++i;
2216 // previously handled by buildSearchPaths()
2217 }
2218 // The one gnu style option we have to keep compatibility
2219 // with gcc. Might as well have the single hyphen one as well.
2220 else if ( (strcmp(arg, "--help") == 0)
2221 || (strcmp(arg, "-help") == 0)) {
2222 fprintf (stdout, "ld64: For information on command line options please use 'man ld'.\n");
2223 exit (0);
2224 }
2225 else if ( strcmp(arg, "-arch") == 0 ) {
2226 parseArch(argv[++i]);
2227 }
2228 else if ( strcmp(arg, "-dynamic") == 0 ) {
2229 // default
2230 }
2231 else if ( strcmp(arg, "-static") == 0 ) {
2232 fForStatic = true;
2233 if ( (fOutputKind != kObjectFile) && (fOutputKind != kKextBundle) ) {
2234 fOutputKind = kStaticExecutable;
2235 }
2236 cannotBeUsedWithBitcode(arg);
2237 }
2238 else if ( strcmp(arg, "-dylib") == 0 ) {
2239 fOutputKind = kDynamicLibrary;
2240 }
2241 else if ( strcmp(arg, "-bundle") == 0 ) {
2242 fOutputKind = kDynamicBundle;
2243 cannotBeUsedWithBitcode(arg);
2244 }
2245 else if ( strcmp(arg, "-dylinker") == 0 ) {
2246 fOutputKind = kDyld;
2247 cannotBeUsedWithBitcode(arg);
2248 }
2249 else if ( strcmp(arg, "-execute") == 0 ) {
2250 if ( fOutputKind != kStaticExecutable )
2251 fOutputKind = kDynamicExecutable;
2252 }
2253 else if ( strcmp(arg, "-preload") == 0 ) {
2254 fOutputKind = kPreload;
2255 cannotBeUsedWithBitcode(arg);
2256 }
2257 else if ( strcmp(arg, "-r") == 0 ) {
2258 fOutputKind = kObjectFile;
2259 }
2260 else if ( strcmp(arg, "-kext") == 0 ) {
2261 fOutputKind = kKextBundle;
2262 cannotBeUsedWithBitcode(arg);
2263 }
2264 else if ( strcmp(arg, "-o") == 0 ) {
2265 snapshotArgCount = 0;
2266 fOutputFile = argv[++i];
2267 fLinkSnapshot.setSnapshotName(fOutputFile);
2268 }
2269 else if ( strncmp(arg, "-lazy-l", 7) == 0 ) {
2270 snapshotArgCount = 0;
2271 FileInfo info = findLibrary(&arg[7], true);
2272 info.options.fLazyLoad = true;
2273 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2274 addLibrary(info);
2275 fUsingLazyDylibLinking = true;
2276 cannotBeUsedWithBitcode(arg);
2277 }
2278 else if ( strcmp(arg, "-lto_library") == 0 ) {
2279 snapshotFileArgIndex = 1;
2280 fOverridePathlibLTO = argv[++i];
2281 if ( fOverridePathlibLTO == NULL )
2282 throw "missing argument to -lto_library";
2283 }
2284 else if ( (arg[1] == 'l') && (strncmp(arg,"-lazy_",6) !=0) ) {
2285 snapshotArgCount = 0;
2286 FileInfo info = findLibrary(&arg[2]);
2287 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2288 addLibrary(info);
2289 }
2290 // This causes a dylib to be weakly bound at
2291 // link time. This corresponds to weak_import.
2292 else if ( strncmp(arg, "-weak-l", 7) == 0 ) {
2293 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2294 snapshotArgCount = 0;
2295 FileInfo info = findLibrary(&arg[7]);
2296 info.options.fWeakImport = true;
2297 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2298 addLibrary(info);
2299 }
2300 // Avoid lazy binding.
2301 else if ( strcmp(arg, "-bind_at_load") == 0 ) {
2302 fBindAtLoad = true;
2303 cannotBeUsedWithBitcode(arg);
2304 }
2305 else if ( strcmp(arg, "-twolevel_namespace") == 0 ) {
2306 fNameSpace = kTwoLevelNameSpace;
2307 }
2308 else if ( strcmp(arg, "-flat_namespace") == 0 ) {
2309 fNameSpace = kFlatNameSpace;
2310 cannotBeUsedWithBitcode(arg);
2311 }
2312 // Also sets a bit to ensure dyld causes everything
2313 // in the namespace to be flat.
2314 // ??? Deprecate
2315 else if ( strcmp(arg, "-force_flat_namespace") == 0 ) {
2316 fNameSpace = kForceFlatNameSpace;
2317 cannotBeUsedWithBitcode(arg);
2318 }
2319 // Similar to --whole-archive.
2320 else if ( strcmp(arg, "-all_load") == 0 ) {
2321 fFullyLoadArchives = true;
2322 }
2323 else if ( strcmp(arg, "-noall_load") == 0) {
2324 warnObsolete(arg);
2325 }
2326 // Similar to -all_load
2327 else if ( strcmp(arg, "-ObjC") == 0 ) {
2328 fLoadAllObjcObjectsFromArchives = true;
2329 }
2330 // Similar to -all_load, but for the following archive only.
2331 else if ( strcmp(arg, "-force_load") == 0 ) {
2332 FileInfo info = findFile(argv[++i]);
2333 info.options.fForceLoad = true;
2334 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2335 addLibrary(info);
2336 }
2337 // Library versioning.
2338 else if ( (strcmp(arg, "-dylib_compatibility_version") == 0)
2339 || (strcmp(arg, "-compatibility_version") == 0)) {
2340 const char* vers = argv[++i];
2341 if ( vers == NULL )
2342 throw "-dylib_compatibility_version missing <version>";
2343 fDylibCompatVersion = parseVersionNumber32(vers);
2344 }
2345 else if ( (strcmp(arg, "-dylib_current_version") == 0)
2346 || (strcmp(arg, "-current_version") == 0)) {
2347 const char* vers = argv[++i];
2348 if ( vers == NULL )
2349 throw "-dylib_current_version missing <version>";
2350 fDylibCurrentVersion = parseVersionNumber64(vers);
2351 }
2352 else if ( strcmp(arg, "-sectorder") == 0 ) {
2353 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2354 throw "-sectorder missing <segment> <section> <file-path>";
2355 snapshotFileArgIndex = 3;
2356 parseSectionOrderFile(argv[i+1], argv[i+2], argv[i+3]);
2357 i += 3;
2358 cannotBeUsedWithBitcode(arg);
2359 }
2360 else if ( strcmp(arg, "-order_file") == 0 ) {
2361 snapshotFileArgIndex = 1;
2362 parseOrderFile(argv[++i], false);
2363 cannotBeUsedWithBitcode(arg);
2364 }
2365 else if ( strcmp(arg, "-order_file_statistics") == 0 ) {
2366 fPrintOrderFileStatistics = true;
2367 cannotBeUsedWithBitcode(arg);
2368 }
2369 // ??? Deprecate segcreate.
2370 // -sectcreate puts whole files into a section in the output.
2371 else if ( (strcmp(arg, "-sectcreate") == 0) || (strcmp(arg, "-segcreate") == 0) ) {
2372 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2373 throw "-sectcreate missing <segment> <section> <file-path>";
2374 snapshotFileArgIndex = 3;
2375 addSection(argv[i+1], argv[i+2], argv[i+3]);
2376 i += 3;
2377 }
2378 // Since we have a full path in binary/library names we need to be able to override it.
2379 else if ( (strcmp(arg, "-dylib_install_name") == 0)
2380 || (strcmp(arg, "-dylinker_install_name") == 0)
2381 || (strcmp(arg, "-install_name") == 0)) {
2382 fDylibInstallName = argv[++i];
2383 if ( fDylibInstallName == NULL )
2384 throw "-install_name missing <path>";
2385 }
2386 // Sets the base address of the output.
2387 else if ( (strcmp(arg, "-seg1addr") == 0) || (strcmp(arg, "-image_base") == 0) ) {
2388 const char* address = argv[++i];
2389 if ( address == NULL )
2390 throwf("%s missing <address>", arg);
2391 fBaseAddress = parseAddress(address);
2392 uint64_t temp = ((fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment));
2393 if ( fBaseAddress != temp ) {
2394 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment);
2395 fBaseAddress = temp;
2396 }
2397 cannotBeUsedWithBitcode(arg);
2398 }
2399 else if ( strcmp(arg, "-e") == 0 ) {
2400 fEntryName = argv[++i];
2401 }
2402 // Same as -@ from the FSF linker.
2403 else if ( strcmp(arg, "-filelist") == 0 ) {
2404 snapshotArgCount = 0;
2405 const char* path = argv[++i];
2406 if ( (path == NULL) || (path[0] == '-') )
2407 throw "-filelist missing <path>";
2408 ld::File::Ordinal baseOrdinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2409 loadFileList(path, baseOrdinal);
2410 }
2411 else if ( strcmp(arg, "-keep_private_externs") == 0 ) {
2412 cannotBeUsedWithBitcode(arg);
2413 fKeepPrivateExterns = true;
2414 }
2415 else if ( strcmp(arg, "-final_output") == 0 ) {
2416 fFinalName = argv[++i];
2417 }
2418 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
2419 // just ensures that this happens for cross object file boundaries.
2420 else if ( (strcmp(arg, "-interposable") == 0) || (strcmp(arg, "-multi_module") == 0)) {
2421 switch ( fInterposeMode ) {
2422 case kInterposeNone:
2423 case kInterposeAllExternal:
2424 fInterposeMode = kInterposeAllExternal;
2425 break;
2426 case kInterposeSome:
2427 // do nothing, -interposable_list overrides -interposable"
2428 break;
2429 }
2430 cannotBeUsedWithBitcode(arg);
2431 }
2432 else if ( strcmp(arg, "-interposable_list") == 0 ) {
2433 snapshotFileArgIndex = 1;
2434 fInterposeMode = kInterposeSome;
2435 loadExportFile(argv[++i], "-interposable_list", fInterposeList);
2436 cannotBeUsedWithBitcode(arg);
2437 }
2438 // Default for -interposable/-multi_module/-single_module.
2439 else if ( strcmp(arg, "-single_module") == 0 ) {
2440 fInterposeMode = kInterposeNone;
2441 }
2442 else if ( strcmp(arg, "-exported_symbols_list") == 0 ) {
2443 snapshotFileArgIndex = 1;
2444 if ( fExportMode == kDontExportSome )
2445 throw "can't use -exported_symbols_list and -unexported_symbols_list";
2446 fExportMode = kExportSome;
2447 loadExportFile(argv[++i], "-exported_symbols_list", fExportSymbols);
2448 }
2449 else if ( strcmp(arg, "-unexported_symbols_list") == 0 ) {
2450 snapshotFileArgIndex = 1;
2451 if ( fExportMode == kExportSome )
2452 throw "can't use -unexported_symbols_list and -exported_symbols_list";
2453 fExportMode = kDontExportSome;
2454 loadExportFile(argv[++i], "-unexported_symbols_list", fDontExportSymbols);
2455 cannotBeUsedWithBitcode(arg);
2456 }
2457 else if ( strcmp(arg, "-exported_symbol") == 0 ) {
2458 if ( fExportMode == kDontExportSome )
2459 throw "can't use -exported_symbol and -unexported_symbols";
2460 fExportMode = kExportSome;
2461 fExportSymbols.insert(argv[++i]);
2462 }
2463 else if ( strcmp(arg, "-unexported_symbol") == 0 ) {
2464 if ( fExportMode == kExportSome )
2465 throw "can't use -unexported_symbol and -exported_symbol";
2466 fExportMode = kDontExportSome;
2467 fDontExportSymbols.insert(argv[++i]);
2468 cannotBeUsedWithBitcode(arg);
2469 }
2470 else if ( strcmp(arg, "-non_global_symbols_no_strip_list") == 0 ) {
2471 snapshotFileArgIndex = 1;
2472 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveExclude )
2473 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2474 fLocalSymbolHandling = kLocalSymbolsSelectiveInclude;
2475 loadExportFile(argv[++i], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded);
2476 cannotBeUsedWithBitcode(arg);
2477 }
2478 else if ( strcmp(arg, "-non_global_symbols_strip_list") == 0 ) {
2479 snapshotFileArgIndex = 1;
2480 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveInclude )
2481 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2482 fLocalSymbolHandling = kLocalSymbolsSelectiveExclude;
2483 loadExportFile(argv[++i], "-non_global_symbols_strip_list", fLocalSymbolsExcluded);
2484 cannotBeUsedWithBitcode(arg);
2485 }
2486 // ??? Deprecate
2487 else if ( strcmp(arg, "-no_arch_warnings") == 0 ) {
2488 fIgnoreOtherArchFiles = true;
2489 }
2490 else if ( strcmp(arg, "-force_cpusubtype_ALL") == 0 ) {
2491 fForceSubtypeAll = true;
2492 fAllowCpuSubtypeMismatches = true;
2493 cannotBeUsedWithBitcode(arg);
2494 }
2495 // Similar to -weak-l but uses the absolute path name to the library.
2496 else if ( strcmp(arg, "-weak_library") == 0 ) {
2497 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2498 snapshotArgCount = 0;
2499 FileInfo info = findFile(argv[++i]);
2500 info.options.fWeakImport = true;
2501 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2502 addLibrary(info);
2503 cannotBeUsedWithBitcode(arg);
2504 }
2505 else if ( strcmp(arg, "-lazy_library") == 0 ) {
2506 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2507 snapshotArgCount = 0;
2508 FileInfo info = findFile(argv[++i]);
2509 info.options.fLazyLoad = true;
2510 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2511 addLibrary(info);
2512 fUsingLazyDylibLinking = true;
2513 cannotBeUsedWithBitcode(arg);
2514 }
2515 else if ( strcmp(arg, "-framework") == 0 ) {
2516 snapshotArgCount = 0;
2517 FileInfo info = findFramework(argv[++i]);
2518 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2519 addLibrary(info);
2520 }
2521 else if ( strcmp(arg, "-weak_framework") == 0 ) {
2522 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2523 snapshotArgCount = 0;
2524 FileInfo info = findFramework(argv[++i]);
2525 info.options.fWeakImport = true;
2526 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2527 addLibrary(info);
2528 }
2529 else if ( strcmp(arg, "-lazy_framework") == 0 ) {
2530 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2531 snapshotArgCount = 0;
2532 FileInfo info = findFramework(argv[++i]);
2533 info.options.fLazyLoad = true;
2534 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2535 addLibrary(info);
2536 fUsingLazyDylibLinking = true;
2537 cannotBeUsedWithBitcode(arg);
2538 }
2539 else if ( strcmp(arg, "-search_paths_first") == 0 ) {
2540 // previously handled by buildSearchPaths()
2541 }
2542 else if ( strcmp(arg, "-search_dylibs_first") == 0 ) {
2543 // previously handled by buildSearchPaths()
2544 }
2545 else if ( strcmp(arg, "-undefined") == 0 ) {
2546 setUndefinedTreatment(argv[++i]);
2547 cannotBeUsedWithBitcode(arg);
2548 }
2549 // Debugging output flag.
2550 else if ( strcmp(arg, "-arch_multiple") == 0 ) {
2551 fMessagesPrefixedWithArchitecture = true;
2552 }
2553 // Specify what to do with relocations in read only
2554 // sections like .text. Could be errors, warnings,
2555 // or suppressed. Currently we do nothing with the
2556 // flag.
2557 else if ( strcmp(arg, "-read_only_relocs") == 0 ) {
2558 switch ( parseTreatment(argv[++i]) ) {
2559 case kNULL:
2560 case kInvalid:
2561 throw "-read_only_relocs missing [ warning | error | suppress ]";
2562 case kWarning:
2563 fWarnTextRelocs = true;
2564 fAllowTextRelocs = true;
2565 cannotBeUsedWithBitcode(arg);
2566 break;
2567 case kSuppress:
2568 fWarnTextRelocs = false;
2569 fAllowTextRelocs = true;
2570 cannotBeUsedWithBitcode(arg);
2571 break;
2572 case kError:
2573 fWarnTextRelocs = false;
2574 fAllowTextRelocs = false;
2575 break;
2576 }
2577 }
2578 else if ( strcmp(arg, "-sect_diff_relocs") == 0 ) {
2579 warnObsolete(arg);
2580 ++i;
2581 }
2582 // Warn, error or make strong a mismatch between weak
2583 // and non-weak references.
2584 else if ( strcmp(arg, "-weak_reference_mismatches") == 0 ) {
2585 setWeakReferenceMismatchTreatment(argv[++i]);
2586 }
2587 // For a deployment target of 10.3 and earlier ld64 will
2588 // prebind an executable with 0s in all addresses that
2589 // are prebound. This can then be fixed up by update_prebinding
2590 // later. Prebinding is less useful on 10.4 and greater.
2591 else if ( strcmp(arg, "-prebind") == 0 ) {
2592 fPrebind = true;
2593 cannotBeUsedWithBitcode(arg);
2594 }
2595 else if ( strcmp(arg, "-noprebind") == 0 ) {
2596 warnObsolete(arg);
2597 fPrebind = false;
2598 }
2599 else if ( strcmp(arg, "-prebind_allow_overlap") == 0 ) {
2600 warnObsolete(arg);
2601 }
2602 else if ( strcmp(arg, "-prebind_all_twolevel_modules") == 0 ) {
2603 warnObsolete(arg);
2604 }
2605 else if ( strcmp(arg, "-noprebind_all_twolevel_modules") == 0 ) {
2606 warnObsolete(arg);
2607 }
2608 else if ( strcmp(arg, "-nofixprebinding") == 0 ) {
2609 warnObsolete(arg);
2610 }
2611 // This should probably be deprecated when we respect -L and -F
2612 // when searching for libraries.
2613 else if ( strcmp(arg, "-dylib_file") == 0 ) {
2614 // ignore for snapshot because a stub dylib will be created in the snapshot
2615 snapshotArgCount = 0;
2616 addDylibOverride(argv[++i]);
2617 cannotBeUsedWithBitcode(arg);
2618 }
2619 // What to expand @executable_path to if found in dependent dylibs
2620 else if ( strcmp(arg, "-executable_path") == 0 ) {
2621 fExecutablePath = argv[++i];
2622 if ( (fExecutablePath == NULL) || (fExecutablePath[0] == '-') )
2623 throw "-executable_path missing <path>";
2624 // if a directory was passed, add / to end
2625 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2626 struct stat statBuffer;
2627 if ( stat(fExecutablePath, &statBuffer) == 0 ) {
2628 if ( (statBuffer.st_mode & S_IFMT) == S_IFDIR ) {
2629 char* pathWithSlash = new char[strlen(fExecutablePath)+2];
2630 strcpy(pathWithSlash, fExecutablePath);
2631 strcat(pathWithSlash, "/");
2632 fExecutablePath = pathWithSlash;
2633 }
2634 }
2635 }
2636 // Aligns all segments to the power of 2 boundary specified.
2637 else if ( strcmp(arg, "-segalign") == 0 ) {
2638 const char* size = argv[++i];
2639 if ( size == NULL )
2640 throw "-segalign missing <size>";
2641 fSegmentAlignment = parseAddress(size);
2642 uint8_t alignment = (uint8_t)__builtin_ctz(fSegmentAlignment);
2643 uint32_t p2aligned = (1 << alignment);
2644 if ( p2aligned != fSegmentAlignment ) {
2645 warning("alignment for -segalign %s is not a power of two, using 0x%X", size, p2aligned);
2646 fSegmentAlignment = p2aligned;
2647 }
2648 cannotBeUsedWithBitcode(arg);
2649 }
2650 // Puts a specified segment at a particular address that must
2651 // be a multiple of the segment alignment.
2652 else if ( strcmp(arg, "-segaddr") == 0 ) {
2653 SegmentStart seg;
2654 seg.name = argv[++i];
2655 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
2656 throw "-segaddr missing segName Adddress";
2657 seg.address = parseAddress(argv[++i]);
2658 uint64_t temp = ((seg.address+fSegmentAlignment-1) & (-fSegmentAlignment));
2659 if ( seg.address != temp )
2660 warning("-segaddr %s not %lld byte aligned", seg.name, fSegmentAlignment);
2661 fCustomSegmentAddresses.push_back(seg);
2662 cannotBeUsedWithBitcode(arg);
2663 }
2664 // ??? Deprecate when we deprecate split-seg.
2665 else if ( strcmp(arg, "-segs_read_only_addr") == 0 ) {
2666 fBaseAddress = parseAddress(argv[++i]);
2667 cannotBeUsedWithBitcode(arg);
2668 }
2669 // ??? Deprecate when we deprecate split-seg.
2670 else if ( strcmp(arg, "-segs_read_write_addr") == 0 ) {
2671 fBaseWritableAddress = parseAddress(argv[++i]);
2672 fSplitSegs = true;
2673 cannotBeUsedWithBitcode(arg);
2674 }
2675 // ??? Deprecate when we get rid of basing at build time.
2676 else if ( strcmp(arg, "-seg_addr_table") == 0 ) {
2677 snapshotFileArgIndex = 1;
2678 const char* name = argv[++i];
2679 if ( name == NULL )
2680 throw "-seg_addr_table missing argument";
2681 fSegAddrTablePath = name;
2682 cannotBeUsedWithBitcode(arg);
2683 }
2684 else if ( strcmp(arg, "-seg_addr_table_filename") == 0 ) {
2685 warnObsolete(arg);
2686 ++i;
2687 }
2688 else if ( strcmp(arg, "-segprot") == 0 ) {
2689 SegmentProtect seg;
2690 seg.name = argv[++i];
2691 if ( (seg.name == NULL) || (argv[i+1] == NULL) || (argv[i+2] == NULL) )
2692 throw "-segprot missing segName max-prot init-prot";
2693 seg.max = parseProtection(argv[++i]);
2694 seg.init = parseProtection(argv[++i]);
2695 fCustomSegmentProtections.push_back(seg);
2696 cannotBeUsedWithBitcode(arg);
2697 }
2698 else if ( strcmp(arg, "-pagezero_size") == 0 ) {
2699 const char* size = argv[++i];
2700 if ( size == NULL )
2701 throw "-pagezero_size missing <size>";
2702 fZeroPageSize = parseAddress(size);
2703 uint64_t temp = fZeroPageSize & (-4096); // page align
2704 if ( (fZeroPageSize != temp) )
2705 warning("-pagezero_size not page aligned, rounding down");
2706 fZeroPageSize = temp;
2707 cannotBeUsedWithBitcode(arg);
2708 }
2709 else if ( strcmp(arg, "-stack_addr") == 0 ) {
2710 const char* address = argv[++i];
2711 if ( address == NULL )
2712 throw "-stack_addr missing <address>";
2713 fStackAddr = parseAddress(address);
2714 cannotBeUsedWithBitcode(arg);
2715 }
2716 else if ( strcmp(arg, "-stack_size") == 0 ) {
2717 const char* size = argv[++i];
2718 if ( size == NULL )
2719 throw "-stack_size missing <address>";
2720 fStackSize = parseAddress(size);
2721 uint64_t temp = fStackSize & (-4096); // page align
2722 if ( (fStackSize != temp) )
2723 warning("-stack_size not page aligned, rounding down");
2724 }
2725 else if ( strcmp(arg, "-allow_stack_execute") == 0 ) {
2726 fExecutableStack = true;
2727 cannotBeUsedWithBitcode(arg);
2728 }
2729 else if ( strcmp(arg, "-allow_heap_execute") == 0 ) {
2730 fDisableNonExecutableHeap = true;
2731 cannotBeUsedWithBitcode(arg);
2732 }
2733 else if ( strcmp(arg, "-sectalign") == 0 ) {
2734 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2735 throw "-sectalign missing <segment> <section> <file-path>";
2736 addSectionAlignment(argv[i+1], argv[i+2], argv[i+3]);
2737 i += 3;
2738 cannotBeUsedWithBitcode(arg);
2739 }
2740 else if ( strcmp(arg, "-sectorder_detail") == 0 ) {
2741 warnObsolete(arg);
2742 }
2743 else if ( strcmp(arg, "-sectobjectsymbols") == 0 ) {
2744 warnObsolete(arg);
2745 i += 2;
2746 }
2747 else if ( strcmp(arg, "-bundle_loader") == 0 ) {
2748 snapshotFileArgIndex = 1;
2749 fBundleLoader = argv[++i];
2750 if ( (fBundleLoader == NULL) || (fBundleLoader[0] == '-') )
2751 throw "-bundle_loader missing <path>";
2752 FileInfo info = findFile(fBundleLoader);
2753 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
2754 info.options.fBundleLoader = true;
2755 fInputFiles.push_back(info);
2756 }
2757 else if ( strcmp(arg, "-private_bundle") == 0 ) {
2758 warnObsolete(arg);
2759 }
2760 else if ( strcmp(arg, "-twolevel_namespace_hints") == 0 ) {
2761 // FIX FIX
2762 }
2763 // Use this flag to set default behavior for deployement targets.
2764 else if ( strcmp(arg, "-macosx_version_min") == 0 ) {
2765 const char* macVers = argv[++i];
2766 const char* envMacVers = getenv("MACOSX_DEPLOYMENT_TARGET");
2767 const char* enviPhoneVers = getenv("IPHONEOS_DEPLOYMENT_TARGET");
2768 if ( (envMacVers != NULL) && (enviPhoneVers != NULL) ) {
2769 // <rdar://problem/13774329> when conflicting deployments set, break tie by looking at syslibroot
2770 warning("both MACOSX_DEPLOYMENT_TARGET and IPHONEOS_DEPLOYMENT_TARGET are set");
2771 if ( !fSDKPaths.empty() ) {
2772 const char* sysrootPath = fSDKPaths.back();
2773 const char* lastSlash = strrchr(sysrootPath, '/');
2774 if ( strstr(lastSlash, "Simulator") != NULL )
2775 setIOSVersionMin(enviPhoneVers);
2776 else
2777 setMacOSXVersionMin(macVers);
2778 }
2779 else {
2780 setMacOSXVersionMin(macVers);
2781 }
2782 }
2783 else {
2784 setMacOSXVersionMin(macVers);
2785 }
2786 }
2787 else if ( (strcmp(arg, "-ios_version_min") == 0) || (strcmp(arg, "-iphoneos_version_min") == 0) ) {
2788 setIOSVersionMin(argv[++i]);
2789 }
2790 else if ( strcmp(arg, "-ios_simulator_version_min") == 0 ) {
2791 setIOSVersionMin(argv[++i]);
2792 fTargetIOSSimulator = true;
2793 }
2794 else if ( strcmp(arg, "-watchos_version_min") == 0 ) {
2795 setWatchOSVersionMin(argv[++i]);
2796 }
2797 else if ( strcmp(arg, "-watchos_simulator_version_min") == 0 ) {
2798 setWatchOSVersionMin(argv[++i]);
2799 fTargetIOSSimulator = true;
2800 }
2801 #if SUPPORT_APPLE_TV
2802 else if ( strcmp(arg, "-tvos_version_min") == 0 ) {
2803 setIOSVersionMin(argv[++i]);
2804 fPlatform = kPlatform_tvOS;
2805 }
2806 else if ( strcmp(arg, "-tvos_simulator_version_min") == 0 ) {
2807 setIOSVersionMin(argv[++i]);
2808 fPlatform = kPlatform_tvOS;
2809 fTargetIOSSimulator = true;
2810 }
2811 #endif
2812 else if ( strcmp(arg, "-multiply_defined") == 0 ) {
2813 //warnObsolete(arg);
2814 ++i;
2815 }
2816 else if ( strcmp(arg, "-multiply_defined_unused") == 0 ) {
2817 warnObsolete(arg);
2818 ++i;
2819 }
2820 else if ( strcmp(arg, "-nomultidefs") == 0 ) {
2821 warnObsolete(arg);
2822 }
2823 // Display each file in which the argument symbol appears and whether
2824 // the file defines or references it. This option takes an argument
2825 // as -y<symbol> note that there is no space.
2826 else if ( strncmp(arg, "-y", 2) == 0 ) {
2827 warnObsolete("-y");
2828 }
2829 // Same output as -y, but output <arg> number of undefined symbols only.
2830 else if ( strcmp(arg, "-Y") == 0 ) {
2831 //warnObsolete(arg);
2832 ++i;
2833 }
2834 // This option affects all objects linked into the final result.
2835 else if ( strcmp(arg, "-m") == 0 ) {
2836 warnObsolete(arg);
2837 }
2838 else if ( (strcmp(arg, "-why_load") == 0) || (strcmp(arg, "-whyload") == 0) ) {
2839 fWhyLoad = true;
2840 }
2841 else if ( strcmp(arg, "-why_live") == 0 ) {
2842 const char* name = argv[++i];
2843 if ( name == NULL )
2844 throw "-why_live missing symbol name argument";
2845 fWhyLive.insert(name);
2846 }
2847 else if ( strcmp(arg, "-u") == 0 ) {
2848 const char* name = argv[++i];
2849 if ( name == NULL )
2850 throw "-u missing argument";
2851 fInitialUndefines.push_back(name);
2852 cannotBeUsedWithBitcode(arg);
2853 }
2854 else if ( strcmp(arg, "-U") == 0 ) {
2855 const char* name = argv[++i];
2856 if ( name == NULL )
2857 throw "-U missing argument";
2858 fAllowedUndefined.insert(name);
2859 cannotBeUsedWithBitcode(arg);
2860 }
2861 else if ( strcmp(arg, "-s") == 0 ) {
2862 warnObsolete(arg);
2863 fLocalSymbolHandling = kLocalSymbolsNone;
2864 fDebugInfoStripping = Options::kDebugInfoNone;
2865 }
2866 else if ( strcmp(arg, "-x") == 0 ) {
2867 fLocalSymbolHandling = kLocalSymbolsNone;
2868 }
2869 else if ( strcmp(arg, "-S") == 0 ) {
2870 fDebugInfoStripping = Options::kDebugInfoNone;
2871 }
2872 else if ( strcmp(arg, "-X") == 0 ) {
2873 warnObsolete(arg);
2874 }
2875 else if ( strcmp(arg, "-Si") == 0 ) {
2876 warnObsolete(arg);
2877 fDebugInfoStripping = Options::kDebugInfoFull;
2878 }
2879 else if ( strcmp(arg, "-b") == 0 ) {
2880 warnObsolete(arg);
2881 }
2882 else if ( strcmp(arg, "-Sn") == 0 ) {
2883 warnObsolete(arg);
2884 fDebugInfoStripping = Options::kDebugInfoFull;
2885 }
2886 else if ( strcmp(arg, "-Sp") == 0 ) {
2887 warnObsolete(arg);
2888 }
2889 else if ( strcmp(arg, "-dead_strip") == 0 ) {
2890 fDeadStrip = true;
2891 }
2892 else if ( strcmp(arg, "-no_dead_strip_inits_and_terms") == 0 ) {
2893 fDeadStrip = true;
2894 }
2895 else if ( strcmp(arg, "-w") == 0 ) {
2896 // previously handled by buildSearchPaths()
2897 }
2898 else if ( strcmp(arg, "-fatal_warnings") == 0 ) {
2899 // previously handled by buildSearchPaths()
2900 }
2901 else if ( strcmp(arg, "-arch_errors_fatal") == 0 ) {
2902 fErrorOnOtherArchFiles = true;
2903 }
2904 else if ( strcmp(arg, "-M") == 0 ) {
2905 // FIX FIX
2906 }
2907 else if ( strcmp(arg, "-headerpad") == 0 ) {
2908 const char* size = argv[++i];
2909 if ( size == NULL )
2910 throw "-headerpad missing argument";
2911 fMinimumHeaderPad = parseAddress(size);
2912 cannotBeUsedWithBitcode(arg);
2913 }
2914 else if ( strcmp(arg, "-headerpad_max_install_names") == 0 ) {
2915 // ignore -headerpad_max_install_names when compiling with bitcode
2916 // rdar://problem/20748962
2917 if ( fBundleBitcode )
2918 warning("-headerpad_max_install_names is ignored when used with -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES)");
2919 else
2920 fMaxMinimumHeaderPad = true;
2921 }
2922 else if ( strcmp(arg, "-t") == 0 ) {
2923 fLogAllFiles = true;
2924 }
2925 else if ( strcmp(arg, "-whatsloaded") == 0 ) {
2926 fLogObjectFiles = true;
2927 }
2928 else if ( strcmp(arg, "-A") == 0 ) {
2929 warnObsolete(arg);
2930 ++i;
2931 }
2932 else if ( strcmp(arg, "-umbrella") == 0 ) {
2933 const char* name = argv[++i];
2934 if ( name == NULL )
2935 throw "-umbrella missing argument";
2936 fUmbrellaName = name;
2937 cannotBeUsedWithBitcode(arg);
2938 }
2939 else if ( strcmp(arg, "-allowable_client") == 0 ) {
2940 const char* name = argv[++i];
2941
2942 if ( name == NULL )
2943 throw "-allowable_client missing argument";
2944
2945 fAllowableClients.push_back(name);
2946 cannotBeUsedWithBitcode(arg);
2947 }
2948 else if ( strcmp(arg, "-client_name") == 0 ) {
2949 const char* name = argv[++i];
2950
2951 if ( name == NULL )
2952 throw "-client_name missing argument";
2953
2954 fClientName = name;
2955 cannotBeUsedWithBitcode(arg);
2956 }
2957 else if ( strcmp(arg, "-sub_umbrella") == 0 ) {
2958 const char* name = argv[++i];
2959 if ( name == NULL )
2960 throw "-sub_umbrella missing argument";
2961 fSubUmbellas.push_back(name);
2962 cannotBeUsedWithBitcode(arg);
2963 }
2964 else if ( strcmp(arg, "-sub_library") == 0 ) {
2965 const char* name = argv[++i];
2966 if ( name == NULL )
2967 throw "-sub_library missing argument";
2968 fSubLibraries.push_back(name);
2969 cannotBeUsedWithBitcode(arg);
2970 }
2971 else if ( strcmp(arg, "-init") == 0 ) {
2972 const char* name = argv[++i];
2973 if ( name == NULL )
2974 throw "-init missing argument";
2975 fInitFunctionName = name;
2976 cannotBeUsedWithBitcode(arg);
2977 }
2978 else if ( strcmp(arg, "-dot") == 0 ) {
2979 const char* name = argv[++i];
2980 if ( name == NULL )
2981 throw "-dot missing argument";
2982 fDotOutputFile = name;
2983 cannotBeUsedWithBitcode(arg);
2984 }
2985 else if ( strcmp(arg, "-warn_commons") == 0 ) {
2986 fWarnCommons = true;
2987 }
2988 else if ( strcmp(arg, "-commons") == 0 ) {
2989 fCommonsMode = parseCommonsTreatment(argv[++i]);
2990 }
2991 else if ( strcmp(arg, "-keep_relocs") == 0 ) {
2992 fKeepRelocations = true;
2993 }
2994 else if ( strcmp(arg, "-warn_stabs") == 0 ) {
2995 fWarnStabs = true;
2996 }
2997 else if ( strcmp(arg, "-pause") == 0 ) {
2998 fPause = true;
2999 }
3000 else if ( strcmp(arg, "-print_statistics") == 0 ) {
3001 fStatistics = true;
3002 }
3003 else if ( strcmp(arg, "-d") == 0 ) {
3004 fMakeTentativeDefinitionsReal = true;
3005 }
3006 else if ( strcmp(arg, "-v") == 0 ) {
3007 // previously handled by buildSearchPaths()
3008 }
3009 else if ( strcmp(arg, "-Z") == 0 ) {
3010 // previously handled by buildSearchPaths()
3011 }
3012 else if ( strcmp(arg, "-syslibroot") == 0 ) {
3013 snapshotArgCount = 0;
3014 ++i;
3015 // previously handled by buildSearchPaths()
3016 }
3017 else if ( strcmp(arg, "-bitcode_bundle") == 0 ) {
3018 snapshotArgCount = 0;
3019 // previously handled by buildSearchPaths()
3020 }
3021 else if ( strcmp(arg, "-no_uuid") == 0 ) {
3022 fUUIDMode = kUUIDNone;
3023 cannotBeUsedWithBitcode(arg);
3024 }
3025 else if ( strcmp(arg, "-random_uuid") == 0 ) {
3026 fUUIDMode = kUUIDRandom;
3027 cannotBeUsedWithBitcode(arg);
3028 }
3029 else if ( strcmp(arg, "-dtrace") == 0 ) {
3030 snapshotFileArgIndex = 1;
3031 const char* name = argv[++i];
3032 if ( name == NULL )
3033 throw "-dtrace missing argument";
3034 fDtraceScriptName = name;
3035 cannotBeUsedWithBitcode(arg);
3036 }
3037 else if ( strcmp(arg, "-root_safe") == 0 ) {
3038 fRootSafe = true;
3039 }
3040 else if ( strcmp(arg, "-setuid_safe") == 0 ) {
3041 fSetuidSafe = true;
3042 }
3043 else if ( strcmp(arg, "-alias") == 0 ) {
3044 Options::AliasPair pair;
3045 pair.realName = argv[++i];
3046 if ( pair.realName == NULL )
3047 throw "missing argument to -alias";
3048 pair.alias = argv[++i];
3049 if ( pair.alias == NULL )
3050 throw "missing argument to -alias";
3051 fAliases.push_back(pair);
3052 cannotBeUsedWithBitcode(arg);
3053 }
3054 else if ( strcmp(arg, "-alias_list") == 0 ) {
3055 snapshotFileArgIndex = 1;
3056 parseAliasFile(argv[++i]);
3057 cannotBeUsedWithBitcode(arg);
3058 }
3059 else if ( strcmp(arg, "-save-temps") == 0 ) {
3060 fSaveTempFiles = true;
3061 }
3062 else if ( strcmp(arg, "-bitcode_hide_symbols") == 0 ) {
3063 fHideSymbols = true;
3064 if ( !fBundleBitcode )
3065 warning("-bitcode_hide_symbols is ignored without -bitcode_bundle");
3066 }
3067 else if ( strcmp(arg, "-bitcode_verify") == 0 ) {
3068 fVerifyBitcode = true;
3069 if ( !fBundleBitcode )
3070 warning("-bitcode_verify is ignored without -bitcode_bundle");
3071 }
3072 else if ( strcmp(arg, "-bitcode_symbol_map") == 0) {
3073 fReverseMapPath = argv[++i];
3074 if ( fReverseMapPath == NULL )
3075 throw "missing argument to -bitcode_symbol_map";
3076 struct stat statbuf;
3077 ::stat(fReverseMapPath, &statbuf);
3078 if (S_ISDIR(statbuf.st_mode)) {
3079 char tempPath[PATH_MAX];
3080 sprintf(tempPath, "%s/XXXXXX", fReverseMapPath);
3081 int tempFile = ::mkstemp(tempPath);
3082 if (tempFile == -1)
3083 throwf("could not write file to symbol map directory: %s", fReverseMapPath);
3084 ::close(tempFile);
3085 fReverseMapTempPath = std::string(tempPath);
3086 fReverseMapUUIDRename = true;
3087 } else
3088 fReverseMapTempPath = std::string(fReverseMapPath);
3089 }
3090 else if ( strcmp(argv[i], "-flto-codegen-only") == 0) {
3091 fLTOCodegenOnly = true;
3092 }
3093 else if ( strcmp(argv[i], "-ignore_auto_link") == 0) {
3094 fIgnoreAutoLink = true;
3095 }
3096 else if ( strcmp(argv[i], "-allow_dead_duplicates") == 0) {
3097 fAllowDeadDups = true;
3098 }
3099 else if ( strcmp(argv[i], "-bitcode_process_mode") == 0 ) {
3100 const char* bitcode_type = argv[++i];
3101 if ( bitcode_type == NULL )
3102 throw "missing argument to -bitcode_process_mode";
3103 else if ( strcmp(bitcode_type, "strip") == 0 )
3104 fBitcodeKind = kBitcodeStrip;
3105 else if ( strcmp(bitcode_type, "marker") == 0 )
3106 fBitcodeKind = kBitcodeMarker;
3107 else if ( strcmp(bitcode_type, "data") == 0 )
3108 fBitcodeKind = kBitcodeAsData;
3109 else if ( strcmp(bitcode_type, "bitcode") == 0 )
3110 fBitcodeKind = kBitcodeProcess;
3111 else
3112 throw "unknown argument to -bitcode_process_mode {strip,marker,data,bitcode}";
3113 }
3114 else if ( strcmp(arg, "-rpath") == 0 ) {
3115 const char* path = argv[++i];
3116 if ( path == NULL )
3117 throw "missing argument to -rpath";
3118 fRPaths.push_back(path);
3119 }
3120 else if ( strcmp(arg, "-read_only_stubs") == 0 ) {
3121 fReadOnlyx86Stubs = true;
3122 }
3123 else if ( strcmp(arg, "-slow_stubs") == 0 ) {
3124 warnObsolete(arg);
3125 }
3126 else if ( strcmp(arg, "-map") == 0 ) {
3127 fMapPath = argv[++i];
3128 if ( fMapPath == NULL )
3129 throw "missing argument to -map";
3130 }
3131 else if ( strcmp(arg, "-pie") == 0 ) {
3132 fPositionIndependentExecutable = true;
3133 fPIEOnCommandLine = true;
3134 }
3135 else if ( strcmp(arg, "-no_pie") == 0 ) {
3136 fDisablePositionIndependentExecutable = true;
3137 cannotBeUsedWithBitcode(arg);
3138 }
3139 else if ( strncmp(arg, "-reexport-l", 11) == 0 ) {
3140 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3141 snapshotArgCount = 0;
3142 FileInfo info = findLibrary(&arg[11], true);
3143 info.options.fReExport = true;
3144 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3145 addLibrary(info);
3146 cannotBeUsedWithBitcode(arg);
3147 }
3148 else if ( strcmp(arg, "-reexport_library") == 0 ) {
3149 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3150 snapshotArgCount = 0;
3151 FileInfo info = findFile(argv[++i]);
3152 info.options.fReExport = true;
3153 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3154 addLibrary(info);
3155 cannotBeUsedWithBitcode(arg);
3156 }
3157 else if ( strcmp(arg, "-reexport_framework") == 0 ) {
3158 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3159 snapshotArgCount = 0;
3160 FileInfo info = findFramework(argv[++i]);
3161 info.options.fReExport = true;
3162 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3163 addLibrary(info);
3164 cannotBeUsedWithBitcode(arg);
3165 }
3166 else if ( strncmp(arg, "-upward-l", 9) == 0 ) {
3167 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3168 snapshotArgCount = 0;
3169 FileInfo info = findLibrary(&arg[9], true);
3170 info.options.fUpward = true;
3171 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3172 addLibrary(info);
3173 cannotBeUsedWithBitcode(arg);
3174 }
3175 else if ( strcmp(arg, "-upward_library") == 0 ) {
3176 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3177 snapshotArgCount = 0;
3178 FileInfo info = findFile(argv[++i]);
3179 info.options.fUpward = true;
3180 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3181 addLibrary(info);
3182 cannotBeUsedWithBitcode(arg);
3183 }
3184 else if ( strcmp(arg, "-upward_framework") == 0 ) {
3185 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3186 snapshotArgCount = 0;
3187 FileInfo info = findFramework(argv[++i]);
3188 info.options.fUpward = true;
3189 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3190 addLibrary(info);
3191 cannotBeUsedWithBitcode(arg);
3192 }
3193 else if ( strcmp(arg, "-dead_strip_dylibs") == 0 ) {
3194 fDeadStripDylibs = true;
3195 cannotBeUsedWithBitcode(arg);
3196 }
3197 else if ( strcmp(arg, "-no_implicit_dylibs") == 0 ) {
3198 fImplicitlyLinkPublicDylibs = false;
3199 }
3200 else if ( strcmp(arg, "-new_linker") == 0 ) {
3201 // ignore
3202 }
3203 else if ( strcmp(arg, "-no_encryption") == 0 ) {
3204 fEncryptableForceOff = true;
3205 cannotBeUsedWithBitcode(arg);
3206 }
3207 else if ( strcmp(arg, "-encryptable") == 0 ) {
3208 fEncryptableForceOn = true;
3209 cannotBeUsedWithBitcode(arg);
3210 }
3211 else if ( strcmp(arg, "-no_compact_unwind") == 0 ) {
3212 fAddCompactUnwindEncoding = false;
3213 cannotBeUsedWithBitcode(arg);
3214 }
3215 else if ( strcmp(arg, "-mllvm") == 0 ) {
3216 const char* opts = argv[++i];
3217 if ( opts == NULL )
3218 throw "missing argument to -mllvm";
3219 fLLVMOptions.push_back(opts);
3220 cannotBeUsedWithBitcode(arg);
3221 }
3222 else if ( strcmp(arg, "-mcpu") == 0 ) {
3223 const char* cpu = argv[++i];
3224 if ( cpu == NULL )
3225 throw "missing argument to -mcpu";
3226 fLtoCpu = cpu;
3227 cannotBeUsedWithBitcode(arg);
3228 }
3229 else if ( strcmp(arg, "-no_order_inits") == 0 ) {
3230 fAutoOrderInitializers = false;
3231 cannotBeUsedWithBitcode(arg);
3232 }
3233 else if ( strcmp(arg, "-no_order_data") == 0 ) {
3234 fOrderData = false;
3235 cannotBeUsedWithBitcode(arg);
3236 }
3237 else if ( strcmp(arg, "-seg_page_size") == 0 ) {
3238 SegmentSize seg;
3239 seg.name = argv[++i];
3240 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
3241 throw "-seg_page_size missing segName Adddress";
3242 seg.size = parseAddress(argv[++i]);
3243 uint64_t temp = seg.size & (-4096); // page align
3244 if ( (seg.size != temp) )
3245 warning("-seg_page_size %s not 4K aligned, rounding down", seg.name);
3246 fCustomSegmentSizes.push_back(seg);
3247 cannotBeUsedWithBitcode(arg);
3248 }
3249 else if ( strcmp(arg, "-mark_dead_strippable_dylib") == 0 ) {
3250 fMarkDeadStrippableDylib = true;
3251 cannotBeUsedWithBitcode(arg);
3252 }
3253 else if ( strcmp(arg, "-exported_symbols_order") == 0 ) {
3254 snapshotFileArgIndex = 1;
3255 loadSymbolOrderFile(argv[++i], fExportSymbolsOrder);
3256 cannotBeUsedWithBitcode(arg);
3257 }
3258 else if ( strcmp(arg, "-no_compact_linkedit") == 0 ) {
3259 warnObsolete("-no_compact_linkedit");
3260 }
3261 else if ( strcmp(arg, "-no_eh_labels") == 0 ) {
3262 fNoEHLabels = true;
3263 cannotBeUsedWithBitcode(arg);
3264 }
3265 else if ( strcmp(arg, "-warn_compact_unwind") == 0 ) {
3266 fWarnCompactUnwind = true;
3267 }
3268 else if ( strcmp(arg, "-allow_sub_type_mismatches") == 0 ) {
3269 fAllowCpuSubtypeMismatches = true;
3270 cannotBeUsedWithBitcode(arg);
3271 }
3272 else if ( strcmp(arg, "-no_zero_fill_sections") == 0 ) {
3273 fOptimizeZeroFill = false;
3274 cannotBeUsedWithBitcode(arg);
3275 }
3276 else if ( strcmp(arg, "-merge_zero_fill_sections") == 0 ) {
3277 fMergeZeroFill = true;
3278 cannotBeUsedWithBitcode(arg);
3279 }
3280 else if ( strcmp(arg, "-objc_abi_version") == 0 ) {
3281 const char* version = argv[++i];
3282 if ( version == NULL )
3283 throw "-objc_abi_version missing version number";
3284 if ( strcmp(version, "2") == 0 ) {
3285 fObjCABIVersion1Override = false;
3286 fObjCABIVersion2Override = true;
3287 }
3288 else if ( strcmp(version, "1") == 0 ) {
3289 fObjCABIVersion1Override = true;
3290 fObjCABIVersion2Override = false;
3291 }
3292 else
3293 warning("ignoring unrecognized argument (%s) to -objc_abi_version", version);
3294 }
3295 else if ( strcmp(arg, "-warn_weak_exports") == 0 ) {
3296 fWarnWeakExports = true;
3297 }
3298 else if ( strcmp(arg, "-objc_gc_compaction") == 0 ) {
3299 fObjcGcCompaction = true;
3300 cannotBeUsedWithBitcode(arg);
3301 }
3302 else if ( strcmp(arg, "-objc_gc") == 0 ) {
3303 fObjCGc = true;
3304 if ( fObjCGcOnly ) {
3305 warning("-objc_gc overriding -objc_gc_only");
3306 fObjCGcOnly = false;
3307 }
3308 cannotBeUsedWithBitcode(arg);
3309 }
3310 else if ( strcmp(arg, "-objc_gc_only") == 0 ) {
3311 fObjCGcOnly = true;
3312 if ( fObjCGc ) {
3313 warning("-objc_gc_only overriding -objc_gc");
3314 fObjCGc = false;
3315 }
3316 cannotBeUsedWithBitcode(arg);
3317 }
3318 else if ( strcmp(arg, "-demangle") == 0 ) {
3319 fDemangle = true;
3320 }
3321 else if ( strcmp(arg, "-version_load_command") == 0 ) {
3322 fVersionLoadCommandForcedOn = true;
3323 fVersionLoadCommandForcedOff = false;
3324 }
3325 else if ( strcmp(arg, "-no_version_load_command") == 0 ) {
3326 fVersionLoadCommandForcedOff = true;
3327 fVersionLoadCommandForcedOn = false;
3328 cannotBeUsedWithBitcode(arg);
3329 }
3330 else if ( strcmp(arg, "-function_starts") == 0 ) {
3331 fFunctionStartsForcedOn = true;
3332 fFunctionStartsForcedOff = false;
3333 }
3334 else if ( strcmp(arg, "-no_function_starts") == 0 ) {
3335 fFunctionStartsForcedOff = true;
3336 fFunctionStartsForcedOn = false;
3337 cannotBeUsedWithBitcode(arg);
3338 }
3339 else if ( strcmp(arg, "-no_data_in_code_info") == 0 ) {
3340 fDataInCodeInfoLoadCommandForcedOff = true;
3341 fDataInCodeInfoLoadCommandForcedOn = false;
3342 cannotBeUsedWithBitcode(arg);
3343 }
3344 else if ( strcmp(arg, "-data_in_code_info") == 0 ) {
3345 fDataInCodeInfoLoadCommandForcedOn = true;
3346 fDataInCodeInfoLoadCommandForcedOff = false;
3347 }
3348 else if ( strcmp(arg, "-object_path_lto") == 0 ) {
3349 fTempLtoObjectPath = argv[++i];
3350 if ( fTempLtoObjectPath == NULL )
3351 throw "missing argument to -object_path_lto";
3352 }
3353 else if ( strcmp(arg, "-no_objc_category_merging") == 0 ) {
3354 fObjcCategoryMerging = false;
3355 }
3356 else if ( strcmp(arg, "-force_symbols_weak_list") == 0 ) {
3357 snapshotFileArgIndex = 1;
3358 loadExportFile(argv[++i], "-force_symbols_weak_list", fForceWeakSymbols);
3359 cannotBeUsedWithBitcode(arg);
3360 }
3361 else if ( strcmp(arg, "-force_symbols_not_weak_list") == 0 ) {
3362 snapshotFileArgIndex = 1;
3363 loadExportFile(argv[++i], "-force_symbols_not_weak_list", fForceNotWeakSymbols);
3364 cannotBeUsedWithBitcode(arg);
3365 }
3366 else if ( strcmp(arg, "-force_symbol_weak") == 0 ) {
3367 const char* symbol = argv[++i];
3368 if ( symbol == NULL )
3369 throw "-force_symbol_weak missing <symbol>";
3370 fForceWeakSymbols.insert(symbol);
3371 cannotBeUsedWithBitcode(arg);
3372 }
3373 else if ( strcmp(arg, "-force_symbol_not_weak") == 0 ) {
3374 const char* symbol = argv[++i];
3375 if ( symbol == NULL )
3376 throw "-force_symbol_not_weak missing <symbol>";
3377 fForceNotWeakSymbols.insert(symbol);
3378 cannotBeUsedWithBitcode(arg);
3379 }
3380 else if ( strcmp(arg, "-reexported_symbols_list") == 0 ) {
3381 snapshotFileArgIndex = 1;
3382 if ( fExportMode == kExportSome )
3383 throw "can't use -exported_symbols_list and -reexported_symbols_list";
3384 loadExportFile(argv[++i], "-reexported_symbols_list", fReExportSymbols);
3385 }
3386 else if ( strcmp(arg, "-dyld_env") == 0 ) {
3387 const char* envarg = argv[++i];
3388 if ( envarg == NULL )
3389 throw "-dyld_env missing ENV=VALUE";
3390 if ( strchr(envarg, '=') == NULL )
3391 throw "-dyld_env missing ENV=VALUE";
3392 fDyldEnvironExtras.push_back(envarg);
3393 cannotBeUsedWithBitcode(arg);
3394 }
3395 else if ( strcmp(arg, "-page_align_data_atoms") == 0 ) {
3396 fPageAlignDataAtoms = true;
3397 cannotBeUsedWithBitcode(arg);
3398 }
3399 else if (strcmp(arg, "-debug_snapshot") == 0) {
3400 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
3401 fSnapshotRequested = true;
3402 cannotBeUsedWithBitcode(arg);
3403 }
3404 else if (strcmp(arg, "-snapshot_dir") == 0) {
3405 const char* path = argv[++i];
3406 if ( path == NULL )
3407 throw "-snapshot_dir missing path";
3408 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
3409 fLinkSnapshot.setSnapshotPath(path);
3410 fSnapshotRequested = true;
3411 cannotBeUsedWithBitcode(arg);
3412 }
3413 else if ( strcmp(arg, "-new_main") == 0 ) {
3414 fEntryPointLoadCommandForceOn = true;
3415 cannotBeUsedWithBitcode(arg);
3416 }
3417 else if ( strcmp(arg, "-no_new_main") == 0 ) {
3418 fEntryPointLoadCommandForceOff = true;
3419 cannotBeUsedWithBitcode(arg);
3420 }
3421 else if ( strcmp(arg, "-source_version") == 0 ) {
3422 const char* vers = argv[++i];
3423 if ( vers == NULL )
3424 throw "-source_version missing <version>";
3425 fSourceVersion = parseVersionNumber64(vers);
3426 }
3427 else if ( strcmp(arg, "-add_source_version") == 0 ) {
3428 fSourceVersionLoadCommandForceOn = true;
3429 }
3430 else if ( strcmp(arg, "-no_source_version") == 0 ) {
3431 fSourceVersionLoadCommandForceOff = true;
3432 cannotBeUsedWithBitcode(arg);
3433 }
3434 else if ( strcmp(arg, "-sdk_version") == 0 ) {
3435 const char* vers = argv[++i];
3436 if ( vers == NULL )
3437 throw "-sdk_version missing <version>";
3438 fSDKVersion = parseVersionNumber32(vers);
3439 }
3440 else if ( strcmp(arg, "-dependent_dr_info") == 0 ) {
3441 warnObsolete(arg);
3442 }
3443 else if ( strcmp(arg, "-no_dependent_dr_info") == 0 ) {
3444 warnObsolete(arg);
3445 }
3446 else if ( strcmp(arg, "-kexts_use_stubs") == 0 ) {
3447 fKextsUseStubs = true;
3448 cannotBeUsedWithBitcode(arg);
3449 }
3450 else if ( strcmp(argv[i], "-dependency_info") == 0 ) {
3451 snapshotArgCount = 0;
3452 ++i;
3453 // previously handled by buildSearchPaths()
3454 }
3455 else if ( strcmp(arg, "-export_dynamic") == 0 ) {
3456 fExportDynamic = true;
3457 }
3458 else if ( strcmp(arg, "-force_symbols_coalesce_list") == 0 ) {
3459 snapshotFileArgIndex = 1;
3460 loadExportFile(argv[++i], "-force_symbols_coalesce_list", fForceCoalesceSymbols);
3461 }
3462 else if ( strcmp(arg, "-add_linker_option") == 0 ) {
3463 // ex: -add_linker_option '-framework Foundation'
3464 const char* optString = argv[++i];
3465 if ( optString == NULL )
3466 throw "-add_linker_option missing <option>";
3467 // break up into list of tokens at whitespace
3468 std::vector<const char*> opts;
3469 char* buffer = strdup(optString);
3470 char* start = buffer;
3471 for (char* s = buffer; ; ++s) {
3472 if ( isspace(*s) ) {
3473 *s = '\0';
3474 opts.push_back(start);
3475 start = s+1;
3476 }
3477 else if ( *s == '\0' ) {
3478 opts.push_back(start);
3479 break;
3480 }
3481 }
3482 fLinkerOptions.push_back(opts);
3483 cannotBeUsedWithBitcode(arg);
3484 }
3485 else if ( strcmp(arg, "-allow_simulator_linking_to_macosx_dylibs") == 0 ) {
3486 fAllowSimulatorToLinkWithMacOSX = true;
3487 cannotBeUsedWithBitcode(arg);
3488 }
3489 else if ( strcmp(arg, "-keep_dwarf_unwind") == 0 ) {
3490 fKeepDwarfUnwindForcedOn = true;
3491 fKeepDwarfUnwindForcedOff = false;
3492 cannotBeUsedWithBitcode(arg);
3493 }
3494 else if ( strcmp(arg, "-no_keep_dwarf_unwind") == 0 ) {
3495 fKeepDwarfUnwindForcedOn = false;
3496 fKeepDwarfUnwindForcedOff = true;
3497 cannotBeUsedWithBitcode(arg);
3498 }
3499 else if ( strcmp(arg, "-verbose_optimization_hints") == 0 ) {
3500 fVerboseOptimizationHints = true;
3501 }
3502 else if ( strcmp(arg, "-ignore_optimization_hints") == 0 ) {
3503 fIgnoreOptimizationHints = true;
3504 cannotBeUsedWithBitcode(arg);
3505 }
3506 else if ( strcmp(arg, "-no_dtrace_dof") == 0 ) {
3507 fGenerateDtraceDOF = false;
3508 }
3509 else if ( strcmp(arg, "-rename_section") == 0 ) {
3510 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) || (argv[i+4]==NULL) )
3511 throw "-rename_section missing <segment> <section> <segment> <section>";
3512 addSectionRename(argv[i+1], argv[i+2], argv[i+3], argv[i+4]);
3513 i += 4;
3514 cannotBeUsedWithBitcode(arg);
3515 }
3516 else if ( strcmp(arg, "-rename_segment") == 0 ) {
3517 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3518 throw "-rename_segment missing <existing-segment> <new-segment>";
3519 addSegmentRename(argv[i+1], argv[i+2]);
3520 i += 2;
3521 cannotBeUsedWithBitcode(arg);
3522 }
3523 else if ( strcmp(arg, "-move_to_ro_segment") == 0 ) {
3524 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3525 throw "-move_to_ro_segment missing <segment> <symbol-list-file>";
3526 addSymbolMove(argv[i+1], argv[i+2], fSymbolsMovesCode, "-move_to_ro_segment");
3527 i += 2;
3528 cannotBeUsedWithBitcode(arg);
3529 }
3530 else if ( strcmp(arg, "-move_to_rw_segment") == 0 ) {
3531 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3532 throw "-move_to_rw_segment missing <segment> <symbol-list-file>";
3533 addSymbolMove(argv[i+1], argv[i+2], fSymbolsMovesData, "-move_to_rw_segment");
3534 i += 2;
3535 cannotBeUsedWithBitcode(arg);
3536 }
3537 else if ( strcmp(arg, "-trace_symbol_layout") == 0 ) {
3538 fTraceSymbolLayout = true;
3539 }
3540 else if ( strcmp(arg, "-no_branch_islands") == 0 ) {
3541 fAllowBranchIslands = false;
3542 cannotBeUsedWithBitcode(arg);
3543 }
3544 else if ( strcmp(arg, "-segment_order") == 0 ) {
3545 // ex: -segment_order __TEXT:__DATA:__JUNK
3546 const char* optString = argv[++i];
3547 if ( optString == NULL )
3548 throw "-segment_order missing colon separated <segment-list>";
3549 if ( !fSegmentOrder.empty() )
3550 throw "-segment_order used more than once";
3551 // break up into list of tokens at colon
3552 char* buffer = strdup(optString);
3553 char* start = buffer;
3554 for (char* s = buffer; ; ++s) {
3555 if ( *s == ':' ) {
3556 *s = '\0';
3557 fSegmentOrder.push_back(start);
3558 start = s+1;
3559 }
3560 else if ( *s == '\0' ) {
3561 fSegmentOrder.push_back(start);
3562 break;
3563 }
3564 }
3565 cannotBeUsedWithBitcode(arg);
3566 }
3567 else if ( strcmp(arg, "-section_order") == 0 ) {
3568 // ex: -section_order __DATA __data:__const:__nl_pointers
3569 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
3570 throw "-section_order missing <segment> <section-list>";
3571 const char* segName = argv[++i];
3572 const char* optString = argv[++i];
3573 if ( sectionOrder(segName) != NULL )
3574 throwf("-section_order %s ... used more than once", segName);
3575 SectionOrderList dummy;
3576 fSectionOrder.push_back(dummy);
3577 SectionOrderList& entry = fSectionOrder.back();
3578 entry.segmentName = segName;
3579 // break up into list of tokens at colon
3580 char* buffer = strdup(optString);
3581 char* start = buffer;
3582 for (char* s = buffer; ; ++s) {
3583 if ( *s == ':' ) {
3584 *s = '\0';
3585 entry.sectionOrder.push_back(start);
3586 start = s+1;
3587 }
3588 else if ( *s == '\0' ) {
3589 entry.sectionOrder.push_back(start);
3590 break;
3591 }
3592 }
3593 cannotBeUsedWithBitcode(arg);
3594 }
3595 else if ( strcmp(arg, "-application_extension") == 0 ) {
3596 fMarkAppExtensionSafe = true;
3597 fCheckAppExtensionSafe = true;
3598 }
3599 else if ( strcmp(arg, "-no_application_extension") == 0 ) {
3600 fMarkAppExtensionSafe = false;
3601 fCheckAppExtensionSafe = false;
3602 }
3603 else if ( strcmp(arg, "-add_ast_path") == 0 ) {
3604 const char* path = argv[++i];
3605 if ( path == NULL )
3606 throw "-add_ast_path missing <option>";
3607 fASTFilePaths.push_back(path);
3608 }
3609 else if ( strcmp(arg, "-force_load_swift_libs") == 0 ) {
3610 fForceLoadSwiftLibs = true;
3611 }
3612 else if ( strcmp(arg, "-not_for_dyld_shared_cache") == 0 ) {
3613 fSharedRegionEligibleForceOff = true;
3614 cannotBeUsedWithBitcode(arg);
3615 }
3616 else if ( strcmp(arg, "-dirty_data_list") == 0 ) {
3617 if ( argv[i+1] == NULL )
3618 throw "-dirty_data_list missing <symbol-list-file>";
3619 addSymbolMove("__DATA_DIRTY", argv[i+1], fSymbolsMovesData, "-dirty_data_list");
3620 ++i;
3621 cannotBeUsedWithBitcode(arg);
3622 }
3623 else if ( strcmp(arg, "-data_const") == 0 ) {
3624 fUseDataConstSegmentForceOn = true;
3625 cannotBeUsedWithBitcode(arg);
3626 }
3627 else if ( strcmp(arg, "-no_data_const") == 0 ) {
3628 fUseDataConstSegmentForceOff = true;
3629 cannotBeUsedWithBitcode(arg);
3630 }
3631 // put this last so that it does not interfer with other options starting with 'i'
3632 else if ( strncmp(arg, "-i", 2) == 0 ) {
3633 const char* colon = strchr(arg, ':');
3634 if ( colon == NULL )
3635 throwf("unknown option: %s", arg);
3636 Options::AliasPair pair;
3637 char* temp = new char[colon-arg];
3638 strlcpy(temp, &arg[2], colon-arg-1);
3639 pair.realName = &colon[1];
3640 pair.alias = temp;
3641 fAliases.push_back(pair);
3642 }
3643 else {
3644 throwf("unknown option: %s", arg);
3645 }
3646
3647 if (snapshotArgCount == -1)
3648 snapshotArgCount = i-snapshotArgIndex+1;
3649 if (snapshotArgCount > 0)
3650 fLinkSnapshot.addSnapshotLinkArg(snapshotArgIndex, snapshotArgCount, snapshotFileArgIndex);
3651 }
3652 else {
3653 FileInfo info = findFile(arg);
3654 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
3655 if ( strcmp(&info.path[strlen(info.path)-2], ".a") == 0 )
3656 addLibrary(info);
3657 else
3658 fInputFiles.push_back(info);
3659 }
3660 }
3661
3662 // if a -lazy option was used, implicitly link in lazydylib1.o
3663 if ( fUsingLazyDylibLinking ) {
3664 FileInfo info = findLibrary("lazydylib1.o");
3665 info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)argc);
3666 addLibrary(info);
3667 }
3668
3669 if (fSnapshotRequested)
3670 fLinkSnapshot.createSnapshot();
3671 }
3672
3673
3674
3675 //
3676 // -syslibroot <path> is used for SDK support.
3677 // The rule is that all search paths (both explicit and default) are
3678 // checked to see if they exist in the SDK. If so, that path is
3679 // replaced with the sdk prefixed path. If not, that search path
3680 // is used as is. If multiple -syslibroot options are specified
3681 // their directory structures are logically overlayed and files
3682 // from sdks specified earlier on the command line used before later ones.
3683
3684 void Options::buildSearchPaths(int argc, const char* argv[])
3685 {
3686 bool addStandardLibraryDirectories = true;
3687 std::vector<const char*> libraryPaths;
3688 std::vector<const char*> frameworkPaths;
3689 libraryPaths.reserve(10);
3690 frameworkPaths.reserve(10);
3691 // scan through argv looking for -L, -F, -Z, and -syslibroot options
3692 for(int i=0; i < argc; ++i) {
3693 if ( (argv[i][0] == '-') && (argv[i][1] == 'L') ) {
3694 const char* libSearchDir = &argv[i][2];
3695 // Allow either "-L{path}" or "-L {path}".
3696 if (argv[i][2] == '\0') {
3697 // -L {path}. Make sure there is an argument following this.
3698 const char* path = argv[++i];
3699 if ( path == NULL )
3700 throw "-L missing argument";
3701 libSearchDir = path;
3702 }
3703 if ( libSearchDir[0] == '\0' )
3704 throw "-L must be immediately followed by a directory path (no space)";
3705 struct stat statbuf;
3706 if ( stat(libSearchDir, &statbuf) == 0 ) {
3707 if ( statbuf.st_mode & S_IFDIR )
3708 libraryPaths.push_back(libSearchDir);
3709 else
3710 warning("path '%s' following -L not a directory", libSearchDir);
3711 }
3712 else {
3713 warning("directory not found for option '-L%s'", libSearchDir);
3714 }
3715 }
3716 else if ( (argv[i][0] == '-') && (argv[i][1] == 'F') ) {
3717 const char* frameworkSearchDir = &argv[i][2];
3718 // Allow either "-F{path}" or "-F {path}".
3719 if (argv[i][2] == '\0') {
3720 // -F {path}. Make sure there is an argument following this.
3721 const char* path = argv[++i];
3722 if ( path == NULL )
3723 throw "-F missing argument";
3724 frameworkSearchDir = path;
3725 }
3726 if ( frameworkSearchDir[0] == '\0' )
3727 throw "-F must be immediately followed by a directory path (no space)";
3728 struct stat statbuf;
3729 if ( stat(frameworkSearchDir, &statbuf) == 0 ) {
3730 if ( statbuf.st_mode & S_IFDIR )
3731 frameworkPaths.push_back(frameworkSearchDir);
3732 else
3733 warning("path '%s' following -F not a directory", frameworkSearchDir);
3734 }
3735 else {
3736 warning("directory not found for option '-F%s'", frameworkSearchDir);
3737 }
3738 }
3739 else if ( strcmp(argv[i], "-Z") == 0 )
3740 addStandardLibraryDirectories = false;
3741 else if ( strcmp(argv[i], "-v") == 0 ) {
3742 fVerbose = true;
3743 extern const char ldVersionString[];
3744 fprintf(stderr, "%s", ldVersionString);
3745 fprintf(stderr, "configured to support archs: %s\n", ALL_SUPPORTED_ARCHS);
3746 // if only -v specified, exit cleanly
3747 if ( argc == 2 ) {
3748 const char* ltoVers = lto::version();
3749 if ( ltoVers != NULL )
3750 fprintf(stderr, "LTO support using: %s\n", ltoVers);
3751 exit(0);
3752 }
3753 }
3754 else if ( strcmp(argv[i], "-syslibroot") == 0 ) {
3755 const char* path = argv[++i];
3756 if ( path == NULL )
3757 throw "-syslibroot missing argument";
3758 fSDKPaths.push_back(path);
3759 }
3760 else if ( strcmp(argv[i], "-search_paths_first") == 0 ) {
3761 fLibrarySearchMode = kSearchDylibAndArchiveInEachDir;
3762 }
3763 else if ( strcmp(argv[i], "-search_dylibs_first") == 0 ) {
3764 fLibrarySearchMode = kSearchAllDirsForDylibsThenAllDirsForArchives;
3765 }
3766 else if ( strcmp(argv[i], "-w") == 0 ) {
3767 sEmitWarnings = false;
3768 }
3769 else if ( strcmp(argv[i], "-fatal_warnings") == 0 ) {
3770 sFatalWarnings = true;
3771 }
3772 else if ( strcmp(argv[i], "-dependency_info") == 0 ) {
3773 const char* path = argv[++i];
3774 if ( path == NULL )
3775 throw "-dependency_info missing <path>";
3776 fDependencyInfoPath = path;
3777 }
3778 else if ( strcmp(argv[i], "-bitcode_bundle") == 0 ) {
3779 fBundleBitcode = true;
3780 }
3781 }
3782 int standardLibraryPathsStartIndex = libraryPaths.size();
3783 int standardFrameworkPathsStartIndex = frameworkPaths.size();
3784 if ( addStandardLibraryDirectories ) {
3785 libraryPaths.push_back("/usr/lib");
3786 libraryPaths.push_back("/usr/local/lib");
3787
3788 frameworkPaths.push_back("/Library/Frameworks/");
3789 frameworkPaths.push_back("/System/Library/Frameworks/");
3790 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
3791 }
3792
3793 // <rdar://problem/5829579> Support for configure based hacks
3794 // if last -syslibroot is /, then ignore all syslibroots
3795 if ( fSDKPaths.size() > 0 ) {
3796 if ( strcmp(fSDKPaths.back(), "/") == 0 ) {
3797 fSDKPaths.clear();
3798 }
3799 }
3800
3801 // now merge sdk and library paths to make real search paths
3802 fLibrarySearchPaths.reserve(libraryPaths.size()*(fSDKPaths.size()+1));
3803 int libIndex = 0;
3804 for (std::vector<const char*>::iterator it = libraryPaths.begin(); it != libraryPaths.end(); ++it, ++libIndex) {
3805 const char* libDir = *it;
3806 bool sdkOverride = false;
3807 if ( libDir[0] == '/' ) {
3808 char betterLibDir[PATH_MAX];
3809 if ( strstr(libDir, "/..") != NULL ) {
3810 if ( realpath(libDir, betterLibDir) != NULL )
3811 libDir = strdup(betterLibDir);
3812 }
3813 const int libDirLen = strlen(libDir);
3814 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
3815 const char* sdkDir = *sdkit;
3816 const int sdkDirLen = strlen(sdkDir);
3817 char newPath[libDirLen + sdkDirLen+4];
3818 strcpy(newPath, sdkDir);
3819 if ( newPath[sdkDirLen-1] == '/' )
3820 newPath[sdkDirLen-1] = '\0';
3821 strcat(newPath, libDir);
3822 struct stat statBuffer;
3823 if ( stat(newPath, &statBuffer) == 0 ) {
3824 fLibrarySearchPaths.push_back(strdup(newPath));
3825 sdkOverride = true;
3826 }
3827 }
3828 }
3829 if ( !sdkOverride ) {
3830 if ( (libIndex >= standardLibraryPathsStartIndex) && (fSDKPaths.size() == 1) ) {
3831 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3832 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3833 }
3834 else {
3835 fLibrarySearchPaths.push_back(libDir);
3836 }
3837 }
3838 }
3839
3840 // now merge sdk and framework paths to make real search paths
3841 fFrameworkSearchPaths.reserve(frameworkPaths.size()*(fSDKPaths.size()+1));
3842 int frameIndex = 0;
3843 for (std::vector<const char*>::iterator it = frameworkPaths.begin(); it != frameworkPaths.end(); ++it, ++frameIndex) {
3844 const char* frameworkDir = *it;
3845 bool sdkOverride = false;
3846 if ( frameworkDir[0] == '/' ) {
3847 char betterFrameworkDir[PATH_MAX];
3848 if ( strstr(frameworkDir, "/..") != NULL ) {
3849 if ( realpath(frameworkDir, betterFrameworkDir) != NULL )
3850 frameworkDir = strdup(betterFrameworkDir);
3851 }
3852 const int frameworkDirLen = strlen(frameworkDir);
3853 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
3854 const char* sdkDir = *sdkit;
3855 const int sdkDirLen = strlen(sdkDir);
3856 char newPath[frameworkDirLen + sdkDirLen+4];
3857 strcpy(newPath, sdkDir);
3858 if ( newPath[sdkDirLen-1] == '/' )
3859 newPath[sdkDirLen-1] = '\0';
3860 strcat(newPath, frameworkDir);
3861 struct stat statBuffer;
3862 if ( stat(newPath, &statBuffer) == 0 ) {
3863 fFrameworkSearchPaths.push_back(strdup(newPath));
3864 sdkOverride = true;
3865 }
3866 }
3867 }
3868 if ( !sdkOverride ) {
3869 if ( (frameIndex >= standardFrameworkPathsStartIndex) && (fSDKPaths.size() == 1) ) {
3870 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3871 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3872 }
3873 else {
3874 fFrameworkSearchPaths.push_back(frameworkDir);
3875 }
3876 }
3877 }
3878
3879 if ( fVerbose ) {
3880 fprintf(stderr,"Library search paths:\n");
3881 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
3882 it != fLibrarySearchPaths.end();
3883 it++)
3884 fprintf(stderr,"\t%s\n", *it);
3885 fprintf(stderr,"Framework search paths:\n");
3886 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
3887 it != fFrameworkSearchPaths.end();
3888 it++)
3889 fprintf(stderr,"\t%s\n", *it);
3890 }
3891 }
3892
3893 // this is run before the command line is parsed
3894 void Options::parsePreCommandLineEnvironmentSettings()
3895 {
3896 if ((getenv("LD_TRACE_ARCHIVES") != NULL)
3897 || (getenv("RC_TRACE_ARCHIVES") != NULL))
3898 fTraceArchives = true;
3899
3900 if ((getenv("LD_TRACE_DYLIBS") != NULL)
3901 || (getenv("RC_TRACE_DYLIBS") != NULL)) {
3902 fTraceDylibs = true;
3903 fTraceIndirectDylibs = true;
3904 }
3905
3906 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL) {
3907 fTraceDylibSearching = true;
3908 }
3909
3910 if (getenv("LD_PRINT_OPTIONS") != NULL)
3911 fPrintOptions = true;
3912
3913 if (fTraceDylibs || fTraceArchives)
3914 fTraceOutputFile = getenv("LD_TRACE_FILE");
3915
3916 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL)
3917 fPrintOrderFileStatistics = true;
3918
3919 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL)
3920 fSplitSegs = true;
3921
3922 if (getenv("LD_NO_ENCRYPT") != NULL) {
3923 fEncryptable = false;
3924 fMarkAppExtensionSafe = true; // temporary
3925 fCheckAppExtensionSafe = false;
3926 }
3927
3928 if (getenv("LD_APPLICATION_EXTENSION_SAFE") != NULL) {
3929 fMarkAppExtensionSafe = true;
3930 fCheckAppExtensionSafe = false;
3931 }
3932
3933 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL)
3934 fAllowCpuSubtypeMismatches = true;
3935
3936 sWarningsSideFilePath = getenv("LD_WARN_FILE");
3937
3938 const char* customDyldPath = getenv("LD_DYLD_PATH");
3939 if ( customDyldPath != NULL )
3940 fDyldInstallPath = customDyldPath;
3941
3942 const char* debugArchivePath = getenv("LD_DEBUG_SNAPSHOT");
3943 if (debugArchivePath != NULL) {
3944 fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
3945 if (strlen(debugArchivePath) > 0)
3946 fLinkSnapshot.setSnapshotPath(debugArchivePath);
3947 fSnapshotRequested = true;
3948 }
3949
3950 const char* pipeFdString = getenv("LD_PIPELINE_FIFO");
3951 if (pipeFdString != NULL) {
3952 fPipelineFifo = pipeFdString;
3953 }
3954 }
3955
3956
3957 // this is run after the command line is parsed
3958 void Options::parsePostCommandLineEnvironmentSettings()
3959 {
3960 // when building a dynamic main executable, default any use of @executable_path to output path
3961 if ( fExecutablePath == NULL && (fOutputKind == kDynamicExecutable) ) {
3962 fExecutablePath = fOutputFile;
3963 }
3964
3965 // allow build system to set default seg_addr_table
3966 if ( fSegAddrTablePath == NULL )
3967 fSegAddrTablePath = getenv("LD_SEG_ADDR_TABLE");
3968
3969 // allow build system to turn on prebinding
3970 if ( !fPrebind ) {
3971 fPrebind = ( getenv("LD_PREBIND") != NULL );
3972 }
3973
3974 // allow build system to force on dead-code-stripping
3975 if ( !fDeadStrip ) {
3976 if ( getenv("LD_DEAD_STRIP") != NULL ) {
3977 switch (fOutputKind) {
3978 case Options::kDynamicLibrary:
3979 case Options::kDynamicExecutable:
3980 case Options::kDynamicBundle:
3981 fDeadStrip = true;
3982 break;
3983 case Options::kPreload:
3984 case Options::kObjectFile:
3985 case Options::kDyld:
3986 case Options::kStaticExecutable:
3987 case Options::kKextBundle:
3988 break;
3989 }
3990 }
3991 }
3992
3993 // allow build system to force on -warn_commons
3994 if ( getenv("LD_WARN_COMMONS") != NULL )
3995 fWarnCommons = true;
3996
3997 // allow B&I to set default -source_version
3998 if ( fSourceVersion == 0 ) {
3999 const char* vers = getenv("RC_ProjectSourceVersion");
4000 if ( vers != NULL )
4001 fSourceVersion = parseVersionNumber64(vers);
4002 }
4003
4004 }
4005
4006 void Options::reconfigureDefaults()
4007 {
4008 // sync reader options
4009 switch ( fOutputKind ) {
4010 case Options::kObjectFile:
4011 fForFinalLinkedImage = false;
4012 break;
4013 case Options::kDyld:
4014 fForDyld = true;
4015 fForFinalLinkedImage = true;
4016 fNoEHLabels = true;
4017 break;
4018 case Options::kDynamicLibrary:
4019 case Options::kDynamicBundle:
4020 case Options::kKextBundle:
4021 fForFinalLinkedImage = true;
4022 fNoEHLabels = true;
4023 break;
4024 case Options::kDynamicExecutable:
4025 case Options::kStaticExecutable:
4026 case Options::kPreload:
4027 fLinkingMainExecutable = true;
4028 fForFinalLinkedImage = true;
4029 fNoEHLabels = true;
4030 break;
4031 }
4032
4033 // set default min OS version
4034 if ( (fMacVersionMin == ld::macVersionUnset) && (fIOSVersionMin == ld::iOSVersionUnset) && (fWatchOSVersionMin == ld::wOSVersionUnset) ) {
4035 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
4036 const char* macVers = getenv("MACOSX_DEPLOYMENT_TARGET");
4037 const char* iPhoneVers = getenv("IPHONEOS_DEPLOYMENT_TARGET");
4038 const char* iOSVers = getenv("IOS_DEPLOYMENT_TARGET");
4039 const char* wOSVers = getenv("WATCHOS_DEPLOYMENT_TARGET");
4040 if ( macVers != NULL )
4041 setMacOSXVersionMin(macVers);
4042 else if ( iPhoneVers != NULL )
4043 setIOSVersionMin(iPhoneVers);
4044 else if ( iOSVers != NULL )
4045 setIOSVersionMin(iOSVers);
4046 else if ( wOSVers != NULL )
4047 setWatchOSVersionMin(wOSVers);
4048 else {
4049 // if still nothing, set default based on architecture
4050 switch ( fArchitecture ) {
4051 case CPU_TYPE_I386:
4052 case CPU_TYPE_X86_64:
4053 if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
4054 #ifdef DEFAULT_MACOSX_MIN_VERSION
4055 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION);
4056 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
4057 #else
4058 warning("-macosx_version_min not specified, assuming 10.6");
4059 setMacOSXVersionMin("10.6");
4060 #endif
4061 }
4062 break;
4063 case CPU_TYPE_ARM:
4064 if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
4065 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
4066 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION);
4067 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION);
4068 #else
4069 if ( fSubArchitecture == CPU_SUBTYPE_ARM_V7K ) {
4070 warning("-watchos_version_min not specified, assuming 2.0");
4071 setWatchOSVersionMin("2.0");
4072 }
4073 else {
4074 warning("-ios_version_min not specified, assuming 6.0");
4075 setIOSVersionMin("6.0");
4076 }
4077 #endif
4078 }
4079 break;
4080 default:
4081 // architecture will be infered later by examining .o files
4082 break;
4083 }
4084 }
4085 }
4086
4087
4088 // adjust min based on architecture
4089 switch ( fArchitecture ) {
4090 case CPU_TYPE_I386:
4091 if ( (fPlatform == kPlatformOSX) && (fMacVersionMin < ld::mac10_4) ) {
4092 //warning("-macosx_version_min should be 10.4 or later for i386");
4093 fMacVersionMin = ld::mac10_4;
4094 }
4095 break;
4096 case CPU_TYPE_X86_64:
4097 if ( (fPlatform == kPlatformOSX) && (fMacVersionMin < ld::mac10_4) ) {
4098 //warning("-macosx_version_min should be 10.4 or later for x86_64");
4099 fMacVersionMin = ld::mac10_4;
4100 }
4101 break;
4102 case CPU_TYPE_ARM64:
4103 if ( (fPlatform == kPlatformiOS) && (fIOSVersionMin < ld::iOS_7_0) ) {
4104 //warning("-mios_version_min should be 7.0 or later for arm64");
4105 fIOSVersionMin = ld::iOS_7_0;
4106 }
4107 break;
4108 }
4109
4110 // default to adding functions start for dynamic code, static code must opt-in
4111 switch ( fOutputKind ) {
4112 case Options::kPreload:
4113 case Options::kStaticExecutable:
4114 case Options::kKextBundle:
4115 if ( fDataInCodeInfoLoadCommandForcedOn )
4116 fDataInCodeInfoLoadCommand = true;
4117 if ( fFunctionStartsForcedOn )
4118 fFunctionStartsLoadCommand = true;
4119 break;
4120 case Options::kObjectFile:
4121 if ( !fDataInCodeInfoLoadCommandForcedOff )
4122 fDataInCodeInfoLoadCommand = true;
4123 if ( fFunctionStartsForcedOn )
4124 fFunctionStartsLoadCommand = true;
4125 break;
4126 case Options::kDynamicExecutable:
4127 case Options::kDyld:
4128 case Options::kDynamicLibrary:
4129 case Options::kDynamicBundle:
4130 if ( !fDataInCodeInfoLoadCommandForcedOff )
4131 fDataInCodeInfoLoadCommand = true;
4132 if ( !fFunctionStartsForcedOff )
4133 fFunctionStartsLoadCommand = true;
4134 break;
4135 }
4136
4137 // adjust kext type based on architecture
4138 if ( fOutputKind == kKextBundle ) {
4139 switch ( fArchitecture ) {
4140 case CPU_TYPE_X86_64:
4141 // x86_64 uses new MH_KEXT_BUNDLE type
4142 fMakeCompressedDyldInfo = false;
4143 fMakeCompressedDyldInfoForceOff = true;
4144 fAllowTextRelocs = true;
4145 fUndefinedTreatment = kUndefinedDynamicLookup;
4146 break;
4147 case CPU_TYPE_ARM64:
4148 // arm64 uses new MH_KEXT_BUNDLE type
4149 fMakeCompressedDyldInfo = false;
4150 fMakeCompressedDyldInfoForceOff = true;
4151 fAllowTextRelocs = false;
4152 fKextsUseStubs = true;
4153 fUndefinedTreatment = kUndefinedDynamicLookup;
4154 break;
4155 case CPU_TYPE_ARM:
4156 if ( min_iOS(ld::iOS_5_0) ) {
4157 // iOS 5.0 and later use new MH_KEXT_BUNDLE type
4158 fMakeCompressedDyldInfo = false;
4159 fMakeCompressedDyldInfoForceOff = true;
4160 // kexts are PIC in iOS 6.0 and later
4161 fAllowTextRelocs = !min_iOS(ld::iOS_6_0);
4162 fKextsUseStubs = !fAllowTextRelocs;
4163 fUndefinedTreatment = kUndefinedDynamicLookup;
4164 break;
4165 }
4166 // else use object file
4167 case CPU_TYPE_I386:
4168 // use .o files
4169 fOutputKind = kObjectFile;
4170 break;
4171 }
4172 }
4173
4174 // disable implicit dylibs when targeting 10.3
4175 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
4176 if ( !minOS(ld::mac10_4, ld::iOS_2_0) )
4177 fImplicitlyLinkPublicDylibs = false;
4178
4179
4180 // allow build system to force linker to ignore -prebind
4181 if ( getenv("LD_FORCE_NO_PREBIND") != NULL )
4182 fPrebind = false;
4183
4184 // allow build system to force linker to ignore -seg_addr_table
4185 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL )
4186 fSegAddrTablePath = NULL;
4187
4188 // check for base address specified externally
4189 if ( (fSegAddrTablePath != NULL) && (fOutputKind == Options::kDynamicLibrary) ) {
4190 parseSegAddrTable(fSegAddrTablePath, this->installPath());
4191 // HACK to support seg_addr_table entries that are physical paths instead of install paths
4192 if ( fBaseAddress == 0 ) {
4193 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
4194 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.4.dylib");
4195 if ( fBaseAddress == 0 )
4196 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.9.dylib");
4197 }
4198
4199 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
4200 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libz.1.2.3.dylib");
4201
4202 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
4203 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libutil1.0.dylib");
4204 }
4205 }
4206
4207 // split segs only allowed for dylibs
4208 if ( fSplitSegs ) {
4209 // split seg only supported for i386, and arm.
4210 switch ( fArchitecture ) {
4211 case CPU_TYPE_I386:
4212 if ( fOutputKind != Options::kDynamicLibrary )
4213 fSplitSegs = false;
4214 // make sure read and write segments are proper distance apart
4215 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x10000000) )
4216 fBaseWritableAddress = fBaseAddress + 0x10000000;
4217 break;
4218 case CPU_TYPE_ARM:
4219 if ( fOutputKind != Options::kDynamicLibrary ) {
4220 fSplitSegs = false;
4221 }
4222 else {
4223 // make sure read and write segments are proper distance apart
4224 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x08000000) )
4225 fBaseWritableAddress = fBaseAddress + 0x08000000;
4226 }
4227 break;
4228 default:
4229 fSplitSegs = false;
4230 fBaseAddress = 0;
4231 fBaseWritableAddress = 0;
4232 }
4233 }
4234
4235 // set too-large size
4236 switch ( fArchitecture ) {
4237 case CPU_TYPE_I386:
4238 fMaxAddress = 0xFFFFFFFF;
4239 break;
4240 case CPU_TYPE_X86_64:
4241 break;
4242 case CPU_TYPE_ARM:
4243 switch ( fOutputKind ) {
4244 case Options::kDynamicExecutable:
4245 case Options::kDynamicLibrary:
4246 case Options::kDynamicBundle:
4247 // user land code is limited to low 1GB
4248 fMaxAddress = 0x2FFFFFFF;
4249 break;
4250 case Options::kStaticExecutable:
4251 case Options::kObjectFile:
4252 case Options::kDyld:
4253 case Options::kPreload:
4254 case Options::kKextBundle:
4255 fMaxAddress = 0xFFFFFFFF;
4256 break;
4257 }
4258 // range check -seg1addr for ARM
4259 if ( fBaseAddress > fMaxAddress ) {
4260 warning("ignoring -seg1addr 0x%08llX. Address out of range.", fBaseAddress);
4261 fBaseAddress = 0;
4262 }
4263 break;
4264 }
4265
4266 // <rdar://problem/6138961> -r implies no prebinding for all architectures
4267 if ( fOutputKind == Options::kObjectFile )
4268 fPrebind = false;
4269
4270 // disable prebinding depending on arch and min OS version
4271 if ( fPrebind ) {
4272 switch ( fArchitecture ) {
4273 case CPU_TYPE_I386:
4274 if ( fMacVersionMin == ld::mac10_4 ) {
4275 // in 10.4 only split seg dylibs are prebound
4276 if ( (fOutputKind != Options::kDynamicLibrary) || ! fSplitSegs )
4277 fPrebind = false;
4278 }
4279 else if ( fMacVersionMin >= ld::mac10_5 ) {
4280 // in 10.5 nothing is prebound
4281 fPrebind = false;
4282 }
4283 else if ( fIOSVersionMin != ld::iOSVersionUnset ) {
4284 // nothing in simulator is prebound
4285 fPrebind = false;
4286 }
4287 else {
4288 // in 10.3 and earlier only dylibs and main executables could be prebound
4289 switch ( fOutputKind ) {
4290 case Options::kDynamicExecutable:
4291 case Options::kDynamicLibrary:
4292 // only main executables and dylibs can be prebound
4293 break;
4294 case Options::kStaticExecutable:
4295 case Options::kDynamicBundle:
4296 case Options::kObjectFile:
4297 case Options::kDyld:
4298 case Options::kPreload:
4299 case Options::kKextBundle:
4300 // disable prebinding for everything else
4301 fPrebind = false;
4302 break;
4303 }
4304 }
4305 break;
4306 case CPU_TYPE_X86_64:
4307 fPrebind = false;
4308 break;
4309 case CPU_TYPE_ARM:
4310 switch ( fOutputKind ) {
4311 case Options::kDynamicExecutable:
4312 case Options::kDynamicLibrary:
4313 // only main executables and dylibs can be prebound
4314 break;
4315 case Options::kStaticExecutable:
4316 case Options::kDynamicBundle:
4317 case Options::kObjectFile:
4318 case Options::kDyld:
4319 case Options::kPreload:
4320 case Options::kKextBundle:
4321 // disable prebinding for everything else
4322 fPrebind = false;
4323 break;
4324 }
4325 break;
4326 }
4327 }
4328
4329 // only prebound images can be split-seg
4330 if ( fSplitSegs && !fPrebind )
4331 fSplitSegs = false;
4332
4333 // determine if info for shared region should be added
4334 if ( fOutputKind == Options::kDynamicLibrary ) {
4335 if ( minOS(ld::mac10_5, ld::iOS_3_1) )
4336 if ( !fPrebind && !fSharedRegionEligibleForceOff )
4337 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
4338 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
4339 fSharedRegionEligible = true;
4340 }
4341 else if ( fOutputKind == Options::kDyld ) {
4342 // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
4343 fSharedRegionEligible = true;
4344 }
4345
4346 // <rdar://problem/18719327> warn if -rpath is used with OS dylibs
4347 if ( fSharedRegionEligible && !fRPaths.empty() )
4348 warning("-rpath cannot be used with dylibs that will be in the dyld shared cache");
4349
4350 // automatically use __DATA_CONST in iOS dylibs
4351 if ( fSharedRegionEligible && minOS(ld::mac10_Future, ld::iOS_9_0) && !fUseDataConstSegmentForceOff ) {
4352 fUseDataConstSegment = true;
4353 }
4354 if ( fUseDataConstSegmentForceOn ) {
4355 fUseDataConstSegment = true;
4356 }
4357 if ( fUseDataConstSegment ) {
4358 addSectionRename("__DATA", "__got", "__DATA_CONST", "__got");
4359 addSectionRename("__DATA", "__la_symbol_ptr", "__DATA_CONST", "__la_symbol_ptr");
4360 addSectionRename("__DATA", "__nl_symbol_ptr", "__DATA_CONST", "__nl_symbol_ptr");
4361 addSectionRename("__DATA", "__const", "__DATA_CONST", "__const");
4362 addSectionRename("__DATA", "__cfstring", "__DATA_CONST", "__cfstring");
4363 addSectionRename("__DATA", "__mod_init_func", "__DATA_CONST", "__mod_init_func");
4364 addSectionRename("__DATA", "__mod_term_func", "__DATA_CONST", "__mod_term_func");
4365 addSectionRename("__DATA", "__objc_classlist", "__DATA_CONST", "__objc_classlist");
4366 addSectionRename("__DATA", "__objc_nlclslist", "__DATA_CONST", "__objc_nlclslist");
4367 addSectionRename("__DATA", "__objc_catlist", "__DATA_CONST", "__objc_catlist");
4368 addSectionRename("__DATA", "__objc_nlcatlist", "__DATA_CONST", "__objc_nlcatlist");
4369 addSectionRename("__DATA", "__objc_protolist", "__DATA_CONST", "__objc_protolist");
4370 addSectionRename("__DATA", "__objc_imageinfo", "__DATA_CONST", "__objc_imageinfo");
4371 addSectionRename("__DATA", "__objc_const", "__DATA_CONST", "__objc_const");
4372 }
4373
4374 // Use V2 shared cache info when targetting newer OSs
4375 if ( fSharedRegionEligible && minOS(ld::mac10_Future, ld::iOS_9_0)) {
4376 fSharedRegionEncodingV2 = true;
4377 fIgnoreOptimizationHints = true;
4378 }
4379
4380 // figure out if module table is needed for compatibility with old ld/dyld
4381 if ( fOutputKind == Options::kDynamicLibrary ) {
4382 switch ( fArchitecture ) {
4383 case CPU_TYPE_I386:
4384 if ( fIOSVersionMin != ld::iOSVersionUnset ) // simulator never needs modules
4385 break;
4386 case CPU_TYPE_ARM:
4387 if ( fPrebind )
4388 fNeedsModuleTable = true; // redo_prebinding requires a module table
4389 break;
4390 }
4391 }
4392
4393 // <rdar://problem/5366363> -r -x implies -S
4394 if ( (fOutputKind == Options::kObjectFile) && (fLocalSymbolHandling == kLocalSymbolsNone) )
4395 fDebugInfoStripping = Options::kDebugInfoNone;
4396
4397 // <rdar://problem/15252891> -r implies -no_uuid
4398 if ( fOutputKind == Options::kObjectFile )
4399 fUUIDMode = kUUIDNone;
4400
4401 // choose how to process unwind info
4402 switch ( fArchitecture ) {
4403 case CPU_TYPE_I386:
4404 case CPU_TYPE_X86_64:
4405 case CPU_TYPE_ARM64:
4406 switch ( fOutputKind ) {
4407 case Options::kObjectFile:
4408 case Options::kStaticExecutable:
4409 case Options::kPreload:
4410 case Options::kKextBundle:
4411 fAddCompactUnwindEncoding = false;
4412 break;
4413 case Options::kDyld:
4414 case Options::kDynamicLibrary:
4415 case Options::kDynamicBundle:
4416 case Options::kDynamicExecutable:
4417 //if ( fAddCompactUnwindEncoding && (fVersionMin >= ld::mac10_6) )
4418 // fRemoveDwarfUnwindIfCompactExists = true;
4419 break;
4420 }
4421 break;
4422 case CPU_TYPE_ARM:
4423 if ( armUsesZeroCostExceptions() ) {
4424 switch ( fOutputKind ) {
4425 case Options::kObjectFile:
4426 case Options::kStaticExecutable:
4427 case Options::kPreload:
4428 case Options::kKextBundle:
4429 fAddCompactUnwindEncoding = false;
4430 break;
4431 case Options::kDyld:
4432 case Options::kDynamicLibrary:
4433 case Options::kDynamicBundle:
4434 case Options::kDynamicExecutable:
4435 fAddCompactUnwindEncoding = true;
4436 break;
4437 }
4438 }
4439 else {
4440 fAddCompactUnwindEncoding = false;
4441 fRemoveDwarfUnwindIfCompactExists = false;
4442 }
4443 break;
4444 case 0:
4445 // if -arch is missing, assume we don't want compact unwind info
4446 fAddCompactUnwindEncoding = false;
4447 break;
4448 }
4449
4450 // only iOS executables should be encryptable
4451 switch ( fOutputKind ) {
4452 case Options::kObjectFile:
4453 case Options::kDyld:
4454 case Options::kStaticExecutable:
4455 case Options::kPreload:
4456 case Options::kKextBundle:
4457 fEncryptable = false;
4458 break;
4459 case Options::kDynamicExecutable:
4460 break;
4461 case Options::kDynamicLibrary:
4462 case Options::kDynamicBundle:
4463 // <rdar://problem/16293398> Add LC_ENCRYPTION_INFO load command to bundled frameworks
4464 if ( !min_iOS(ld::iOS_7_0) )
4465 fEncryptable = false;
4466 break;
4467 }
4468 if ( (fArchitecture != CPU_TYPE_ARM) && (fArchitecture != CPU_TYPE_ARM64) )
4469 fEncryptable = false;
4470 if ( fEncryptableForceOn )
4471 fEncryptable = true;
4472 else if ( fEncryptableForceOff )
4473 fEncryptable = false;
4474
4475 // don't move inits in dyld because dyld wants certain
4476 // entries point at stable locations at the start of __text
4477 if ( fOutputKind == Options::kDyld )
4478 fAutoOrderInitializers = false;
4479
4480
4481 // disable __data ordering for some output kinds
4482 switch ( fOutputKind ) {
4483 case Options::kObjectFile:
4484 case Options::kDyld:
4485 case Options::kStaticExecutable:
4486 case Options::kPreload:
4487 case Options::kKextBundle:
4488 fOrderData = false;
4489 break;
4490 case Options::kDynamicExecutable:
4491 case Options::kDynamicLibrary:
4492 case Options::kDynamicBundle:
4493 break;
4494 }
4495
4496 // only use compressed LINKEDIT for final linked images
4497 switch ( fOutputKind ) {
4498 case Options::kDynamicExecutable:
4499 case Options::kDynamicLibrary:
4500 case Options::kDynamicBundle:
4501 break;
4502 case Options::kPreload:
4503 case Options::kStaticExecutable:
4504 case Options::kObjectFile:
4505 case Options::kDyld:
4506 case Options::kKextBundle:
4507 fMakeCompressedDyldInfoForceOff = true;
4508 break;
4509 }
4510 if ( fMakeCompressedDyldInfoForceOff )
4511 fMakeCompressedDyldInfo = false;
4512
4513
4514 // only use compressed LINKEDIT for:
4515 // Mac OS X 10.6 or later
4516 // iOS 3.1 or later
4517 if ( fMakeCompressedDyldInfo ) {
4518 if ( !minOS(ld::mac10_6, ld::iOS_3_1) )
4519 fMakeCompressedDyldInfo = false;
4520 }
4521
4522 // only ARM and x86_64 enforces that cpu-sub-types must match
4523 switch ( fArchitecture ) {
4524 case CPU_TYPE_ARM:
4525 case CPU_TYPE_X86_64:
4526 break;
4527 case CPU_TYPE_I386:
4528 case CPU_TYPE_ARM64:
4529 fAllowCpuSubtypeMismatches = true;
4530 break;
4531 }
4532
4533
4534 // only final linked images can not optimize zero fill sections
4535 if ( fOutputKind == Options::kObjectFile )
4536 fOptimizeZeroFill = true;
4537
4538 // all undefines in -r mode
4539 // if ( fOutputKind == Options::kObjectFile )
4540 // fUndefinedTreatment = kUndefinedSuppress;
4541
4542 // only dynamic final linked images should warn about use of commmons
4543 if ( fWarnCommons ) {
4544 switch ( fOutputKind ) {
4545 case Options::kDynamicExecutable:
4546 case Options::kDynamicLibrary:
4547 case Options::kDynamicBundle:
4548 break;
4549 case Options::kPreload:
4550 case Options::kStaticExecutable:
4551 case Options::kObjectFile:
4552 case Options::kDyld:
4553 case Options::kKextBundle:
4554 fWarnCommons = false;
4555 break;
4556 }
4557 }
4558
4559 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
4560 if ( minOS(ld::mac10_5, ld::iOS_2_0) )
4561 fUseSimplifiedDylibReExports = true;
4562
4563 // Mac OS X 10.7 and iOS 4.2 support LC_LOAD_UPWARD_DYLIB
4564 if ( minOS(ld::mac10_7, ld::iOS_4_2) && (fOutputKind == kDynamicLibrary) )
4565 fCanUseUpwardDylib = true;
4566
4567 // MacOSX 10.7 defaults to PIE
4568 if ( ((fArchitecture == CPU_TYPE_X86_64) || (fArchitecture == CPU_TYPE_I386))
4569 && (fOutputKind == kDynamicExecutable)
4570 && (fMacVersionMin >= ld::mac10_7) ) {
4571 fPositionIndependentExecutable = true;
4572 }
4573
4574 // armv7 for iOS4.3 defaults to PIE
4575 if ( (fArchitecture == CPU_TYPE_ARM)
4576 && fArchSupportsThumb2
4577 && (fOutputKind == kDynamicExecutable)
4578 && min_iOS(ld::iOS_4_3) ) {
4579 fPositionIndependentExecutable = true;
4580 }
4581
4582 // Simulator defaults to PIE
4583 if ( fTargetIOSSimulator && (fOutputKind == kDynamicExecutable) )
4584 fPositionIndependentExecutable = true;
4585
4586 // -no_pie anywhere on command line disable PIE
4587 if ( fDisablePositionIndependentExecutable )
4588 fPositionIndependentExecutable = false;
4589
4590 // arm64 is always PIE
4591 if ( (fArchitecture == CPU_TYPE_ARM64) && (fOutputKind == kDynamicExecutable) ) {
4592 fPositionIndependentExecutable = true;
4593 }
4594
4595 // set fOutputSlidable
4596 switch ( fOutputKind ) {
4597 case Options::kObjectFile:
4598 fOutputSlidable = false;
4599 break;
4600 case Options::kStaticExecutable:
4601 case Options::kDynamicExecutable:
4602 fOutputSlidable = fPositionIndependentExecutable;
4603 break;
4604 case Options::kPreload:
4605 fOutputSlidable = fPIEOnCommandLine;
4606 break;
4607 case Options::kDyld:
4608 case Options::kDynamicLibrary:
4609 case Options::kDynamicBundle:
4610 case Options::kKextBundle:
4611 fOutputSlidable = true;
4612 break;
4613 }
4614
4615 // let linker know if thread local variables are supported
4616 if ( fMacVersionMin >= ld::mac10_7 ) {
4617 fTLVSupport = true;
4618 }
4619 else if ( (fArchitecture == CPU_TYPE_ARM64) && min_iOS(ld::iOS_8_0) ) {
4620 fTLVSupport = true;
4621 }
4622 else if ( (fArchitecture == CPU_TYPE_ARM) && min_iOS(ld::iOS_9_0) ) {
4623 fTLVSupport = true;
4624 }
4625
4626 // default to adding version load command for dynamic code, static code must opt-in
4627 switch ( fOutputKind ) {
4628 case Options::kObjectFile:
4629 fVersionLoadCommand = false;
4630 break;
4631 case Options::kStaticExecutable:
4632 case Options::kPreload:
4633 case Options::kKextBundle:
4634 if ( fVersionLoadCommandForcedOn )
4635 fVersionLoadCommand = true;
4636 break;
4637 case Options::kDynamicExecutable:
4638 case Options::kDyld:
4639 case Options::kDynamicLibrary:
4640 case Options::kDynamicBundle:
4641 if ( !fVersionLoadCommandForcedOff )
4642 fVersionLoadCommand = true;
4643 break;
4644 }
4645
4646 // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
4647 if ( (fOutputKind == kDynamicLibrary) && minOS(ld::mac10_7, ld::iOS_4_2) )
4648 fCanReExportSymbols = true;
4649
4650 // ObjC optimization is only in dynamic final linked images
4651 switch ( fOutputKind ) {
4652 case Options::kObjectFile:
4653 case Options::kStaticExecutable:
4654 case Options::kPreload:
4655 case Options::kKextBundle:
4656 case Options::kDyld:
4657 fObjcCategoryMerging = false;
4658 break;
4659 case Options::kDynamicExecutable:
4660 case Options::kDynamicLibrary:
4661 case Options::kDynamicBundle:
4662 break;
4663 }
4664
4665 // i386 main executables linked on Mac OS X 10.7 default to NX heap
4666 // regardless of target unless overriden with -allow_heap_execute anywhere
4667 // on the command line
4668 if ( (fArchitecture == CPU_TYPE_I386) && (fOutputKind == kDynamicExecutable) && !fDisableNonExecutableHeap)
4669 fNonExecutableHeap = true;
4670
4671 // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
4672 switch ( fOutputKind ) {
4673 case Options::kDynamicExecutable:
4674 if ( fEntryPointLoadCommandForceOn ) {
4675 fEntryPointLoadCommand = true;
4676 if ( fEntryName == NULL )
4677 fEntryName = "_main";
4678 }
4679 else if ( fEntryPointLoadCommandForceOff ) {
4680 fNeedsThreadLoadCommand = true;
4681 if ( fEntryName == NULL )
4682 fEntryName = "start";
4683 }
4684 else {
4685 // <rdar://problem/16310363> Linker should look for "_main" not "start" when building for sim regardless of min OS
4686 if ( minOS(ld::mac10_8, ld::iOS_6_0) || fTargetIOSSimulator ) {
4687 fEntryPointLoadCommand = true;
4688 if ( fEntryName == NULL )
4689 fEntryName = "_main";
4690 if ( strcmp(fEntryName, "start") == 0 ) {
4691 warning("Ignoring '-e start' because entry point 'start' is not used for the targeted OS version");
4692 fEntryName = "_main";
4693 }
4694 }
4695 else {
4696 fNeedsThreadLoadCommand = true;
4697 if ( fEntryName == NULL )
4698 fEntryName = "start";
4699 }
4700 }
4701 break;
4702 case Options::kObjectFile:
4703 case Options::kKextBundle:
4704 case Options::kDynamicLibrary:
4705 case Options::kDynamicBundle:
4706 break;
4707
4708 case Options::kStaticExecutable:
4709 case Options::kPreload:
4710 case Options::kDyld:
4711 fNeedsThreadLoadCommand = true;
4712 if ( fEntryName == NULL )
4713 fEntryName = "start"; // Perhaps these should have no default and require -e
4714 break;
4715 }
4716
4717 // add LC_SOURCE_VERSION
4718 switch ( fOutputKind ) {
4719 case Options::kDynamicExecutable:
4720 case Options::kKextBundle:
4721 case Options::kDynamicLibrary:
4722 case Options::kDynamicBundle:
4723 case Options::kDyld:
4724 case Options::kStaticExecutable:
4725 if ( fSourceVersionLoadCommandForceOn ) {
4726 fSourceVersionLoadCommand = true;
4727 }
4728 else if ( fSourceVersionLoadCommandForceOff ) {
4729 fSourceVersionLoadCommand = false;
4730 }
4731 else {
4732 if ( minOS(ld::mac10_8, ld::iOS_6_0) ) {
4733 fSourceVersionLoadCommand = true;
4734 }
4735 else
4736 fSourceVersionLoadCommand = false;
4737 }
4738 break;
4739 case Options::kObjectFile:
4740 case Options::kPreload:
4741 fSourceVersionLoadCommand = false;
4742 break;
4743 }
4744
4745 // if -sdk_version not on command line, infer from -syslibroot
4746 if ( (fSDKVersion == 0) && (fSDKPaths.size() > 0) ) {
4747 const char* sdkPath = fSDKPaths.front();
4748 const char* end = &sdkPath[strlen(sdkPath)-1];
4749 while ( !isdigit(*end) && (end > sdkPath) )
4750 --end;
4751 const char* start = end-1;
4752 while ( (isdigit(*start) || (*start == '.')) && (start > sdkPath))
4753 --start;
4754 char sdkVersionStr[32];
4755 int len = end-start+1;
4756 if ( len > 2 ) {
4757 strlcpy(sdkVersionStr, start+1, len);
4758 fSDKVersion = parseVersionNumber32(sdkVersionStr);
4759 }
4760 }
4761
4762 // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
4763 if ( (fSDKVersion == 0) && (fMacVersionMin != ld::macVersionUnset) ) {
4764 // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
4765 if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
4766 fSDKVersion = fMacVersionMin;
4767 }
4768 else {
4769 int mib[2] = { CTL_KERN, KERN_OSRELEASE };
4770 char kernVersStr[100];
4771 size_t strlen = sizeof(kernVersStr);
4772 if ( sysctl(mib, 2, kernVersStr, &strlen, NULL, 0) != -1 ) {
4773 uint32_t kernVers = parseVersionNumber32(kernVersStr);
4774 int minor = (kernVers >> 16) - 4; // kernel major version is 4 ahead of x in 10.x
4775 fSDKVersion = 0x000A0000 + (minor << 8);
4776 }
4777 }
4778 }
4779
4780 // allow trie based absolute symbols if targeting new enough OS
4781 if ( fMakeCompressedDyldInfo ) {
4782 if ( minOS(ld::mac10_9, ld::iOS_7_0) ) {
4783 fAbsoluteSymbols = true;
4784 }
4785 }
4786
4787 // <rdar://problem/12959510> iOS main executables now default to 16KB page size
4788 if ( (fIOSVersionMin != ld::iOSVersionUnset) && (fOutputKind == Options::kDynamicExecutable) ) {
4789 // <rdar://problem/13070042> Only third party apps should have 16KB page segments by default
4790 if ( fEncryptable ) {
4791 if ( fSegmentAlignment == 4096 )
4792 fSegmentAlignment = 4096*4;
4793 }
4794 }
4795
4796 // <rdar://problem/12258065> ARM64 needs 16KB page size for user land code
4797 // <rdar://problem/15974532> make armv7[s] use 16KB pages in user land code for iOS 8 or later
4798 if ( fSegmentAlignment == 4096 ) {
4799 switch ( fOutputKind ) {
4800 case Options::kDynamicExecutable:
4801 case Options::kDynamicLibrary:
4802 case Options::kDynamicBundle:
4803 case Options::kDyld:
4804 if ( (fArchitecture == CPU_TYPE_ARM64)
4805 || ((fArchitecture == CPU_TYPE_ARM) && min_iOS(ld::iOS_7_0)) ) {
4806 fSegmentAlignment = 4096*4;
4807 }
4808 break;
4809 case Options::kStaticExecutable:
4810 case Options::kKextBundle:
4811 // <rdar://problem/14676611> 16KB segments for arm64 kexts
4812 if ( (fArchitecture == CPU_TYPE_ARM64) && min_iOS(ld::iOS_9_0) ) {
4813 fSegmentAlignment = 4096*4;
4814 }
4815 break;
4816 case Options::kObjectFile:
4817 case Options::kPreload:
4818 break;
4819 }
4820 }
4821
4822
4823
4824 // <rdar://problem/13624134> linker should not convert dwarf unwind if .o file has compact unwind section
4825 switch ( fOutputKind ) {
4826 case Options::kDynamicExecutable:
4827 case Options::kDynamicLibrary:
4828 case Options::kDynamicBundle:
4829 case Options::kDyld:
4830 if ( fKeepDwarfUnwindForcedOn ) {
4831 fKeepDwarfUnwind = true;
4832 }
4833 else if ( fKeepDwarfUnwindForcedOff ) {
4834 fKeepDwarfUnwind = false;
4835 }
4836 else {
4837 if ( minOS(ld::mac10_9, ld::iOS_7_0) )
4838 fKeepDwarfUnwind = false;
4839 else
4840 fKeepDwarfUnwind = true;
4841 }
4842 break;
4843 case Options::kKextBundle:
4844 case Options::kStaticExecutable:
4845 case Options::kObjectFile:
4846 case Options::kPreload:
4847 fKeepDwarfUnwind = true;
4848 break;
4849 }
4850
4851 // Make sure -image_base matches alignment
4852 uint64_t alignedBaseAddress = (fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment);
4853 if ( alignedBaseAddress != fBaseAddress ) {
4854 warning("base address 0x%llX is not properly aligned. Changing it to 0x%llX", fBaseAddress, alignedBaseAddress);
4855 fBaseAddress = alignedBaseAddress;
4856 }
4857
4858 // If -dirty_data_list not specified, look in $SDKROOT/AppleInternal/DirtyDataFiles/<dylib>.dirty for dirty data list
4859 if ( fSymbolsMovesData.empty() && fUseDataConstSegment && ( fDylibInstallName != NULL) && !fSDKPaths.empty() ) {
4860 const char* dylibLeaf = strrchr(fDylibInstallName, '/');
4861 if ( dylibLeaf ) {
4862 char path[PATH_MAX];
4863 strlcpy(path , fSDKPaths.front(), sizeof(path));
4864 strlcat(path , "/AppleInternal/DirtyDataFiles", sizeof(path));
4865 strlcat(path , dylibLeaf, sizeof(path));
4866 strlcat(path , ".dirty", sizeof(path));
4867 FileInfo info;
4868 if ( info.checkFileExists(*this, path) )
4869 addSymbolMove("__DATA_DIRTY", path, fSymbolsMovesData, "-dirty_data_list");
4870 }
4871 }
4872
4873 }
4874
4875 void Options::checkIllegalOptionCombinations()
4876 {
4877 // check -undefined setting
4878 switch ( fUndefinedTreatment ) {
4879 case kUndefinedError:
4880 case kUndefinedDynamicLookup:
4881 // always legal
4882 break;
4883 case kUndefinedWarning:
4884 case kUndefinedSuppress:
4885 // requires flat namespace
4886 if ( fNameSpace == kTwoLevelNameSpace )
4887 throw "can't use -undefined warning or suppress with -twolevel_namespace";
4888 break;
4889 }
4890
4891 // unify -sub_umbrella with dylibs
4892 for (std::vector<const char*>::iterator it = fSubUmbellas.begin(); it != fSubUmbellas.end(); it++) {
4893 const char* subUmbrella = *it;
4894 bool found = false;
4895 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
4896 Options::FileInfo& info = *fit;
4897 const char* lastSlash = strrchr(info.path, '/');
4898 if ( lastSlash == NULL )
4899 lastSlash = info.path - 1;
4900 if ( strcmp(&lastSlash[1], subUmbrella) == 0 ) {
4901 info.options.fReExport = true;
4902 found = true;
4903 fLinkSnapshot.recordSubUmbrella(info.path);
4904 break;
4905 }
4906 }
4907 if ( ! found )
4908 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella);
4909 }
4910
4911 // unify -sub_library with dylibs
4912 for (std::vector<const char*>::iterator it = fSubLibraries.begin(); it != fSubLibraries.end(); it++) {
4913 const char* subLibrary = *it;
4914 bool found = false;
4915 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
4916 Options::FileInfo& info = *fit;
4917 const char* lastSlash = strrchr(info.path, '/');
4918 if ( lastSlash == NULL )
4919 lastSlash = info.path - 1;
4920 const char* dot = strchr(&lastSlash[1], '.');
4921 if ( dot == NULL )
4922 dot = &lastSlash[strlen(lastSlash)];
4923 if ( strncmp(&lastSlash[1], subLibrary, dot-lastSlash-1) == 0 ) {
4924 info.options.fReExport = true;
4925 found = true;
4926 fLinkSnapshot.recordSubLibrary(info.path);
4927 break;
4928 }
4929 }
4930 if ( ! found )
4931 warning("-sub_library %s does not match a supplied dylib", subLibrary);
4932 }
4933
4934 // sync reader options
4935 if ( fNameSpace != kTwoLevelNameSpace )
4936 fFlatNamespace = true;
4937
4938 // check -stack_addr
4939 if ( fStackAddr != 0 ) {
4940 switch (fArchitecture) {
4941 case CPU_TYPE_I386:
4942 case CPU_TYPE_ARM:
4943 if ( fStackAddr > 0xFFFFFFFF )
4944 throw "-stack_addr must be < 4G for 32-bit processes";
4945 break;
4946 case CPU_TYPE_X86_64:
4947 case CPU_TYPE_ARM64:
4948 break;
4949 }
4950 if ( (fStackAddr & -4096) != fStackAddr )
4951 throw "-stack_addr must be multiples of 4K";
4952 if ( fStackSize == 0 )
4953 throw "-stack_addr must be used with -stack_size";
4954 }
4955
4956 // check -stack_size
4957 if ( fStackSize != 0 ) {
4958 switch (fArchitecture) {
4959 case CPU_TYPE_I386:
4960 if ( fStackSize > 0xFFFFFFFF )
4961 throw "-stack_size must be < 4G for 32-bit processes";
4962 if ( fStackAddr == 0 ) {
4963 fStackAddr = 0xC0000000;
4964 }
4965 if ( (fStackAddr > 0xB0000000) && ((fStackAddr-fStackSize) < 0xB0000000) )
4966 warning("custom stack placement overlaps and will disable shared region");
4967 break;
4968 case CPU_TYPE_ARM:
4969 if ( fStackSize > 0x2F000000 )
4970 throw "-stack_size must be < 752MB";
4971 if ( fStackAddr == 0 )
4972 fStackAddr = 0x2F000000;
4973 if ( fStackAddr > 0x30000000)
4974 throw "-stack_addr must be < 0x30000000 for arm";
4975 break;
4976 case CPU_TYPE_X86_64:
4977 if ( fStackAddr == 0 ) {
4978 fStackAddr = 0x00007FFF5C000000LL;
4979 }
4980 break;
4981 case CPU_TYPE_ARM64:
4982 if ( fStackSize > 0x20000000 )
4983 throw "-stack_size must be < 512MB";
4984 if ( fStackAddr == 0 ) {
4985 fStackAddr = 0x120000000;
4986 }
4987 break;
4988 }
4989 if ( (fStackSize & -4096) != fStackSize )
4990 throw "-stack_size must be multiples of 4K";
4991 switch ( fOutputKind ) {
4992 case Options::kDynamicExecutable:
4993 case Options::kStaticExecutable:
4994 // custom stack size only legal when building main executable
4995 break;
4996 case Options::kDynamicLibrary:
4997 case Options::kDynamicBundle:
4998 case Options::kObjectFile:
4999 case Options::kDyld:
5000 case Options::kPreload:
5001 case Options::kKextBundle:
5002 throw "-stack_size option can only be used when linking a main executable";
5003 }
5004 if ( fStackSize > fStackAddr )
5005 throwf("-stack_size (0x%08llX) must be smaller than -stack_addr (0x%08llX)", fStackSize, fStackAddr);
5006 }
5007
5008 // check that -allow_stack_execute is only used with main executables
5009 if ( fExecutableStack ) {
5010 switch ( fOutputKind ) {
5011 case Options::kDynamicExecutable:
5012 case Options::kStaticExecutable:
5013 // -allow_stack_execute size only legal when building main executable
5014 break;
5015 case Options::kDynamicLibrary:
5016 case Options::kDynamicBundle:
5017 case Options::kObjectFile:
5018 case Options::kDyld:
5019 case Options::kPreload:
5020 case Options::kKextBundle:
5021 throw "-allow_stack_execute option can only be used when linking a main executable";
5022 }
5023 }
5024
5025 // check that -allow_heap_execute is only used with i386 main executables
5026 if ( fDisableNonExecutableHeap ) {
5027 if ( fArchitecture != CPU_TYPE_I386 )
5028 throw "-allow_heap_execute option can only be used when linking for i386";
5029 switch ( fOutputKind ) {
5030 case Options::kDynamicExecutable:
5031 // -allow_heap_execute only legal when building main executable
5032 break;
5033 case Options::kStaticExecutable:
5034 case Options::kDynamicLibrary:
5035 case Options::kDynamicBundle:
5036 case Options::kObjectFile:
5037 case Options::kDyld:
5038 case Options::kPreload:
5039 case Options::kKextBundle:
5040 throw "-allow_heap_execute option can only be used when linking a main executable";
5041 }
5042 }
5043
5044 // check -client_name is only used when making a bundle or main executable
5045 if ( fClientName != NULL ) {
5046 switch ( fOutputKind ) {
5047 case Options::kDynamicExecutable:
5048 case Options::kDynamicBundle:
5049 break;
5050 case Options::kStaticExecutable:
5051 case Options::kDynamicLibrary:
5052 case Options::kObjectFile:
5053 case Options::kDyld:
5054 case Options::kPreload:
5055 case Options::kKextBundle:
5056 throw "-client_name can only be used with -bundle";
5057 }
5058 }
5059
5060 // check -init is only used when building a dylib
5061 if ( (fInitFunctionName != NULL) && (fOutputKind != Options::kDynamicLibrary) )
5062 throw "-init can only be used with -dynamiclib";
5063
5064 // check -bundle_loader only used with -bundle
5065 if ( (fBundleLoader != NULL) && (fOutputKind != Options::kDynamicBundle) )
5066 throw "-bundle_loader can only be used with -bundle";
5067
5068 // check -dtrace not used with -r
5069 if ( (fDtraceScriptName != NULL) && (fOutputKind == Options::kObjectFile) )
5070 throw "-dtrace can only be used when creating final linked images";
5071
5072 // check -d can only be used with -r
5073 if ( fMakeTentativeDefinitionsReal && (fOutputKind != Options::kObjectFile) )
5074 throw "-d can only be used with -r";
5075
5076 // check that -root_safe is not used with -r
5077 if ( fRootSafe && (fOutputKind == Options::kObjectFile) )
5078 throw "-root_safe cannot be used with -r";
5079
5080 // check that -setuid_safe is not used with -r
5081 if ( fSetuidSafe && (fOutputKind == Options::kObjectFile) )
5082 throw "-setuid_safe cannot be used with -r";
5083
5084 // <rdar://problem/12781832> compiler driver no longer uses -objc_abi_version, it uses -ios_simulator_version_min instead
5085 if ( !fObjCABIVersion1Override && !fObjCABIVersion2Override && fTargetIOSSimulator )
5086 fObjCABIVersion2Override = true;
5087
5088 // rdar://problem/4718189 map ObjC class names to new runtime names
5089 bool alterObjC1ClassNamesToObjC2 = false;
5090 switch (fArchitecture) {
5091 case CPU_TYPE_I386:
5092 // i386 only uses new symbols when using objc2 ABI
5093 if ( fObjCABIVersion2Override )
5094 alterObjC1ClassNamesToObjC2 = true;
5095 break;
5096 case CPU_TYPE_X86_64:
5097 case CPU_TYPE_ARM:
5098 case CPU_TYPE_ARM64:
5099 alterObjC1ClassNamesToObjC2 = true;
5100 break;
5101 }
5102
5103 // make sure all required exported symbols exist
5104 std::vector<const char*> impliedExports;
5105 for (NameSet::iterator it=fExportSymbols.regularBegin(); it != fExportSymbols.regularEnd(); ++it) {
5106 const char* name = *it;
5107 const int len = strlen(name);
5108 if ( (strcmp(&name[len-3], ".eh") == 0) || (strncmp(name, ".objc_category_name_", 20) == 0) ) {
5109 // never export .eh symbols
5110 warning("ignoring %s in export list", name);
5111 }
5112 else if ( (fArchitecture == CPU_TYPE_I386) && !fObjCABIVersion2Override && (strncmp(name, "_OBJC_CLASS_$", 13) == 0) ) {
5113 warning("ignoring Objc2 Class symbol %s in i386 export list", name);
5114 fRemovedExports.insert(name);
5115 }
5116 else if ( alterObjC1ClassNamesToObjC2 && (strncmp(name, ".objc_class_name_", 17) == 0) ) {
5117 // linking ObjC2 ABI, but have ObjC1 ABI name in export list. Change it to intended name
5118 fRemovedExports.insert(name);
5119 char* temp;
5120 asprintf(&temp, "_OBJC_CLASS_$_%s", &name[17]);
5121 impliedExports.push_back(temp);
5122 asprintf(&temp, "_OBJC_METACLASS_$_%s", &name[17]);
5123 impliedExports.push_back(temp);
5124 }
5125 else {
5126 fInitialUndefines.push_back(name);
5127 }
5128 }
5129 fExportSymbols.remove(fRemovedExports);
5130 for (std::vector<const char*>::iterator it=impliedExports.begin(); it != impliedExports.end(); ++it) {
5131 const char* name = *it;
5132 fExportSymbols.insert(name);
5133 fInitialUndefines.push_back(name);
5134 }
5135
5136 // make sure all required re-exported symbols exist
5137 for (NameSet::iterator it=fReExportSymbols.regularBegin(); it != fReExportSymbols.regularEnd(); ++it) {
5138 fInitialUndefines.push_back(*it);
5139 }
5140
5141 // make sure that -init symbol exists
5142 if ( fInitFunctionName != NULL )
5143 fInitialUndefines.push_back(fInitFunctionName);
5144
5145 // make sure that entry symbol exists
5146 switch ( fOutputKind ) {
5147 case Options::kDynamicExecutable:
5148 case Options::kStaticExecutable:
5149 case Options::kDyld:
5150 case Options::kPreload:
5151 fInitialUndefines.push_back(fEntryName);
5152 break;
5153 case Options::kDynamicLibrary:
5154 case Options::kDynamicBundle:
5155 case Options::kObjectFile:
5156 case Options::kKextBundle:
5157 break;
5158 }
5159
5160 // make sure every alias base exists
5161 for (std::vector<AliasPair>::iterator it=fAliases.begin(); it != fAliases.end(); ++it) {
5162 fInitialUndefines.push_back(it->realName);
5163 }
5164
5165 // check custom segments
5166 if ( fCustomSegmentAddresses.size() != 0 ) {
5167 // verify no segment is in zero page
5168 if ( fZeroPageSize != ULLONG_MAX ) {
5169 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
5170 if ( it->address < fZeroPageSize )
5171 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it->name, it->address);
5172 }
5173 }
5174 // verify no duplicates
5175 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
5176 for (std::vector<SegmentStart>::iterator it2 = fCustomSegmentAddresses.begin(); it2 != fCustomSegmentAddresses.end(); ++it2) {
5177 if ( (it->address == it2->address) && (it != it2) )
5178 throwf("duplicate -segaddr addresses for %s and %s", it->name, it2->name);
5179 }
5180 // a custom segment address of zero will disable the use of a zero page
5181 if ( it->address == 0 )
5182 fZeroPageSize = 0;
5183 }
5184 }
5185
5186 if ( fZeroPageSize == ULLONG_MAX ) {
5187 // zero page size not specified on command line, set default
5188 switch (fArchitecture) {
5189 case CPU_TYPE_I386:
5190 case CPU_TYPE_ARM:
5191 // first 4KB for 32-bit architectures
5192 fZeroPageSize = 0x1000;
5193 break;
5194 case CPU_TYPE_ARM64:
5195 case CPU_TYPE_X86_64:
5196 // first 4GB for x86_64 on all OS's
5197 fZeroPageSize = 0x100000000ULL;
5198 break;
5199 default:
5200 // if -arch not used, default to 4K zero-page
5201 fZeroPageSize = 0x1000;
5202 }
5203 }
5204 else {
5205 switch ( fOutputKind ) {
5206 case Options::kDynamicExecutable:
5207 case Options::kStaticExecutable:
5208 // -pagezero_size size only legal when building main executable
5209 break;
5210 case Options::kDynamicLibrary:
5211 case Options::kDynamicBundle:
5212 case Options::kObjectFile:
5213 case Options::kDyld:
5214 case Options::kPreload:
5215 case Options::kKextBundle:
5216 if ( fZeroPageSize != 0 )
5217 throw "-pagezero_size option can only be used when linking a main executable";
5218 }
5219 }
5220
5221 // if main executable with custom base address, model zero page as custom segment
5222 if ( (fOutputKind == Options::kDynamicExecutable) && (fBaseAddress != 0) && (fZeroPageSize != 0) ) {
5223 SegmentStart seg;
5224 seg.name = "__PAGEZERO";
5225 seg.address = 0;;
5226 fCustomSegmentAddresses.push_back(seg);
5227 }
5228
5229 // -dead_strip and -r are incompatible
5230 if ( fDeadStrip && (fOutputKind == Options::kObjectFile) )
5231 throw "-r and -dead_strip cannot be used together";
5232
5233 // can't use -rpath unless targeting 10.5 or later
5234 if ( fRPaths.size() > 0 ) {
5235 if ( !minOS(ld::mac10_5, ld::iOS_2_0) )
5236 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
5237 switch ( fOutputKind ) {
5238 case Options::kDynamicExecutable:
5239 case Options::kDynamicLibrary:
5240 case Options::kDynamicBundle:
5241 break;
5242 case Options::kStaticExecutable:
5243 case Options::kObjectFile:
5244 case Options::kDyld:
5245 case Options::kPreload:
5246 case Options::kKextBundle:
5247 throw "-rpath can only be used when creating a dynamic final linked image";
5248 }
5249 }
5250
5251 if ( fPositionIndependentExecutable ) {
5252 switch ( fOutputKind ) {
5253 case Options::kDynamicExecutable:
5254 // check -pie is only used when building a dynamic main executable for 10.5
5255 if ( !minOS(ld::mac10_5, ld::iOS_4_2) ) {
5256 if ( fIOSVersionMin == ld::iOSVersionUnset )
5257 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
5258 else
5259 throw "-pie can only be used when targeting iOS 4.2 or later";
5260 }
5261 break;
5262 case Options::kStaticExecutable:
5263 case Options::kPreload:
5264 // -pie is ok with -static or -preload
5265 break;
5266 case Options::kDynamicLibrary:
5267 case Options::kDynamicBundle:
5268 warning("-pie being ignored. It is only used when linking a main executable");
5269 fPositionIndependentExecutable = false;
5270 break;
5271 case Options::kObjectFile:
5272 case Options::kDyld:
5273 case Options::kKextBundle:
5274 throw "-pie can only be used when linking a main executable";
5275 }
5276 }
5277
5278 // check -read_only_relocs is not used with x86_64
5279 if ( fAllowTextRelocs ) {
5280 if ( (fArchitecture == CPU_TYPE_X86_64) && (fOutputKind != kKextBundle) ) {
5281 warning("-read_only_relocs cannot be used with x86_64");
5282 fAllowTextRelocs = false;
5283 }
5284 }
5285
5286 // check -mark_auto_dead_strip is only used with dylibs
5287 if ( fMarkDeadStrippableDylib ) {
5288 if ( fOutputKind != Options::kDynamicLibrary ) {
5289 warning("-mark_auto_dead_strip can only be used when creating a dylib");
5290 fMarkDeadStrippableDylib = false;
5291 }
5292 }
5293
5294 // -force_cpusubtype_ALL is not supported for ARM
5295 if ( fForceSubtypeAll ) {
5296 if ( fArchitecture == CPU_TYPE_ARM ) {
5297 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
5298 }
5299 }
5300
5301 // -reexported_symbols_list can only be used with -dynamiclib
5302 if ( !fReExportSymbols.empty() ) {
5303 if ( fOutputKind != Options::kDynamicLibrary )
5304 throw "-reexported_symbols_list can only used used when created dynamic libraries";
5305 if ( !minOS(ld::mac10_7, ld::iOS_4_2) )
5306 throw "targeted OS version does not support -reexported_symbols_list";
5307 }
5308
5309 // -dyld_env can only be used with main executables
5310 if ( (fOutputKind != Options::kDynamicExecutable) && (fDyldEnvironExtras.size() != 0) )
5311 throw "-dyld_env can only used used when created main executables";
5312
5313 // -segment_order can only be used with -preload
5314 if ( !fSegmentOrder.empty() && (fOutputKind != Options::kPreload) )
5315 throw "-segment_order can only used used with -preload output";
5316
5317 if ( fBitcodeKind != kBitcodeProcess &&
5318 fOutputKind != Options::kObjectFile ) {
5319 throw "-bitcode_process_mode can only be used together with -r";
5320 }
5321 // auto fix up the process type for strip -S.
5322 // when there is only one input and output type is object file, downgrade kBitcodeProcess to kBitcodeAsData.
5323 if ( fOutputKind == Options::kObjectFile && fInputFiles.size() == 1 && fBitcodeKind == Options::kBitcodeProcess )
5324 fBitcodeKind = Options::kBitcodeAsData;
5325
5326 // <rdar://problem/17598404> warn if building an embedded iOS dylib for pre-iOS 8
5327 // <rdar://problem/18935714> How can we suppress "ld: warning: embedded dylibs/frameworks only run on iOS 8 or laterÓ when building XCTest?
5328 if ( (fOutputKind == Options::kDynamicLibrary) && (fIOSVersionMin != ld::iOSVersionUnset) && (fDylibInstallName != NULL) ) {
5329 if ( !min_iOS(ld::iOS_8_0) && (fDylibInstallName[0] == '@') && !fEncryptableForceOff )
5330 warning("embedded dylibs/frameworks only run on iOS 8 or later");
5331 }
5332 }
5333
5334
5335 void Options::checkForClassic(int argc, const char* argv[])
5336 {
5337 // scan options
5338 bool archFound = false;
5339 bool staticFound = false;
5340 bool dtraceFound = false;
5341 bool kextFound = false;
5342 bool rFound = false;
5343 bool creatingMachKernel = false;
5344 bool newLinker = false;
5345
5346 // build command line buffer in case ld crashes
5347 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
5348 CRSetCrashLogMessage(crashreporterBuffer);
5349 #endif
5350 const char* srcRoot = getenv("SRCROOT");
5351 if ( srcRoot != NULL ) {
5352 strlcpy(crashreporterBuffer, "SRCROOT=", crashreporterBufferSize);
5353 strlcat(crashreporterBuffer, srcRoot, crashreporterBufferSize);
5354 strlcat(crashreporterBuffer, "\n", crashreporterBufferSize);
5355 }
5356 #ifdef LD_VERS
5357 strlcat(crashreporterBuffer, LD_VERS, crashreporterBufferSize);
5358 strlcat(crashreporterBuffer, "\n", crashreporterBufferSize);
5359 #endif
5360 strlcat(crashreporterBuffer, "ld ", crashreporterBufferSize);
5361 for(int i=1; i < argc; ++i) {
5362 strlcat(crashreporterBuffer, argv[i], crashreporterBufferSize);
5363 strlcat(crashreporterBuffer, " ", crashreporterBufferSize);
5364 }
5365
5366 for(int i=0; i < argc; ++i) {
5367 const char* arg = argv[i];
5368 if ( arg[0] == '-' ) {
5369 if ( strcmp(arg, "-arch") == 0 ) {
5370 parseArch(argv[++i]);
5371 archFound = true;
5372 }
5373 else if ( strcmp(arg, "-static") == 0 ) {
5374 staticFound = true;
5375 }
5376 else if ( strcmp(arg, "-kext") == 0 ) {
5377 kextFound = true;
5378 }
5379 else if ( strcmp(arg, "-dtrace") == 0 ) {
5380 dtraceFound = true;
5381 }
5382 else if ( strcmp(arg, "-r") == 0 ) {
5383 rFound = true;
5384 }
5385 else if ( strcmp(arg, "-new_linker") == 0 ) {
5386 newLinker = true;
5387 }
5388 else if ( strcmp(arg, "-classic_linker") == 0 ) {
5389 // ld_classic does not understand this option, so remove it
5390 for(int j=i; j < argc; ++j)
5391 argv[j] = argv[j+1];
5392 warning("using ld_classic");
5393 this->gotoClassicLinker(argc-1, argv);
5394 }
5395 else if ( strcmp(arg, "-o") == 0 ) {
5396 const char* outfile = argv[++i];
5397 if ( (outfile != NULL) && (strstr(outfile, "/mach_kernel") != NULL) )
5398 creatingMachKernel = true;
5399 }
5400 }
5401 }
5402 }
5403
5404 void Options::gotoClassicLinker(int argc, const char* argv[])
5405 {
5406 argv[0] = "ld_classic";
5407 // ld_classic does not support -iphoneos_version_min, so change
5408 for(int j=0; j < argc; ++j) {
5409 if ( (strcmp(argv[j], "-iphoneos_version_min") == 0) || (strcmp(argv[j], "-ios_version_min") == 0) ) {
5410 argv[j] = "-macosx_version_min";
5411 if ( j < argc-1 )
5412 argv[j+1] = "10.5";
5413 break;
5414 }
5415 }
5416 // ld classic does not understand -kext (change to -static -r)
5417 for(int j=0; j < argc; ++j) {
5418 if ( strcmp(argv[j], "-kext") == 0)
5419 argv[j] = "-r";
5420 else if ( strcmp(argv[j], "-dynamic") == 0)
5421 argv[j] = "-static";
5422 }
5423 // ld classic does not understand -demangle
5424 for(int j=0; j < argc; ++j) {
5425 if ( strcmp(argv[j], "-demangle") == 0)
5426 argv[j] = "-noprebind";
5427 }
5428 // in -v mode, print command line passed to ld_classic
5429 for(int i=0; i < argc; ++i) {
5430 if ( strcmp(argv[i], "-v") == 0 ) {
5431 for(int j=0; j < argc; ++j)
5432 printf("%s ", argv[j]);
5433 printf("\n");
5434 break;
5435 }
5436 }
5437 char rawPath[PATH_MAX];
5438 char path[PATH_MAX];
5439 uint32_t bufSize = PATH_MAX;
5440 if ( _NSGetExecutablePath(rawPath, &bufSize) != -1 ) {
5441 if ( realpath(rawPath, path) != NULL ) {
5442 char* lastSlash = strrchr(path, '/');
5443 if ( lastSlash != NULL ) {
5444 strcpy(lastSlash+1, "ld_classic");
5445 argv[0] = path;
5446 execvp(path, (char**)argv);
5447 }
5448 }
5449 }
5450 // in case of error in above, try searching for ld_classic via PATH
5451 execvp(argv[0], (char**)argv);
5452 fprintf(stderr, "can't exec ld_classic\n");
5453 exit(1);
5454 }
5455
5456
5457 // Note, returned string buffer is own by this function.
5458 // It should not be freed
5459 // It will be reused, so clients need to strdup() if they want
5460 // to use it long term.
5461 const char* Options::demangleSymbol(const char* sym) const
5462 {
5463 // only try to demangle symbols if -demangle on command line
5464 if ( !fDemangle )
5465 return sym;
5466
5467 static size_t size = 1024;
5468 static char* buff = (char*)malloc(size);
5469
5470 #if DEMANGLE_SWIFT
5471 // only try to demangle symbols that look like Swift symbols
5472 if ( strncmp(sym, "__T", 3) == 0 ) {
5473 size_t demangledSize = fnd_get_demangled_name(&sym[1], buff, size);
5474 if ( demangledSize > size ) {
5475 size = demangledSize+2;
5476 buff = (char*)realloc(buff, size);
5477 demangledSize = fnd_get_demangled_name(&sym[1], buff, size);
5478 }
5479 if ( demangledSize != 0 )
5480 return buff;
5481 }
5482 #endif
5483
5484 // only try to demangle symbols that look like C++ symbols
5485 if ( strncmp(sym, "__Z", 3) != 0 )
5486 return sym;
5487
5488 int status;
5489 char* result = abi::__cxa_demangle(&sym[1], buff, &size, &status);
5490 if ( result != NULL ) {
5491 // if demangling successful, keep buffer for next demangle
5492 buff = result;
5493 return buff;
5494 }
5495 return sym;
5496 }
5497
5498
5499 void Options::dumpDependency(uint8_t opcode, const char* path) const
5500 {
5501 if ( !this->dumpDependencyInfo() )
5502 return;
5503
5504 // one time open() of -dependency_info file
5505 if ( fDependencyFileDescriptor == -1 ) {
5506 fDependencyFileDescriptor = open(this->dependencyInfoPath(), O_WRONLY | O_TRUNC | O_CREAT, 0666);
5507 if ( fDependencyFileDescriptor == -1 )
5508 throwf("Could not open or create -dependency_info file: %s", this->dependencyInfoPath());
5509
5510 // write header
5511 uint8_t version = depLinkerVersion;
5512 if ( write(fDependencyFileDescriptor, &version, 1) == -1 )
5513 throwf("write() to -dependency_info failed, errno=%d", errno);
5514 extern const char ldVersionString[];
5515 if ( write(fDependencyFileDescriptor, ldVersionString, strlen(ldVersionString)+1) == -1 )
5516 throwf("write() to -dependency_info failed, errno=%d", errno);
5517 }
5518
5519 char realPath[PATH_MAX];
5520 if ( path[0] != '/' ) {
5521 if ( realpath(path, realPath) != NULL ) {
5522 path = realPath;
5523 }
5524 }
5525
5526 if ( write(fDependencyFileDescriptor, &opcode, 1) == -1 )
5527 throwf("write() to -dependency_info failed, errno=%d", errno);
5528 if ( write(fDependencyFileDescriptor, path, strlen(path)+1) == -1 )
5529 throwf("write() to -dependency_info failed, errno=%d", errno);
5530
5531 //fprintf(stderr, "0x%02X %s\n", opcode, path);
5532 }
5533
5534
5535