1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
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
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.
22 * @APPLE_LICENSE_HEADER_END@
26 #include <sys/types.h>
28 #include <mach/vm_prot.h>
29 #include <sys/sysctl.h>
30 #include <mach-o/dyld.h>
36 #include <Availability.h>
43 #include "Architectures.hpp"
44 #include "MachOFileAbstraction.hpp"
48 // from FunctionNameDemangle.h
49 extern "C" size_t fnd_get_demangled_name(const char *mangledName
, char *outputBuffer
, size_t length
);
52 // upward dependency on lto::version()
54 extern const char* version();
57 // magic to place command line in crash reports
58 const int crashreporterBufferSize
= 2000;
59 static char crashreporterBuffer
[crashreporterBufferSize
];
60 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
61 #include <CrashReporterClient.h>
62 // hack until ld does not need to build on 10.6 anymore
63 struct crashreporter_annotations_t gCRAnnotations
64 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION
)))
65 = { CRASHREPORTER_ANNOTATIONS_VERSION
, 0, 0, 0, 0, 0, 0 };
67 extern "C" char* __crashreporter_info__
;
69 char* __crashreporter_info__
= crashreporterBuffer
;
73 static bool sEmitWarnings
= true;
74 static bool sFatalWarnings
= false;
75 static const char* sWarningsSideFilePath
= NULL
;
76 static FILE* sWarningsSideFile
= NULL
;
77 static int sWarningsCount
= 0;
79 void warning(const char* format
, ...)
82 if ( sEmitWarnings
) {
84 if ( sWarningsSideFilePath
!= NULL
) {
85 if ( sWarningsSideFile
== NULL
)
86 sWarningsSideFile
= fopen(sWarningsSideFilePath
, "a");
88 va_start(list
, format
);
89 fprintf(stderr
, "ld: warning: ");
90 vfprintf(stderr
, format
, list
);
91 fprintf(stderr
, "\n");
92 if ( sWarningsSideFile
!= NULL
) {
93 fprintf(sWarningsSideFile
, "ld: warning: ");
94 vfprintf(sWarningsSideFile
, format
, list
);
95 fprintf(sWarningsSideFile
, "\n");
96 fflush(sWarningsSideFile
);
102 void throwf(const char* format
, ...)
106 va_start(list
, format
);
107 vasprintf(&p
, format
, list
);
115 bool Options::FileInfo::checkFileExists(const Options
& options
, const char *p
)
117 struct stat statBuffer
;
120 if ( stat(p
, &statBuffer
) == 0 ) {
121 if (p
!= path
) path
= strdup(p
);
122 fileLen
= statBuffer
.st_size
;
123 modTime
= statBuffer
.st_mtime
;
126 if ( options
.dumpDependencyInfo() )
127 options
.dumpDependency(Options::depNotFound
, p
);
132 Options::Options(int argc
, const char* argv
[])
133 : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fArchitectureName("unknown"), fOutputKind(kDynamicExecutable
),
134 fHasPreferredSubType(false), fArchSupportsThumb2(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
135 fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fErrorOnOtherArchFiles(false), fForceSubtypeAll(false),
136 fInterposeMode(kInterposeNone
), fDeadStrip(false), fNameSpace(kTwoLevelNameSpace
),
137 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL
), fFinalName(NULL
), fEntryName(NULL
),
138 fBaseAddress(0), fMaxAddress(0x7FFFFFFFFFFFFFFFLL
),
139 fBaseWritableAddress(0), fSplitSegs(false),
140 fExportMode(kExportDefault
), fLibrarySearchMode(kSearchDylibAndArchiveInEachDir
),
141 fUndefinedTreatment(kUndefinedError
), fMessagesPrefixedWithArchitecture(true),
142 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchNonWeak
),
144 fUmbrellaName(NULL
), fInitFunctionName(NULL
), fDotOutputFile(NULL
), fExecutablePath(NULL
),
145 fBundleLoader(NULL
), fDtraceScriptName(NULL
), fSegAddrTablePath(NULL
), fMapPath(NULL
),
146 fDyldInstallPath("/usr/lib/dyld"), fTempLtoObjectPath(NULL
), fOverridePathlibLTO(NULL
), fLtoCpu(NULL
),
147 fZeroPageSize(ULLONG_MAX
), fStackSize(0), fStackAddr(0), fSourceVersion(0), fSDKVersion(0), fExecutableStack(false),
148 fNonExecutableHeap(false), fDisableNonExecutableHeap(false),
149 fMinimumHeaderPad(32), fSegmentAlignment(4096),
150 fCommonsMode(kCommonsIgnoreDylibs
), fUUIDMode(kUUIDContent
), fLocalSymbolHandling(kLocalSymbolsAll
), fWarnCommons(false),
151 fVerbose(false), fKeepRelocations(false), fWarnStabs(false),
152 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
153 fSharedRegionEligible(false), fSharedRegionEligibleForceOff(false), fPrintOrderFileStatistics(false),
154 fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fPIEOnCommandLine(false),
155 fDisablePositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
156 fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false), fKextsUseStubs(false),
157 fUsingLazyDylibLinking(false), fEncryptable(true), fEncryptableForceOn(false), fEncryptableForceOff(false),
158 fOrderData(true), fMarkDeadStrippableDylib(false),
159 fMakeCompressedDyldInfo(true), fMakeCompressedDyldInfoForceOff(false), fNoEHLabels(false),
160 fAllowCpuSubtypeMismatches(false), fUseSimplifiedDylibReExports(false),
161 fObjCABIVersion2Override(false), fObjCABIVersion1Override(false), fCanUseUpwardDylib(false),
162 fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false),
163 fLinkingMainExecutable(false), fForFinalLinkedImage(false), fForStatic(false),
164 fForDyld(false), fMakeTentativeDefinitionsReal(false), fWhyLoad(false), fRootSafe(false),
165 fSetuidSafe(false), fImplicitlyLinkPublicDylibs(true), fAddCompactUnwindEncoding(true),
166 fWarnCompactUnwind(false), fRemoveDwarfUnwindIfCompactExists(false),
167 fAutoOrderInitializers(true), fOptimizeZeroFill(true), fMergeZeroFill(false), fLogObjectFiles(false),
168 fLogAllFiles(false), fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false),
169 fOutputSlidable(false), fWarnWeakExports(false),
170 fObjcGcCompaction(false), fObjCGc(false), fObjCGcOnly(false),
171 fDemangle(false), fTLVSupport(false),
172 fVersionLoadCommand(false), fVersionLoadCommandForcedOn(false),
173 fVersionLoadCommandForcedOff(false), fFunctionStartsLoadCommand(false),
174 fFunctionStartsForcedOn(false), fFunctionStartsForcedOff(false),
175 fDataInCodeInfoLoadCommand(false), fDataInCodeInfoLoadCommandForcedOn(false), fDataInCodeInfoLoadCommandForcedOff(false),
176 fCanReExportSymbols(false), fObjcCategoryMerging(true), fPageAlignDataAtoms(false),
177 fNeedsThreadLoadCommand(false), fEntryPointLoadCommand(false),
178 fEntryPointLoadCommandForceOn(false), fEntryPointLoadCommandForceOff(false),
179 fSourceVersionLoadCommand(false),
180 fSourceVersionLoadCommandForceOn(false), fSourceVersionLoadCommandForceOff(false),
181 fTargetIOSSimulator(false), fExportDynamic(false), fAbsoluteSymbols(false),
182 fAllowSimulatorToLinkWithMacOSX(false), fKeepDwarfUnwind(true),
183 fKeepDwarfUnwindForcedOn(false), fKeepDwarfUnwindForcedOff(false),
184 fVerboseOptimizationHints(false), fIgnoreOptimizationHints(false),
185 fGenerateDtraceDOF(true), fAllowBranchIslands(true), fTraceSymbolLayout(false),
186 fMarkAppExtensionSafe(false), fCheckAppExtensionSafe(false), fForceLoadSwiftLibs(false),
187 fSharedRegionEncodingV2(false), fUseDataConstSegment(false),
188 fUseDataConstSegmentForceOn(false), fUseDataConstSegmentForceOff(false),
189 fBundleBitcode(false), fHideSymbols(false), fVerifyBitcode(false),
190 fReverseMapUUIDRename(false), fReverseMapPath(NULL
), fLTOCodegenOnly(false),
191 fIgnoreAutoLink(false), fAllowDeadDups(false), fBitcodeKind(kBitcodeProcess
),
192 fPlatform(kPlatformUnknown
), fDebugInfoStripping(kDebugInfoMinimal
), fTraceOutputFile(NULL
),
193 fMacVersionMin(ld::macVersionUnset
), fIOSVersionMin(ld::iOSVersionUnset
),
194 fSaveTempFiles(false), fSnapshotRequested(false), fPipelineFifo(NULL
),
195 fDependencyInfoPath(NULL
), fDependencyFileDescriptor(-1)
197 this->checkForClassic(argc
, argv
);
198 this->parsePreCommandLineEnvironmentSettings();
199 this->parse(argc
, argv
);
200 this->parsePostCommandLineEnvironmentSettings();
201 this->reconfigureDefaults();
202 this->checkIllegalOptionCombinations();
204 if ( this->dumpDependencyInfo() ) {
205 this->dumpDependency(depOutputFile
, fOutputFile
);
206 if ( fMapPath
!= NULL
)
207 this->dumpDependency(depOutputFile
, fMapPath
);
213 if ( fDependencyFileDescriptor
!= -1 )
214 ::close(fDependencyFileDescriptor
);
217 bool Options::errorBecauseOfWarnings() const
219 return (sFatalWarnings
&& (sWarningsCount
> 0));
223 const char* Options::installPath() const
225 if ( fDylibInstallName
!= NULL
)
226 return fDylibInstallName
;
227 else if ( fFinalName
!= NULL
)
234 bool Options::interposable(const char* name
) const
236 switch ( fInterposeMode
) {
239 case kInterposeAllExternal
:
242 return fInterposeList
.contains(name
);
244 throw "internal error";
248 bool Options::printWhyLive(const char* symbolName
) const
250 return fWhyLive
.contains(symbolName
);
254 const char* Options::dotOutputFile()
256 return fDotOutputFile
;
260 bool Options::hasWildCardExportRestrictList() const
262 // has -exported_symbols_list which contains some wildcards
263 return ((fExportMode
== kExportSome
) && fExportSymbols
.hasWildCards());
266 bool Options::hasWeakBitTweaks() const
268 // has -exported_symbols_list which contains some wildcards
269 return (!fForceWeakSymbols
.empty() || !fForceNotWeakSymbols
.empty());
272 bool Options::allGlobalsAreDeadStripRoots() const
274 // -exported_symbols_list means globals are not exported by default
275 if ( fExportMode
== kExportSome
)
278 switch ( fOutputKind
) {
279 case Options::kDynamicExecutable
:
280 // <rdar://problem/12839986> Add the -export_dynamic flag
281 return fExportDynamic
;
282 case Options::kStaticExecutable
:
283 // <rdar://problem/13361218> Support the -export_dynamic flag for xnu
284 return fExportDynamic
;
285 case Options::kPreload
:
286 // by default unused globals in a main executable are stripped
288 case Options::kDynamicLibrary
:
289 case Options::kDynamicBundle
:
290 case Options::kObjectFile
:
292 case Options::kKextBundle
:
299 bool Options::keepRelocations()
301 return fKeepRelocations
;
304 bool Options::warnStabs()
309 const char* Options::executablePath()
311 return fExecutablePath
;
314 uint32_t Options::initialSegProtection(const char* segName
) const
316 for(std::vector
<Options::SegmentProtect
>::const_iterator it
= fCustomSegmentProtections
.begin(); it
!= fCustomSegmentProtections
.end(); ++it
) {
317 if ( strcmp(it
->name
, segName
) == 0 ) {
321 if ( strcmp(segName
, "__PAGEZERO") == 0 ) {
324 else if ( strcmp(segName
, "__TEXT") == 0 ) {
325 return VM_PROT_READ
| VM_PROT_EXECUTE
;
327 else if ( strcmp(segName
, "__LINKEDIT") == 0 ) {
331 // all others default to read-write
332 return VM_PROT_READ
| VM_PROT_WRITE
;
335 uint32_t Options::maxSegProtection(const char* segName
) const
337 // iPhoneOS always uses same protection for max and initial
338 // <rdar://problem/11663436> simulator apps need to use MacOSX max-prot
339 if ( (fPlatform
!= kPlatformOSX
) && !fTargetIOSSimulator
)
340 return initialSegProtection(segName
);
342 for(std::vector
<Options::SegmentProtect
>::const_iterator it
= fCustomSegmentProtections
.begin(); it
!= fCustomSegmentProtections
.end(); ++it
) {
343 if ( strcmp(it
->name
, segName
) == 0 ) {
347 if ( strcmp(segName
, "__PAGEZERO") == 0 ) {
350 // all others default to all
351 return VM_PROT_READ
| VM_PROT_WRITE
| VM_PROT_EXECUTE
;
354 uint64_t Options::segPageSize(const char* segName
) const
356 for(std::vector
<SegmentSize
>::const_iterator it
=fCustomSegmentSizes
.begin(); it
!= fCustomSegmentSizes
.end(); ++it
) {
357 if ( strcmp(it
->name
, segName
) == 0 )
360 return fSegmentAlignment
;
363 uint64_t Options::customSegmentAddress(const char* segName
) const
365 for(std::vector
<SegmentStart
>::const_iterator it
=fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
366 if ( strcmp(it
->name
, segName
) == 0 )
369 // if custom stack in use, model as segment with custom address
370 if ( (fStackSize
!= 0) && (strcmp("__UNIXSTACK", segName
) == 0) )
371 return fStackAddr
- fStackSize
;
375 bool Options::hasCustomSegmentAddress(const char* segName
) const
377 for(std::vector
<SegmentStart
>::const_iterator it
=fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
378 if ( strcmp(it
->name
, segName
) == 0 )
381 // if custom stack in use, model as segment with custom address
382 if ( (fStackSize
!= 0) && (strcmp("__UNIXSTACK", segName
) == 0) )
387 bool Options::hasCustomSectionAlignment(const char* segName
, const char* sectName
) const
389 for (std::vector
<SectionAlignment
>::const_iterator it
= fSectionAlignments
.begin(); it
!= fSectionAlignments
.end(); ++it
) {
390 if ( (strcmp(it
->segmentName
, segName
) == 0) && (strcmp(it
->sectionName
, sectName
) == 0) )
396 uint8_t Options::customSectionAlignment(const char* segName
, const char* sectName
) const
398 for (std::vector
<SectionAlignment
>::const_iterator it
= fSectionAlignments
.begin(); it
!= fSectionAlignments
.end(); ++it
) {
399 if ( (strcmp(it
->segmentName
, segName
) == 0) && (strcmp(it
->sectionName
, sectName
) == 0) )
400 return it
->alignment
;
405 bool Options::segmentOrderAfterFixedAddressSegment(const char* segName
) const
407 bool nowPinned
= false;
408 for (std::vector
<const char*>::const_iterator it
=fSegmentOrder
.begin(); it
!= fSegmentOrder
.end(); ++it
) {
409 if ( strcmp(*it
, segName
) == 0 )
411 if ( hasCustomSegmentAddress(*it
) )
417 bool Options::hasExportedSymbolOrder()
419 return (fExportSymbolsOrder
.size() > 0);
422 bool Options::exportedSymbolOrder(const char* sym
, unsigned int* order
) const
424 NameToOrder::const_iterator pos
= fExportSymbolsOrder
.find(sym
);
425 if ( pos
!= fExportSymbolsOrder
.end() ) {
426 *order
= pos
->second
;
435 void Options::loadSymbolOrderFile(const char* fileOfExports
, NameToOrder
& orderMapping
)
437 // read in whole file
438 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
440 throwf("can't open -exported_symbols_order file: %s", fileOfExports
);
441 struct stat stat_buf
;
442 ::fstat(fd
, &stat_buf
);
443 char* p
= (char*)malloc(stat_buf
.st_size
);
445 throwf("can't process -exported_symbols_order file: %s", fileOfExports
);
447 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
448 throwf("can't read -exported_symbols_order file: %s", fileOfExports
);
452 // parse into symbols and add to unordered_set
453 unsigned int count
= 0;
454 char * const end
= &p
[stat_buf
.st_size
];
455 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
456 char* symbolStart
= NULL
;
457 for (char* s
= p
; s
< end
; ++s
) {
463 else if ( !isspace(*s
) ) {
469 if ( (*s
== '\n') || (*s
== '\r') ) {
471 // removing any trailing spaces
473 while ( isspace(*last
) ) {
477 orderMapping
[symbolStart
] = ++count
;
483 if ( (*s
== '\n') || (*s
== '\r') )
488 if ( state
== inSymbol
) {
489 warning("missing line-end at end of file \"%s\"", fileOfExports
);
490 int len
= end
-symbolStart
+1;
491 char* temp
= new char[len
];
492 strlcpy(temp
, symbolStart
, len
);
494 // remove any trailing spaces
495 char* last
= &temp
[len
-2];
496 while ( isspace(*last
) ) {
500 orderMapping
[temp
] = ++count
;
503 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
506 bool Options::forceWeak(const char* symbolName
) const
508 return fForceWeakSymbols
.contains(symbolName
);
511 bool Options::forceNotWeak(const char* symbolName
) const
513 return fForceNotWeakSymbols
.contains(symbolName
);
516 bool Options::forceWeakNonWildCard(const char* symbolName
) const
518 return fForceWeakSymbols
.containsNonWildcard(symbolName
);
521 bool Options::forceNotWeakNonWildcard(const char* symbolName
) const
523 return fForceNotWeakSymbols
.containsNonWildcard(symbolName
);
526 bool Options::forceCoalesce(const char* symbolName
) const
528 return fForceCoalesceSymbols
.contains(symbolName
);
532 bool Options::shouldExport(const char* symbolName
) const
534 switch (fExportMode
) {
536 return fExportSymbols
.contains(symbolName
);
537 case kDontExportSome
:
538 return ! fDontExportSymbols
.contains(symbolName
);
542 throw "internal error";
545 bool Options::shouldReExport(const char* symbolName
) const
547 return fReExportSymbols
.contains(symbolName
);
550 bool Options::keepLocalSymbol(const char* symbolName
) const
552 switch (fLocalSymbolHandling
) {
553 case kLocalSymbolsAll
:
555 case kLocalSymbolsNone
:
557 case kLocalSymbolsSelectiveInclude
:
558 return fLocalSymbolsIncluded
.contains(symbolName
);
559 case kLocalSymbolsSelectiveExclude
:
560 return ! fLocalSymbolsExcluded
.contains(symbolName
);
562 throw "internal error";
565 const std::vector
<const char*>* Options::sectionOrder(const char* segName
) const
567 for (std::vector
<SectionOrderList
>::const_iterator it
=fSectionOrder
.begin(); it
!= fSectionOrder
.end(); ++it
) {
568 if ( strcmp(it
->segmentName
, segName
) == 0 )
569 return &it
->sectionOrder
;
574 uint32_t Options::minOSversion() const
578 return iOSVersionMin();
580 return macosxVersionMin();
581 case kPlatformWatchOS
:
582 return watchOSVersionMin();
584 case Options::kPlatform_tvOS
:
585 return iOSVersionMin();
593 void Options::setArchitecture(cpu_type_t type
, cpu_subtype_t subtype
, Options::Platform platform
)
595 for (const ArchInfo
* t
=archInfoArray
; t
->archName
!= NULL
; ++t
) {
596 if ( (type
== t
->cpuType
) && (subtype
== t
->cpuSubType
) ) {
597 fArchitecture
= type
;
598 fSubArchitecture
= subtype
;
599 fArchitectureName
= t
->archName
;
600 fHasPreferredSubType
= t
->isSubType
;
601 fArchSupportsThumb2
= t
->supportsThumb2
;
602 fPlatform
= platform
;
605 case CPU_TYPE_X86_64
:
606 if ( (fPlatform
== kPlatformOSX
) && (fOutputKind
!= Options::kObjectFile
) ) {
607 #ifdef DEFAULT_MACOSX_MIN_VERSION
608 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
609 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
611 warning("-macosx_version_min not specified, assuming 10.6");
612 fMacVersionMin
= ld::mac10_6
;
618 if ( (fPlatform
== kPlatformiOS
) && (fOutputKind
!= Options::kObjectFile
) ) {
619 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
620 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION
);
621 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION
);
623 warning("-ios_version_min not specified, assuming 6.0");
624 setIOSVersionMin("6.0");
629 fLinkSnapshot
.recordArch(fArchitectureName
);
630 // only use compressed LINKEDIT for:
631 // Mac OS X 10.6 or later
633 if ( !fMakeCompressedDyldInfo
&& minOS(ld::mac10_6
, ld::iOS_3_1
) && !fMakeCompressedDyldInfoForceOff
)
634 fMakeCompressedDyldInfo
= true;
635 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
636 if ( minOS(ld::mac10_5
, ld::iOS_2_0
) )
637 fUseSimplifiedDylibReExports
= true;
641 fArchitectureName
= "unknown architecture";
644 bool Options::armUsesZeroCostExceptions() const
646 return ( (fArchitecture
== CPU_TYPE_ARM
) && (fSubArchitecture
== CPU_SUBTYPE_ARM_V7K
) );
649 void Options::parseArch(const char* arch
)
652 throw "-arch must be followed by an architecture string";
653 for (const ArchInfo
* t
=archInfoArray
; t
->archName
!= NULL
; ++t
) {
654 if ( strcmp(t
->archName
,arch
) == 0 ) {
655 fArchitectureName
= arch
;
656 fArchitecture
= t
->cpuType
;
657 fSubArchitecture
= t
->cpuSubType
;
658 fHasPreferredSubType
= t
->isSubType
;
659 fArchSupportsThumb2
= t
->supportsThumb2
;
663 throwf("unknown/unsupported architecture name for: -arch %s", arch
);
666 bool Options::checkForFile(const char* format
, const char* dir
, const char* rootName
, FileInfo
& result
) const
668 char possiblePath
[strlen(dir
)+strlen(rootName
)+strlen(format
)+8];
669 sprintf(possiblePath
, format
, dir
, rootName
);
670 bool found
= result
.checkFileExists(*this, possiblePath
);
671 if ( fTraceDylibSearching
)
672 printf("[Logging for XBS]%sfound library: '%s'\n", (found
? " " : " not "), possiblePath
);
677 Options::FileInfo
Options::findLibrary(const char* rootName
, bool dylibsOnly
) const
680 const int rootNameLen
= strlen(rootName
);
681 // if rootName ends in .o there is no .a vs .dylib choice
682 if ( (rootNameLen
> 3) && (strcmp(&rootName
[rootNameLen
-2], ".o") == 0) ) {
683 for (std::vector
<const char*>::const_iterator it
= fLibrarySearchPaths
.begin();
684 it
!= fLibrarySearchPaths
.end();
686 const char* dir
= *it
;
687 if ( checkForFile("%s/%s", dir
, rootName
, result
) )
692 bool lookForDylibs
= false;
693 switch ( fOutputKind
) {
694 case Options::kDynamicExecutable
:
695 case Options::kDynamicLibrary
:
696 case Options::kDynamicBundle
:
697 case Options::kObjectFile
: // <rdar://problem/15914513>
698 lookForDylibs
= true;
700 case Options::kStaticExecutable
:
702 case Options::kPreload
:
703 case Options::kKextBundle
:
704 lookForDylibs
= false;
707 switch ( fLibrarySearchMode
) {
708 case kSearchAllDirsForDylibsThenAllDirsForArchives
:
709 // first look in all directories for just for dylibs
710 if ( lookForDylibs
) {
711 for (std::vector
<const char*>::const_iterator it
= fLibrarySearchPaths
.begin();
712 it
!= fLibrarySearchPaths
.end();
714 const char* dir
= *it
;
715 if ( checkForFile("%s/lib%s.tbd", dir
, rootName
, result
) )
717 if ( checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
720 for (std::vector
<const char*>::const_iterator it
= fLibrarySearchPaths
.begin();
721 it
!= fLibrarySearchPaths
.end();
723 const char* dir
= *it
;
724 if ( checkForFile("%s/lib%s.so", dir
, rootName
, result
) )
728 // next look in all directories for just for archives
730 for (std::vector
<const char*>::const_iterator it
= fLibrarySearchPaths
.begin();
731 it
!= fLibrarySearchPaths
.end();
733 const char* dir
= *it
;
734 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
740 case kSearchDylibAndArchiveInEachDir
:
741 // look in each directory for just for a dylib then for an archive
742 for (std::vector
<const char*>::const_iterator it
= fLibrarySearchPaths
.begin();
743 it
!= fLibrarySearchPaths
.end();
745 const char* dir
= *it
;
746 if ( lookForDylibs
&& checkForFile("%s/lib%s.tbd", dir
, rootName
, result
) )
748 if ( lookForDylibs
&& checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
750 if ( lookForDylibs
&& checkForFile("%s/lib%s.so", dir
, rootName
, result
) )
752 if ( !dylibsOnly
&& checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
758 throwf("library not found for -l%s", rootName
);
761 Options::FileInfo
Options::findFramework(const char* frameworkName
) const
763 if ( frameworkName
== NULL
)
764 throw "-framework missing next argument";
765 char temp
[strlen(frameworkName
)+1];
766 strcpy(temp
, frameworkName
);
767 const char* name
= temp
;
768 const char* suffix
= NULL
;
769 char* comma
= strchr(temp
, ',');
770 if ( comma
!= NULL
) {
774 return findFramework(name
, suffix
);
777 Options::FileInfo
Options::findFramework(const char* rootName
, const char* suffix
) const
779 for (const auto* path
: fFrameworkSearchPaths
) {
780 auto possiblePath
= std::string(path
).append("/").append(rootName
).append(".framework/").append(rootName
);
781 if ( suffix
!= nullptr ) {
782 char realPath
[PATH_MAX
];
783 // no symlink in framework to suffix variants, so follow main symlink
784 if ( realpath(possiblePath
.c_str(), realPath
) != nullptr )
785 possiblePath
= std::string(realPath
).append(suffix
);
788 bool found
= result
.checkFileExists(*this, (possiblePath
+ ".tbd").c_str());
790 found
= result
.checkFileExists(*this, possiblePath
.c_str());
791 if ( fTraceDylibSearching
)
792 printf("[Logging for XBS]%sfound framework: '%s'\n",
793 (found
? " " : " not "), possiblePath
.c_str());
798 // try without suffix
799 if ( suffix
!= NULL
)
800 return findFramework(rootName
, NULL
);
802 throwf("framework not found %s", rootName
);
805 Options::FileInfo
Options::findFile(const std::string
&path
) const
809 // if absolute path and not a .o file, then use SDK prefix
810 if ( (path
[0] == '/') && (strcmp(&path
[path
.size()-2], ".o") != 0) ) {
812 auto lastSlashIdx
= tbdFile
.find_last_of('/');
813 auto lastDotIdx
= tbdFile
.find_last_of('.');
814 if (lastDotIdx
!= std::string::npos
&& lastDotIdx
> lastSlashIdx
)
815 tbdFile
.erase(lastDotIdx
, std::string::npos
);
816 tbdFile
.append(".tbd");
818 for (const auto* sdkPathDir
: fSDKPaths
) {
819 auto possiblePath
= std::string(sdkPathDir
) + tbdFile
;
820 if ( result
.checkFileExists(*this, possiblePath
.c_str()) )
822 possiblePath
= std::string(sdkPathDir
) + path
;
823 if ( result
.checkFileExists(*this, possiblePath
.c_str()) )
829 std::string file
= path
;
830 auto lastDotIdx
= file
.find_last_of('.');
831 if (lastDotIdx
!= std::string::npos
)
832 file
.erase(lastDotIdx
, std::string::npos
);
833 if ( result
.checkFileExists(*this, file
.append(".tbd").c_str()) )
836 if ( result
.checkFileExists(*this, path
.c_str()) ) {
841 // try @executable_path substitution
842 if ( (path
.find("@executable_path/") == 0) && (fExecutablePath
!= nullptr) ) {
843 char newPath
[strlen(fExecutablePath
) + path
.size()];
844 strcpy(newPath
, fExecutablePath
);
845 char* addPoint
= strrchr(newPath
,'/');
846 if ( addPoint
!= nullptr )
847 strcpy(&addPoint
[1], &path
[17]);
849 strcpy(newPath
, &path
[17]);
851 std::string file
= newPath
;
852 auto lastDotIdx
= file
.find_last_of('.');
853 if (lastDotIdx
!= std::string::npos
)
854 file
.erase(lastDotIdx
, std::string::npos
);
855 if ( result
.checkFileExists(*this, file
.append(".tbd").c_str()) ) {
858 if ( result
.checkFileExists(*this, newPath
) ) {
864 throwf("file not found: %s", path
.c_str());
867 Options::FileInfo
Options::findFileUsingPaths(const std::string
&path
) const
871 auto lastSlashPos
= path
.find_last_of('/');
872 auto pos
= ( lastSlashPos
!= std::string::npos
) ? lastSlashPos
+ 1 : 0;
873 auto leafName
= path
.substr(pos
);
875 // Is this in a framework?
876 // /path/Foo.framework/Foo ==> true (Foo)
877 // /path/Foo.framework/Frameworks/Bar.framework/Bar ==> true (Bar)
878 // /path/Foo.framework/Resources/Bar ==> false
879 bool isFramework
= false;
880 if ( lastSlashPos
!= std::string::npos
) {
881 auto frameworkDir
= std::string("/").append(leafName
).append(".framework/");
882 if ( path
.rfind(frameworkDir
) != std::string::npos
)
886 // These are abbreviated versions of the routines findFramework and findLibrary above
887 // because we already know the final name of the file that we're looking for and so
888 // don't need to try variations, just paths. We do need to add the additional bits
889 // onto the framework path though.
891 auto endPos
= path
.rfind(".framework");
892 auto beginPos
= path
.find_last_of('/', endPos
);
893 auto leafPath
= path
.substr(beginPos
);
894 for (const auto* dir
: fFrameworkSearchPaths
) {
895 auto possiblePath
= dir
+ leafPath
;
896 if ( checkForFile("%s.%s", possiblePath
.c_str(), "tbd", result
) )
898 if ( checkForFile("%s", possiblePath
.c_str(), "", result
) )
902 // if this is a .dylib inside a framework, do not search -L paths
903 // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
904 bool embeddedDylib
= ( (leafName
.size() > 6)
905 && (leafName
.find(".dylib", leafName
.size()-6) != std::string::npos
)
906 && (path
.find(".framework/") != std::string::npos
) );
907 if ( !embeddedDylib
) {
908 for (const auto* dir
: fLibrarySearchPaths
) {
909 //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
910 if ( checkForFile("%s/%s", dir
, std::string(leafName
).append(".tbd").c_str(), result
) )
912 if ( checkForFile("%s/%s", dir
, leafName
.c_str(), result
) )
918 // If we didn't find it fall back to findFile.
919 return findFile(path
);
924 void Options::parseSegAddrTable(const char* segAddrPath
, const char* installPth
)
926 FILE* file
= fopen(segAddrPath
, "r");
927 if ( file
== NULL
) {
928 warning("-seg_addr_table file cannot be read: %s", segAddrPath
);
933 uint64_t firstColumAddress
= 0;
934 uint64_t secondColumAddress
= 0;
935 bool hasSecondColumn
= false;
936 while ( fgets(path
, PATH_MAX
, file
) != NULL
) {
937 path
[PATH_MAX
-1] = '\0';
938 char* eol
= strchr(path
, '\n');
941 // ignore lines not starting with 0x number
942 if ( (path
[0] == '0') && (path
[1] == 'x') ) {
944 firstColumAddress
= strtoull(path
, &p
, 16);
945 while ( isspace(*p
) )
947 // see if second column is a number
948 if ( (p
[0] == '0') && (p
[1] == 'x') ) {
949 secondColumAddress
= strtoull(p
, &p
, 16);
950 hasSecondColumn
= true;
951 while ( isspace(*p
) )
954 while ( isspace(*p
) )
957 // remove any trailing whitespace
958 for(char* end
= eol
-1; (end
> p
) && isspace(*end
); --end
)
960 // see if this line is for the dylib being linked
961 if ( strcmp(p
, installPth
) == 0 ) {
962 fBaseAddress
= firstColumAddress
;
963 if ( hasSecondColumn
) {
964 fBaseWritableAddress
= secondColumAddress
;
967 break; // out of while loop
976 void Options::loadFileList(const char* fileOfPaths
, ld::File::Ordinal baseOrdinal
)
979 const char* comma
= strrchr(fileOfPaths
, ',');
980 const char* prefix
= NULL
;
981 if ( comma
!= NULL
) {
982 // <rdar://problem/5907981> -filelist fails with comma in path
983 file
= fopen(fileOfPaths
, "r");
984 if ( file
== NULL
) {
986 int realFileOfPathsLen
= comma
-fileOfPaths
;
987 char realFileOfPaths
[realFileOfPathsLen
+1];
988 strncpy(realFileOfPaths
,fileOfPaths
, realFileOfPathsLen
);
989 realFileOfPaths
[realFileOfPathsLen
] = '\0';
990 file
= fopen(realFileOfPaths
, "r");
992 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", realFileOfPaths
, errno
, strerror(errno
));
993 if ( this->dumpDependencyInfo() )
994 this->dumpDependency(Options::depFileList
, realFileOfPaths
);
998 file
= fopen(fileOfPaths
, "r");
1000 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", fileOfPaths
, errno
, strerror(errno
));
1001 if ( this->dumpDependencyInfo() )
1002 this->dumpDependency(Options::depFileList
, fileOfPaths
);
1005 char path
[PATH_MAX
];
1006 ld::File::Ordinal previousOrdinal
= baseOrdinal
;
1007 while ( fgets(path
, PATH_MAX
, file
) != NULL
) {
1008 path
[PATH_MAX
-1] = '\0';
1009 char* eol
= strchr(path
, '\n');
1012 if ( prefix
!= NULL
) {
1013 char builtPath
[strlen(prefix
)+strlen(path
)+2];
1014 strcpy(builtPath
, prefix
);
1015 strcat(builtPath
, "/");
1016 strcat(builtPath
, path
);
1017 if (fPipelineFifo
!= NULL
) {
1018 FileInfo info
= FileInfo(builtPath
);
1019 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
1020 previousOrdinal
= info
.ordinal
;
1021 info
.fromFileList
= true;
1022 fInputFiles
.push_back(info
);
1024 FileInfo info
= findFile(builtPath
);
1025 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
1026 previousOrdinal
= info
.ordinal
;
1027 info
.fromFileList
= true;
1028 fInputFiles
.push_back(info
);
1032 if (fPipelineFifo
!= NULL
) {
1033 FileInfo info
= FileInfo(path
);
1034 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
1035 previousOrdinal
= info
.ordinal
;
1036 info
.fromFileList
= true;
1037 fInputFiles
.push_back(info
);
1039 FileInfo info
= findFile(path
);
1040 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
1041 previousOrdinal
= info
.ordinal
;
1042 info
.fromFileList
= true;
1043 fInputFiles
.push_back(info
);
1051 void Options::SetWithWildcards::remove(const NameSet
& toBeRemoved
)
1053 for(NameSet::const_iterator it
=toBeRemoved
.begin(); it
!= toBeRemoved
.end(); ++it
) {
1054 const char* symbolName
= *it
;
1055 NameSet::iterator pos
= fRegular
.find(symbolName
);
1056 if ( pos
!= fRegular
.end() )
1057 fRegular
.erase(pos
);
1061 bool Options::SetWithWildcards::hasWildCards(const char* symbol
)
1063 // an exported symbol name containing *, ?, or [ requires wildcard matching
1064 return ( strpbrk(symbol
, "*?[") != NULL
);
1067 void Options::SetWithWildcards::insert(const char* symbol
)
1069 if ( hasWildCards(symbol
) )
1070 fWildCard
.push_back(symbol
);
1072 fRegular
.insert(symbol
);
1075 bool Options::SetWithWildcards::contains(const char* symbol
, bool* matchBecauseOfWildcard
) const
1077 if ( matchBecauseOfWildcard
!= NULL
)
1078 *matchBecauseOfWildcard
= false;
1079 // first look at hash table on non-wildcard symbols
1080 if ( fRegular
.find(symbol
) != fRegular
.end() )
1082 // next walk list of wild card symbols looking for a match
1083 for(std::vector
<const char*>::const_iterator it
= fWildCard
.begin(); it
!= fWildCard
.end(); ++it
) {
1084 if ( wildCardMatch(*it
, symbol
) ) {
1085 if ( matchBecauseOfWildcard
!= NULL
)
1086 *matchBecauseOfWildcard
= true;
1093 // Support "foo.o:_bar" to mean symbol _bar in file foo.o
1094 bool Options::SetWithWildcards::containsWithPrefix(const char* symbol
, const char* file
, bool& wildCardMatch
) const
1096 wildCardMatch
= false;
1097 if ( contains(symbol
, &wildCardMatch
) )
1101 const char* s
= strrchr(file
, '/');
1104 char buff
[strlen(file
)+strlen(symbol
)+2];
1105 sprintf(buff
, "%s:%s", file
, symbol
);
1106 return contains(buff
, &wildCardMatch
);
1109 bool Options::SetWithWildcards::containsNonWildcard(const char* symbol
) const
1111 // look at hash table on non-wildcard symbols
1112 return ( fRegular
.find(symbol
) != fRegular
.end() );
1116 std::vector
<const char*> Options::exportsData() const
1118 return fExportSymbols
.data();
1122 std::vector
<const char*> Options::SetWithWildcards::data() const
1124 std::vector
<const char*> data
;
1125 for (NameSet::iterator it
=regularBegin(); it
!= regularEnd(); ++it
) {
1126 data
.push_back(*it
);
1128 for (std::vector
<const char*>::const_iterator it
=fWildCard
.begin(); it
!= fWildCard
.end(); ++it
) {
1129 data
.push_back(*it
);
1134 bool Options::SetWithWildcards::inCharRange(const char*& p
, unsigned char c
) const
1138 while ( *p
!= '\0' ) {
1141 // found beginining [ and ending ]
1142 unsigned char last
= '\0';
1143 for ( const char* s
= b
; s
< e
; ++s
) {
1145 unsigned char next
= *(++s
);
1146 if ( (last
<= c
) && (c
<= next
) )
1163 bool Options::SetWithWildcards::wildCardMatch(const char* pattern
, const char* symbol
) const
1165 const char* s
= symbol
;
1166 for (const char* p
= pattern
; *p
!= '\0'; ++p
) {
1171 for (const char* t
= s
; *t
!= '\0'; ++t
) {
1172 if ( wildCardMatch(&p
[1], t
) )
1182 if ( ! inCharRange(p
, *s
) )
1192 return (*s
== '\0');
1196 void Options::loadExportFile(const char* fileOfExports
, const char* option
, SetWithWildcards
& set
)
1198 if ( fileOfExports
== NULL
)
1199 throwf("missing file after %s", option
);
1200 // read in whole file
1201 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
1203 throwf("can't open %s file: %s", option
, fileOfExports
);
1204 struct stat stat_buf
;
1205 ::fstat(fd
, &stat_buf
);
1206 char* p
= (char*)malloc(stat_buf
.st_size
);
1208 throwf("can't process %s file: %s", option
, fileOfExports
);
1210 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1211 throwf("can't read %s file: %s", option
, fileOfExports
);
1213 if ( this->dumpDependencyInfo() )
1214 this->dumpDependency(Options::depMisc
, fileOfExports
);
1218 // parse into symbols and add to unordered_set
1219 char * const end
= &p
[stat_buf
.st_size
];
1220 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
1221 char* symbolStart
= NULL
;
1222 for (char* s
= p
; s
< end
; ++s
) {
1228 else if ( !isspace(*s
) ) {
1234 if ( (*s
== '\n') || (*s
== '\r') ) {
1236 // removing any trailing spaces
1238 while ( isspace(*last
) ) {
1242 set
.insert(symbolStart
);
1248 if ( (*s
== '\n') || (*s
== '\r') )
1253 if ( state
== inSymbol
) {
1254 warning("missing line-end at end of file \"%s\"", fileOfExports
);
1255 int len
= end
-symbolStart
+1;
1256 char* temp
= new char[len
];
1257 strlcpy(temp
, symbolStart
, len
);
1259 // remove any trailing spaces
1260 char* last
= &temp
[len
-2];
1261 while ( isspace(*last
) ) {
1268 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
1271 void Options::parseAliasFile(const char* fileOfAliases
)
1273 // read in whole file
1274 int fd
= ::open(fileOfAliases
, O_RDONLY
, 0);
1276 throwf("can't open alias file: %s", fileOfAliases
);
1277 struct stat stat_buf
;
1278 ::fstat(fd
, &stat_buf
);
1279 char* p
= (char*)malloc(stat_buf
.st_size
+1);
1281 throwf("can't process alias file: %s", fileOfAliases
);
1283 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1284 throwf("can't read alias file: %s", fileOfAliases
);
1285 p
[stat_buf
.st_size
] = '\n';
1287 if ( this->dumpDependencyInfo() )
1288 this->dumpDependency(Options::depMisc
, fileOfAliases
);
1290 // parse into symbols and add to fAliases
1292 char * const end
= &p
[stat_buf
.st_size
+1];
1293 enum { lineStart
, inRealName
, inBetween
, inAliasName
, inComment
} state
= lineStart
;
1295 for (char* s
= p
; s
< end
; ++s
) {
1301 else if ( !isspace(*s
) ) {
1308 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber
, fileOfAliases
);
1312 else if ( isspace(*s
) ) {
1319 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber
, fileOfAliases
);
1323 else if ( ! isspace(*s
) ) {
1324 state
= inAliasName
;
1331 // removing any trailing spaces
1333 while ( isspace(*last
) ) {
1337 fAliases
.push_back(pair
);
1340 else if ( *s
== '\n' ) {
1342 // removing any trailing spaces
1344 while ( isspace(*last
) ) {
1348 fAliases
.push_back(pair
);
1359 // Note: we do not free() the malloc buffer, because the strings therein are used by fAliases
1364 void Options::setUndefinedTreatment(const char* treatment
)
1366 if ( treatment
== NULL
)
1367 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
1369 if ( strcmp(treatment
, "warning") == 0 )
1370 fUndefinedTreatment
= kUndefinedWarning
;
1371 else if ( strcmp(treatment
, "error") == 0 )
1372 fUndefinedTreatment
= kUndefinedError
;
1373 else if ( strcmp(treatment
, "suppress") == 0 )
1374 fUndefinedTreatment
= kUndefinedSuppress
;
1375 else if ( strcmp(treatment
, "dynamic_lookup") == 0 )
1376 fUndefinedTreatment
= kUndefinedDynamicLookup
;
1378 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
1381 Options::Treatment
Options::parseTreatment(const char* treatment
)
1383 if ( treatment
== NULL
)
1386 if ( strcmp(treatment
, "warning") == 0 )
1388 else if ( strcmp(treatment
, "error") == 0 )
1390 else if ( strcmp(treatment
, "suppress") == 0 )
1396 void Options::setMacOSXVersionMin(const char* version
)
1398 if ( version
== NULL
)
1399 throw "-macosx_version_min argument missing";
1401 if ( (strncmp(version
, "10.", 3) == 0) && isdigit(version
[3]) ) {
1402 unsigned int minorVersion
= 0;
1403 for (int i
=3; isdigit(version
[i
]); ++i
) {
1404 minorVersion
= minorVersion
*10 + (version
[i
] - '0');
1406 if ( minorVersion
> 255 ) {
1407 warning("Mac OS X minor version > 255 in '%s'", version
);
1410 fMacVersionMin
= (ld::MacVersionMin
)(0x000A0000 | (minorVersion
<< 8));
1411 fPlatform
= kPlatformOSX
;
1414 warning("unknown option to -macosx_version_min, not 10.x");
1418 void Options::setIOSVersionMin(const char* version
)
1420 if ( version
== NULL
)
1421 throw "-ios_version_min argument missing";
1422 if ( ! isdigit(version
[0]) )
1423 throw "-ios_version_min argument is not a number";
1424 if ( version
[1] != '.' )
1425 throw "-ios_version_min argument is missing period as second character";
1426 if ( ! isdigit(version
[2]) )
1427 throw "-ios_version_min argument is not a number";
1429 unsigned int majorVersion
= version
[0] - '0';
1430 unsigned int minorVersion
= version
[2] - '0';
1431 fIOSVersionMin
= (ld::IOSVersionMin
)((majorVersion
<< 16) | (minorVersion
<< 8));
1432 fPlatform
= kPlatformiOS
;
1436 void Options::setWatchOSVersionMin(const char* version
)
1438 if ( version
== NULL
)
1439 throw "-watchos_version_min argument missing";
1440 if ( ! isdigit(version
[0]) )
1441 throw "-watchos_version_min argument is not a number";
1442 if ( version
[1] != '.' )
1443 throw "-watchos_version_min argument is missing period as second character";
1444 if ( ! isdigit(version
[2]) )
1445 throw "-watchos_version_min argument is not a number";
1447 unsigned int majorVersion
= version
[0] - '0';
1448 unsigned int minorVersion
= version
[2] - '0';
1449 fWatchOSVersionMin
= (ld::WatchOSVersionMin
)((majorVersion
<< 16) | (minorVersion
<< 8));
1450 fPlatform
= kPlatformWatchOS
;
1454 bool Options::minOS(ld::MacVersionMin requiredMacMin
, ld::IOSVersionMin requirediPhoneOSMin
)
1456 if ( fMacVersionMin
!= ld::macVersionUnset
) {
1457 return ( fMacVersionMin
>= requiredMacMin
);
1459 else if ( fWatchOSVersionMin
!= ld::wOSVersionUnset
) {
1460 // Hack until we fully track watch and ios versions seperately
1461 return ( (fWatchOSVersionMin
+ 0x00070000) >= requirediPhoneOSMin
);
1464 return ( fIOSVersionMin
>= requirediPhoneOSMin
);
1468 bool Options::min_iOS(ld::IOSVersionMin requirediOSMin
)
1470 if ( fWatchOSVersionMin
!= ld::wOSVersionUnset
) {
1471 // Hack until we fully track watch and ios versions seperately
1472 return ( (fWatchOSVersionMin
+ 0x00070000) >= requirediOSMin
);
1475 return ( fIOSVersionMin
>= requirediOSMin
);
1479 void Options::setWeakReferenceMismatchTreatment(const char* treatment
)
1481 if ( treatment
== NULL
)
1482 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
1484 if ( strcmp(treatment
, "error") == 0 )
1485 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchError
;
1486 else if ( strcmp(treatment
, "weak") == 0 )
1487 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchWeak
;
1488 else if ( strcmp(treatment
, "non-weak") == 0 )
1489 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchNonWeak
;
1491 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
1494 Options::CommonsMode
Options::parseCommonsTreatment(const char* mode
)
1497 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
1499 if ( strcmp(mode
, "ignore_dylibs") == 0 )
1500 return kCommonsIgnoreDylibs
;
1501 else if ( strcmp(mode
, "use_dylibs") == 0 )
1502 return kCommonsOverriddenByDylibs
;
1503 else if ( strcmp(mode
, "error") == 0 )
1504 return kCommonsConflictsDylibsError
;
1506 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
1509 void Options::addDylibOverride(const char* paths
)
1511 if ( paths
== NULL
)
1512 throw "-dylib_file must followed by two colon separated paths";
1513 const char* colon
= strchr(paths
, ':');
1514 if ( colon
== NULL
)
1515 throw "-dylib_file must followed by two colon separated paths";
1516 int len
= colon
-paths
;
1517 char* target
= new char[len
+2];
1518 strncpy(target
, paths
, len
);
1520 DylibOverride entry
;
1521 entry
.installName
= target
;
1522 entry
.useInstead
= &colon
[1];
1523 fDylibOverrides
.push_back(entry
);
1526 uint64_t Options::parseAddress(const char* addr
)
1529 uint64_t result
= strtoull(addr
, &endptr
, 16);
1533 uint32_t Options::parseProtection(const char* prot
)
1535 uint32_t result
= 0;
1536 for(const char* p
= prot
; *p
!= '\0'; ++p
) {
1537 switch(tolower(*p
)) {
1539 result
|= VM_PROT_READ
;
1542 result
|= VM_PROT_WRITE
;
1545 result
|= VM_PROT_EXECUTE
;
1550 throwf("unknown -segprot lettter in %s", prot
);
1558 // Parses number of form A[.B[.B[.D[.E]]]] into a uint64_t where the bits are a24.b10.c10.d10.e10
1560 uint64_t Options::parseVersionNumber64(const char* versionString
)
1568 a
= strtoul(versionString
, &end
, 10);
1569 if ( *end
== '.' ) {
1570 b
= strtoul(&end
[1], &end
, 10);
1571 if ( *end
== '.' ) {
1572 c
= strtoul(&end
[1], &end
, 10);
1573 if ( *end
== '.' ) {
1574 d
= strtoul(&end
[1], &end
, 10);
1575 if ( *end
== '.' ) {
1576 e
= strtoul(&end
[1], &end
, 10);
1581 if ( (*end
!= '\0') || (a
> 0xFFFFFF) || (b
> 0x3FF) || (c
> 0x3FF) || (d
> 0x3FF) || (e
> 0x3FF) )
1582 throwf("malformed 64-bit a.b.c.d.e version number: %s", versionString
);
1584 return (a
<< 40) | ( b
<< 30 ) | ( c
<< 20 ) | ( d
<< 10 ) | e
;
1588 uint32_t Options::currentVersion32() const
1590 // warn if it does not fit into 32 bit vers number
1591 uint32_t a
= (fDylibCurrentVersion
>> 40) & 0xFFFF;
1592 uint32_t b
= (fDylibCurrentVersion
>> 30) & 0xFF;
1593 uint32_t c
= (fDylibCurrentVersion
>> 20) & 0xFF;
1594 uint64_t rep32
= ((uint64_t)a
<< 40) | ((uint64_t)b
<< 30) | ((uint64_t)c
<< 20);
1595 if ( rep32
!= fDylibCurrentVersion
) {
1596 warning("truncating -current_version to fit in 32-bit space used by old mach-o format");
1597 a
= (fDylibCurrentVersion
>> 40) & 0xFFFFFF;
1600 b
= (fDylibCurrentVersion
>> 30) & 0x3FF;
1603 c
= (fDylibCurrentVersion
>> 20) & 0x3FF;
1607 return (a
<< 16) | ( b
<< 8 ) | c
;
1611 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
1613 uint32_t Options::parseVersionNumber32(const char* versionString
)
1619 x
= strtoul(versionString
, &end
, 10);
1620 if ( *end
== '.' ) {
1621 y
= strtoul(&end
[1], &end
, 10);
1622 if ( *end
== '.' ) {
1623 z
= strtoul(&end
[1], &end
, 10);
1626 if ( (*end
!= '\0') || (x
> 0xffff) || (y
> 0xff) || (z
> 0xff) )
1627 throwf("malformed 32-bit x.y.z version number: %s", versionString
);
1629 return (x
<< 16) | ( y
<< 8 ) | z
;
1632 static const char* cstringSymbolName(const char* orderFileString
)
1635 asprintf(&result
, "cstring=%s", orderFileString
);
1636 // convert escaped characters
1638 for(const char* s
=result
; *s
!= '\0'; ++s
, ++d
) {
1676 // hexadecimal value of char
1680 while ( isxdigit(*s
) ) {
1685 value
+= ((toupper(*s
)-'A') + 10);
1692 if ( isdigit(*s
) ) {
1693 // octal value of char
1695 while ( isdigit(*s
) ) {
1696 value
= (value
<< 3) + (*s
-'0');
1711 void Options::parseOrderFile(const char* path
, bool cstring
)
1713 // order files override auto-ordering
1714 fAutoOrderInitializers
= false;
1716 // read in whole file
1717 int fd
= ::open(path
, O_RDONLY
, 0);
1719 throwf("can't open order file: %s", path
);
1720 struct stat stat_buf
;
1721 ::fstat(fd
, &stat_buf
);
1722 char* p
= (char*)malloc(stat_buf
.st_size
+1);
1724 throwf("can't process order file: %s", path
);
1725 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1726 throwf("can't read order file: %s", path
);
1728 p
[stat_buf
.st_size
] = '\n';
1729 if ( this->dumpDependencyInfo() )
1730 this->dumpDependency(Options::depMisc
, path
);
1732 // parse into vector of pairs
1733 char * const end
= &p
[stat_buf
.st_size
+1];
1734 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
1735 char* symbolStart
= NULL
;
1736 for (char* s
= p
; s
< end
; ++s
) {
1742 else if ( !isspace(*s
) || cstring
) {
1748 if ( (*s
== '\n') || (!cstring
&& (*s
== '#')) ) {
1749 bool wasComment
= (*s
== '#');
1751 // removing any trailing spaces
1753 while ( isspace(*last
) ) {
1757 // if there is an architecture prefix, only use this symbol it if matches current arch
1758 if ( strncmp(symbolStart
, "ppc:", 4) == 0 ) {
1761 else if ( strncmp(symbolStart
, "ppc64:", 6) == 0 ) {
1764 else if ( strncmp(symbolStart
, "i386:", 5) == 0 ) {
1765 if ( fArchitecture
== CPU_TYPE_I386
)
1766 symbolStart
= &symbolStart
[5];
1770 else if ( strncmp(symbolStart
, "x86_64:", 7) == 0 ) {
1771 if ( fArchitecture
== CPU_TYPE_X86_64
)
1772 symbolStart
= &symbolStart
[7];
1776 else if ( strncmp(symbolStart
, "arm:", 4) == 0 ) {
1777 if ( fArchitecture
== CPU_TYPE_ARM
)
1778 symbolStart
= &symbolStart
[4];
1782 if ( symbolStart
!= NULL
) {
1783 char* objFileName
= NULL
;
1784 char* colon
= strstr(symbolStart
, ".o:");
1785 if ( colon
!= NULL
) {
1787 objFileName
= symbolStart
;
1788 symbolStart
= &colon
[3];
1791 colon
= strstr(symbolStart
, ".o):");
1792 if ( colon
!= NULL
) {
1794 objFileName
= symbolStart
;
1795 symbolStart
= &colon
[4];
1798 // trim leading spaces
1799 while ( isspace(*symbolStart
) )
1801 Options::OrderedSymbol pair
;
1803 pair
.symbolName
= cstringSymbolName(symbolStart
);
1805 pair
.symbolName
= symbolStart
;
1806 pair
.objectFileName
= objFileName
;
1807 fOrderedSymbols
.push_back(pair
);
1822 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1825 void Options::parseSectionOrderFile(const char* segment
, const char* section
, const char* path
)
1827 if ( (strcmp(section
, "__cstring") == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1828 parseOrderFile(path
, true);
1830 else if ( (strncmp(section
, "__literal",9) == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1831 warning("sorting of __literal[4,8,16] sections not supported");
1834 // ignore section information and append all symbol names to global order file
1835 parseOrderFile(path
, false);
1839 void Options::addSection(const char* segment
, const char* section
, const char* path
)
1841 if ( strlen(segment
) > 16 )
1842 throw "-seccreate segment name max 16 chars";
1843 if ( strlen(section
) > 16 ) {
1844 char* tmp
= strdup(section
);
1846 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section
, tmp
);
1850 // read in whole file
1851 int fd
= ::open(path
, O_RDONLY
, 0);
1853 throwf("can't open -sectcreate file: %s", path
);
1854 struct stat stat_buf
;
1855 ::fstat(fd
, &stat_buf
);
1856 char* p
= (char*)malloc(stat_buf
.st_size
);
1858 throwf("can't process -sectcreate file: %s", path
);
1859 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1860 throwf("can't read -sectcreate file: %s", path
);
1863 // record section to create
1864 ExtraSection info
= { segment
, section
, path
, (uint8_t*)p
, (uint64_t)stat_buf
.st_size
};
1865 fExtraSections
.push_back(info
);
1868 void Options::addSectionRename(const char* srcSegment
, const char* srcSection
, const char* dstSegment
, const char* dstSection
)
1870 if ( strlen(srcSegment
) > 16 )
1871 throw "-rename_section segment name max 16 chars";
1872 if ( strlen(srcSection
) > 16 )
1873 throw "-rename_section section name max 16 chars";
1874 if ( strlen(dstSegment
) > 16 )
1875 throw "-rename_section segment name max 16 chars";
1876 if ( strlen(dstSection
) > 16 )
1877 throw "-rename_section section name max 16 chars";
1880 info
.fromSegment
= srcSegment
;
1881 info
.fromSection
= srcSection
;
1882 info
.toSegment
= dstSegment
;
1883 info
.toSection
= dstSection
;
1885 fSectionRenames
.push_back(info
);
1889 void Options::addSegmentRename(const char* srcSegment
, const char* dstSegment
)
1891 if ( strlen(srcSegment
) > 16 )
1892 throw "-rename_segment segment name max 16 chars";
1893 if ( strlen(dstSegment
) > 16 )
1894 throw "-rename_segment segment name max 16 chars";
1897 info
.fromSegment
= srcSegment
;
1898 info
.toSegment
= dstSegment
;
1900 fSegmentRenames
.push_back(info
);
1905 void Options::addSymbolMove(const char* dstSegment
, const char* symbolList
,
1906 std::vector
<SymbolsMove
>& list
, const char* optionName
)
1908 if ( strlen(dstSegment
) > 16 )
1909 throwf("%s segment name max 16 chars", optionName
);
1912 list
.push_back(tmp
);
1913 SymbolsMove
& info
= list
.back();
1914 info
.toSegment
= dstSegment
;
1915 loadExportFile(symbolList
, optionName
, info
.symbols
);
1918 bool Options::moveRwSymbol(const char* symName
, const char* filePath
, const char*& seg
, bool& wildCardMatch
) const
1920 for (std::vector
<SymbolsMove
>::const_iterator it
=fSymbolsMovesData
.begin(); it
!= fSymbolsMovesData
.end(); ++it
) {
1921 const SymbolsMove
& info
= *it
;
1922 if ( info
.symbols
.containsWithPrefix(symName
, filePath
, wildCardMatch
)) {
1923 seg
= info
.toSegment
;
1930 bool Options::moveRoSymbol(const char* symName
, const char* filePath
, const char*& seg
, bool& wildCardMatch
) const
1932 for (std::vector
<SymbolsMove
>::const_iterator it
=fSymbolsMovesCode
.begin(); it
!= fSymbolsMovesCode
.end(); ++it
) {
1933 const SymbolsMove
& info
= *it
;
1934 if ( info
.symbols
.containsWithPrefix(symName
, filePath
, wildCardMatch
)) {
1935 seg
= info
.toSegment
;
1942 void Options::addSectionAlignment(const char* segment
, const char* section
, const char* alignmentStr
)
1944 if ( strlen(segment
) > 16 )
1945 throw "-sectalign segment name max 16 chars";
1946 if ( strlen(section
) > 16 )
1947 throw "-sectalign section name max 16 chars";
1949 // argument to -sectalign is a hexadecimal number
1951 unsigned long value
= strtoul(alignmentStr
, &endptr
, 16);
1952 if ( *endptr
!= '\0')
1953 throw "argument for -sectalign is not a hexadecimal number";
1954 if ( value
> 0x8000 )
1955 throw "argument for -sectalign must be less than or equal to 0x8000";
1957 warning("zero is not a valid -sectalign");
1961 // alignment is power of 2 (e.g. page alignment = 12)
1962 uint8_t alignment
= (uint8_t)__builtin_ctz(value
);
1963 if ( (unsigned long)(1 << alignment
) != value
) {
1964 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1965 segment
, section
, 1 << alignment
);
1968 SectionAlignment info
= { segment
, section
, alignment
};
1969 fSectionAlignments
.push_back(info
);
1972 void Options::addLibrary(const FileInfo
& info
)
1974 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1975 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1976 if ( strcmp(info
.path
, fit
->path
) == 0 ) {
1977 // if dylib is specified again but weak, record that it should be weak
1978 if ( info
.options
.fWeakImport
)
1979 fit
->options
.fWeakImport
= true;
1984 fInputFiles
.push_back(info
);
1987 void Options::warnObsolete(const char* arg
)
1989 warning("option %s is obsolete and being ignored", arg
);
1993 void Options::cannotBeUsedWithBitcode(const char* arg
)
1995 if ( fBundleBitcode
)
1996 throwf("%s and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together", arg
);
1999 std::string
Options::getVersionString32(uint32_t ver
) const
2001 if (ver
== 0 || ver
>= 0x10000000)
2004 unsigned microVersion
= ver
& 0xFF;
2005 unsigned minorVersion
= (ver
>> 8) & 0xFF;
2006 unsigned majorVersion
= (ver
>> 16) & 0xFF;
2007 std::stringstream versionString
;
2008 versionString
<< majorVersion
<< "." << minorVersion
<< "." << microVersion
;
2009 return versionString
.str();
2012 std::string
Options::getVersionString64(uint64_t ver
) const
2014 uint64_t a
= (ver
>> 40) & 0xFFFFFF;
2015 uint64_t b
= (ver
>> 30) & 0x3FF;
2016 uint64_t c
= (ver
>> 20) & 0x3FF;
2017 uint64_t d
= (ver
>> 10) & 0x3FF;
2018 uint64_t e
= ver
& 0x3FF;
2019 std::stringstream versionString
;
2020 versionString
<< a
<< "." << b
<< "." << c
<< "." << d
<< "." << e
;
2021 return versionString
.str();
2024 std::string
Options::getSDKVersionStr() const
2026 return getVersionString32(fSDKVersion
);
2029 std::string
Options::getPlatformStr() const
2031 switch (fPlatform
) {
2032 case Options::kPlatformOSX
:
2034 case Options::kPlatformiOS
:
2035 if (targetIOSSimulator())
2036 return "iPhoneSimulator";
2039 case Options::kPlatformWatchOS
:
2040 if (targetIOSSimulator())
2041 return "watchOS Simulator";
2044 #if SUPPORT_APPLE_TV
2045 case Options::kPlatform_tvOS
:
2046 if (targetIOSSimulator())
2047 return "AppleTVSimulator";
2052 case Options::kPlatformUnknown
:
2057 std::vector
<std::string
> Options::writeBitcodeLinkOptions() const
2059 std::vector
<std::string
> linkCommand
;
2060 switch ( fOutputKind
) {
2061 case Options::kDynamicLibrary
:
2062 linkCommand
.push_back("-dylib");
2063 linkCommand
.push_back("-compatibility_version");
2064 if ( fDylibCompatVersion
!= 0 ) {
2065 linkCommand
.push_back(getVersionString32(fDylibCompatVersion
));
2067 linkCommand
.push_back(getVersionString32(currentVersion32()));
2069 if ( fDylibCurrentVersion
!= 0 ) {
2070 linkCommand
.push_back("-current_version");
2071 linkCommand
.push_back(getVersionString64(fDylibCurrentVersion
));
2073 linkCommand
.push_back("-install_name");
2074 linkCommand
.push_back(installPath());
2076 case Options::kDynamicExecutable
:
2077 linkCommand
.push_back("-execute");
2079 case Options::kObjectFile
:
2080 linkCommand
.push_back("-r");
2083 throwf("could not write bitcode options file output kind\n");
2086 if (!fImplicitlyLinkPublicDylibs
)
2087 linkCommand
.push_back("-no_implicit_dylibs");
2089 // Add deployment target.
2090 // Platform is allowed to be unknown for "ld -r".
2091 switch (fPlatform
) {
2092 case Options::kPlatformOSX
:
2093 linkCommand
.push_back("-macosx_version_min");
2094 linkCommand
.push_back(getVersionString32((unsigned)fMacVersionMin
));
2096 case Options::kPlatformiOS
:
2097 if (targetIOSSimulator())
2098 linkCommand
.push_back("-ios_simulator_version_min");
2100 linkCommand
.push_back("-ios_version_min");
2101 linkCommand
.push_back(getVersionString32((unsigned)fIOSVersionMin
));
2103 case Options::kPlatformWatchOS
:
2104 if (targetIOSSimulator())
2105 linkCommand
.push_back("-watchos_simulator_version_min");
2107 linkCommand
.push_back("-watchos_version_min");
2108 linkCommand
.push_back(getVersionString32((unsigned)fIOSVersionMin
));
2110 #if SUPPORT_APPLE_TV
2111 case Options::kPlatform_tvOS
:
2112 if (targetIOSSimulator())
2113 linkCommand
.push_back("-tvos_simulator_version_min");
2115 linkCommand
.push_back("-tvos_version_min");
2116 linkCommand
.push_back(getVersionString32((unsigned)fIOSVersionMin
));
2119 case Options::kPlatformUnknown
:
2120 if ( fOutputKind
!= Options::kObjectFile
) {
2121 throwf("platform is unknown for final bitcode bundle,"
2122 "deployment target and min version is required for -bitcode_bundle");
2130 linkCommand
.push_back("-e");
2131 linkCommand
.push_back(fEntryName
);
2135 if (!fRPaths
.empty()) {
2136 for (std::vector
<const char*>::const_iterator it
=fRPaths
.begin(); it
!= fRPaths
.end(); ++it
) {
2137 linkCommand
.push_back("-rpath");
2138 linkCommand
.push_back(*it
);
2142 // Other bitcode compatiable options
2143 if ( fObjCABIVersion1Override
) {
2144 linkCommand
.push_back("-objc_abi_version");
2145 linkCommand
.push_back("1");
2146 } else if ( fObjCABIVersion2Override
) {
2147 linkCommand
.push_back("-objc_abi_version");
2148 linkCommand
.push_back("2");
2150 if ( fExecutablePath
) {
2151 linkCommand
.push_back("-executable_path");
2152 linkCommand
.push_back(fExecutablePath
);
2155 linkCommand
.push_back("-dead_strip");
2156 if ( fExportDynamic
)
2157 linkCommand
.push_back("-export_dynamic");
2158 if ( fMarkAppExtensionSafe
&& fCheckAppExtensionSafe
)
2159 linkCommand
.push_back("-application_extension");
2161 if ( fSourceVersionLoadCommandForceOn
)
2162 linkCommand
.push_back("-add_source_version");
2163 if ( fSourceVersion
!= 0 ) {
2164 linkCommand
.push_back("-source_version");
2165 linkCommand
.push_back(getVersionString64(fSourceVersion
));
2168 // linker flag added by swift driver
2169 // rdar://problem/20108072
2170 if ( !fObjcCategoryMerging
)
2171 linkCommand
.push_back("-no_objc_category_merging");
2177 // Process all command line arguments.
2179 // The only error checking done here is that each option is valid and if it has arguments
2180 // that they too are valid.
2182 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
2183 // whichever was last on the command line is used.
2185 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
2187 void Options::parse(int argc
, const char* argv
[])
2189 // Store the original args in the link snapshot.
2190 fLinkSnapshot
.recordRawArgs(argc
, argv
);
2192 // pass one builds search list from -L and -F options
2193 this->buildSearchPaths(argc
, argv
);
2195 // reduce re-allocations
2196 fInputFiles
.reserve(32);
2198 // pass two parse all other options
2199 for(int i
=1; i
< argc
; ++i
) {
2200 const char* arg
= argv
[i
];
2202 if ( arg
[0] == '-' ) {
2203 // by default, copy one arg to the snapshot link command, and do no file copying
2204 int snapshotArgIndex
= i
;
2205 int snapshotArgCount
= -1; // -1 means compute count based on change in index
2206 int snapshotFileArgIndex
= -1; // -1 means no data file parameter to arg
2208 // Since we don't care about the files passed, just the option names, we do this here.
2210 fprintf (stderr
, "[Logging ld64 options]\t%s\n", arg
);
2212 if ( (arg
[1] == 'L') || (arg
[1] == 'F') ) {
2213 snapshotArgCount
= 0; // stripped out of link snapshot
2216 // previously handled by buildSearchPaths()
2218 // The one gnu style option we have to keep compatibility
2219 // with gcc. Might as well have the single hyphen one as well.
2220 else if ( (strcmp(arg
, "--help") == 0)
2221 || (strcmp(arg
, "-help") == 0)) {
2222 fprintf (stdout
, "ld64: For information on command line options please use 'man ld'.\n");
2225 else if ( strcmp(arg
, "-arch") == 0 ) {
2226 parseArch(argv
[++i
]);
2228 else if ( strcmp(arg
, "-dynamic") == 0 ) {
2231 else if ( strcmp(arg
, "-static") == 0 ) {
2233 if ( (fOutputKind
!= kObjectFile
) && (fOutputKind
!= kKextBundle
) ) {
2234 fOutputKind
= kStaticExecutable
;
2236 cannotBeUsedWithBitcode(arg
);
2238 else if ( strcmp(arg
, "-dylib") == 0 ) {
2239 fOutputKind
= kDynamicLibrary
;
2241 else if ( strcmp(arg
, "-bundle") == 0 ) {
2242 fOutputKind
= kDynamicBundle
;
2243 cannotBeUsedWithBitcode(arg
);
2245 else if ( strcmp(arg
, "-dylinker") == 0 ) {
2246 fOutputKind
= kDyld
;
2247 cannotBeUsedWithBitcode(arg
);
2249 else if ( strcmp(arg
, "-execute") == 0 ) {
2250 if ( fOutputKind
!= kStaticExecutable
)
2251 fOutputKind
= kDynamicExecutable
;
2253 else if ( strcmp(arg
, "-preload") == 0 ) {
2254 fOutputKind
= kPreload
;
2255 cannotBeUsedWithBitcode(arg
);
2257 else if ( strcmp(arg
, "-r") == 0 ) {
2258 fOutputKind
= kObjectFile
;
2260 else if ( strcmp(arg
, "-kext") == 0 ) {
2261 fOutputKind
= kKextBundle
;
2262 cannotBeUsedWithBitcode(arg
);
2264 else if ( strcmp(arg
, "-o") == 0 ) {
2265 snapshotArgCount
= 0;
2266 fOutputFile
= argv
[++i
];
2267 fLinkSnapshot
.setSnapshotName(fOutputFile
);
2269 else if ( strncmp(arg
, "-lazy-l", 7) == 0 ) {
2270 snapshotArgCount
= 0;
2271 FileInfo info
= findLibrary(&arg
[7], true);
2272 info
.options
.fLazyLoad
= true;
2273 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2275 fUsingLazyDylibLinking
= true;
2276 cannotBeUsedWithBitcode(arg
);
2278 else if ( strcmp(arg
, "-lto_library") == 0 ) {
2279 snapshotFileArgIndex
= 1;
2280 fOverridePathlibLTO
= argv
[++i
];
2281 if ( fOverridePathlibLTO
== NULL
)
2282 throw "missing argument to -lto_library";
2284 else if ( (arg
[1] == 'l') && (strncmp(arg
,"-lazy_",6) !=0) ) {
2285 snapshotArgCount
= 0;
2286 FileInfo info
= findLibrary(&arg
[2]);
2287 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2290 // This causes a dylib to be weakly bound at
2291 // link time. This corresponds to weak_import.
2292 else if ( strncmp(arg
, "-weak-l", 7) == 0 ) {
2293 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2294 snapshotArgCount
= 0;
2295 FileInfo info
= findLibrary(&arg
[7]);
2296 info
.options
.fWeakImport
= true;
2297 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2300 // Avoid lazy binding.
2301 else if ( strcmp(arg
, "-bind_at_load") == 0 ) {
2303 cannotBeUsedWithBitcode(arg
);
2305 else if ( strcmp(arg
, "-twolevel_namespace") == 0 ) {
2306 fNameSpace
= kTwoLevelNameSpace
;
2308 else if ( strcmp(arg
, "-flat_namespace") == 0 ) {
2309 fNameSpace
= kFlatNameSpace
;
2310 cannotBeUsedWithBitcode(arg
);
2312 // Also sets a bit to ensure dyld causes everything
2313 // in the namespace to be flat.
2315 else if ( strcmp(arg
, "-force_flat_namespace") == 0 ) {
2316 fNameSpace
= kForceFlatNameSpace
;
2317 cannotBeUsedWithBitcode(arg
);
2319 // Similar to --whole-archive.
2320 else if ( strcmp(arg
, "-all_load") == 0 ) {
2321 fFullyLoadArchives
= true;
2323 else if ( strcmp(arg
, "-noall_load") == 0) {
2326 // Similar to -all_load
2327 else if ( strcmp(arg
, "-ObjC") == 0 ) {
2328 fLoadAllObjcObjectsFromArchives
= true;
2330 // Similar to -all_load, but for the following archive only.
2331 else if ( strcmp(arg
, "-force_load") == 0 ) {
2332 FileInfo info
= findFile(argv
[++i
]);
2333 info
.options
.fForceLoad
= true;
2334 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2337 // Library versioning.
2338 else if ( (strcmp(arg
, "-dylib_compatibility_version") == 0)
2339 || (strcmp(arg
, "-compatibility_version") == 0)) {
2340 const char* vers
= argv
[++i
];
2342 throw "-dylib_compatibility_version missing <version>";
2343 fDylibCompatVersion
= parseVersionNumber32(vers
);
2345 else if ( (strcmp(arg
, "-dylib_current_version") == 0)
2346 || (strcmp(arg
, "-current_version") == 0)) {
2347 const char* vers
= argv
[++i
];
2349 throw "-dylib_current_version missing <version>";
2350 fDylibCurrentVersion
= parseVersionNumber64(vers
);
2352 else if ( strcmp(arg
, "-sectorder") == 0 ) {
2353 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2354 throw "-sectorder missing <segment> <section> <file-path>";
2355 snapshotFileArgIndex
= 3;
2356 parseSectionOrderFile(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2358 cannotBeUsedWithBitcode(arg
);
2360 else if ( strcmp(arg
, "-order_file") == 0 ) {
2361 snapshotFileArgIndex
= 1;
2362 parseOrderFile(argv
[++i
], false);
2363 cannotBeUsedWithBitcode(arg
);
2365 else if ( strcmp(arg
, "-order_file_statistics") == 0 ) {
2366 fPrintOrderFileStatistics
= true;
2367 cannotBeUsedWithBitcode(arg
);
2369 // ??? Deprecate segcreate.
2370 // -sectcreate puts whole files into a section in the output.
2371 else if ( (strcmp(arg
, "-sectcreate") == 0) || (strcmp(arg
, "-segcreate") == 0) ) {
2372 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2373 throw "-sectcreate missing <segment> <section> <file-path>";
2374 snapshotFileArgIndex
= 3;
2375 addSection(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2378 // Since we have a full path in binary/library names we need to be able to override it.
2379 else if ( (strcmp(arg
, "-dylib_install_name") == 0)
2380 || (strcmp(arg
, "-dylinker_install_name") == 0)
2381 || (strcmp(arg
, "-install_name") == 0)) {
2382 fDylibInstallName
= argv
[++i
];
2383 if ( fDylibInstallName
== NULL
)
2384 throw "-install_name missing <path>";
2386 // Sets the base address of the output.
2387 else if ( (strcmp(arg
, "-seg1addr") == 0) || (strcmp(arg
, "-image_base") == 0) ) {
2388 const char* address
= argv
[++i
];
2389 if ( address
== NULL
)
2390 throwf("%s missing <address>", arg
);
2391 fBaseAddress
= parseAddress(address
);
2392 uint64_t temp
= ((fBaseAddress
+fSegmentAlignment
-1) & (-fSegmentAlignment
));
2393 if ( fBaseAddress
!= temp
) {
2394 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment
);
2395 fBaseAddress
= temp
;
2397 cannotBeUsedWithBitcode(arg
);
2399 else if ( strcmp(arg
, "-e") == 0 ) {
2400 fEntryName
= argv
[++i
];
2402 // Same as -@ from the FSF linker.
2403 else if ( strcmp(arg
, "-filelist") == 0 ) {
2404 snapshotArgCount
= 0;
2405 const char* path
= argv
[++i
];
2406 if ( (path
== NULL
) || (path
[0] == '-') )
2407 throw "-filelist missing <path>";
2408 ld::File::Ordinal baseOrdinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2409 loadFileList(path
, baseOrdinal
);
2411 else if ( strcmp(arg
, "-keep_private_externs") == 0 ) {
2412 cannotBeUsedWithBitcode(arg
);
2413 fKeepPrivateExterns
= true;
2415 else if ( strcmp(arg
, "-final_output") == 0 ) {
2416 fFinalName
= argv
[++i
];
2418 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
2419 // just ensures that this happens for cross object file boundaries.
2420 else if ( (strcmp(arg
, "-interposable") == 0) || (strcmp(arg
, "-multi_module") == 0)) {
2421 switch ( fInterposeMode
) {
2422 case kInterposeNone
:
2423 case kInterposeAllExternal
:
2424 fInterposeMode
= kInterposeAllExternal
;
2426 case kInterposeSome
:
2427 // do nothing, -interposable_list overrides -interposable"
2430 cannotBeUsedWithBitcode(arg
);
2432 else if ( strcmp(arg
, "-interposable_list") == 0 ) {
2433 snapshotFileArgIndex
= 1;
2434 fInterposeMode
= kInterposeSome
;
2435 loadExportFile(argv
[++i
], "-interposable_list", fInterposeList
);
2436 cannotBeUsedWithBitcode(arg
);
2438 // Default for -interposable/-multi_module/-single_module.
2439 else if ( strcmp(arg
, "-single_module") == 0 ) {
2440 fInterposeMode
= kInterposeNone
;
2442 else if ( strcmp(arg
, "-exported_symbols_list") == 0 ) {
2443 snapshotFileArgIndex
= 1;
2444 if ( fExportMode
== kDontExportSome
)
2445 throw "can't use -exported_symbols_list and -unexported_symbols_list";
2446 fExportMode
= kExportSome
;
2447 loadExportFile(argv
[++i
], "-exported_symbols_list", fExportSymbols
);
2449 else if ( strcmp(arg
, "-unexported_symbols_list") == 0 ) {
2450 snapshotFileArgIndex
= 1;
2451 if ( fExportMode
== kExportSome
)
2452 throw "can't use -unexported_symbols_list and -exported_symbols_list";
2453 fExportMode
= kDontExportSome
;
2454 loadExportFile(argv
[++i
], "-unexported_symbols_list", fDontExportSymbols
);
2455 cannotBeUsedWithBitcode(arg
);
2457 else if ( strcmp(arg
, "-exported_symbol") == 0 ) {
2458 if ( fExportMode
== kDontExportSome
)
2459 throw "can't use -exported_symbol and -unexported_symbols";
2460 fExportMode
= kExportSome
;
2461 fExportSymbols
.insert(argv
[++i
]);
2463 else if ( strcmp(arg
, "-unexported_symbol") == 0 ) {
2464 if ( fExportMode
== kExportSome
)
2465 throw "can't use -unexported_symbol and -exported_symbol";
2466 fExportMode
= kDontExportSome
;
2467 fDontExportSymbols
.insert(argv
[++i
]);
2468 cannotBeUsedWithBitcode(arg
);
2470 else if ( strcmp(arg
, "-non_global_symbols_no_strip_list") == 0 ) {
2471 snapshotFileArgIndex
= 1;
2472 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveExclude
)
2473 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2474 fLocalSymbolHandling
= kLocalSymbolsSelectiveInclude
;
2475 loadExportFile(argv
[++i
], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded
);
2476 cannotBeUsedWithBitcode(arg
);
2478 else if ( strcmp(arg
, "-non_global_symbols_strip_list") == 0 ) {
2479 snapshotFileArgIndex
= 1;
2480 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveInclude
)
2481 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2482 fLocalSymbolHandling
= kLocalSymbolsSelectiveExclude
;
2483 loadExportFile(argv
[++i
], "-non_global_symbols_strip_list", fLocalSymbolsExcluded
);
2484 cannotBeUsedWithBitcode(arg
);
2487 else if ( strcmp(arg
, "-no_arch_warnings") == 0 ) {
2488 fIgnoreOtherArchFiles
= true;
2490 else if ( strcmp(arg
, "-force_cpusubtype_ALL") == 0 ) {
2491 fForceSubtypeAll
= true;
2492 fAllowCpuSubtypeMismatches
= true;
2493 cannotBeUsedWithBitcode(arg
);
2495 // Similar to -weak-l but uses the absolute path name to the library.
2496 else if ( strcmp(arg
, "-weak_library") == 0 ) {
2497 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2498 snapshotArgCount
= 0;
2499 FileInfo info
= findFile(argv
[++i
]);
2500 info
.options
.fWeakImport
= true;
2501 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2503 cannotBeUsedWithBitcode(arg
);
2505 else if ( strcmp(arg
, "-lazy_library") == 0 ) {
2506 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2507 snapshotArgCount
= 0;
2508 FileInfo info
= findFile(argv
[++i
]);
2509 info
.options
.fLazyLoad
= true;
2510 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2512 fUsingLazyDylibLinking
= true;
2513 cannotBeUsedWithBitcode(arg
);
2515 else if ( strcmp(arg
, "-framework") == 0 ) {
2516 snapshotArgCount
= 0;
2517 FileInfo info
= findFramework(argv
[++i
]);
2518 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2521 else if ( strcmp(arg
, "-weak_framework") == 0 ) {
2522 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2523 snapshotArgCount
= 0;
2524 FileInfo info
= findFramework(argv
[++i
]);
2525 info
.options
.fWeakImport
= true;
2526 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2529 else if ( strcmp(arg
, "-lazy_framework") == 0 ) {
2530 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2531 snapshotArgCount
= 0;
2532 FileInfo info
= findFramework(argv
[++i
]);
2533 info
.options
.fLazyLoad
= true;
2534 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2536 fUsingLazyDylibLinking
= true;
2537 cannotBeUsedWithBitcode(arg
);
2539 else if ( strcmp(arg
, "-search_paths_first") == 0 ) {
2540 // previously handled by buildSearchPaths()
2542 else if ( strcmp(arg
, "-search_dylibs_first") == 0 ) {
2543 // previously handled by buildSearchPaths()
2545 else if ( strcmp(arg
, "-undefined") == 0 ) {
2546 setUndefinedTreatment(argv
[++i
]);
2547 cannotBeUsedWithBitcode(arg
);
2549 // Debugging output flag.
2550 else if ( strcmp(arg
, "-arch_multiple") == 0 ) {
2551 fMessagesPrefixedWithArchitecture
= true;
2553 // Specify what to do with relocations in read only
2554 // sections like .text. Could be errors, warnings,
2555 // or suppressed. Currently we do nothing with the
2557 else if ( strcmp(arg
, "-read_only_relocs") == 0 ) {
2558 switch ( parseTreatment(argv
[++i
]) ) {
2561 throw "-read_only_relocs missing [ warning | error | suppress ]";
2563 fWarnTextRelocs
= true;
2564 fAllowTextRelocs
= true;
2565 cannotBeUsedWithBitcode(arg
);
2568 fWarnTextRelocs
= false;
2569 fAllowTextRelocs
= true;
2570 cannotBeUsedWithBitcode(arg
);
2573 fWarnTextRelocs
= false;
2574 fAllowTextRelocs
= false;
2578 else if ( strcmp(arg
, "-sect_diff_relocs") == 0 ) {
2582 // Warn, error or make strong a mismatch between weak
2583 // and non-weak references.
2584 else if ( strcmp(arg
, "-weak_reference_mismatches") == 0 ) {
2585 setWeakReferenceMismatchTreatment(argv
[++i
]);
2587 // For a deployment target of 10.3 and earlier ld64 will
2588 // prebind an executable with 0s in all addresses that
2589 // are prebound. This can then be fixed up by update_prebinding
2590 // later. Prebinding is less useful on 10.4 and greater.
2591 else if ( strcmp(arg
, "-prebind") == 0 ) {
2593 cannotBeUsedWithBitcode(arg
);
2595 else if ( strcmp(arg
, "-noprebind") == 0 ) {
2599 else if ( strcmp(arg
, "-prebind_allow_overlap") == 0 ) {
2602 else if ( strcmp(arg
, "-prebind_all_twolevel_modules") == 0 ) {
2605 else if ( strcmp(arg
, "-noprebind_all_twolevel_modules") == 0 ) {
2608 else if ( strcmp(arg
, "-nofixprebinding") == 0 ) {
2611 // This should probably be deprecated when we respect -L and -F
2612 // when searching for libraries.
2613 else if ( strcmp(arg
, "-dylib_file") == 0 ) {
2614 // ignore for snapshot because a stub dylib will be created in the snapshot
2615 snapshotArgCount
= 0;
2616 addDylibOverride(argv
[++i
]);
2617 cannotBeUsedWithBitcode(arg
);
2619 // What to expand @executable_path to if found in dependent dylibs
2620 else if ( strcmp(arg
, "-executable_path") == 0 ) {
2621 fExecutablePath
= argv
[++i
];
2622 if ( (fExecutablePath
== NULL
) || (fExecutablePath
[0] == '-') )
2623 throw "-executable_path missing <path>";
2624 // if a directory was passed, add / to end
2625 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2626 struct stat statBuffer
;
2627 if ( stat(fExecutablePath
, &statBuffer
) == 0 ) {
2628 if ( (statBuffer
.st_mode
& S_IFMT
) == S_IFDIR
) {
2629 char* pathWithSlash
= new char[strlen(fExecutablePath
)+2];
2630 strcpy(pathWithSlash
, fExecutablePath
);
2631 strcat(pathWithSlash
, "/");
2632 fExecutablePath
= pathWithSlash
;
2636 // Aligns all segments to the power of 2 boundary specified.
2637 else if ( strcmp(arg
, "-segalign") == 0 ) {
2638 const char* size
= argv
[++i
];
2640 throw "-segalign missing <size>";
2641 fSegmentAlignment
= parseAddress(size
);
2642 uint8_t alignment
= (uint8_t)__builtin_ctz(fSegmentAlignment
);
2643 uint32_t p2aligned
= (1 << alignment
);
2644 if ( p2aligned
!= fSegmentAlignment
) {
2645 warning("alignment for -segalign %s is not a power of two, using 0x%X", size
, p2aligned
);
2646 fSegmentAlignment
= p2aligned
;
2648 cannotBeUsedWithBitcode(arg
);
2650 // Puts a specified segment at a particular address that must
2651 // be a multiple of the segment alignment.
2652 else if ( strcmp(arg
, "-segaddr") == 0 ) {
2654 seg
.name
= argv
[++i
];
2655 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
2656 throw "-segaddr missing segName Adddress";
2657 seg
.address
= parseAddress(argv
[++i
]);
2658 uint64_t temp
= ((seg
.address
+fSegmentAlignment
-1) & (-fSegmentAlignment
));
2659 if ( seg
.address
!= temp
)
2660 warning("-segaddr %s not %lld byte aligned", seg
.name
, fSegmentAlignment
);
2661 fCustomSegmentAddresses
.push_back(seg
);
2662 cannotBeUsedWithBitcode(arg
);
2664 // ??? Deprecate when we deprecate split-seg.
2665 else if ( strcmp(arg
, "-segs_read_only_addr") == 0 ) {
2666 fBaseAddress
= parseAddress(argv
[++i
]);
2667 cannotBeUsedWithBitcode(arg
);
2669 // ??? Deprecate when we deprecate split-seg.
2670 else if ( strcmp(arg
, "-segs_read_write_addr") == 0 ) {
2671 fBaseWritableAddress
= parseAddress(argv
[++i
]);
2673 cannotBeUsedWithBitcode(arg
);
2675 // ??? Deprecate when we get rid of basing at build time.
2676 else if ( strcmp(arg
, "-seg_addr_table") == 0 ) {
2677 snapshotFileArgIndex
= 1;
2678 const char* name
= argv
[++i
];
2680 throw "-seg_addr_table missing argument";
2681 fSegAddrTablePath
= name
;
2682 cannotBeUsedWithBitcode(arg
);
2684 else if ( strcmp(arg
, "-seg_addr_table_filename") == 0 ) {
2688 else if ( strcmp(arg
, "-segprot") == 0 ) {
2690 seg
.name
= argv
[++i
];
2691 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) || (argv
[i
+2] == NULL
) )
2692 throw "-segprot missing segName max-prot init-prot";
2693 seg
.max
= parseProtection(argv
[++i
]);
2694 seg
.init
= parseProtection(argv
[++i
]);
2695 fCustomSegmentProtections
.push_back(seg
);
2696 cannotBeUsedWithBitcode(arg
);
2698 else if ( strcmp(arg
, "-pagezero_size") == 0 ) {
2699 const char* size
= argv
[++i
];
2701 throw "-pagezero_size missing <size>";
2702 fZeroPageSize
= parseAddress(size
);
2703 uint64_t temp
= fZeroPageSize
& (-4096); // page align
2704 if ( (fZeroPageSize
!= temp
) )
2705 warning("-pagezero_size not page aligned, rounding down");
2706 fZeroPageSize
= temp
;
2707 cannotBeUsedWithBitcode(arg
);
2709 else if ( strcmp(arg
, "-stack_addr") == 0 ) {
2710 const char* address
= argv
[++i
];
2711 if ( address
== NULL
)
2712 throw "-stack_addr missing <address>";
2713 fStackAddr
= parseAddress(address
);
2714 cannotBeUsedWithBitcode(arg
);
2716 else if ( strcmp(arg
, "-stack_size") == 0 ) {
2717 const char* size
= argv
[++i
];
2719 throw "-stack_size missing <address>";
2720 fStackSize
= parseAddress(size
);
2721 uint64_t temp
= fStackSize
& (-4096); // page align
2722 if ( (fStackSize
!= temp
) )
2723 warning("-stack_size not page aligned, rounding down");
2725 else if ( strcmp(arg
, "-allow_stack_execute") == 0 ) {
2726 fExecutableStack
= true;
2727 cannotBeUsedWithBitcode(arg
);
2729 else if ( strcmp(arg
, "-allow_heap_execute") == 0 ) {
2730 fDisableNonExecutableHeap
= true;
2731 cannotBeUsedWithBitcode(arg
);
2733 else if ( strcmp(arg
, "-sectalign") == 0 ) {
2734 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2735 throw "-sectalign missing <segment> <section> <file-path>";
2736 addSectionAlignment(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2738 cannotBeUsedWithBitcode(arg
);
2740 else if ( strcmp(arg
, "-sectorder_detail") == 0 ) {
2743 else if ( strcmp(arg
, "-sectobjectsymbols") == 0 ) {
2747 else if ( strcmp(arg
, "-bundle_loader") == 0 ) {
2748 snapshotFileArgIndex
= 1;
2749 fBundleLoader
= argv
[++i
];
2750 if ( (fBundleLoader
== NULL
) || (fBundleLoader
[0] == '-') )
2751 throw "-bundle_loader missing <path>";
2752 FileInfo info
= findFile(fBundleLoader
);
2753 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2754 info
.options
.fBundleLoader
= true;
2755 fInputFiles
.push_back(info
);
2757 else if ( strcmp(arg
, "-private_bundle") == 0 ) {
2760 else if ( strcmp(arg
, "-twolevel_namespace_hints") == 0 ) {
2763 // Use this flag to set default behavior for deployement targets.
2764 else if ( strcmp(arg
, "-macosx_version_min") == 0 ) {
2765 const char* macVers
= argv
[++i
];
2766 const char* envMacVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
2767 const char* enviPhoneVers
= getenv("IPHONEOS_DEPLOYMENT_TARGET");
2768 if ( (envMacVers
!= NULL
) && (enviPhoneVers
!= NULL
) ) {
2769 // <rdar://problem/13774329> when conflicting deployments set, break tie by looking at syslibroot
2770 warning("both MACOSX_DEPLOYMENT_TARGET and IPHONEOS_DEPLOYMENT_TARGET are set");
2771 if ( !fSDKPaths
.empty() ) {
2772 const char* sysrootPath
= fSDKPaths
.back();
2773 const char* lastSlash
= strrchr(sysrootPath
, '/');
2774 if ( strstr(lastSlash
, "Simulator") != NULL
)
2775 setIOSVersionMin(enviPhoneVers
);
2777 setMacOSXVersionMin(macVers
);
2780 setMacOSXVersionMin(macVers
);
2784 setMacOSXVersionMin(macVers
);
2787 else if ( (strcmp(arg
, "-ios_version_min") == 0) || (strcmp(arg
, "-iphoneos_version_min") == 0) ) {
2788 setIOSVersionMin(argv
[++i
]);
2790 else if ( strcmp(arg
, "-ios_simulator_version_min") == 0 ) {
2791 setIOSVersionMin(argv
[++i
]);
2792 fTargetIOSSimulator
= true;
2794 else if ( strcmp(arg
, "-watchos_version_min") == 0 ) {
2795 setWatchOSVersionMin(argv
[++i
]);
2797 else if ( strcmp(arg
, "-watchos_simulator_version_min") == 0 ) {
2798 setWatchOSVersionMin(argv
[++i
]);
2799 fTargetIOSSimulator
= true;
2801 #if SUPPORT_APPLE_TV
2802 else if ( strcmp(arg
, "-tvos_version_min") == 0 ) {
2803 setIOSVersionMin(argv
[++i
]);
2804 fPlatform
= kPlatform_tvOS
;
2806 else if ( strcmp(arg
, "-tvos_simulator_version_min") == 0 ) {
2807 setIOSVersionMin(argv
[++i
]);
2808 fPlatform
= kPlatform_tvOS
;
2809 fTargetIOSSimulator
= true;
2812 else if ( strcmp(arg
, "-multiply_defined") == 0 ) {
2813 //warnObsolete(arg);
2816 else if ( strcmp(arg
, "-multiply_defined_unused") == 0 ) {
2820 else if ( strcmp(arg
, "-nomultidefs") == 0 ) {
2823 // Display each file in which the argument symbol appears and whether
2824 // the file defines or references it. This option takes an argument
2825 // as -y<symbol> note that there is no space.
2826 else if ( strncmp(arg
, "-y", 2) == 0 ) {
2829 // Same output as -y, but output <arg> number of undefined symbols only.
2830 else if ( strcmp(arg
, "-Y") == 0 ) {
2831 //warnObsolete(arg);
2834 // This option affects all objects linked into the final result.
2835 else if ( strcmp(arg
, "-m") == 0 ) {
2838 else if ( (strcmp(arg
, "-why_load") == 0) || (strcmp(arg
, "-whyload") == 0) ) {
2841 else if ( strcmp(arg
, "-why_live") == 0 ) {
2842 const char* name
= argv
[++i
];
2844 throw "-why_live missing symbol name argument";
2845 fWhyLive
.insert(name
);
2847 else if ( strcmp(arg
, "-u") == 0 ) {
2848 const char* name
= argv
[++i
];
2850 throw "-u missing argument";
2851 fInitialUndefines
.push_back(name
);
2852 cannotBeUsedWithBitcode(arg
);
2854 else if ( strcmp(arg
, "-U") == 0 ) {
2855 const char* name
= argv
[++i
];
2857 throw "-U missing argument";
2858 fAllowedUndefined
.insert(name
);
2859 cannotBeUsedWithBitcode(arg
);
2861 else if ( strcmp(arg
, "-s") == 0 ) {
2863 fLocalSymbolHandling
= kLocalSymbolsNone
;
2864 fDebugInfoStripping
= Options::kDebugInfoNone
;
2866 else if ( strcmp(arg
, "-x") == 0 ) {
2867 fLocalSymbolHandling
= kLocalSymbolsNone
;
2869 else if ( strcmp(arg
, "-S") == 0 ) {
2870 fDebugInfoStripping
= Options::kDebugInfoNone
;
2872 else if ( strcmp(arg
, "-X") == 0 ) {
2875 else if ( strcmp(arg
, "-Si") == 0 ) {
2877 fDebugInfoStripping
= Options::kDebugInfoFull
;
2879 else if ( strcmp(arg
, "-b") == 0 ) {
2882 else if ( strcmp(arg
, "-Sn") == 0 ) {
2884 fDebugInfoStripping
= Options::kDebugInfoFull
;
2886 else if ( strcmp(arg
, "-Sp") == 0 ) {
2889 else if ( strcmp(arg
, "-dead_strip") == 0 ) {
2892 else if ( strcmp(arg
, "-no_dead_strip_inits_and_terms") == 0 ) {
2895 else if ( strcmp(arg
, "-w") == 0 ) {
2896 // previously handled by buildSearchPaths()
2898 else if ( strcmp(arg
, "-fatal_warnings") == 0 ) {
2899 // previously handled by buildSearchPaths()
2901 else if ( strcmp(arg
, "-arch_errors_fatal") == 0 ) {
2902 fErrorOnOtherArchFiles
= true;
2904 else if ( strcmp(arg
, "-M") == 0 ) {
2907 else if ( strcmp(arg
, "-headerpad") == 0 ) {
2908 const char* size
= argv
[++i
];
2910 throw "-headerpad missing argument";
2911 fMinimumHeaderPad
= parseAddress(size
);
2912 cannotBeUsedWithBitcode(arg
);
2914 else if ( strcmp(arg
, "-headerpad_max_install_names") == 0 ) {
2915 // ignore -headerpad_max_install_names when compiling with bitcode
2916 // rdar://problem/20748962
2917 if ( fBundleBitcode
)
2918 warning("-headerpad_max_install_names is ignored when used with -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES)");
2920 fMaxMinimumHeaderPad
= true;
2922 else if ( strcmp(arg
, "-t") == 0 ) {
2923 fLogAllFiles
= true;
2925 else if ( strcmp(arg
, "-whatsloaded") == 0 ) {
2926 fLogObjectFiles
= true;
2928 else if ( strcmp(arg
, "-A") == 0 ) {
2932 else if ( strcmp(arg
, "-umbrella") == 0 ) {
2933 const char* name
= argv
[++i
];
2935 throw "-umbrella missing argument";
2936 fUmbrellaName
= name
;
2937 cannotBeUsedWithBitcode(arg
);
2939 else if ( strcmp(arg
, "-allowable_client") == 0 ) {
2940 const char* name
= argv
[++i
];
2943 throw "-allowable_client missing argument";
2945 fAllowableClients
.push_back(name
);
2946 cannotBeUsedWithBitcode(arg
);
2948 else if ( strcmp(arg
, "-client_name") == 0 ) {
2949 const char* name
= argv
[++i
];
2952 throw "-client_name missing argument";
2955 cannotBeUsedWithBitcode(arg
);
2957 else if ( strcmp(arg
, "-sub_umbrella") == 0 ) {
2958 const char* name
= argv
[++i
];
2960 throw "-sub_umbrella missing argument";
2961 fSubUmbellas
.push_back(name
);
2962 cannotBeUsedWithBitcode(arg
);
2964 else if ( strcmp(arg
, "-sub_library") == 0 ) {
2965 const char* name
= argv
[++i
];
2967 throw "-sub_library missing argument";
2968 fSubLibraries
.push_back(name
);
2969 cannotBeUsedWithBitcode(arg
);
2971 else if ( strcmp(arg
, "-init") == 0 ) {
2972 const char* name
= argv
[++i
];
2974 throw "-init missing argument";
2975 fInitFunctionName
= name
;
2976 cannotBeUsedWithBitcode(arg
);
2978 else if ( strcmp(arg
, "-dot") == 0 ) {
2979 const char* name
= argv
[++i
];
2981 throw "-dot missing argument";
2982 fDotOutputFile
= name
;
2983 cannotBeUsedWithBitcode(arg
);
2985 else if ( strcmp(arg
, "-warn_commons") == 0 ) {
2986 fWarnCommons
= true;
2988 else if ( strcmp(arg
, "-commons") == 0 ) {
2989 fCommonsMode
= parseCommonsTreatment(argv
[++i
]);
2991 else if ( strcmp(arg
, "-keep_relocs") == 0 ) {
2992 fKeepRelocations
= true;
2994 else if ( strcmp(arg
, "-warn_stabs") == 0 ) {
2997 else if ( strcmp(arg
, "-pause") == 0 ) {
3000 else if ( strcmp(arg
, "-print_statistics") == 0 ) {
3003 else if ( strcmp(arg
, "-d") == 0 ) {
3004 fMakeTentativeDefinitionsReal
= true;
3006 else if ( strcmp(arg
, "-v") == 0 ) {
3007 // previously handled by buildSearchPaths()
3009 else if ( strcmp(arg
, "-Z") == 0 ) {
3010 // previously handled by buildSearchPaths()
3012 else if ( strcmp(arg
, "-syslibroot") == 0 ) {
3013 snapshotArgCount
= 0;
3015 // previously handled by buildSearchPaths()
3017 else if ( strcmp(arg
, "-bitcode_bundle") == 0 ) {
3018 snapshotArgCount
= 0;
3019 // previously handled by buildSearchPaths()
3021 else if ( strcmp(arg
, "-no_uuid") == 0 ) {
3022 fUUIDMode
= kUUIDNone
;
3023 cannotBeUsedWithBitcode(arg
);
3025 else if ( strcmp(arg
, "-random_uuid") == 0 ) {
3026 fUUIDMode
= kUUIDRandom
;
3027 cannotBeUsedWithBitcode(arg
);
3029 else if ( strcmp(arg
, "-dtrace") == 0 ) {
3030 snapshotFileArgIndex
= 1;
3031 const char* name
= argv
[++i
];
3033 throw "-dtrace missing argument";
3034 fDtraceScriptName
= name
;
3035 cannotBeUsedWithBitcode(arg
);
3037 else if ( strcmp(arg
, "-root_safe") == 0 ) {
3040 else if ( strcmp(arg
, "-setuid_safe") == 0 ) {
3043 else if ( strcmp(arg
, "-alias") == 0 ) {
3044 Options::AliasPair pair
;
3045 pair
.realName
= argv
[++i
];
3046 if ( pair
.realName
== NULL
)
3047 throw "missing argument to -alias";
3048 pair
.alias
= argv
[++i
];
3049 if ( pair
.alias
== NULL
)
3050 throw "missing argument to -alias";
3051 fAliases
.push_back(pair
);
3052 cannotBeUsedWithBitcode(arg
);
3054 else if ( strcmp(arg
, "-alias_list") == 0 ) {
3055 snapshotFileArgIndex
= 1;
3056 parseAliasFile(argv
[++i
]);
3057 cannotBeUsedWithBitcode(arg
);
3059 else if ( strcmp(arg
, "-save-temps") == 0 ) {
3060 fSaveTempFiles
= true;
3062 else if ( strcmp(arg
, "-bitcode_hide_symbols") == 0 ) {
3063 fHideSymbols
= true;
3064 if ( !fBundleBitcode
)
3065 warning("-bitcode_hide_symbols is ignored without -bitcode_bundle");
3067 else if ( strcmp(arg
, "-bitcode_verify") == 0 ) {
3068 fVerifyBitcode
= true;
3069 if ( !fBundleBitcode
)
3070 warning("-bitcode_verify is ignored without -bitcode_bundle");
3072 else if ( strcmp(arg
, "-bitcode_symbol_map") == 0) {
3073 fReverseMapPath
= argv
[++i
];
3074 if ( fReverseMapPath
== NULL
)
3075 throw "missing argument to -bitcode_symbol_map";
3076 struct stat statbuf
;
3077 ::stat(fReverseMapPath
, &statbuf
);
3078 if (S_ISDIR(statbuf
.st_mode
)) {
3079 char tempPath
[PATH_MAX
];
3080 sprintf(tempPath
, "%s/XXXXXX", fReverseMapPath
);
3081 int tempFile
= ::mkstemp(tempPath
);
3083 throwf("could not write file to symbol map directory: %s", fReverseMapPath
);
3085 fReverseMapTempPath
= std::string(tempPath
);
3086 fReverseMapUUIDRename
= true;
3088 fReverseMapTempPath
= std::string(fReverseMapPath
);
3090 else if ( strcmp(argv
[i
], "-flto-codegen-only") == 0) {
3091 fLTOCodegenOnly
= true;
3093 else if ( strcmp(argv
[i
], "-ignore_auto_link") == 0) {
3094 fIgnoreAutoLink
= true;
3096 else if ( strcmp(argv
[i
], "-allow_dead_duplicates") == 0) {
3097 fAllowDeadDups
= true;
3099 else if ( strcmp(argv
[i
], "-bitcode_process_mode") == 0 ) {
3100 const char* bitcode_type
= argv
[++i
];
3101 if ( bitcode_type
== NULL
)
3102 throw "missing argument to -bitcode_process_mode";
3103 else if ( strcmp(bitcode_type
, "strip") == 0 )
3104 fBitcodeKind
= kBitcodeStrip
;
3105 else if ( strcmp(bitcode_type
, "marker") == 0 )
3106 fBitcodeKind
= kBitcodeMarker
;
3107 else if ( strcmp(bitcode_type
, "data") == 0 )
3108 fBitcodeKind
= kBitcodeAsData
;
3109 else if ( strcmp(bitcode_type
, "bitcode") == 0 )
3110 fBitcodeKind
= kBitcodeProcess
;
3112 throw "unknown argument to -bitcode_process_mode {strip,marker,data,bitcode}";
3114 else if ( strcmp(arg
, "-rpath") == 0 ) {
3115 const char* path
= argv
[++i
];
3117 throw "missing argument to -rpath";
3118 fRPaths
.push_back(path
);
3120 else if ( strcmp(arg
, "-read_only_stubs") == 0 ) {
3121 fReadOnlyx86Stubs
= true;
3123 else if ( strcmp(arg
, "-slow_stubs") == 0 ) {
3126 else if ( strcmp(arg
, "-map") == 0 ) {
3127 fMapPath
= argv
[++i
];
3128 if ( fMapPath
== NULL
)
3129 throw "missing argument to -map";
3131 else if ( strcmp(arg
, "-pie") == 0 ) {
3132 fPositionIndependentExecutable
= true;
3133 fPIEOnCommandLine
= true;
3135 else if ( strcmp(arg
, "-no_pie") == 0 ) {
3136 fDisablePositionIndependentExecutable
= true;
3137 cannotBeUsedWithBitcode(arg
);
3139 else if ( strncmp(arg
, "-reexport-l", 11) == 0 ) {
3140 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3141 snapshotArgCount
= 0;
3142 FileInfo info
= findLibrary(&arg
[11], true);
3143 info
.options
.fReExport
= true;
3144 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3146 cannotBeUsedWithBitcode(arg
);
3148 else if ( strcmp(arg
, "-reexport_library") == 0 ) {
3149 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3150 snapshotArgCount
= 0;
3151 FileInfo info
= findFile(argv
[++i
]);
3152 info
.options
.fReExport
= true;
3153 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3155 cannotBeUsedWithBitcode(arg
);
3157 else if ( strcmp(arg
, "-reexport_framework") == 0 ) {
3158 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3159 snapshotArgCount
= 0;
3160 FileInfo info
= findFramework(argv
[++i
]);
3161 info
.options
.fReExport
= true;
3162 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3164 cannotBeUsedWithBitcode(arg
);
3166 else if ( strncmp(arg
, "-upward-l", 9) == 0 ) {
3167 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3168 snapshotArgCount
= 0;
3169 FileInfo info
= findLibrary(&arg
[9], true);
3170 info
.options
.fUpward
= true;
3171 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3173 cannotBeUsedWithBitcode(arg
);
3175 else if ( strcmp(arg
, "-upward_library") == 0 ) {
3176 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3177 snapshotArgCount
= 0;
3178 FileInfo info
= findFile(argv
[++i
]);
3179 info
.options
.fUpward
= true;
3180 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3182 cannotBeUsedWithBitcode(arg
);
3184 else if ( strcmp(arg
, "-upward_framework") == 0 ) {
3185 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3186 snapshotArgCount
= 0;
3187 FileInfo info
= findFramework(argv
[++i
]);
3188 info
.options
.fUpward
= true;
3189 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3191 cannotBeUsedWithBitcode(arg
);
3193 else if ( strcmp(arg
, "-dead_strip_dylibs") == 0 ) {
3194 fDeadStripDylibs
= true;
3195 cannotBeUsedWithBitcode(arg
);
3197 else if ( strcmp(arg
, "-no_implicit_dylibs") == 0 ) {
3198 fImplicitlyLinkPublicDylibs
= false;
3200 else if ( strcmp(arg
, "-new_linker") == 0 ) {
3203 else if ( strcmp(arg
, "-no_encryption") == 0 ) {
3204 fEncryptableForceOff
= true;
3205 cannotBeUsedWithBitcode(arg
);
3207 else if ( strcmp(arg
, "-encryptable") == 0 ) {
3208 fEncryptableForceOn
= true;
3209 cannotBeUsedWithBitcode(arg
);
3211 else if ( strcmp(arg
, "-no_compact_unwind") == 0 ) {
3212 fAddCompactUnwindEncoding
= false;
3213 cannotBeUsedWithBitcode(arg
);
3215 else if ( strcmp(arg
, "-mllvm") == 0 ) {
3216 const char* opts
= argv
[++i
];
3218 throw "missing argument to -mllvm";
3219 fLLVMOptions
.push_back(opts
);
3220 cannotBeUsedWithBitcode(arg
);
3222 else if ( strcmp(arg
, "-mcpu") == 0 ) {
3223 const char* cpu
= argv
[++i
];
3225 throw "missing argument to -mcpu";
3227 cannotBeUsedWithBitcode(arg
);
3229 else if ( strcmp(arg
, "-no_order_inits") == 0 ) {
3230 fAutoOrderInitializers
= false;
3231 cannotBeUsedWithBitcode(arg
);
3233 else if ( strcmp(arg
, "-no_order_data") == 0 ) {
3235 cannotBeUsedWithBitcode(arg
);
3237 else if ( strcmp(arg
, "-seg_page_size") == 0 ) {
3239 seg
.name
= argv
[++i
];
3240 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
3241 throw "-seg_page_size missing segName Adddress";
3242 seg
.size
= parseAddress(argv
[++i
]);
3243 uint64_t temp
= seg
.size
& (-4096); // page align
3244 if ( (seg
.size
!= temp
) )
3245 warning("-seg_page_size %s not 4K aligned, rounding down", seg
.name
);
3246 fCustomSegmentSizes
.push_back(seg
);
3247 cannotBeUsedWithBitcode(arg
);
3249 else if ( strcmp(arg
, "-mark_dead_strippable_dylib") == 0 ) {
3250 fMarkDeadStrippableDylib
= true;
3251 cannotBeUsedWithBitcode(arg
);
3253 else if ( strcmp(arg
, "-exported_symbols_order") == 0 ) {
3254 snapshotFileArgIndex
= 1;
3255 loadSymbolOrderFile(argv
[++i
], fExportSymbolsOrder
);
3256 cannotBeUsedWithBitcode(arg
);
3258 else if ( strcmp(arg
, "-no_compact_linkedit") == 0 ) {
3259 warnObsolete("-no_compact_linkedit");
3261 else if ( strcmp(arg
, "-no_eh_labels") == 0 ) {
3263 cannotBeUsedWithBitcode(arg
);
3265 else if ( strcmp(arg
, "-warn_compact_unwind") == 0 ) {
3266 fWarnCompactUnwind
= true;
3268 else if ( strcmp(arg
, "-allow_sub_type_mismatches") == 0 ) {
3269 fAllowCpuSubtypeMismatches
= true;
3270 cannotBeUsedWithBitcode(arg
);
3272 else if ( strcmp(arg
, "-no_zero_fill_sections") == 0 ) {
3273 fOptimizeZeroFill
= false;
3274 cannotBeUsedWithBitcode(arg
);
3276 else if ( strcmp(arg
, "-merge_zero_fill_sections") == 0 ) {
3277 fMergeZeroFill
= true;
3278 cannotBeUsedWithBitcode(arg
);
3280 else if ( strcmp(arg
, "-objc_abi_version") == 0 ) {
3281 const char* version
= argv
[++i
];
3282 if ( version
== NULL
)
3283 throw "-objc_abi_version missing version number";
3284 if ( strcmp(version
, "2") == 0 ) {
3285 fObjCABIVersion1Override
= false;
3286 fObjCABIVersion2Override
= true;
3288 else if ( strcmp(version
, "1") == 0 ) {
3289 fObjCABIVersion1Override
= true;
3290 fObjCABIVersion2Override
= false;
3293 warning("ignoring unrecognized argument (%s) to -objc_abi_version", version
);
3295 else if ( strcmp(arg
, "-warn_weak_exports") == 0 ) {
3296 fWarnWeakExports
= true;
3298 else if ( strcmp(arg
, "-objc_gc_compaction") == 0 ) {
3299 fObjcGcCompaction
= true;
3300 cannotBeUsedWithBitcode(arg
);
3302 else if ( strcmp(arg
, "-objc_gc") == 0 ) {
3304 if ( fObjCGcOnly
) {
3305 warning("-objc_gc overriding -objc_gc_only");
3306 fObjCGcOnly
= false;
3308 cannotBeUsedWithBitcode(arg
);
3310 else if ( strcmp(arg
, "-objc_gc_only") == 0 ) {
3313 warning("-objc_gc_only overriding -objc_gc");
3316 cannotBeUsedWithBitcode(arg
);
3318 else if ( strcmp(arg
, "-demangle") == 0 ) {
3321 else if ( strcmp(arg
, "-version_load_command") == 0 ) {
3322 fVersionLoadCommandForcedOn
= true;
3323 fVersionLoadCommandForcedOff
= false;
3325 else if ( strcmp(arg
, "-no_version_load_command") == 0 ) {
3326 fVersionLoadCommandForcedOff
= true;
3327 fVersionLoadCommandForcedOn
= false;
3328 cannotBeUsedWithBitcode(arg
);
3330 else if ( strcmp(arg
, "-function_starts") == 0 ) {
3331 fFunctionStartsForcedOn
= true;
3332 fFunctionStartsForcedOff
= false;
3334 else if ( strcmp(arg
, "-no_function_starts") == 0 ) {
3335 fFunctionStartsForcedOff
= true;
3336 fFunctionStartsForcedOn
= false;
3337 cannotBeUsedWithBitcode(arg
);
3339 else if ( strcmp(arg
, "-no_data_in_code_info") == 0 ) {
3340 fDataInCodeInfoLoadCommandForcedOff
= true;
3341 fDataInCodeInfoLoadCommandForcedOn
= false;
3342 cannotBeUsedWithBitcode(arg
);
3344 else if ( strcmp(arg
, "-data_in_code_info") == 0 ) {
3345 fDataInCodeInfoLoadCommandForcedOn
= true;
3346 fDataInCodeInfoLoadCommandForcedOff
= false;
3348 else if ( strcmp(arg
, "-object_path_lto") == 0 ) {
3349 fTempLtoObjectPath
= argv
[++i
];
3350 if ( fTempLtoObjectPath
== NULL
)
3351 throw "missing argument to -object_path_lto";
3353 else if ( strcmp(arg
, "-no_objc_category_merging") == 0 ) {
3354 fObjcCategoryMerging
= false;
3356 else if ( strcmp(arg
, "-force_symbols_weak_list") == 0 ) {
3357 snapshotFileArgIndex
= 1;
3358 loadExportFile(argv
[++i
], "-force_symbols_weak_list", fForceWeakSymbols
);
3359 cannotBeUsedWithBitcode(arg
);
3361 else if ( strcmp(arg
, "-force_symbols_not_weak_list") == 0 ) {
3362 snapshotFileArgIndex
= 1;
3363 loadExportFile(argv
[++i
], "-force_symbols_not_weak_list", fForceNotWeakSymbols
);
3364 cannotBeUsedWithBitcode(arg
);
3366 else if ( strcmp(arg
, "-force_symbol_weak") == 0 ) {
3367 const char* symbol
= argv
[++i
];
3368 if ( symbol
== NULL
)
3369 throw "-force_symbol_weak missing <symbol>";
3370 fForceWeakSymbols
.insert(symbol
);
3371 cannotBeUsedWithBitcode(arg
);
3373 else if ( strcmp(arg
, "-force_symbol_not_weak") == 0 ) {
3374 const char* symbol
= argv
[++i
];
3375 if ( symbol
== NULL
)
3376 throw "-force_symbol_not_weak missing <symbol>";
3377 fForceNotWeakSymbols
.insert(symbol
);
3378 cannotBeUsedWithBitcode(arg
);
3380 else if ( strcmp(arg
, "-reexported_symbols_list") == 0 ) {
3381 snapshotFileArgIndex
= 1;
3382 if ( fExportMode
== kExportSome
)
3383 throw "can't use -exported_symbols_list and -reexported_symbols_list";
3384 loadExportFile(argv
[++i
], "-reexported_symbols_list", fReExportSymbols
);
3386 else if ( strcmp(arg
, "-dyld_env") == 0 ) {
3387 const char* envarg
= argv
[++i
];
3388 if ( envarg
== NULL
)
3389 throw "-dyld_env missing ENV=VALUE";
3390 if ( strchr(envarg
, '=') == NULL
)
3391 throw "-dyld_env missing ENV=VALUE";
3392 fDyldEnvironExtras
.push_back(envarg
);
3393 cannotBeUsedWithBitcode(arg
);
3395 else if ( strcmp(arg
, "-page_align_data_atoms") == 0 ) {
3396 fPageAlignDataAtoms
= true;
3397 cannotBeUsedWithBitcode(arg
);
3399 else if (strcmp(arg
, "-debug_snapshot") == 0) {
3400 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3401 fSnapshotRequested
= true;
3402 cannotBeUsedWithBitcode(arg
);
3404 else if (strcmp(arg
, "-snapshot_dir") == 0) {
3405 const char* path
= argv
[++i
];
3407 throw "-snapshot_dir missing path";
3408 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3409 fLinkSnapshot
.setSnapshotPath(path
);
3410 fSnapshotRequested
= true;
3411 cannotBeUsedWithBitcode(arg
);
3413 else if ( strcmp(arg
, "-new_main") == 0 ) {
3414 fEntryPointLoadCommandForceOn
= true;
3415 cannotBeUsedWithBitcode(arg
);
3417 else if ( strcmp(arg
, "-no_new_main") == 0 ) {
3418 fEntryPointLoadCommandForceOff
= true;
3419 cannotBeUsedWithBitcode(arg
);
3421 else if ( strcmp(arg
, "-source_version") == 0 ) {
3422 const char* vers
= argv
[++i
];
3424 throw "-source_version missing <version>";
3425 fSourceVersion
= parseVersionNumber64(vers
);
3427 else if ( strcmp(arg
, "-add_source_version") == 0 ) {
3428 fSourceVersionLoadCommandForceOn
= true;
3430 else if ( strcmp(arg
, "-no_source_version") == 0 ) {
3431 fSourceVersionLoadCommandForceOff
= true;
3432 cannotBeUsedWithBitcode(arg
);
3434 else if ( strcmp(arg
, "-sdk_version") == 0 ) {
3435 const char* vers
= argv
[++i
];
3437 throw "-sdk_version missing <version>";
3438 fSDKVersion
= parseVersionNumber32(vers
);
3440 else if ( strcmp(arg
, "-dependent_dr_info") == 0 ) {
3443 else if ( strcmp(arg
, "-no_dependent_dr_info") == 0 ) {
3446 else if ( strcmp(arg
, "-kexts_use_stubs") == 0 ) {
3447 fKextsUseStubs
= true;
3448 cannotBeUsedWithBitcode(arg
);
3450 else if ( strcmp(argv
[i
], "-dependency_info") == 0 ) {
3451 snapshotArgCount
= 0;
3453 // previously handled by buildSearchPaths()
3455 else if ( strcmp(arg
, "-export_dynamic") == 0 ) {
3456 fExportDynamic
= true;
3458 else if ( strcmp(arg
, "-force_symbols_coalesce_list") == 0 ) {
3459 snapshotFileArgIndex
= 1;
3460 loadExportFile(argv
[++i
], "-force_symbols_coalesce_list", fForceCoalesceSymbols
);
3462 else if ( strcmp(arg
, "-add_linker_option") == 0 ) {
3463 // ex: -add_linker_option '-framework Foundation'
3464 const char* optString
= argv
[++i
];
3465 if ( optString
== NULL
)
3466 throw "-add_linker_option missing <option>";
3467 // break up into list of tokens at whitespace
3468 std::vector
<const char*> opts
;
3469 char* buffer
= strdup(optString
);
3470 char* start
= buffer
;
3471 for (char* s
= buffer
; ; ++s
) {
3472 if ( isspace(*s
) ) {
3474 opts
.push_back(start
);
3477 else if ( *s
== '\0' ) {
3478 opts
.push_back(start
);
3482 fLinkerOptions
.push_back(opts
);
3483 cannotBeUsedWithBitcode(arg
);
3485 else if ( strcmp(arg
, "-allow_simulator_linking_to_macosx_dylibs") == 0 ) {
3486 fAllowSimulatorToLinkWithMacOSX
= true;
3487 cannotBeUsedWithBitcode(arg
);
3489 else if ( strcmp(arg
, "-keep_dwarf_unwind") == 0 ) {
3490 fKeepDwarfUnwindForcedOn
= true;
3491 fKeepDwarfUnwindForcedOff
= false;
3492 cannotBeUsedWithBitcode(arg
);
3494 else if ( strcmp(arg
, "-no_keep_dwarf_unwind") == 0 ) {
3495 fKeepDwarfUnwindForcedOn
= false;
3496 fKeepDwarfUnwindForcedOff
= true;
3497 cannotBeUsedWithBitcode(arg
);
3499 else if ( strcmp(arg
, "-verbose_optimization_hints") == 0 ) {
3500 fVerboseOptimizationHints
= true;
3502 else if ( strcmp(arg
, "-ignore_optimization_hints") == 0 ) {
3503 fIgnoreOptimizationHints
= true;
3504 cannotBeUsedWithBitcode(arg
);
3506 else if ( strcmp(arg
, "-no_dtrace_dof") == 0 ) {
3507 fGenerateDtraceDOF
= false;
3509 else if ( strcmp(arg
, "-rename_section") == 0 ) {
3510 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) || (argv
[i
+4]==NULL
) )
3511 throw "-rename_section missing <segment> <section> <segment> <section>";
3512 addSectionRename(argv
[i
+1], argv
[i
+2], argv
[i
+3], argv
[i
+4]);
3514 cannotBeUsedWithBitcode(arg
);
3516 else if ( strcmp(arg
, "-rename_segment") == 0 ) {
3517 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3518 throw "-rename_segment missing <existing-segment> <new-segment>";
3519 addSegmentRename(argv
[i
+1], argv
[i
+2]);
3521 cannotBeUsedWithBitcode(arg
);
3523 else if ( strcmp(arg
, "-move_to_ro_segment") == 0 ) {
3524 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3525 throw "-move_to_ro_segment missing <segment> <symbol-list-file>";
3526 addSymbolMove(argv
[i
+1], argv
[i
+2], fSymbolsMovesCode
, "-move_to_ro_segment");
3528 cannotBeUsedWithBitcode(arg
);
3530 else if ( strcmp(arg
, "-move_to_rw_segment") == 0 ) {
3531 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3532 throw "-move_to_rw_segment missing <segment> <symbol-list-file>";
3533 addSymbolMove(argv
[i
+1], argv
[i
+2], fSymbolsMovesData
, "-move_to_rw_segment");
3535 cannotBeUsedWithBitcode(arg
);
3537 else if ( strcmp(arg
, "-trace_symbol_layout") == 0 ) {
3538 fTraceSymbolLayout
= true;
3540 else if ( strcmp(arg
, "-no_branch_islands") == 0 ) {
3541 fAllowBranchIslands
= false;
3542 cannotBeUsedWithBitcode(arg
);
3544 else if ( strcmp(arg
, "-segment_order") == 0 ) {
3545 // ex: -segment_order __TEXT:__DATA:__JUNK
3546 const char* optString
= argv
[++i
];
3547 if ( optString
== NULL
)
3548 throw "-segment_order missing colon separated <segment-list>";
3549 if ( !fSegmentOrder
.empty() )
3550 throw "-segment_order used more than once";
3551 // break up into list of tokens at colon
3552 char* buffer
= strdup(optString
);
3553 char* start
= buffer
;
3554 for (char* s
= buffer
; ; ++s
) {
3557 fSegmentOrder
.push_back(start
);
3560 else if ( *s
== '\0' ) {
3561 fSegmentOrder
.push_back(start
);
3565 cannotBeUsedWithBitcode(arg
);
3567 else if ( strcmp(arg
, "-section_order") == 0 ) {
3568 // ex: -section_order __DATA __data:__const:__nl_pointers
3569 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3570 throw "-section_order missing <segment> <section-list>";
3571 const char* segName
= argv
[++i
];
3572 const char* optString
= argv
[++i
];
3573 if ( sectionOrder(segName
) != NULL
)
3574 throwf("-section_order %s ... used more than once", segName
);
3575 SectionOrderList dummy
;
3576 fSectionOrder
.push_back(dummy
);
3577 SectionOrderList
& entry
= fSectionOrder
.back();
3578 entry
.segmentName
= segName
;
3579 // break up into list of tokens at colon
3580 char* buffer
= strdup(optString
);
3581 char* start
= buffer
;
3582 for (char* s
= buffer
; ; ++s
) {
3585 entry
.sectionOrder
.push_back(start
);
3588 else if ( *s
== '\0' ) {
3589 entry
.sectionOrder
.push_back(start
);
3593 cannotBeUsedWithBitcode(arg
);
3595 else if ( strcmp(arg
, "-application_extension") == 0 ) {
3596 fMarkAppExtensionSafe
= true;
3597 fCheckAppExtensionSafe
= true;
3599 else if ( strcmp(arg
, "-no_application_extension") == 0 ) {
3600 fMarkAppExtensionSafe
= false;
3601 fCheckAppExtensionSafe
= false;
3603 else if ( strcmp(arg
, "-add_ast_path") == 0 ) {
3604 const char* path
= argv
[++i
];
3606 throw "-add_ast_path missing <option>";
3607 fASTFilePaths
.push_back(path
);
3609 else if ( strcmp(arg
, "-force_load_swift_libs") == 0 ) {
3610 fForceLoadSwiftLibs
= true;
3612 else if ( strcmp(arg
, "-not_for_dyld_shared_cache") == 0 ) {
3613 fSharedRegionEligibleForceOff
= true;
3614 cannotBeUsedWithBitcode(arg
);
3616 else if ( strcmp(arg
, "-dirty_data_list") == 0 ) {
3617 if ( argv
[i
+1] == NULL
)
3618 throw "-dirty_data_list missing <symbol-list-file>";
3619 addSymbolMove("__DATA_DIRTY", argv
[i
+1], fSymbolsMovesData
, "-dirty_data_list");
3621 cannotBeUsedWithBitcode(arg
);
3623 else if ( strcmp(arg
, "-data_const") == 0 ) {
3624 fUseDataConstSegmentForceOn
= true;
3625 cannotBeUsedWithBitcode(arg
);
3627 else if ( strcmp(arg
, "-no_data_const") == 0 ) {
3628 fUseDataConstSegmentForceOff
= true;
3629 cannotBeUsedWithBitcode(arg
);
3631 // put this last so that it does not interfer with other options starting with 'i'
3632 else if ( strncmp(arg
, "-i", 2) == 0 ) {
3633 const char* colon
= strchr(arg
, ':');
3634 if ( colon
== NULL
)
3635 throwf("unknown option: %s", arg
);
3636 Options::AliasPair pair
;
3637 char* temp
= new char[colon
-arg
];
3638 strlcpy(temp
, &arg
[2], colon
-arg
-1);
3639 pair
.realName
= &colon
[1];
3641 fAliases
.push_back(pair
);
3644 throwf("unknown option: %s", arg
);
3647 if (snapshotArgCount
== -1)
3648 snapshotArgCount
= i
-snapshotArgIndex
+1;
3649 if (snapshotArgCount
> 0)
3650 fLinkSnapshot
.addSnapshotLinkArg(snapshotArgIndex
, snapshotArgCount
, snapshotFileArgIndex
);
3653 FileInfo info
= findFile(arg
);
3654 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3655 if ( strcmp(&info
.path
[strlen(info
.path
)-2], ".a") == 0 )
3658 fInputFiles
.push_back(info
);
3662 // if a -lazy option was used, implicitly link in lazydylib1.o
3663 if ( fUsingLazyDylibLinking
) {
3664 FileInfo info
= findLibrary("lazydylib1.o");
3665 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)argc
);
3669 if (fSnapshotRequested
)
3670 fLinkSnapshot
.createSnapshot();
3676 // -syslibroot <path> is used for SDK support.
3677 // The rule is that all search paths (both explicit and default) are
3678 // checked to see if they exist in the SDK. If so, that path is
3679 // replaced with the sdk prefixed path. If not, that search path
3680 // is used as is. If multiple -syslibroot options are specified
3681 // their directory structures are logically overlayed and files
3682 // from sdks specified earlier on the command line used before later ones.
3684 void Options::buildSearchPaths(int argc
, const char* argv
[])
3686 bool addStandardLibraryDirectories
= true;
3687 std::vector
<const char*> libraryPaths
;
3688 std::vector
<const char*> frameworkPaths
;
3689 libraryPaths
.reserve(10);
3690 frameworkPaths
.reserve(10);
3691 // scan through argv looking for -L, -F, -Z, and -syslibroot options
3692 for(int i
=0; i
< argc
; ++i
) {
3693 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') ) {
3694 const char* libSearchDir
= &argv
[i
][2];
3695 // Allow either "-L{path}" or "-L {path}".
3696 if (argv
[i
][2] == '\0') {
3697 // -L {path}. Make sure there is an argument following this.
3698 const char* path
= argv
[++i
];
3700 throw "-L missing argument";
3701 libSearchDir
= path
;
3703 if ( libSearchDir
[0] == '\0' )
3704 throw "-L must be immediately followed by a directory path (no space)";
3705 struct stat statbuf
;
3706 if ( stat(libSearchDir
, &statbuf
) == 0 ) {
3707 if ( statbuf
.st_mode
& S_IFDIR
)
3708 libraryPaths
.push_back(libSearchDir
);
3710 warning("path '%s' following -L not a directory", libSearchDir
);
3713 warning("directory not found for option '-L%s'", libSearchDir
);
3716 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') ) {
3717 const char* frameworkSearchDir
= &argv
[i
][2];
3718 // Allow either "-F{path}" or "-F {path}".
3719 if (argv
[i
][2] == '\0') {
3720 // -F {path}. Make sure there is an argument following this.
3721 const char* path
= argv
[++i
];
3723 throw "-F missing argument";
3724 frameworkSearchDir
= path
;
3726 if ( frameworkSearchDir
[0] == '\0' )
3727 throw "-F must be immediately followed by a directory path (no space)";
3728 struct stat statbuf
;
3729 if ( stat(frameworkSearchDir
, &statbuf
) == 0 ) {
3730 if ( statbuf
.st_mode
& S_IFDIR
)
3731 frameworkPaths
.push_back(frameworkSearchDir
);
3733 warning("path '%s' following -F not a directory", frameworkSearchDir
);
3736 warning("directory not found for option '-F%s'", frameworkSearchDir
);
3739 else if ( strcmp(argv
[i
], "-Z") == 0 )
3740 addStandardLibraryDirectories
= false;
3741 else if ( strcmp(argv
[i
], "-v") == 0 ) {
3743 extern const char ldVersionString
[];
3744 fprintf(stderr
, "%s", ldVersionString
);
3745 fprintf(stderr
, "configured to support archs: %s\n", ALL_SUPPORTED_ARCHS
);
3746 // if only -v specified, exit cleanly
3748 const char* ltoVers
= lto::version();
3749 if ( ltoVers
!= NULL
)
3750 fprintf(stderr
, "LTO support using: %s\n", ltoVers
);
3754 else if ( strcmp(argv
[i
], "-syslibroot") == 0 ) {
3755 const char* path
= argv
[++i
];
3757 throw "-syslibroot missing argument";
3758 fSDKPaths
.push_back(path
);
3760 else if ( strcmp(argv
[i
], "-search_paths_first") == 0 ) {
3761 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
3763 else if ( strcmp(argv
[i
], "-search_dylibs_first") == 0 ) {
3764 fLibrarySearchMode
= kSearchAllDirsForDylibsThenAllDirsForArchives
;
3766 else if ( strcmp(argv
[i
], "-w") == 0 ) {
3767 sEmitWarnings
= false;
3769 else if ( strcmp(argv
[i
], "-fatal_warnings") == 0 ) {
3770 sFatalWarnings
= true;
3772 else if ( strcmp(argv
[i
], "-dependency_info") == 0 ) {
3773 const char* path
= argv
[++i
];
3775 throw "-dependency_info missing <path>";
3776 fDependencyInfoPath
= path
;
3778 else if ( strcmp(argv
[i
], "-bitcode_bundle") == 0 ) {
3779 fBundleBitcode
= true;
3782 int standardLibraryPathsStartIndex
= libraryPaths
.size();
3783 int standardFrameworkPathsStartIndex
= frameworkPaths
.size();
3784 if ( addStandardLibraryDirectories
) {
3785 libraryPaths
.push_back("/usr/lib");
3786 libraryPaths
.push_back("/usr/local/lib");
3788 frameworkPaths
.push_back("/Library/Frameworks/");
3789 frameworkPaths
.push_back("/System/Library/Frameworks/");
3790 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
3793 // <rdar://problem/5829579> Support for configure based hacks
3794 // if last -syslibroot is /, then ignore all syslibroots
3795 if ( fSDKPaths
.size() > 0 ) {
3796 if ( strcmp(fSDKPaths
.back(), "/") == 0 ) {
3801 // now merge sdk and library paths to make real search paths
3802 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
3804 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); ++it
, ++libIndex
) {
3805 const char* libDir
= *it
;
3806 bool sdkOverride
= false;
3807 if ( libDir
[0] == '/' ) {
3808 char betterLibDir
[PATH_MAX
];
3809 if ( strstr(libDir
, "/..") != NULL
) {
3810 if ( realpath(libDir
, betterLibDir
) != NULL
)
3811 libDir
= strdup(betterLibDir
);
3813 const int libDirLen
= strlen(libDir
);
3814 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
3815 const char* sdkDir
= *sdkit
;
3816 const int sdkDirLen
= strlen(sdkDir
);
3817 char newPath
[libDirLen
+ sdkDirLen
+4];
3818 strcpy(newPath
, sdkDir
);
3819 if ( newPath
[sdkDirLen
-1] == '/' )
3820 newPath
[sdkDirLen
-1] = '\0';
3821 strcat(newPath
, libDir
);
3822 struct stat statBuffer
;
3823 if ( stat(newPath
, &statBuffer
) == 0 ) {
3824 fLibrarySearchPaths
.push_back(strdup(newPath
));
3829 if ( !sdkOverride
) {
3830 if ( (libIndex
>= standardLibraryPathsStartIndex
) && (fSDKPaths
.size() == 1) ) {
3831 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3832 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3835 fLibrarySearchPaths
.push_back(libDir
);
3840 // now merge sdk and framework paths to make real search paths
3841 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
3843 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); ++it
, ++frameIndex
) {
3844 const char* frameworkDir
= *it
;
3845 bool sdkOverride
= false;
3846 if ( frameworkDir
[0] == '/' ) {
3847 char betterFrameworkDir
[PATH_MAX
];
3848 if ( strstr(frameworkDir
, "/..") != NULL
) {
3849 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
3850 frameworkDir
= strdup(betterFrameworkDir
);
3852 const int frameworkDirLen
= strlen(frameworkDir
);
3853 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
3854 const char* sdkDir
= *sdkit
;
3855 const int sdkDirLen
= strlen(sdkDir
);
3856 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
3857 strcpy(newPath
, sdkDir
);
3858 if ( newPath
[sdkDirLen
-1] == '/' )
3859 newPath
[sdkDirLen
-1] = '\0';
3860 strcat(newPath
, frameworkDir
);
3861 struct stat statBuffer
;
3862 if ( stat(newPath
, &statBuffer
) == 0 ) {
3863 fFrameworkSearchPaths
.push_back(strdup(newPath
));
3868 if ( !sdkOverride
) {
3869 if ( (frameIndex
>= standardFrameworkPathsStartIndex
) && (fSDKPaths
.size() == 1) ) {
3870 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3871 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3874 fFrameworkSearchPaths
.push_back(frameworkDir
);
3880 fprintf(stderr
,"Library search paths:\n");
3881 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
3882 it
!= fLibrarySearchPaths
.end();
3884 fprintf(stderr
,"\t%s\n", *it
);
3885 fprintf(stderr
,"Framework search paths:\n");
3886 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
3887 it
!= fFrameworkSearchPaths
.end();
3889 fprintf(stderr
,"\t%s\n", *it
);
3893 // this is run before the command line is parsed
3894 void Options::parsePreCommandLineEnvironmentSettings()
3896 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
3897 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
3898 fTraceArchives
= true;
3900 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
3901 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
3902 fTraceDylibs
= true;
3903 fTraceIndirectDylibs
= true;
3906 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
3907 fTraceDylibSearching
= true;
3910 if (getenv("LD_PRINT_OPTIONS") != NULL
)
3911 fPrintOptions
= true;
3913 if (fTraceDylibs
|| fTraceArchives
)
3914 fTraceOutputFile
= getenv("LD_TRACE_FILE");
3916 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL
)
3917 fPrintOrderFileStatistics
= true;
3919 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL
)
3922 if (getenv("LD_NO_ENCRYPT") != NULL
) {
3923 fEncryptable
= false;
3924 fMarkAppExtensionSafe
= true; // temporary
3925 fCheckAppExtensionSafe
= false;
3928 if (getenv("LD_APPLICATION_EXTENSION_SAFE") != NULL
) {
3929 fMarkAppExtensionSafe
= true;
3930 fCheckAppExtensionSafe
= false;
3933 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL
)
3934 fAllowCpuSubtypeMismatches
= true;
3936 sWarningsSideFilePath
= getenv("LD_WARN_FILE");
3938 const char* customDyldPath
= getenv("LD_DYLD_PATH");
3939 if ( customDyldPath
!= NULL
)
3940 fDyldInstallPath
= customDyldPath
;
3942 const char* debugArchivePath
= getenv("LD_DEBUG_SNAPSHOT");
3943 if (debugArchivePath
!= NULL
) {
3944 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3945 if (strlen(debugArchivePath
) > 0)
3946 fLinkSnapshot
.setSnapshotPath(debugArchivePath
);
3947 fSnapshotRequested
= true;
3950 const char* pipeFdString
= getenv("LD_PIPELINE_FIFO");
3951 if (pipeFdString
!= NULL
) {
3952 fPipelineFifo
= pipeFdString
;
3957 // this is run after the command line is parsed
3958 void Options::parsePostCommandLineEnvironmentSettings()
3960 // when building a dynamic main executable, default any use of @executable_path to output path
3961 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
3962 fExecutablePath
= fOutputFile
;
3965 // allow build system to set default seg_addr_table
3966 if ( fSegAddrTablePath
== NULL
)
3967 fSegAddrTablePath
= getenv("LD_SEG_ADDR_TABLE");
3969 // allow build system to turn on prebinding
3971 fPrebind
= ( getenv("LD_PREBIND") != NULL
);
3974 // allow build system to force on dead-code-stripping
3975 if ( !fDeadStrip
) {
3976 if ( getenv("LD_DEAD_STRIP") != NULL
) {
3977 switch (fOutputKind
) {
3978 case Options::kDynamicLibrary
:
3979 case Options::kDynamicExecutable
:
3980 case Options::kDynamicBundle
:
3983 case Options::kPreload
:
3984 case Options::kObjectFile
:
3985 case Options::kDyld
:
3986 case Options::kStaticExecutable
:
3987 case Options::kKextBundle
:
3993 // allow build system to force on -warn_commons
3994 if ( getenv("LD_WARN_COMMONS") != NULL
)
3995 fWarnCommons
= true;
3997 // allow B&I to set default -source_version
3998 if ( fSourceVersion
== 0 ) {
3999 const char* vers
= getenv("RC_ProjectSourceVersion");
4001 fSourceVersion
= parseVersionNumber64(vers
);
4006 void Options::reconfigureDefaults()
4008 // sync reader options
4009 switch ( fOutputKind
) {
4010 case Options::kObjectFile
:
4011 fForFinalLinkedImage
= false;
4013 case Options::kDyld
:
4015 fForFinalLinkedImage
= true;
4018 case Options::kDynamicLibrary
:
4019 case Options::kDynamicBundle
:
4020 case Options::kKextBundle
:
4021 fForFinalLinkedImage
= true;
4024 case Options::kDynamicExecutable
:
4025 case Options::kStaticExecutable
:
4026 case Options::kPreload
:
4027 fLinkingMainExecutable
= true;
4028 fForFinalLinkedImage
= true;
4033 // set default min OS version
4034 if ( (fMacVersionMin
== ld::macVersionUnset
) && (fIOSVersionMin
== ld::iOSVersionUnset
) && (fWatchOSVersionMin
== ld::wOSVersionUnset
) ) {
4035 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
4036 const char* macVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
4037 const char* iPhoneVers
= getenv("IPHONEOS_DEPLOYMENT_TARGET");
4038 const char* iOSVers
= getenv("IOS_DEPLOYMENT_TARGET");
4039 const char* wOSVers
= getenv("WATCHOS_DEPLOYMENT_TARGET");
4040 if ( macVers
!= NULL
)
4041 setMacOSXVersionMin(macVers
);
4042 else if ( iPhoneVers
!= NULL
)
4043 setIOSVersionMin(iPhoneVers
);
4044 else if ( iOSVers
!= NULL
)
4045 setIOSVersionMin(iOSVers
);
4046 else if ( wOSVers
!= NULL
)
4047 setWatchOSVersionMin(wOSVers
);
4049 // if still nothing, set default based on architecture
4050 switch ( fArchitecture
) {
4052 case CPU_TYPE_X86_64
:
4053 if ( (fOutputKind
!= Options::kObjectFile
) && (fOutputKind
!= Options::kPreload
) ) {
4054 #ifdef DEFAULT_MACOSX_MIN_VERSION
4055 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
4056 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
4058 warning("-macosx_version_min not specified, assuming 10.6");
4059 setMacOSXVersionMin("10.6");
4064 if ( (fOutputKind
!= Options::kObjectFile
) && (fOutputKind
!= Options::kPreload
) ) {
4065 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
4066 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION
);
4067 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION
);
4069 if ( fSubArchitecture
== CPU_SUBTYPE_ARM_V7K
) {
4070 warning("-watchos_version_min not specified, assuming 2.0");
4071 setWatchOSVersionMin("2.0");
4074 warning("-ios_version_min not specified, assuming 6.0");
4075 setIOSVersionMin("6.0");
4081 // architecture will be infered later by examining .o files
4088 // adjust min based on architecture
4089 switch ( fArchitecture
) {
4091 if ( (fPlatform
== kPlatformOSX
) && (fMacVersionMin
< ld::mac10_4
) ) {
4092 //warning("-macosx_version_min should be 10.4 or later for i386");
4093 fMacVersionMin
= ld::mac10_4
;
4096 case CPU_TYPE_X86_64
:
4097 if ( (fPlatform
== kPlatformOSX
) && (fMacVersionMin
< ld::mac10_4
) ) {
4098 //warning("-macosx_version_min should be 10.4 or later for x86_64");
4099 fMacVersionMin
= ld::mac10_4
;
4102 case CPU_TYPE_ARM64
:
4103 if ( (fPlatform
== kPlatformiOS
) && (fIOSVersionMin
< ld::iOS_7_0
) ) {
4104 //warning("-mios_version_min should be 7.0 or later for arm64");
4105 fIOSVersionMin
= ld::iOS_7_0
;
4110 // default to adding functions start for dynamic code, static code must opt-in
4111 switch ( fOutputKind
) {
4112 case Options::kPreload
:
4113 case Options::kStaticExecutable
:
4114 case Options::kKextBundle
:
4115 if ( fDataInCodeInfoLoadCommandForcedOn
)
4116 fDataInCodeInfoLoadCommand
= true;
4117 if ( fFunctionStartsForcedOn
)
4118 fFunctionStartsLoadCommand
= true;
4120 case Options::kObjectFile
:
4121 if ( !fDataInCodeInfoLoadCommandForcedOff
)
4122 fDataInCodeInfoLoadCommand
= true;
4123 if ( fFunctionStartsForcedOn
)
4124 fFunctionStartsLoadCommand
= true;
4126 case Options::kDynamicExecutable
:
4127 case Options::kDyld
:
4128 case Options::kDynamicLibrary
:
4129 case Options::kDynamicBundle
:
4130 if ( !fDataInCodeInfoLoadCommandForcedOff
)
4131 fDataInCodeInfoLoadCommand
= true;
4132 if ( !fFunctionStartsForcedOff
)
4133 fFunctionStartsLoadCommand
= true;
4137 // adjust kext type based on architecture
4138 if ( fOutputKind
== kKextBundle
) {
4139 switch ( fArchitecture
) {
4140 case CPU_TYPE_X86_64
:
4141 // x86_64 uses new MH_KEXT_BUNDLE type
4142 fMakeCompressedDyldInfo
= false;
4143 fMakeCompressedDyldInfoForceOff
= true;
4144 fAllowTextRelocs
= true;
4145 fUndefinedTreatment
= kUndefinedDynamicLookup
;
4147 case CPU_TYPE_ARM64
:
4148 // arm64 uses new MH_KEXT_BUNDLE type
4149 fMakeCompressedDyldInfo
= false;
4150 fMakeCompressedDyldInfoForceOff
= true;
4151 fAllowTextRelocs
= false;
4152 fKextsUseStubs
= true;
4153 fUndefinedTreatment
= kUndefinedDynamicLookup
;
4156 if ( min_iOS(ld::iOS_5_0
) ) {
4157 // iOS 5.0 and later use new MH_KEXT_BUNDLE type
4158 fMakeCompressedDyldInfo
= false;
4159 fMakeCompressedDyldInfoForceOff
= true;
4160 // kexts are PIC in iOS 6.0 and later
4161 fAllowTextRelocs
= !min_iOS(ld::iOS_6_0
);
4162 fKextsUseStubs
= !fAllowTextRelocs
;
4163 fUndefinedTreatment
= kUndefinedDynamicLookup
;
4166 // else use object file
4169 fOutputKind
= kObjectFile
;
4174 // disable implicit dylibs when targeting 10.3
4175 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
4176 if ( !minOS(ld::mac10_4
, ld::iOS_2_0
) )
4177 fImplicitlyLinkPublicDylibs
= false;
4180 // allow build system to force linker to ignore -prebind
4181 if ( getenv("LD_FORCE_NO_PREBIND") != NULL
)
4184 // allow build system to force linker to ignore -seg_addr_table
4185 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL
)
4186 fSegAddrTablePath
= NULL
;
4188 // check for base address specified externally
4189 if ( (fSegAddrTablePath
!= NULL
) && (fOutputKind
== Options::kDynamicLibrary
) ) {
4190 parseSegAddrTable(fSegAddrTablePath
, this->installPath());
4191 // HACK to support seg_addr_table entries that are physical paths instead of install paths
4192 if ( fBaseAddress
== 0 ) {
4193 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
4194 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.4.dylib");
4195 if ( fBaseAddress
== 0 )
4196 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.9.dylib");
4199 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
4200 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libz.1.2.3.dylib");
4202 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
4203 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libutil1.0.dylib");
4207 // split segs only allowed for dylibs
4209 // split seg only supported for i386, and arm.
4210 switch ( fArchitecture
) {
4212 if ( fOutputKind
!= Options::kDynamicLibrary
)
4214 // make sure read and write segments are proper distance apart
4215 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x10000000) )
4216 fBaseWritableAddress
= fBaseAddress
+ 0x10000000;
4219 if ( fOutputKind
!= Options::kDynamicLibrary
) {
4223 // make sure read and write segments are proper distance apart
4224 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x08000000) )
4225 fBaseWritableAddress
= fBaseAddress
+ 0x08000000;
4231 fBaseWritableAddress
= 0;
4235 // set too-large size
4236 switch ( fArchitecture
) {
4238 fMaxAddress
= 0xFFFFFFFF;
4240 case CPU_TYPE_X86_64
:
4243 switch ( fOutputKind
) {
4244 case Options::kDynamicExecutable
:
4245 case Options::kDynamicLibrary
:
4246 case Options::kDynamicBundle
:
4247 // user land code is limited to low 1GB
4248 fMaxAddress
= 0x2FFFFFFF;
4250 case Options::kStaticExecutable
:
4251 case Options::kObjectFile
:
4252 case Options::kDyld
:
4253 case Options::kPreload
:
4254 case Options::kKextBundle
:
4255 fMaxAddress
= 0xFFFFFFFF;
4258 // range check -seg1addr for ARM
4259 if ( fBaseAddress
> fMaxAddress
) {
4260 warning("ignoring -seg1addr 0x%08llX. Address out of range.", fBaseAddress
);
4266 // <rdar://problem/6138961> -r implies no prebinding for all architectures
4267 if ( fOutputKind
== Options::kObjectFile
)
4270 // disable prebinding depending on arch and min OS version
4272 switch ( fArchitecture
) {
4274 if ( fMacVersionMin
== ld::mac10_4
) {
4275 // in 10.4 only split seg dylibs are prebound
4276 if ( (fOutputKind
!= Options::kDynamicLibrary
) || ! fSplitSegs
)
4279 else if ( fMacVersionMin
>= ld::mac10_5
) {
4280 // in 10.5 nothing is prebound
4283 else if ( fIOSVersionMin
!= ld::iOSVersionUnset
) {
4284 // nothing in simulator is prebound
4288 // in 10.3 and earlier only dylibs and main executables could be prebound
4289 switch ( fOutputKind
) {
4290 case Options::kDynamicExecutable
:
4291 case Options::kDynamicLibrary
:
4292 // only main executables and dylibs can be prebound
4294 case Options::kStaticExecutable
:
4295 case Options::kDynamicBundle
:
4296 case Options::kObjectFile
:
4297 case Options::kDyld
:
4298 case Options::kPreload
:
4299 case Options::kKextBundle
:
4300 // disable prebinding for everything else
4306 case CPU_TYPE_X86_64
:
4310 switch ( fOutputKind
) {
4311 case Options::kDynamicExecutable
:
4312 case Options::kDynamicLibrary
:
4313 // only main executables and dylibs can be prebound
4315 case Options::kStaticExecutable
:
4316 case Options::kDynamicBundle
:
4317 case Options::kObjectFile
:
4318 case Options::kDyld
:
4319 case Options::kPreload
:
4320 case Options::kKextBundle
:
4321 // disable prebinding for everything else
4329 // only prebound images can be split-seg
4330 if ( fSplitSegs
&& !fPrebind
)
4333 // determine if info for shared region should be added
4334 if ( fOutputKind
== Options::kDynamicLibrary
) {
4335 if ( minOS(ld::mac10_5
, ld::iOS_3_1
) )
4336 if ( !fPrebind
&& !fSharedRegionEligibleForceOff
)
4337 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
4338 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
4339 fSharedRegionEligible
= true;
4341 else if ( fOutputKind
== Options::kDyld
) {
4342 // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
4343 fSharedRegionEligible
= true;
4346 // <rdar://problem/18719327> warn if -rpath is used with OS dylibs
4347 if ( fSharedRegionEligible
&& !fRPaths
.empty() )
4348 warning("-rpath cannot be used with dylibs that will be in the dyld shared cache");
4350 // automatically use __DATA_CONST in iOS dylibs
4351 if ( fSharedRegionEligible
&& minOS(ld::mac10_Future
, ld::iOS_9_0
) && !fUseDataConstSegmentForceOff
) {
4352 fUseDataConstSegment
= true;
4354 if ( fUseDataConstSegmentForceOn
) {
4355 fUseDataConstSegment
= true;
4357 if ( fUseDataConstSegment
) {
4358 addSectionRename("__DATA", "__got", "__DATA_CONST", "__got");
4359 addSectionRename("__DATA", "__la_symbol_ptr", "__DATA_CONST", "__la_symbol_ptr");
4360 addSectionRename("__DATA", "__nl_symbol_ptr", "__DATA_CONST", "__nl_symbol_ptr");
4361 addSectionRename("__DATA", "__const", "__DATA_CONST", "__const");
4362 addSectionRename("__DATA", "__cfstring", "__DATA_CONST", "__cfstring");
4363 addSectionRename("__DATA", "__mod_init_func", "__DATA_CONST", "__mod_init_func");
4364 addSectionRename("__DATA", "__mod_term_func", "__DATA_CONST", "__mod_term_func");
4365 addSectionRename("__DATA", "__objc_classlist", "__DATA_CONST", "__objc_classlist");
4366 addSectionRename("__DATA", "__objc_nlclslist", "__DATA_CONST", "__objc_nlclslist");
4367 addSectionRename("__DATA", "__objc_catlist", "__DATA_CONST", "__objc_catlist");
4368 addSectionRename("__DATA", "__objc_nlcatlist", "__DATA_CONST", "__objc_nlcatlist");
4369 addSectionRename("__DATA", "__objc_protolist", "__DATA_CONST", "__objc_protolist");
4370 addSectionRename("__DATA", "__objc_imageinfo", "__DATA_CONST", "__objc_imageinfo");
4371 addSectionRename("__DATA", "__objc_const", "__DATA_CONST", "__objc_const");
4374 // Use V2 shared cache info when targetting newer OSs
4375 if ( fSharedRegionEligible
&& minOS(ld::mac10_Future
, ld::iOS_9_0
)) {
4376 fSharedRegionEncodingV2
= true;
4377 fIgnoreOptimizationHints
= true;
4380 // figure out if module table is needed for compatibility with old ld/dyld
4381 if ( fOutputKind
== Options::kDynamicLibrary
) {
4382 switch ( fArchitecture
) {
4384 if ( fIOSVersionMin
!= ld::iOSVersionUnset
) // simulator never needs modules
4388 fNeedsModuleTable
= true; // redo_prebinding requires a module table
4393 // <rdar://problem/5366363> -r -x implies -S
4394 if ( (fOutputKind
== Options::kObjectFile
) && (fLocalSymbolHandling
== kLocalSymbolsNone
) )
4395 fDebugInfoStripping
= Options::kDebugInfoNone
;
4397 // <rdar://problem/15252891> -r implies -no_uuid
4398 if ( fOutputKind
== Options::kObjectFile
)
4399 fUUIDMode
= kUUIDNone
;
4401 // choose how to process unwind info
4402 switch ( fArchitecture
) {
4404 case CPU_TYPE_X86_64
:
4405 case CPU_TYPE_ARM64
:
4406 switch ( fOutputKind
) {
4407 case Options::kObjectFile
:
4408 case Options::kStaticExecutable
:
4409 case Options::kPreload
:
4410 case Options::kKextBundle
:
4411 fAddCompactUnwindEncoding
= false;
4413 case Options::kDyld
:
4414 case Options::kDynamicLibrary
:
4415 case Options::kDynamicBundle
:
4416 case Options::kDynamicExecutable
:
4417 //if ( fAddCompactUnwindEncoding && (fVersionMin >= ld::mac10_6) )
4418 // fRemoveDwarfUnwindIfCompactExists = true;
4423 if ( armUsesZeroCostExceptions() ) {
4424 switch ( fOutputKind
) {
4425 case Options::kObjectFile
:
4426 case Options::kStaticExecutable
:
4427 case Options::kPreload
:
4428 case Options::kKextBundle
:
4429 fAddCompactUnwindEncoding
= false;
4431 case Options::kDyld
:
4432 case Options::kDynamicLibrary
:
4433 case Options::kDynamicBundle
:
4434 case Options::kDynamicExecutable
:
4435 fAddCompactUnwindEncoding
= true;
4440 fAddCompactUnwindEncoding
= false;
4441 fRemoveDwarfUnwindIfCompactExists
= false;
4445 // if -arch is missing, assume we don't want compact unwind info
4446 fAddCompactUnwindEncoding
= false;
4450 // only iOS executables should be encryptable
4451 switch ( fOutputKind
) {
4452 case Options::kObjectFile
:
4453 case Options::kDyld
:
4454 case Options::kStaticExecutable
:
4455 case Options::kPreload
:
4456 case Options::kKextBundle
:
4457 fEncryptable
= false;
4459 case Options::kDynamicExecutable
:
4461 case Options::kDynamicLibrary
:
4462 case Options::kDynamicBundle
:
4463 // <rdar://problem/16293398> Add LC_ENCRYPTION_INFO load command to bundled frameworks
4464 if ( !min_iOS(ld::iOS_7_0
) )
4465 fEncryptable
= false;
4468 if ( (fArchitecture
!= CPU_TYPE_ARM
) && (fArchitecture
!= CPU_TYPE_ARM64
) )
4469 fEncryptable
= false;
4470 if ( fEncryptableForceOn
)
4471 fEncryptable
= true;
4472 else if ( fEncryptableForceOff
)
4473 fEncryptable
= false;
4475 // don't move inits in dyld because dyld wants certain
4476 // entries point at stable locations at the start of __text
4477 if ( fOutputKind
== Options::kDyld
)
4478 fAutoOrderInitializers
= false;
4481 // disable __data ordering for some output kinds
4482 switch ( fOutputKind
) {
4483 case Options::kObjectFile
:
4484 case Options::kDyld
:
4485 case Options::kStaticExecutable
:
4486 case Options::kPreload
:
4487 case Options::kKextBundle
:
4490 case Options::kDynamicExecutable
:
4491 case Options::kDynamicLibrary
:
4492 case Options::kDynamicBundle
:
4496 // only use compressed LINKEDIT for final linked images
4497 switch ( fOutputKind
) {
4498 case Options::kDynamicExecutable
:
4499 case Options::kDynamicLibrary
:
4500 case Options::kDynamicBundle
:
4502 case Options::kPreload
:
4503 case Options::kStaticExecutable
:
4504 case Options::kObjectFile
:
4505 case Options::kDyld
:
4506 case Options::kKextBundle
:
4507 fMakeCompressedDyldInfoForceOff
= true;
4510 if ( fMakeCompressedDyldInfoForceOff
)
4511 fMakeCompressedDyldInfo
= false;
4514 // only use compressed LINKEDIT for:
4515 // Mac OS X 10.6 or later
4517 if ( fMakeCompressedDyldInfo
) {
4518 if ( !minOS(ld::mac10_6
, ld::iOS_3_1
) )
4519 fMakeCompressedDyldInfo
= false;
4522 // only ARM and x86_64 enforces that cpu-sub-types must match
4523 switch ( fArchitecture
) {
4525 case CPU_TYPE_X86_64
:
4528 case CPU_TYPE_ARM64
:
4529 fAllowCpuSubtypeMismatches
= true;
4534 // only final linked images can not optimize zero fill sections
4535 if ( fOutputKind
== Options::kObjectFile
)
4536 fOptimizeZeroFill
= true;
4538 // all undefines in -r mode
4539 // if ( fOutputKind == Options::kObjectFile )
4540 // fUndefinedTreatment = kUndefinedSuppress;
4542 // only dynamic final linked images should warn about use of commmons
4543 if ( fWarnCommons
) {
4544 switch ( fOutputKind
) {
4545 case Options::kDynamicExecutable
:
4546 case Options::kDynamicLibrary
:
4547 case Options::kDynamicBundle
:
4549 case Options::kPreload
:
4550 case Options::kStaticExecutable
:
4551 case Options::kObjectFile
:
4552 case Options::kDyld
:
4553 case Options::kKextBundle
:
4554 fWarnCommons
= false;
4559 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
4560 if ( minOS(ld::mac10_5
, ld::iOS_2_0
) )
4561 fUseSimplifiedDylibReExports
= true;
4563 // Mac OS X 10.7 and iOS 4.2 support LC_LOAD_UPWARD_DYLIB
4564 if ( minOS(ld::mac10_7
, ld::iOS_4_2
) && (fOutputKind
== kDynamicLibrary
) )
4565 fCanUseUpwardDylib
= true;
4567 // MacOSX 10.7 defaults to PIE
4568 if ( ((fArchitecture
== CPU_TYPE_X86_64
) || (fArchitecture
== CPU_TYPE_I386
))
4569 && (fOutputKind
== kDynamicExecutable
)
4570 && (fMacVersionMin
>= ld::mac10_7
) ) {
4571 fPositionIndependentExecutable
= true;
4574 // armv7 for iOS4.3 defaults to PIE
4575 if ( (fArchitecture
== CPU_TYPE_ARM
)
4576 && fArchSupportsThumb2
4577 && (fOutputKind
== kDynamicExecutable
)
4578 && min_iOS(ld::iOS_4_3
) ) {
4579 fPositionIndependentExecutable
= true;
4582 // Simulator defaults to PIE
4583 if ( fTargetIOSSimulator
&& (fOutputKind
== kDynamicExecutable
) )
4584 fPositionIndependentExecutable
= true;
4586 // -no_pie anywhere on command line disable PIE
4587 if ( fDisablePositionIndependentExecutable
)
4588 fPositionIndependentExecutable
= false;
4590 // arm64 is always PIE
4591 if ( (fArchitecture
== CPU_TYPE_ARM64
) && (fOutputKind
== kDynamicExecutable
) ) {
4592 fPositionIndependentExecutable
= true;
4595 // set fOutputSlidable
4596 switch ( fOutputKind
) {
4597 case Options::kObjectFile
:
4598 fOutputSlidable
= false;
4600 case Options::kStaticExecutable
:
4601 case Options::kDynamicExecutable
:
4602 fOutputSlidable
= fPositionIndependentExecutable
;
4604 case Options::kPreload
:
4605 fOutputSlidable
= fPIEOnCommandLine
;
4607 case Options::kDyld
:
4608 case Options::kDynamicLibrary
:
4609 case Options::kDynamicBundle
:
4610 case Options::kKextBundle
:
4611 fOutputSlidable
= true;
4615 // let linker know if thread local variables are supported
4616 if ( fMacVersionMin
>= ld::mac10_7
) {
4619 else if ( (fArchitecture
== CPU_TYPE_ARM64
) && min_iOS(ld::iOS_8_0
) ) {
4622 else if ( (fArchitecture
== CPU_TYPE_ARM
) && min_iOS(ld::iOS_9_0
) ) {
4626 // default to adding version load command for dynamic code, static code must opt-in
4627 switch ( fOutputKind
) {
4628 case Options::kObjectFile
:
4629 fVersionLoadCommand
= false;
4631 case Options::kStaticExecutable
:
4632 case Options::kPreload
:
4633 case Options::kKextBundle
:
4634 if ( fVersionLoadCommandForcedOn
)
4635 fVersionLoadCommand
= true;
4637 case Options::kDynamicExecutable
:
4638 case Options::kDyld
:
4639 case Options::kDynamicLibrary
:
4640 case Options::kDynamicBundle
:
4641 if ( !fVersionLoadCommandForcedOff
)
4642 fVersionLoadCommand
= true;
4646 // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
4647 if ( (fOutputKind
== kDynamicLibrary
) && minOS(ld::mac10_7
, ld::iOS_4_2
) )
4648 fCanReExportSymbols
= true;
4650 // ObjC optimization is only in dynamic final linked images
4651 switch ( fOutputKind
) {
4652 case Options::kObjectFile
:
4653 case Options::kStaticExecutable
:
4654 case Options::kPreload
:
4655 case Options::kKextBundle
:
4656 case Options::kDyld
:
4657 fObjcCategoryMerging
= false;
4659 case Options::kDynamicExecutable
:
4660 case Options::kDynamicLibrary
:
4661 case Options::kDynamicBundle
:
4665 // i386 main executables linked on Mac OS X 10.7 default to NX heap
4666 // regardless of target unless overriden with -allow_heap_execute anywhere
4667 // on the command line
4668 if ( (fArchitecture
== CPU_TYPE_I386
) && (fOutputKind
== kDynamicExecutable
) && !fDisableNonExecutableHeap
)
4669 fNonExecutableHeap
= true;
4671 // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
4672 switch ( fOutputKind
) {
4673 case Options::kDynamicExecutable
:
4674 if ( fEntryPointLoadCommandForceOn
) {
4675 fEntryPointLoadCommand
= true;
4676 if ( fEntryName
== NULL
)
4677 fEntryName
= "_main";
4679 else if ( fEntryPointLoadCommandForceOff
) {
4680 fNeedsThreadLoadCommand
= true;
4681 if ( fEntryName
== NULL
)
4682 fEntryName
= "start";
4685 // <rdar://problem/16310363> Linker should look for "_main" not "start" when building for sim regardless of min OS
4686 if ( minOS(ld::mac10_8
, ld::iOS_6_0
) || fTargetIOSSimulator
) {
4687 fEntryPointLoadCommand
= true;
4688 if ( fEntryName
== NULL
)
4689 fEntryName
= "_main";
4690 if ( strcmp(fEntryName
, "start") == 0 ) {
4691 warning("Ignoring '-e start' because entry point 'start' is not used for the targeted OS version");
4692 fEntryName
= "_main";
4696 fNeedsThreadLoadCommand
= true;
4697 if ( fEntryName
== NULL
)
4698 fEntryName
= "start";
4702 case Options::kObjectFile
:
4703 case Options::kKextBundle
:
4704 case Options::kDynamicLibrary
:
4705 case Options::kDynamicBundle
:
4708 case Options::kStaticExecutable
:
4709 case Options::kPreload
:
4710 case Options::kDyld
:
4711 fNeedsThreadLoadCommand
= true;
4712 if ( fEntryName
== NULL
)
4713 fEntryName
= "start"; // Perhaps these should have no default and require -e
4717 // add LC_SOURCE_VERSION
4718 switch ( fOutputKind
) {
4719 case Options::kDynamicExecutable
:
4720 case Options::kKextBundle
:
4721 case Options::kDynamicLibrary
:
4722 case Options::kDynamicBundle
:
4723 case Options::kDyld
:
4724 case Options::kStaticExecutable
:
4725 if ( fSourceVersionLoadCommandForceOn
) {
4726 fSourceVersionLoadCommand
= true;
4728 else if ( fSourceVersionLoadCommandForceOff
) {
4729 fSourceVersionLoadCommand
= false;
4732 if ( minOS(ld::mac10_8
, ld::iOS_6_0
) ) {
4733 fSourceVersionLoadCommand
= true;
4736 fSourceVersionLoadCommand
= false;
4739 case Options::kObjectFile
:
4740 case Options::kPreload
:
4741 fSourceVersionLoadCommand
= false;
4745 // if -sdk_version not on command line, infer from -syslibroot
4746 if ( (fSDKVersion
== 0) && (fSDKPaths
.size() > 0) ) {
4747 const char* sdkPath
= fSDKPaths
.front();
4748 const char* end
= &sdkPath
[strlen(sdkPath
)-1];
4749 while ( !isdigit(*end
) && (end
> sdkPath
) )
4751 const char* start
= end
-1;
4752 while ( (isdigit(*start
) || (*start
== '.')) && (start
> sdkPath
))
4754 char sdkVersionStr
[32];
4755 int len
= end
-start
+1;
4757 strlcpy(sdkVersionStr
, start
+1, len
);
4758 fSDKVersion
= parseVersionNumber32(sdkVersionStr
);
4762 // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
4763 if ( (fSDKVersion
== 0) && (fMacVersionMin
!= ld::macVersionUnset
) ) {
4764 // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
4765 if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
4766 fSDKVersion
= fMacVersionMin
;
4769 int mib
[2] = { CTL_KERN
, KERN_OSRELEASE
};
4770 char kernVersStr
[100];
4771 size_t strlen
= sizeof(kernVersStr
);
4772 if ( sysctl(mib
, 2, kernVersStr
, &strlen
, NULL
, 0) != -1 ) {
4773 uint32_t kernVers
= parseVersionNumber32(kernVersStr
);
4774 int minor
= (kernVers
>> 16) - 4; // kernel major version is 4 ahead of x in 10.x
4775 fSDKVersion
= 0x000A0000 + (minor
<< 8);
4780 // allow trie based absolute symbols if targeting new enough OS
4781 if ( fMakeCompressedDyldInfo
) {
4782 if ( minOS(ld::mac10_9
, ld::iOS_7_0
) ) {
4783 fAbsoluteSymbols
= true;
4787 // <rdar://problem/12959510> iOS main executables now default to 16KB page size
4788 if ( (fIOSVersionMin
!= ld::iOSVersionUnset
) && (fOutputKind
== Options::kDynamicExecutable
) ) {
4789 // <rdar://problem/13070042> Only third party apps should have 16KB page segments by default
4790 if ( fEncryptable
) {
4791 if ( fSegmentAlignment
== 4096 )
4792 fSegmentAlignment
= 4096*4;
4796 // <rdar://problem/12258065> ARM64 needs 16KB page size for user land code
4797 // <rdar://problem/15974532> make armv7[s] use 16KB pages in user land code for iOS 8 or later
4798 if ( fSegmentAlignment
== 4096 ) {
4799 switch ( fOutputKind
) {
4800 case Options::kDynamicExecutable
:
4801 case Options::kDynamicLibrary
:
4802 case Options::kDynamicBundle
:
4803 case Options::kDyld
:
4804 if ( (fArchitecture
== CPU_TYPE_ARM64
)
4805 || ((fArchitecture
== CPU_TYPE_ARM
) && min_iOS(ld::iOS_7_0
)) ) {
4806 fSegmentAlignment
= 4096*4;
4809 case Options::kStaticExecutable
:
4810 case Options::kKextBundle
:
4811 // <rdar://problem/14676611> 16KB segments for arm64 kexts
4812 if ( (fArchitecture
== CPU_TYPE_ARM64
) && min_iOS(ld::iOS_9_0
) ) {
4813 fSegmentAlignment
= 4096*4;
4816 case Options::kObjectFile
:
4817 case Options::kPreload
:
4824 // <rdar://problem/13624134> linker should not convert dwarf unwind if .o file has compact unwind section
4825 switch ( fOutputKind
) {
4826 case Options::kDynamicExecutable
:
4827 case Options::kDynamicLibrary
:
4828 case Options::kDynamicBundle
:
4829 case Options::kDyld
:
4830 if ( fKeepDwarfUnwindForcedOn
) {
4831 fKeepDwarfUnwind
= true;
4833 else if ( fKeepDwarfUnwindForcedOff
) {
4834 fKeepDwarfUnwind
= false;
4837 if ( minOS(ld::mac10_9
, ld::iOS_7_0
) )
4838 fKeepDwarfUnwind
= false;
4840 fKeepDwarfUnwind
= true;
4843 case Options::kKextBundle
:
4844 case Options::kStaticExecutable
:
4845 case Options::kObjectFile
:
4846 case Options::kPreload
:
4847 fKeepDwarfUnwind
= true;
4851 // Make sure -image_base matches alignment
4852 uint64_t alignedBaseAddress
= (fBaseAddress
+fSegmentAlignment
-1) & (-fSegmentAlignment
);
4853 if ( alignedBaseAddress
!= fBaseAddress
) {
4854 warning("base address 0x%llX is not properly aligned. Changing it to 0x%llX", fBaseAddress
, alignedBaseAddress
);
4855 fBaseAddress
= alignedBaseAddress
;
4858 // If -dirty_data_list not specified, look in $SDKROOT/AppleInternal/DirtyDataFiles/<dylib>.dirty for dirty data list
4859 if ( fSymbolsMovesData
.empty() && fUseDataConstSegment
&& ( fDylibInstallName
!= NULL
) && !fSDKPaths
.empty() ) {
4860 const char* dylibLeaf
= strrchr(fDylibInstallName
, '/');
4862 char path
[PATH_MAX
];
4863 strlcpy(path
, fSDKPaths
.front(), sizeof(path
));
4864 strlcat(path
, "/AppleInternal/DirtyDataFiles", sizeof(path
));
4865 strlcat(path
, dylibLeaf
, sizeof(path
));
4866 strlcat(path
, ".dirty", sizeof(path
));
4868 if ( info
.checkFileExists(*this, path
) )
4869 addSymbolMove("__DATA_DIRTY", path
, fSymbolsMovesData
, "-dirty_data_list");
4875 void Options::checkIllegalOptionCombinations()
4877 // check -undefined setting
4878 switch ( fUndefinedTreatment
) {
4879 case kUndefinedError
:
4880 case kUndefinedDynamicLookup
:
4883 case kUndefinedWarning
:
4884 case kUndefinedSuppress
:
4885 // requires flat namespace
4886 if ( fNameSpace
== kTwoLevelNameSpace
)
4887 throw "can't use -undefined warning or suppress with -twolevel_namespace";
4891 // unify -sub_umbrella with dylibs
4892 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
4893 const char* subUmbrella
= *it
;
4895 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
4896 Options::FileInfo
& info
= *fit
;
4897 const char* lastSlash
= strrchr(info
.path
, '/');
4898 if ( lastSlash
== NULL
)
4899 lastSlash
= info
.path
- 1;
4900 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
4901 info
.options
.fReExport
= true;
4903 fLinkSnapshot
.recordSubUmbrella(info
.path
);
4908 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella
);
4911 // unify -sub_library with dylibs
4912 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
4913 const char* subLibrary
= *it
;
4915 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
4916 Options::FileInfo
& info
= *fit
;
4917 const char* lastSlash
= strrchr(info
.path
, '/');
4918 if ( lastSlash
== NULL
)
4919 lastSlash
= info
.path
- 1;
4920 const char* dot
= strchr(&lastSlash
[1], '.');
4922 dot
= &lastSlash
[strlen(lastSlash
)];
4923 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
4924 info
.options
.fReExport
= true;
4926 fLinkSnapshot
.recordSubLibrary(info
.path
);
4931 warning("-sub_library %s does not match a supplied dylib", subLibrary
);
4934 // sync reader options
4935 if ( fNameSpace
!= kTwoLevelNameSpace
)
4936 fFlatNamespace
= true;
4938 // check -stack_addr
4939 if ( fStackAddr
!= 0 ) {
4940 switch (fArchitecture
) {
4943 if ( fStackAddr
> 0xFFFFFFFF )
4944 throw "-stack_addr must be < 4G for 32-bit processes";
4946 case CPU_TYPE_X86_64
:
4947 case CPU_TYPE_ARM64
:
4950 if ( (fStackAddr
& -4096) != fStackAddr
)
4951 throw "-stack_addr must be multiples of 4K";
4952 if ( fStackSize
== 0 )
4953 throw "-stack_addr must be used with -stack_size";
4956 // check -stack_size
4957 if ( fStackSize
!= 0 ) {
4958 switch (fArchitecture
) {
4960 if ( fStackSize
> 0xFFFFFFFF )
4961 throw "-stack_size must be < 4G for 32-bit processes";
4962 if ( fStackAddr
== 0 ) {
4963 fStackAddr
= 0xC0000000;
4965 if ( (fStackAddr
> 0xB0000000) && ((fStackAddr
-fStackSize
) < 0xB0000000) )
4966 warning("custom stack placement overlaps and will disable shared region");
4969 if ( fStackSize
> 0x2F000000 )
4970 throw "-stack_size must be < 752MB";
4971 if ( fStackAddr
== 0 )
4972 fStackAddr
= 0x2F000000;
4973 if ( fStackAddr
> 0x30000000)
4974 throw "-stack_addr must be < 0x30000000 for arm";
4976 case CPU_TYPE_X86_64
:
4977 if ( fStackAddr
== 0 ) {
4978 fStackAddr
= 0x00007FFF5C000000LL
;
4981 case CPU_TYPE_ARM64
:
4982 if ( fStackSize
> 0x20000000 )
4983 throw "-stack_size must be < 512MB";
4984 if ( fStackAddr
== 0 ) {
4985 fStackAddr
= 0x120000000;
4989 if ( (fStackSize
& -4096) != fStackSize
)
4990 throw "-stack_size must be multiples of 4K";
4991 switch ( fOutputKind
) {
4992 case Options::kDynamicExecutable
:
4993 case Options::kStaticExecutable
:
4994 // custom stack size only legal when building main executable
4996 case Options::kDynamicLibrary
:
4997 case Options::kDynamicBundle
:
4998 case Options::kObjectFile
:
4999 case Options::kDyld
:
5000 case Options::kPreload
:
5001 case Options::kKextBundle
:
5002 throw "-stack_size option can only be used when linking a main executable";
5004 if ( fStackSize
> fStackAddr
)
5005 throwf("-stack_size (0x%08llX) must be smaller than -stack_addr (0x%08llX)", fStackSize
, fStackAddr
);
5008 // check that -allow_stack_execute is only used with main executables
5009 if ( fExecutableStack
) {
5010 switch ( fOutputKind
) {
5011 case Options::kDynamicExecutable
:
5012 case Options::kStaticExecutable
:
5013 // -allow_stack_execute size only legal when building main executable
5015 case Options::kDynamicLibrary
:
5016 case Options::kDynamicBundle
:
5017 case Options::kObjectFile
:
5018 case Options::kDyld
:
5019 case Options::kPreload
:
5020 case Options::kKextBundle
:
5021 throw "-allow_stack_execute option can only be used when linking a main executable";
5025 // check that -allow_heap_execute is only used with i386 main executables
5026 if ( fDisableNonExecutableHeap
) {
5027 if ( fArchitecture
!= CPU_TYPE_I386
)
5028 throw "-allow_heap_execute option can only be used when linking for i386";
5029 switch ( fOutputKind
) {
5030 case Options::kDynamicExecutable
:
5031 // -allow_heap_execute only legal when building main executable
5033 case Options::kStaticExecutable
:
5034 case Options::kDynamicLibrary
:
5035 case Options::kDynamicBundle
:
5036 case Options::kObjectFile
:
5037 case Options::kDyld
:
5038 case Options::kPreload
:
5039 case Options::kKextBundle
:
5040 throw "-allow_heap_execute option can only be used when linking a main executable";
5044 // check -client_name is only used when making a bundle or main executable
5045 if ( fClientName
!= NULL
) {
5046 switch ( fOutputKind
) {
5047 case Options::kDynamicExecutable
:
5048 case Options::kDynamicBundle
:
5050 case Options::kStaticExecutable
:
5051 case Options::kDynamicLibrary
:
5052 case Options::kObjectFile
:
5053 case Options::kDyld
:
5054 case Options::kPreload
:
5055 case Options::kKextBundle
:
5056 throw "-client_name can only be used with -bundle";
5060 // check -init is only used when building a dylib
5061 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
5062 throw "-init can only be used with -dynamiclib";
5064 // check -bundle_loader only used with -bundle
5065 if ( (fBundleLoader
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
5066 throw "-bundle_loader can only be used with -bundle";
5068 // check -dtrace not used with -r
5069 if ( (fDtraceScriptName
!= NULL
) && (fOutputKind
== Options::kObjectFile
) )
5070 throw "-dtrace can only be used when creating final linked images";
5072 // check -d can only be used with -r
5073 if ( fMakeTentativeDefinitionsReal
&& (fOutputKind
!= Options::kObjectFile
) )
5074 throw "-d can only be used with -r";
5076 // check that -root_safe is not used with -r
5077 if ( fRootSafe
&& (fOutputKind
== Options::kObjectFile
) )
5078 throw "-root_safe cannot be used with -r";
5080 // check that -setuid_safe is not used with -r
5081 if ( fSetuidSafe
&& (fOutputKind
== Options::kObjectFile
) )
5082 throw "-setuid_safe cannot be used with -r";
5084 // <rdar://problem/12781832> compiler driver no longer uses -objc_abi_version, it uses -ios_simulator_version_min instead
5085 if ( !fObjCABIVersion1Override
&& !fObjCABIVersion2Override
&& fTargetIOSSimulator
)
5086 fObjCABIVersion2Override
= true;
5088 // rdar://problem/4718189 map ObjC class names to new runtime names
5089 bool alterObjC1ClassNamesToObjC2
= false;
5090 switch (fArchitecture
) {
5092 // i386 only uses new symbols when using objc2 ABI
5093 if ( fObjCABIVersion2Override
)
5094 alterObjC1ClassNamesToObjC2
= true;
5096 case CPU_TYPE_X86_64
:
5098 case CPU_TYPE_ARM64
:
5099 alterObjC1ClassNamesToObjC2
= true;
5103 // make sure all required exported symbols exist
5104 std::vector
<const char*> impliedExports
;
5105 for (NameSet::iterator it
=fExportSymbols
.regularBegin(); it
!= fExportSymbols
.regularEnd(); ++it
) {
5106 const char* name
= *it
;
5107 const int len
= strlen(name
);
5108 if ( (strcmp(&name
[len
-3], ".eh") == 0) || (strncmp(name
, ".objc_category_name_", 20) == 0) ) {
5109 // never export .eh symbols
5110 warning("ignoring %s in export list", name
);
5112 else if ( (fArchitecture
== CPU_TYPE_I386
) && !fObjCABIVersion2Override
&& (strncmp(name
, "_OBJC_CLASS_$", 13) == 0) ) {
5113 warning("ignoring Objc2 Class symbol %s in i386 export list", name
);
5114 fRemovedExports
.insert(name
);
5116 else if ( alterObjC1ClassNamesToObjC2
&& (strncmp(name
, ".objc_class_name_", 17) == 0) ) {
5117 // linking ObjC2 ABI, but have ObjC1 ABI name in export list. Change it to intended name
5118 fRemovedExports
.insert(name
);
5120 asprintf(&temp
, "_OBJC_CLASS_$_%s", &name
[17]);
5121 impliedExports
.push_back(temp
);
5122 asprintf(&temp
, "_OBJC_METACLASS_$_%s", &name
[17]);
5123 impliedExports
.push_back(temp
);
5126 fInitialUndefines
.push_back(name
);
5129 fExportSymbols
.remove(fRemovedExports
);
5130 for (std::vector
<const char*>::iterator it
=impliedExports
.begin(); it
!= impliedExports
.end(); ++it
) {
5131 const char* name
= *it
;
5132 fExportSymbols
.insert(name
);
5133 fInitialUndefines
.push_back(name
);
5136 // make sure all required re-exported symbols exist
5137 for (NameSet::iterator it
=fReExportSymbols
.regularBegin(); it
!= fReExportSymbols
.regularEnd(); ++it
) {
5138 fInitialUndefines
.push_back(*it
);
5141 // make sure that -init symbol exists
5142 if ( fInitFunctionName
!= NULL
)
5143 fInitialUndefines
.push_back(fInitFunctionName
);
5145 // make sure that entry symbol exists
5146 switch ( fOutputKind
) {
5147 case Options::kDynamicExecutable
:
5148 case Options::kStaticExecutable
:
5149 case Options::kDyld
:
5150 case Options::kPreload
:
5151 fInitialUndefines
.push_back(fEntryName
);
5153 case Options::kDynamicLibrary
:
5154 case Options::kDynamicBundle
:
5155 case Options::kObjectFile
:
5156 case Options::kKextBundle
:
5160 // make sure every alias base exists
5161 for (std::vector
<AliasPair
>::iterator it
=fAliases
.begin(); it
!= fAliases
.end(); ++it
) {
5162 fInitialUndefines
.push_back(it
->realName
);
5165 // check custom segments
5166 if ( fCustomSegmentAddresses
.size() != 0 ) {
5167 // verify no segment is in zero page
5168 if ( fZeroPageSize
!= ULLONG_MAX
) {
5169 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
5170 if ( it
->address
< fZeroPageSize
)
5171 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it
->name
, it
->address
);
5174 // verify no duplicates
5175 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
5176 for (std::vector
<SegmentStart
>::iterator it2
= fCustomSegmentAddresses
.begin(); it2
!= fCustomSegmentAddresses
.end(); ++it2
) {
5177 if ( (it
->address
== it2
->address
) && (it
!= it2
) )
5178 throwf("duplicate -segaddr addresses for %s and %s", it
->name
, it2
->name
);
5180 // a custom segment address of zero will disable the use of a zero page
5181 if ( it
->address
== 0 )
5186 if ( fZeroPageSize
== ULLONG_MAX
) {
5187 // zero page size not specified on command line, set default
5188 switch (fArchitecture
) {
5191 // first 4KB for 32-bit architectures
5192 fZeroPageSize
= 0x1000;
5194 case CPU_TYPE_ARM64
:
5195 case CPU_TYPE_X86_64
:
5196 // first 4GB for x86_64 on all OS's
5197 fZeroPageSize
= 0x100000000ULL
;
5200 // if -arch not used, default to 4K zero-page
5201 fZeroPageSize
= 0x1000;
5205 switch ( fOutputKind
) {
5206 case Options::kDynamicExecutable
:
5207 case Options::kStaticExecutable
:
5208 // -pagezero_size size only legal when building main executable
5210 case Options::kDynamicLibrary
:
5211 case Options::kDynamicBundle
:
5212 case Options::kObjectFile
:
5213 case Options::kDyld
:
5214 case Options::kPreload
:
5215 case Options::kKextBundle
:
5216 if ( fZeroPageSize
!= 0 )
5217 throw "-pagezero_size option can only be used when linking a main executable";
5221 // if main executable with custom base address, model zero page as custom segment
5222 if ( (fOutputKind
== Options::kDynamicExecutable
) && (fBaseAddress
!= 0) && (fZeroPageSize
!= 0) ) {
5224 seg
.name
= "__PAGEZERO";
5226 fCustomSegmentAddresses
.push_back(seg
);
5229 // -dead_strip and -r are incompatible
5230 if ( fDeadStrip
&& (fOutputKind
== Options::kObjectFile
) )
5231 throw "-r and -dead_strip cannot be used together";
5233 // can't use -rpath unless targeting 10.5 or later
5234 if ( fRPaths
.size() > 0 ) {
5235 if ( !minOS(ld::mac10_5
, ld::iOS_2_0
) )
5236 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
5237 switch ( fOutputKind
) {
5238 case Options::kDynamicExecutable
:
5239 case Options::kDynamicLibrary
:
5240 case Options::kDynamicBundle
:
5242 case Options::kStaticExecutable
:
5243 case Options::kObjectFile
:
5244 case Options::kDyld
:
5245 case Options::kPreload
:
5246 case Options::kKextBundle
:
5247 throw "-rpath can only be used when creating a dynamic final linked image";
5251 if ( fPositionIndependentExecutable
) {
5252 switch ( fOutputKind
) {
5253 case Options::kDynamicExecutable
:
5254 // check -pie is only used when building a dynamic main executable for 10.5
5255 if ( !minOS(ld::mac10_5
, ld::iOS_4_2
) ) {
5256 if ( fIOSVersionMin
== ld::iOSVersionUnset
)
5257 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
5259 throw "-pie can only be used when targeting iOS 4.2 or later";
5262 case Options::kStaticExecutable
:
5263 case Options::kPreload
:
5264 // -pie is ok with -static or -preload
5266 case Options::kDynamicLibrary
:
5267 case Options::kDynamicBundle
:
5268 warning("-pie being ignored. It is only used when linking a main executable");
5269 fPositionIndependentExecutable
= false;
5271 case Options::kObjectFile
:
5272 case Options::kDyld
:
5273 case Options::kKextBundle
:
5274 throw "-pie can only be used when linking a main executable";
5278 // check -read_only_relocs is not used with x86_64
5279 if ( fAllowTextRelocs
) {
5280 if ( (fArchitecture
== CPU_TYPE_X86_64
) && (fOutputKind
!= kKextBundle
) ) {
5281 warning("-read_only_relocs cannot be used with x86_64");
5282 fAllowTextRelocs
= false;
5286 // check -mark_auto_dead_strip is only used with dylibs
5287 if ( fMarkDeadStrippableDylib
) {
5288 if ( fOutputKind
!= Options::kDynamicLibrary
) {
5289 warning("-mark_auto_dead_strip can only be used when creating a dylib");
5290 fMarkDeadStrippableDylib
= false;
5294 // -force_cpusubtype_ALL is not supported for ARM
5295 if ( fForceSubtypeAll
) {
5296 if ( fArchitecture
== CPU_TYPE_ARM
) {
5297 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
5301 // -reexported_symbols_list can only be used with -dynamiclib
5302 if ( !fReExportSymbols
.empty() ) {
5303 if ( fOutputKind
!= Options::kDynamicLibrary
)
5304 throw "-reexported_symbols_list can only used used when created dynamic libraries";
5305 if ( !minOS(ld::mac10_7
, ld::iOS_4_2
) )
5306 throw "targeted OS version does not support -reexported_symbols_list";
5309 // -dyld_env can only be used with main executables
5310 if ( (fOutputKind
!= Options::kDynamicExecutable
) && (fDyldEnvironExtras
.size() != 0) )
5311 throw "-dyld_env can only used used when created main executables";
5313 // -segment_order can only be used with -preload
5314 if ( !fSegmentOrder
.empty() && (fOutputKind
!= Options::kPreload
) )
5315 throw "-segment_order can only used used with -preload output";
5317 if ( fBitcodeKind
!= kBitcodeProcess
&&
5318 fOutputKind
!= Options::kObjectFile
) {
5319 throw "-bitcode_process_mode can only be used together with -r";
5321 // auto fix up the process type for strip -S.
5322 // when there is only one input and output type is object file, downgrade kBitcodeProcess to kBitcodeAsData.
5323 if ( fOutputKind
== Options::kObjectFile
&& fInputFiles
.size() == 1 && fBitcodeKind
== Options::kBitcodeProcess
)
5324 fBitcodeKind
= Options::kBitcodeAsData
;
5326 // <rdar://problem/17598404> warn if building an embedded iOS dylib for pre-iOS 8
5327 // <rdar://problem/18935714> How can we suppress "ld: warning: embedded dylibs/frameworks only run on iOS 8 or laterÓ when building XCTest?
5328 if ( (fOutputKind
== Options::kDynamicLibrary
) && (fIOSVersionMin
!= ld::iOSVersionUnset
) && (fDylibInstallName
!= NULL
) ) {
5329 if ( !min_iOS(ld::iOS_8_0
) && (fDylibInstallName
[0] == '@') && !fEncryptableForceOff
)
5330 warning("embedded dylibs/frameworks only run on iOS 8 or later");
5335 void Options::checkForClassic(int argc
, const char* argv
[])
5338 bool archFound
= false;
5339 bool staticFound
= false;
5340 bool dtraceFound
= false;
5341 bool kextFound
= false;
5342 bool rFound
= false;
5343 bool creatingMachKernel
= false;
5344 bool newLinker
= false;
5346 // build command line buffer in case ld crashes
5347 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
5348 CRSetCrashLogMessage(crashreporterBuffer
);
5350 const char* srcRoot
= getenv("SRCROOT");
5351 if ( srcRoot
!= NULL
) {
5352 strlcpy(crashreporterBuffer
, "SRCROOT=", crashreporterBufferSize
);
5353 strlcat(crashreporterBuffer
, srcRoot
, crashreporterBufferSize
);
5354 strlcat(crashreporterBuffer
, "\n", crashreporterBufferSize
);
5357 strlcat(crashreporterBuffer
, LD_VERS
, crashreporterBufferSize
);
5358 strlcat(crashreporterBuffer
, "\n", crashreporterBufferSize
);
5360 strlcat(crashreporterBuffer
, "ld ", crashreporterBufferSize
);
5361 for(int i
=1; i
< argc
; ++i
) {
5362 strlcat(crashreporterBuffer
, argv
[i
], crashreporterBufferSize
);
5363 strlcat(crashreporterBuffer
, " ", crashreporterBufferSize
);
5366 for(int i
=0; i
< argc
; ++i
) {
5367 const char* arg
= argv
[i
];
5368 if ( arg
[0] == '-' ) {
5369 if ( strcmp(arg
, "-arch") == 0 ) {
5370 parseArch(argv
[++i
]);
5373 else if ( strcmp(arg
, "-static") == 0 ) {
5376 else if ( strcmp(arg
, "-kext") == 0 ) {
5379 else if ( strcmp(arg
, "-dtrace") == 0 ) {
5382 else if ( strcmp(arg
, "-r") == 0 ) {
5385 else if ( strcmp(arg
, "-new_linker") == 0 ) {
5388 else if ( strcmp(arg
, "-classic_linker") == 0 ) {
5389 // ld_classic does not understand this option, so remove it
5390 for(int j
=i
; j
< argc
; ++j
)
5391 argv
[j
] = argv
[j
+1];
5392 warning("using ld_classic");
5393 this->gotoClassicLinker(argc
-1, argv
);
5395 else if ( strcmp(arg
, "-o") == 0 ) {
5396 const char* outfile
= argv
[++i
];
5397 if ( (outfile
!= NULL
) && (strstr(outfile
, "/mach_kernel") != NULL
) )
5398 creatingMachKernel
= true;
5404 void Options::gotoClassicLinker(int argc
, const char* argv
[])
5406 argv
[0] = "ld_classic";
5407 // ld_classic does not support -iphoneos_version_min, so change
5408 for(int j
=0; j
< argc
; ++j
) {
5409 if ( (strcmp(argv
[j
], "-iphoneos_version_min") == 0) || (strcmp(argv
[j
], "-ios_version_min") == 0) ) {
5410 argv
[j
] = "-macosx_version_min";
5416 // ld classic does not understand -kext (change to -static -r)
5417 for(int j
=0; j
< argc
; ++j
) {
5418 if ( strcmp(argv
[j
], "-kext") == 0)
5420 else if ( strcmp(argv
[j
], "-dynamic") == 0)
5421 argv
[j
] = "-static";
5423 // ld classic does not understand -demangle
5424 for(int j
=0; j
< argc
; ++j
) {
5425 if ( strcmp(argv
[j
], "-demangle") == 0)
5426 argv
[j
] = "-noprebind";
5428 // in -v mode, print command line passed to ld_classic
5429 for(int i
=0; i
< argc
; ++i
) {
5430 if ( strcmp(argv
[i
], "-v") == 0 ) {
5431 for(int j
=0; j
< argc
; ++j
)
5432 printf("%s ", argv
[j
]);
5437 char rawPath
[PATH_MAX
];
5438 char path
[PATH_MAX
];
5439 uint32_t bufSize
= PATH_MAX
;
5440 if ( _NSGetExecutablePath(rawPath
, &bufSize
) != -1 ) {
5441 if ( realpath(rawPath
, path
) != NULL
) {
5442 char* lastSlash
= strrchr(path
, '/');
5443 if ( lastSlash
!= NULL
) {
5444 strcpy(lastSlash
+1, "ld_classic");
5446 execvp(path
, (char**)argv
);
5450 // in case of error in above, try searching for ld_classic via PATH
5451 execvp(argv
[0], (char**)argv
);
5452 fprintf(stderr
, "can't exec ld_classic\n");
5457 // Note, returned string buffer is own by this function.
5458 // It should not be freed
5459 // It will be reused, so clients need to strdup() if they want
5460 // to use it long term.
5461 const char* Options::demangleSymbol(const char* sym
) const
5463 // only try to demangle symbols if -demangle on command line
5467 static size_t size
= 1024;
5468 static char* buff
= (char*)malloc(size
);
5471 // only try to demangle symbols that look like Swift symbols
5472 if ( strncmp(sym
, "__T", 3) == 0 ) {
5473 size_t demangledSize
= fnd_get_demangled_name(&sym
[1], buff
, size
);
5474 if ( demangledSize
> size
) {
5475 size
= demangledSize
+2;
5476 buff
= (char*)realloc(buff
, size
);
5477 demangledSize
= fnd_get_demangled_name(&sym
[1], buff
, size
);
5479 if ( demangledSize
!= 0 )
5484 // only try to demangle symbols that look like C++ symbols
5485 if ( strncmp(sym
, "__Z", 3) != 0 )
5489 char* result
= abi::__cxa_demangle(&sym
[1], buff
, &size
, &status
);
5490 if ( result
!= NULL
) {
5491 // if demangling successful, keep buffer for next demangle
5499 void Options::dumpDependency(uint8_t opcode
, const char* path
) const
5501 if ( !this->dumpDependencyInfo() )
5504 // one time open() of -dependency_info file
5505 if ( fDependencyFileDescriptor
== -1 ) {
5506 fDependencyFileDescriptor
= open(this->dependencyInfoPath(), O_WRONLY
| O_TRUNC
| O_CREAT
, 0666);
5507 if ( fDependencyFileDescriptor
== -1 )
5508 throwf("Could not open or create -dependency_info file: %s", this->dependencyInfoPath());
5511 uint8_t version
= depLinkerVersion
;
5512 if ( write(fDependencyFileDescriptor
, &version
, 1) == -1 )
5513 throwf("write() to -dependency_info failed, errno=%d", errno
);
5514 extern const char ldVersionString
[];
5515 if ( write(fDependencyFileDescriptor
, ldVersionString
, strlen(ldVersionString
)+1) == -1 )
5516 throwf("write() to -dependency_info failed, errno=%d", errno
);
5519 char realPath
[PATH_MAX
];
5520 if ( path
[0] != '/' ) {
5521 if ( realpath(path
, realPath
) != NULL
) {
5526 if ( write(fDependencyFileDescriptor
, &opcode
, 1) == -1 )
5527 throwf("write() to -dependency_info failed, errno=%d", errno
);
5528 if ( write(fDependencyFileDescriptor
, path
, strlen(path
)+1) == -1 )
5529 throwf("write() to -dependency_info failed, errno=%d", errno
);
5531 //fprintf(stderr, "0x%02X %s\n", opcode, path);