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