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