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 else if ( strncmp(symbolStart
, "arm64:", 6) == 0 ) {
1783 if ( fArchitecture
== CPU_TYPE_ARM64
)
1784 symbolStart
= &symbolStart
[6];
1788 if ( symbolStart
!= NULL
) {
1789 char* objFileName
= NULL
;
1790 char* colon
= strstr(symbolStart
, ".o:");
1791 if ( colon
!= NULL
) {
1793 objFileName
= symbolStart
;
1794 symbolStart
= &colon
[3];
1797 colon
= strstr(symbolStart
, ".o):");
1798 if ( colon
!= NULL
) {
1800 objFileName
= symbolStart
;
1801 symbolStart
= &colon
[4];
1804 // trim leading spaces
1805 while ( isspace(*symbolStart
) )
1807 Options::OrderedSymbol pair
;
1809 pair
.symbolName
= cstringSymbolName(symbolStart
);
1811 pair
.symbolName
= symbolStart
;
1812 pair
.objectFileName
= objFileName
;
1813 fOrderedSymbols
.push_back(pair
);
1828 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1831 void Options::parseSectionOrderFile(const char* segment
, const char* section
, const char* path
)
1833 if ( (strcmp(section
, "__cstring") == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1834 parseOrderFile(path
, true);
1836 else if ( (strncmp(section
, "__literal",9) == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1837 warning("sorting of __literal[4,8,16] sections not supported");
1840 // ignore section information and append all symbol names to global order file
1841 parseOrderFile(path
, false);
1845 void Options::addSection(const char* segment
, const char* section
, const char* path
)
1847 if ( strlen(segment
) > 16 )
1848 throw "-seccreate segment name max 16 chars";
1849 if ( strlen(section
) > 16 ) {
1850 char* tmp
= strdup(section
);
1852 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section
, tmp
);
1856 // read in whole file
1857 int fd
= ::open(path
, O_RDONLY
, 0);
1859 throwf("can't open -sectcreate file: %s", path
);
1860 struct stat stat_buf
;
1861 ::fstat(fd
, &stat_buf
);
1862 char* p
= (char*)malloc(stat_buf
.st_size
);
1864 throwf("can't process -sectcreate file: %s", path
);
1865 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1866 throwf("can't read -sectcreate file: %s", path
);
1869 // record section to create
1870 ExtraSection info
= { segment
, section
, path
, (uint8_t*)p
, (uint64_t)stat_buf
.st_size
};
1871 fExtraSections
.push_back(info
);
1874 void Options::addSectionRename(const char* srcSegment
, const char* srcSection
, const char* dstSegment
, const char* dstSection
)
1876 if ( strlen(srcSegment
) > 16 )
1877 throw "-rename_section segment name max 16 chars";
1878 if ( strlen(srcSection
) > 16 )
1879 throw "-rename_section section name max 16 chars";
1880 if ( strlen(dstSegment
) > 16 )
1881 throw "-rename_section segment name max 16 chars";
1882 if ( strlen(dstSection
) > 16 )
1883 throw "-rename_section section name max 16 chars";
1886 info
.fromSegment
= srcSegment
;
1887 info
.fromSection
= srcSection
;
1888 info
.toSegment
= dstSegment
;
1889 info
.toSection
= dstSection
;
1891 fSectionRenames
.push_back(info
);
1895 void Options::addSegmentRename(const char* srcSegment
, const char* dstSegment
)
1897 if ( strlen(srcSegment
) > 16 )
1898 throw "-rename_segment segment name max 16 chars";
1899 if ( strlen(dstSegment
) > 16 )
1900 throw "-rename_segment segment name max 16 chars";
1903 info
.fromSegment
= srcSegment
;
1904 info
.toSegment
= dstSegment
;
1906 fSegmentRenames
.push_back(info
);
1911 void Options::addSymbolMove(const char* dstSegment
, const char* symbolList
,
1912 std::vector
<SymbolsMove
>& list
, const char* optionName
)
1914 if ( strlen(dstSegment
) > 16 )
1915 throwf("%s segment name max 16 chars", optionName
);
1918 list
.push_back(tmp
);
1919 SymbolsMove
& info
= list
.back();
1920 info
.toSegment
= dstSegment
;
1921 loadExportFile(symbolList
, optionName
, info
.symbols
);
1924 bool Options::moveRwSymbol(const char* symName
, const char* filePath
, const char*& seg
, bool& wildCardMatch
) const
1926 for (std::vector
<SymbolsMove
>::const_iterator it
=fSymbolsMovesData
.begin(); it
!= fSymbolsMovesData
.end(); ++it
) {
1927 const SymbolsMove
& info
= *it
;
1928 if ( info
.symbols
.containsWithPrefix(symName
, filePath
, wildCardMatch
)) {
1929 seg
= info
.toSegment
;
1936 bool Options::moveRoSymbol(const char* symName
, const char* filePath
, const char*& seg
, bool& wildCardMatch
) const
1938 for (std::vector
<SymbolsMove
>::const_iterator it
=fSymbolsMovesCode
.begin(); it
!= fSymbolsMovesCode
.end(); ++it
) {
1939 const SymbolsMove
& info
= *it
;
1940 if ( info
.symbols
.containsWithPrefix(symName
, filePath
, wildCardMatch
)) {
1941 seg
= info
.toSegment
;
1948 void Options::addSectionAlignment(const char* segment
, const char* section
, const char* alignmentStr
)
1950 if ( strlen(segment
) > 16 )
1951 throw "-sectalign segment name max 16 chars";
1952 if ( strlen(section
) > 16 )
1953 throw "-sectalign section name max 16 chars";
1955 // argument to -sectalign is a hexadecimal number
1957 unsigned long value
= strtoul(alignmentStr
, &endptr
, 16);
1958 if ( *endptr
!= '\0')
1959 throw "argument for -sectalign is not a hexadecimal number";
1960 if ( value
> 0x8000 )
1961 throw "argument for -sectalign must be less than or equal to 0x8000";
1963 warning("zero is not a valid -sectalign");
1967 // alignment is power of 2 (e.g. page alignment = 12)
1968 uint8_t alignment
= (uint8_t)__builtin_ctz(value
);
1969 if ( (unsigned long)(1 << alignment
) != value
) {
1970 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1971 segment
, section
, 1 << alignment
);
1974 SectionAlignment info
= { segment
, section
, alignment
};
1975 fSectionAlignments
.push_back(info
);
1978 void Options::addLibrary(const FileInfo
& info
)
1980 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1981 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1982 if ( strcmp(info
.path
, fit
->path
) == 0 ) {
1983 // if dylib is specified again but weak, record that it should be weak
1984 if ( info
.options
.fWeakImport
)
1985 fit
->options
.fWeakImport
= true;
1990 fInputFiles
.push_back(info
);
1993 void Options::warnObsolete(const char* arg
)
1995 warning("option %s is obsolete and being ignored", arg
);
1999 void Options::cannotBeUsedWithBitcode(const char* arg
)
2001 if ( fBundleBitcode
)
2002 throwf("%s and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together", arg
);
2005 std::string
Options::getVersionString32(uint32_t ver
) const
2007 if (ver
== 0 || ver
>= 0x10000000)
2010 unsigned microVersion
= ver
& 0xFF;
2011 unsigned minorVersion
= (ver
>> 8) & 0xFF;
2012 unsigned majorVersion
= (ver
>> 16) & 0xFF;
2013 std::stringstream versionString
;
2014 versionString
<< majorVersion
<< "." << minorVersion
<< "." << microVersion
;
2015 return versionString
.str();
2018 std::string
Options::getVersionString64(uint64_t ver
) const
2020 uint64_t a
= (ver
>> 40) & 0xFFFFFF;
2021 uint64_t b
= (ver
>> 30) & 0x3FF;
2022 uint64_t c
= (ver
>> 20) & 0x3FF;
2023 uint64_t d
= (ver
>> 10) & 0x3FF;
2024 uint64_t e
= ver
& 0x3FF;
2025 std::stringstream versionString
;
2026 versionString
<< a
<< "." << b
<< "." << c
<< "." << d
<< "." << e
;
2027 return versionString
.str();
2030 std::string
Options::getSDKVersionStr() const
2032 return getVersionString32(fSDKVersion
);
2035 std::string
Options::getPlatformStr() const
2037 switch (fPlatform
) {
2038 case Options::kPlatformOSX
:
2040 case Options::kPlatformiOS
:
2041 if (targetIOSSimulator())
2042 return "iPhoneSimulator";
2045 case Options::kPlatformWatchOS
:
2046 if (targetIOSSimulator())
2047 return "watchOS Simulator";
2050 #if SUPPORT_APPLE_TV
2051 case Options::kPlatform_tvOS
:
2052 if (targetIOSSimulator())
2053 return "AppleTVSimulator";
2058 case Options::kPlatformUnknown
:
2063 std::vector
<std::string
> Options::writeBitcodeLinkOptions() const
2065 std::vector
<std::string
> linkCommand
;
2066 switch ( fOutputKind
) {
2067 case Options::kDynamicLibrary
:
2068 linkCommand
.push_back("-dylib");
2069 linkCommand
.push_back("-compatibility_version");
2070 if ( fDylibCompatVersion
!= 0 ) {
2071 linkCommand
.push_back(getVersionString32(fDylibCompatVersion
));
2073 linkCommand
.push_back(getVersionString32(currentVersion32()));
2075 if ( fDylibCurrentVersion
!= 0 ) {
2076 linkCommand
.push_back("-current_version");
2077 linkCommand
.push_back(getVersionString64(fDylibCurrentVersion
));
2079 linkCommand
.push_back("-install_name");
2080 linkCommand
.push_back(installPath());
2082 case Options::kDynamicExecutable
:
2083 linkCommand
.push_back("-execute");
2085 case Options::kObjectFile
:
2086 linkCommand
.push_back("-r");
2089 throwf("could not write bitcode options file output kind\n");
2092 if (!fImplicitlyLinkPublicDylibs
)
2093 linkCommand
.push_back("-no_implicit_dylibs");
2095 // Add deployment target.
2096 // Platform is allowed to be unknown for "ld -r".
2097 switch (fPlatform
) {
2098 case Options::kPlatformOSX
:
2099 linkCommand
.push_back("-macosx_version_min");
2100 linkCommand
.push_back(getVersionString32((unsigned)fMacVersionMin
));
2102 case Options::kPlatformiOS
:
2103 if (targetIOSSimulator())
2104 linkCommand
.push_back("-ios_simulator_version_min");
2106 linkCommand
.push_back("-ios_version_min");
2107 linkCommand
.push_back(getVersionString32((unsigned)fIOSVersionMin
));
2109 case Options::kPlatformWatchOS
:
2110 if (targetIOSSimulator())
2111 linkCommand
.push_back("-watchos_simulator_version_min");
2113 linkCommand
.push_back("-watchos_version_min");
2114 linkCommand
.push_back(getVersionString32((unsigned)fIOSVersionMin
));
2116 #if SUPPORT_APPLE_TV
2117 case Options::kPlatform_tvOS
:
2118 if (targetIOSSimulator())
2119 linkCommand
.push_back("-tvos_simulator_version_min");
2121 linkCommand
.push_back("-tvos_version_min");
2122 linkCommand
.push_back(getVersionString32((unsigned)fIOSVersionMin
));
2125 case Options::kPlatformUnknown
:
2126 if ( fOutputKind
!= Options::kObjectFile
) {
2127 throwf("platform is unknown for final bitcode bundle,"
2128 "deployment target and min version is required for -bitcode_bundle");
2136 linkCommand
.push_back("-e");
2137 linkCommand
.push_back(fEntryName
);
2141 if (!fRPaths
.empty()) {
2142 for (std::vector
<const char*>::const_iterator it
=fRPaths
.begin(); it
!= fRPaths
.end(); ++it
) {
2143 linkCommand
.push_back("-rpath");
2144 linkCommand
.push_back(*it
);
2148 // Other bitcode compatiable options
2149 if ( fObjCABIVersion1Override
) {
2150 linkCommand
.push_back("-objc_abi_version");
2151 linkCommand
.push_back("1");
2152 } else if ( fObjCABIVersion2Override
) {
2153 linkCommand
.push_back("-objc_abi_version");
2154 linkCommand
.push_back("2");
2156 if ( fExecutablePath
) {
2157 linkCommand
.push_back("-executable_path");
2158 linkCommand
.push_back(fExecutablePath
);
2161 linkCommand
.push_back("-dead_strip");
2162 if ( fExportDynamic
)
2163 linkCommand
.push_back("-export_dynamic");
2164 if ( fMarkAppExtensionSafe
&& fCheckAppExtensionSafe
)
2165 linkCommand
.push_back("-application_extension");
2167 if ( fSourceVersionLoadCommandForceOn
)
2168 linkCommand
.push_back("-add_source_version");
2169 if ( fSourceVersion
!= 0 ) {
2170 linkCommand
.push_back("-source_version");
2171 linkCommand
.push_back(getVersionString64(fSourceVersion
));
2174 // linker flag added by swift driver
2175 // rdar://problem/20108072
2176 if ( !fObjcCategoryMerging
)
2177 linkCommand
.push_back("-no_objc_category_merging");
2183 // Process all command line arguments.
2185 // The only error checking done here is that each option is valid and if it has arguments
2186 // that they too are valid.
2188 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
2189 // whichever was last on the command line is used.
2191 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
2193 void Options::parse(int argc
, const char* argv
[])
2195 // Store the original args in the link snapshot.
2196 fLinkSnapshot
.recordRawArgs(argc
, argv
);
2198 // pass one builds search list from -L and -F options
2199 this->buildSearchPaths(argc
, argv
);
2201 // reduce re-allocations
2202 fInputFiles
.reserve(32);
2204 // pass two parse all other options
2205 for(int i
=1; i
< argc
; ++i
) {
2206 const char* arg
= argv
[i
];
2208 if ( arg
[0] == '-' ) {
2209 // by default, copy one arg to the snapshot link command, and do no file copying
2210 int snapshotArgIndex
= i
;
2211 int snapshotArgCount
= -1; // -1 means compute count based on change in index
2212 int snapshotFileArgIndex
= -1; // -1 means no data file parameter to arg
2214 // Since we don't care about the files passed, just the option names, we do this here.
2216 fprintf (stderr
, "[Logging ld64 options]\t%s\n", arg
);
2218 if ( (arg
[1] == 'L') || (arg
[1] == 'F') ) {
2219 snapshotArgCount
= 0; // stripped out of link snapshot
2222 // previously handled by buildSearchPaths()
2224 // The one gnu style option we have to keep compatibility
2225 // with gcc. Might as well have the single hyphen one as well.
2226 else if ( (strcmp(arg
, "--help") == 0)
2227 || (strcmp(arg
, "-help") == 0)) {
2228 fprintf (stdout
, "ld64: For information on command line options please use 'man ld'.\n");
2231 else if ( strcmp(arg
, "-arch") == 0 ) {
2232 parseArch(argv
[++i
]);
2234 else if ( strcmp(arg
, "-dynamic") == 0 ) {
2237 else if ( strcmp(arg
, "-static") == 0 ) {
2239 if ( (fOutputKind
!= kObjectFile
) && (fOutputKind
!= kKextBundle
) ) {
2240 fOutputKind
= kStaticExecutable
;
2242 cannotBeUsedWithBitcode(arg
);
2244 else if ( strcmp(arg
, "-dylib") == 0 ) {
2245 fOutputKind
= kDynamicLibrary
;
2247 else if ( strcmp(arg
, "-bundle") == 0 ) {
2248 fOutputKind
= kDynamicBundle
;
2249 cannotBeUsedWithBitcode(arg
);
2251 else if ( strcmp(arg
, "-dylinker") == 0 ) {
2252 fOutputKind
= kDyld
;
2253 cannotBeUsedWithBitcode(arg
);
2255 else if ( strcmp(arg
, "-execute") == 0 ) {
2256 if ( fOutputKind
!= kStaticExecutable
)
2257 fOutputKind
= kDynamicExecutable
;
2259 else if ( strcmp(arg
, "-preload") == 0 ) {
2260 fOutputKind
= kPreload
;
2261 cannotBeUsedWithBitcode(arg
);
2263 else if ( strcmp(arg
, "-r") == 0 ) {
2264 fOutputKind
= kObjectFile
;
2266 else if ( strcmp(arg
, "-kext") == 0 ) {
2267 fOutputKind
= kKextBundle
;
2268 cannotBeUsedWithBitcode(arg
);
2270 else if ( strcmp(arg
, "-o") == 0 ) {
2271 snapshotArgCount
= 0;
2272 fOutputFile
= argv
[++i
];
2273 fLinkSnapshot
.setSnapshotName(fOutputFile
);
2275 else if ( strncmp(arg
, "-lazy-l", 7) == 0 ) {
2276 snapshotArgCount
= 0;
2277 FileInfo info
= findLibrary(&arg
[7], true);
2278 info
.options
.fLazyLoad
= true;
2279 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2281 fUsingLazyDylibLinking
= true;
2282 cannotBeUsedWithBitcode(arg
);
2284 else if ( strcmp(arg
, "-lto_library") == 0 ) {
2285 snapshotFileArgIndex
= 1;
2286 fOverridePathlibLTO
= argv
[++i
];
2287 if ( fOverridePathlibLTO
== NULL
)
2288 throw "missing argument to -lto_library";
2290 else if ( (arg
[1] == 'l') && (strncmp(arg
,"-lazy_",6) !=0) ) {
2291 snapshotArgCount
= 0;
2292 FileInfo info
= findLibrary(&arg
[2]);
2293 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2296 // This causes a dylib to be weakly bound at
2297 // link time. This corresponds to weak_import.
2298 else if ( strncmp(arg
, "-weak-l", 7) == 0 ) {
2299 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2300 snapshotArgCount
= 0;
2301 FileInfo info
= findLibrary(&arg
[7]);
2302 info
.options
.fWeakImport
= true;
2303 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2306 // Avoid lazy binding.
2307 else if ( strcmp(arg
, "-bind_at_load") == 0 ) {
2309 cannotBeUsedWithBitcode(arg
);
2311 else if ( strcmp(arg
, "-twolevel_namespace") == 0 ) {
2312 fNameSpace
= kTwoLevelNameSpace
;
2314 else if ( strcmp(arg
, "-flat_namespace") == 0 ) {
2315 fNameSpace
= kFlatNameSpace
;
2316 cannotBeUsedWithBitcode(arg
);
2318 // Also sets a bit to ensure dyld causes everything
2319 // in the namespace to be flat.
2321 else if ( strcmp(arg
, "-force_flat_namespace") == 0 ) {
2322 fNameSpace
= kForceFlatNameSpace
;
2323 cannotBeUsedWithBitcode(arg
);
2325 // Similar to --whole-archive.
2326 else if ( strcmp(arg
, "-all_load") == 0 ) {
2327 fFullyLoadArchives
= true;
2329 else if ( strcmp(arg
, "-noall_load") == 0) {
2332 // Similar to -all_load
2333 else if ( strcmp(arg
, "-ObjC") == 0 ) {
2334 fLoadAllObjcObjectsFromArchives
= true;
2336 // Similar to -all_load, but for the following archive only.
2337 else if ( strcmp(arg
, "-force_load") == 0 ) {
2338 FileInfo info
= findFile(argv
[++i
]);
2339 info
.options
.fForceLoad
= true;
2340 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2343 // Library versioning.
2344 else if ( (strcmp(arg
, "-dylib_compatibility_version") == 0)
2345 || (strcmp(arg
, "-compatibility_version") == 0)) {
2346 const char* vers
= argv
[++i
];
2348 throw "-dylib_compatibility_version missing <version>";
2349 fDylibCompatVersion
= parseVersionNumber32(vers
);
2351 else if ( (strcmp(arg
, "-dylib_current_version") == 0)
2352 || (strcmp(arg
, "-current_version") == 0)) {
2353 const char* vers
= argv
[++i
];
2355 throw "-dylib_current_version missing <version>";
2356 fDylibCurrentVersion
= parseVersionNumber64(vers
);
2358 else if ( strcmp(arg
, "-sectorder") == 0 ) {
2359 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2360 throw "-sectorder missing <segment> <section> <file-path>";
2361 snapshotFileArgIndex
= 3;
2362 parseSectionOrderFile(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2364 cannotBeUsedWithBitcode(arg
);
2366 else if ( strcmp(arg
, "-order_file") == 0 ) {
2367 snapshotFileArgIndex
= 1;
2368 parseOrderFile(argv
[++i
], false);
2370 else if ( strcmp(arg
, "-order_file_statistics") == 0 ) {
2371 fPrintOrderFileStatistics
= true;
2372 cannotBeUsedWithBitcode(arg
);
2374 // ??? Deprecate segcreate.
2375 // -sectcreate puts whole files into a section in the output.
2376 else if ( (strcmp(arg
, "-sectcreate") == 0) || (strcmp(arg
, "-segcreate") == 0) ) {
2377 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2378 throw "-sectcreate missing <segment> <section> <file-path>";
2379 snapshotFileArgIndex
= 3;
2380 addSection(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2383 // Since we have a full path in binary/library names we need to be able to override it.
2384 else if ( (strcmp(arg
, "-dylib_install_name") == 0)
2385 || (strcmp(arg
, "-dylinker_install_name") == 0)
2386 || (strcmp(arg
, "-install_name") == 0)) {
2387 fDylibInstallName
= argv
[++i
];
2388 if ( fDylibInstallName
== NULL
)
2389 throw "-install_name missing <path>";
2391 // Sets the base address of the output.
2392 else if ( (strcmp(arg
, "-seg1addr") == 0) || (strcmp(arg
, "-image_base") == 0) ) {
2393 const char* address
= argv
[++i
];
2394 if ( address
== NULL
)
2395 throwf("%s missing <address>", arg
);
2396 fBaseAddress
= parseAddress(address
);
2397 uint64_t temp
= ((fBaseAddress
+fSegmentAlignment
-1) & (-fSegmentAlignment
));
2398 if ( fBaseAddress
!= temp
) {
2399 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment
);
2400 fBaseAddress
= temp
;
2402 cannotBeUsedWithBitcode(arg
);
2404 else if ( strcmp(arg
, "-e") == 0 ) {
2405 fEntryName
= argv
[++i
];
2407 // Same as -@ from the FSF linker.
2408 else if ( strcmp(arg
, "-filelist") == 0 ) {
2409 snapshotArgCount
= 0;
2410 const char* path
= argv
[++i
];
2411 if ( (path
== NULL
) || (path
[0] == '-') )
2412 throw "-filelist missing <path>";
2413 ld::File::Ordinal baseOrdinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2414 loadFileList(path
, baseOrdinal
);
2416 else if ( strcmp(arg
, "-keep_private_externs") == 0 ) {
2417 cannotBeUsedWithBitcode(arg
);
2418 fKeepPrivateExterns
= true;
2420 else if ( strcmp(arg
, "-final_output") == 0 ) {
2421 fFinalName
= argv
[++i
];
2423 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
2424 // just ensures that this happens for cross object file boundaries.
2425 else if ( (strcmp(arg
, "-interposable") == 0) || (strcmp(arg
, "-multi_module") == 0)) {
2426 switch ( fInterposeMode
) {
2427 case kInterposeNone
:
2428 case kInterposeAllExternal
:
2429 fInterposeMode
= kInterposeAllExternal
;
2431 case kInterposeSome
:
2432 // do nothing, -interposable_list overrides -interposable"
2435 cannotBeUsedWithBitcode(arg
);
2437 else if ( strcmp(arg
, "-interposable_list") == 0 ) {
2438 snapshotFileArgIndex
= 1;
2439 fInterposeMode
= kInterposeSome
;
2440 loadExportFile(argv
[++i
], "-interposable_list", fInterposeList
);
2441 cannotBeUsedWithBitcode(arg
);
2443 // Default for -interposable/-multi_module/-single_module.
2444 else if ( strcmp(arg
, "-single_module") == 0 ) {
2445 fInterposeMode
= kInterposeNone
;
2447 else if ( strcmp(arg
, "-exported_symbols_list") == 0 ) {
2448 snapshotFileArgIndex
= 1;
2449 if ( fExportMode
== kDontExportSome
)
2450 throw "can't use -exported_symbols_list and -unexported_symbols_list";
2451 fExportMode
= kExportSome
;
2452 loadExportFile(argv
[++i
], "-exported_symbols_list", fExportSymbols
);
2454 else if ( strcmp(arg
, "-unexported_symbols_list") == 0 ) {
2455 snapshotFileArgIndex
= 1;
2456 if ( fExportMode
== kExportSome
)
2457 throw "can't use -unexported_symbols_list and -exported_symbols_list";
2458 fExportMode
= kDontExportSome
;
2459 loadExportFile(argv
[++i
], "-unexported_symbols_list", fDontExportSymbols
);
2461 else if ( strcmp(arg
, "-exported_symbol") == 0 ) {
2462 if ( fExportMode
== kDontExportSome
)
2463 throw "can't use -exported_symbol and -unexported_symbols";
2464 fExportMode
= kExportSome
;
2465 fExportSymbols
.insert(argv
[++i
]);
2467 else if ( strcmp(arg
, "-unexported_symbol") == 0 ) {
2468 if ( fExportMode
== kExportSome
)
2469 throw "can't use -unexported_symbol and -exported_symbol";
2470 fExportMode
= kDontExportSome
;
2471 fDontExportSymbols
.insert(argv
[++i
]);
2473 else if ( strcmp(arg
, "-non_global_symbols_no_strip_list") == 0 ) {
2474 snapshotFileArgIndex
= 1;
2475 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveExclude
)
2476 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2477 fLocalSymbolHandling
= kLocalSymbolsSelectiveInclude
;
2478 loadExportFile(argv
[++i
], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded
);
2479 cannotBeUsedWithBitcode(arg
);
2481 else if ( strcmp(arg
, "-non_global_symbols_strip_list") == 0 ) {
2482 snapshotFileArgIndex
= 1;
2483 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveInclude
)
2484 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2485 fLocalSymbolHandling
= kLocalSymbolsSelectiveExclude
;
2486 loadExportFile(argv
[++i
], "-non_global_symbols_strip_list", fLocalSymbolsExcluded
);
2487 cannotBeUsedWithBitcode(arg
);
2490 else if ( strcmp(arg
, "-no_arch_warnings") == 0 ) {
2491 fIgnoreOtherArchFiles
= true;
2493 else if ( strcmp(arg
, "-force_cpusubtype_ALL") == 0 ) {
2494 fForceSubtypeAll
= true;
2495 fAllowCpuSubtypeMismatches
= true;
2496 cannotBeUsedWithBitcode(arg
);
2498 // Similar to -weak-l but uses the absolute path name to the library.
2499 else if ( strcmp(arg
, "-weak_library") == 0 ) {
2500 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2501 snapshotArgCount
= 0;
2502 FileInfo info
= findFile(argv
[++i
]);
2503 info
.options
.fWeakImport
= true;
2504 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2506 cannotBeUsedWithBitcode(arg
);
2508 else if ( strcmp(arg
, "-lazy_library") == 0 ) {
2509 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2510 snapshotArgCount
= 0;
2511 FileInfo info
= findFile(argv
[++i
]);
2512 info
.options
.fLazyLoad
= true;
2513 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2515 fUsingLazyDylibLinking
= true;
2516 cannotBeUsedWithBitcode(arg
);
2518 else if ( strcmp(arg
, "-framework") == 0 ) {
2519 snapshotArgCount
= 0;
2520 FileInfo info
= findFramework(argv
[++i
]);
2521 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2524 else if ( strcmp(arg
, "-weak_framework") == 0 ) {
2525 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2526 snapshotArgCount
= 0;
2527 FileInfo info
= findFramework(argv
[++i
]);
2528 info
.options
.fWeakImport
= true;
2529 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2532 else if ( strcmp(arg
, "-lazy_framework") == 0 ) {
2533 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2534 snapshotArgCount
= 0;
2535 FileInfo info
= findFramework(argv
[++i
]);
2536 info
.options
.fLazyLoad
= true;
2537 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2539 fUsingLazyDylibLinking
= true;
2540 cannotBeUsedWithBitcode(arg
);
2542 else if ( strcmp(arg
, "-search_paths_first") == 0 ) {
2543 // previously handled by buildSearchPaths()
2545 else if ( strcmp(arg
, "-search_dylibs_first") == 0 ) {
2546 // previously handled by buildSearchPaths()
2548 else if ( strcmp(arg
, "-undefined") == 0 ) {
2549 setUndefinedTreatment(argv
[++i
]);
2550 cannotBeUsedWithBitcode(arg
);
2552 // Debugging output flag.
2553 else if ( strcmp(arg
, "-arch_multiple") == 0 ) {
2554 fMessagesPrefixedWithArchitecture
= true;
2556 // Specify what to do with relocations in read only
2557 // sections like .text. Could be errors, warnings,
2558 // or suppressed. Currently we do nothing with the
2560 else if ( strcmp(arg
, "-read_only_relocs") == 0 ) {
2561 switch ( parseTreatment(argv
[++i
]) ) {
2564 throw "-read_only_relocs missing [ warning | error | suppress ]";
2566 fWarnTextRelocs
= true;
2567 fAllowTextRelocs
= true;
2568 cannotBeUsedWithBitcode(arg
);
2571 fWarnTextRelocs
= false;
2572 fAllowTextRelocs
= true;
2573 cannotBeUsedWithBitcode(arg
);
2576 fWarnTextRelocs
= false;
2577 fAllowTextRelocs
= false;
2581 else if ( strcmp(arg
, "-sect_diff_relocs") == 0 ) {
2585 // Warn, error or make strong a mismatch between weak
2586 // and non-weak references.
2587 else if ( strcmp(arg
, "-weak_reference_mismatches") == 0 ) {
2588 setWeakReferenceMismatchTreatment(argv
[++i
]);
2590 // For a deployment target of 10.3 and earlier ld64 will
2591 // prebind an executable with 0s in all addresses that
2592 // are prebound. This can then be fixed up by update_prebinding
2593 // later. Prebinding is less useful on 10.4 and greater.
2594 else if ( strcmp(arg
, "-prebind") == 0 ) {
2596 cannotBeUsedWithBitcode(arg
);
2598 else if ( strcmp(arg
, "-noprebind") == 0 ) {
2602 else if ( strcmp(arg
, "-prebind_allow_overlap") == 0 ) {
2605 else if ( strcmp(arg
, "-prebind_all_twolevel_modules") == 0 ) {
2608 else if ( strcmp(arg
, "-noprebind_all_twolevel_modules") == 0 ) {
2611 else if ( strcmp(arg
, "-nofixprebinding") == 0 ) {
2614 // This should probably be deprecated when we respect -L and -F
2615 // when searching for libraries.
2616 else if ( strcmp(arg
, "-dylib_file") == 0 ) {
2617 // ignore for snapshot because a stub dylib will be created in the snapshot
2618 snapshotArgCount
= 0;
2619 addDylibOverride(argv
[++i
]);
2620 cannotBeUsedWithBitcode(arg
);
2622 // What to expand @executable_path to if found in dependent dylibs
2623 else if ( strcmp(arg
, "-executable_path") == 0 ) {
2624 fExecutablePath
= argv
[++i
];
2625 if ( (fExecutablePath
== NULL
) || (fExecutablePath
[0] == '-') )
2626 throw "-executable_path missing <path>";
2627 // if a directory was passed, add / to end
2628 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2629 struct stat statBuffer
;
2630 if ( stat(fExecutablePath
, &statBuffer
) == 0 ) {
2631 if ( (statBuffer
.st_mode
& S_IFMT
) == S_IFDIR
) {
2632 char* pathWithSlash
= new char[strlen(fExecutablePath
)+2];
2633 strcpy(pathWithSlash
, fExecutablePath
);
2634 strcat(pathWithSlash
, "/");
2635 fExecutablePath
= pathWithSlash
;
2639 // Aligns all segments to the power of 2 boundary specified.
2640 else if ( strcmp(arg
, "-segalign") == 0 ) {
2641 const char* size
= argv
[++i
];
2643 throw "-segalign missing <size>";
2644 fSegmentAlignment
= parseAddress(size
);
2645 uint8_t alignment
= (uint8_t)__builtin_ctz(fSegmentAlignment
);
2646 uint32_t p2aligned
= (1 << alignment
);
2647 if ( p2aligned
!= fSegmentAlignment
) {
2648 warning("alignment for -segalign %s is not a power of two, using 0x%X", size
, p2aligned
);
2649 fSegmentAlignment
= p2aligned
;
2651 cannotBeUsedWithBitcode(arg
);
2653 // Puts a specified segment at a particular address that must
2654 // be a multiple of the segment alignment.
2655 else if ( strcmp(arg
, "-segaddr") == 0 ) {
2657 seg
.name
= argv
[++i
];
2658 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
2659 throw "-segaddr missing segName Adddress";
2660 seg
.address
= parseAddress(argv
[++i
]);
2661 uint64_t temp
= ((seg
.address
+fSegmentAlignment
-1) & (-fSegmentAlignment
));
2662 if ( seg
.address
!= temp
)
2663 warning("-segaddr %s not %lld byte aligned", seg
.name
, fSegmentAlignment
);
2664 fCustomSegmentAddresses
.push_back(seg
);
2665 cannotBeUsedWithBitcode(arg
);
2667 // ??? Deprecate when we deprecate split-seg.
2668 else if ( strcmp(arg
, "-segs_read_only_addr") == 0 ) {
2669 fBaseAddress
= parseAddress(argv
[++i
]);
2670 cannotBeUsedWithBitcode(arg
);
2672 // ??? Deprecate when we deprecate split-seg.
2673 else if ( strcmp(arg
, "-segs_read_write_addr") == 0 ) {
2674 fBaseWritableAddress
= parseAddress(argv
[++i
]);
2676 cannotBeUsedWithBitcode(arg
);
2678 // ??? Deprecate when we get rid of basing at build time.
2679 else if ( strcmp(arg
, "-seg_addr_table") == 0 ) {
2680 snapshotFileArgIndex
= 1;
2681 const char* name
= argv
[++i
];
2683 throw "-seg_addr_table missing argument";
2684 fSegAddrTablePath
= name
;
2685 cannotBeUsedWithBitcode(arg
);
2687 else if ( strcmp(arg
, "-seg_addr_table_filename") == 0 ) {
2691 else if ( strcmp(arg
, "-segprot") == 0 ) {
2693 seg
.name
= argv
[++i
];
2694 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) || (argv
[i
+2] == NULL
) )
2695 throw "-segprot missing segName max-prot init-prot";
2696 seg
.max
= parseProtection(argv
[++i
]);
2697 seg
.init
= parseProtection(argv
[++i
]);
2698 fCustomSegmentProtections
.push_back(seg
);
2699 cannotBeUsedWithBitcode(arg
);
2701 else if ( strcmp(arg
, "-pagezero_size") == 0 ) {
2702 const char* size
= argv
[++i
];
2704 throw "-pagezero_size missing <size>";
2705 fZeroPageSize
= parseAddress(size
);
2706 uint64_t temp
= fZeroPageSize
& (-4096); // page align
2707 if ( (fZeroPageSize
!= temp
) )
2708 warning("-pagezero_size not page aligned, rounding down");
2709 fZeroPageSize
= temp
;
2710 cannotBeUsedWithBitcode(arg
);
2712 else if ( strcmp(arg
, "-stack_addr") == 0 ) {
2713 const char* address
= argv
[++i
];
2714 if ( address
== NULL
)
2715 throw "-stack_addr missing <address>";
2716 fStackAddr
= parseAddress(address
);
2717 cannotBeUsedWithBitcode(arg
);
2719 else if ( strcmp(arg
, "-stack_size") == 0 ) {
2720 const char* size
= argv
[++i
];
2722 throw "-stack_size missing <address>";
2723 fStackSize
= parseAddress(size
);
2724 uint64_t temp
= fStackSize
& (-4096); // page align
2725 if ( (fStackSize
!= temp
) )
2726 warning("-stack_size not page aligned, rounding down");
2728 else if ( strcmp(arg
, "-allow_stack_execute") == 0 ) {
2729 fExecutableStack
= true;
2730 cannotBeUsedWithBitcode(arg
);
2732 else if ( strcmp(arg
, "-allow_heap_execute") == 0 ) {
2733 fDisableNonExecutableHeap
= true;
2734 cannotBeUsedWithBitcode(arg
);
2736 else if ( strcmp(arg
, "-sectalign") == 0 ) {
2737 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2738 throw "-sectalign missing <segment> <section> <file-path>";
2739 addSectionAlignment(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2741 cannotBeUsedWithBitcode(arg
);
2743 else if ( strcmp(arg
, "-sectorder_detail") == 0 ) {
2746 else if ( strcmp(arg
, "-sectobjectsymbols") == 0 ) {
2750 else if ( strcmp(arg
, "-bundle_loader") == 0 ) {
2751 snapshotFileArgIndex
= 1;
2752 fBundleLoader
= argv
[++i
];
2753 if ( (fBundleLoader
== NULL
) || (fBundleLoader
[0] == '-') )
2754 throw "-bundle_loader missing <path>";
2755 FileInfo info
= findFile(fBundleLoader
);
2756 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2757 info
.options
.fBundleLoader
= true;
2758 fInputFiles
.push_back(info
);
2760 else if ( strcmp(arg
, "-private_bundle") == 0 ) {
2763 else if ( strcmp(arg
, "-twolevel_namespace_hints") == 0 ) {
2766 // Use this flag to set default behavior for deployement targets.
2767 else if ( strcmp(arg
, "-macosx_version_min") == 0 ) {
2768 const char* macVers
= argv
[++i
];
2769 const char* envMacVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
2770 const char* enviPhoneVers
= getenv("IPHONEOS_DEPLOYMENT_TARGET");
2771 if ( (envMacVers
!= NULL
) && (enviPhoneVers
!= NULL
) ) {
2772 // <rdar://problem/13774329> when conflicting deployments set, break tie by looking at syslibroot
2773 warning("both MACOSX_DEPLOYMENT_TARGET and IPHONEOS_DEPLOYMENT_TARGET are set");
2774 if ( !fSDKPaths
.empty() ) {
2775 const char* sysrootPath
= fSDKPaths
.back();
2776 const char* lastSlash
= strrchr(sysrootPath
, '/');
2777 if ( strstr(lastSlash
, "Simulator") != NULL
)
2778 setIOSVersionMin(enviPhoneVers
);
2780 setMacOSXVersionMin(macVers
);
2783 setMacOSXVersionMin(macVers
);
2787 setMacOSXVersionMin(macVers
);
2790 else if ( (strcmp(arg
, "-ios_version_min") == 0) || (strcmp(arg
, "-iphoneos_version_min") == 0) ) {
2791 setIOSVersionMin(argv
[++i
]);
2793 else if ( strcmp(arg
, "-ios_simulator_version_min") == 0 ) {
2794 setIOSVersionMin(argv
[++i
]);
2795 fTargetIOSSimulator
= true;
2797 else if ( strcmp(arg
, "-watchos_version_min") == 0 ) {
2798 setWatchOSVersionMin(argv
[++i
]);
2800 else if ( strcmp(arg
, "-watchos_simulator_version_min") == 0 ) {
2801 setWatchOSVersionMin(argv
[++i
]);
2802 fTargetIOSSimulator
= true;
2804 #if SUPPORT_APPLE_TV
2805 else if ( strcmp(arg
, "-tvos_version_min") == 0 ) {
2806 setIOSVersionMin(argv
[++i
]);
2807 fPlatform
= kPlatform_tvOS
;
2809 else if ( strcmp(arg
, "-tvos_simulator_version_min") == 0 ) {
2810 setIOSVersionMin(argv
[++i
]);
2811 fPlatform
= kPlatform_tvOS
;
2812 fTargetIOSSimulator
= true;
2815 else if ( strcmp(arg
, "-multiply_defined") == 0 ) {
2816 //warnObsolete(arg);
2819 else if ( strcmp(arg
, "-multiply_defined_unused") == 0 ) {
2823 else if ( strcmp(arg
, "-nomultidefs") == 0 ) {
2826 // Display each file in which the argument symbol appears and whether
2827 // the file defines or references it. This option takes an argument
2828 // as -y<symbol> note that there is no space.
2829 else if ( strncmp(arg
, "-y", 2) == 0 ) {
2832 // Same output as -y, but output <arg> number of undefined symbols only.
2833 else if ( strcmp(arg
, "-Y") == 0 ) {
2834 //warnObsolete(arg);
2837 // This option affects all objects linked into the final result.
2838 else if ( strcmp(arg
, "-m") == 0 ) {
2841 else if ( (strcmp(arg
, "-why_load") == 0) || (strcmp(arg
, "-whyload") == 0) ) {
2844 else if ( strcmp(arg
, "-why_live") == 0 ) {
2845 const char* name
= argv
[++i
];
2847 throw "-why_live missing symbol name argument";
2848 fWhyLive
.insert(name
);
2850 else if ( strcmp(arg
, "-u") == 0 ) {
2851 const char* name
= argv
[++i
];
2853 throw "-u missing argument";
2854 fInitialUndefines
.push_back(name
);
2855 cannotBeUsedWithBitcode(arg
);
2857 else if ( strcmp(arg
, "-U") == 0 ) {
2858 const char* name
= argv
[++i
];
2860 throw "-U missing argument";
2861 fAllowedUndefined
.insert(name
);
2862 cannotBeUsedWithBitcode(arg
);
2864 else if ( strcmp(arg
, "-s") == 0 ) {
2866 fLocalSymbolHandling
= kLocalSymbolsNone
;
2867 fDebugInfoStripping
= Options::kDebugInfoNone
;
2869 else if ( strcmp(arg
, "-x") == 0 ) {
2870 fLocalSymbolHandling
= kLocalSymbolsNone
;
2872 else if ( strcmp(arg
, "-S") == 0 ) {
2873 fDebugInfoStripping
= Options::kDebugInfoNone
;
2875 else if ( strcmp(arg
, "-X") == 0 ) {
2878 else if ( strcmp(arg
, "-Si") == 0 ) {
2880 fDebugInfoStripping
= Options::kDebugInfoFull
;
2882 else if ( strcmp(arg
, "-b") == 0 ) {
2885 else if ( strcmp(arg
, "-Sn") == 0 ) {
2887 fDebugInfoStripping
= Options::kDebugInfoFull
;
2889 else if ( strcmp(arg
, "-Sp") == 0 ) {
2892 else if ( strcmp(arg
, "-dead_strip") == 0 ) {
2895 else if ( strcmp(arg
, "-no_dead_strip_inits_and_terms") == 0 ) {
2898 else if ( strcmp(arg
, "-w") == 0 ) {
2899 // previously handled by buildSearchPaths()
2901 else if ( strcmp(arg
, "-fatal_warnings") == 0 ) {
2902 // previously handled by buildSearchPaths()
2904 else if ( strcmp(arg
, "-arch_errors_fatal") == 0 ) {
2905 fErrorOnOtherArchFiles
= true;
2907 else if ( strcmp(arg
, "-M") == 0 ) {
2910 else if ( strcmp(arg
, "-headerpad") == 0 ) {
2911 const char* size
= argv
[++i
];
2913 throw "-headerpad missing argument";
2914 fMinimumHeaderPad
= parseAddress(size
);
2915 cannotBeUsedWithBitcode(arg
);
2917 else if ( strcmp(arg
, "-headerpad_max_install_names") == 0 ) {
2918 // ignore -headerpad_max_install_names when compiling with bitcode
2919 // rdar://problem/20748962
2920 if ( fBundleBitcode
)
2921 warning("-headerpad_max_install_names is ignored when used with -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES)");
2923 fMaxMinimumHeaderPad
= true;
2925 else if ( strcmp(arg
, "-t") == 0 ) {
2926 fLogAllFiles
= true;
2928 else if ( strcmp(arg
, "-whatsloaded") == 0 ) {
2929 fLogObjectFiles
= true;
2931 else if ( strcmp(arg
, "-A") == 0 ) {
2935 else if ( strcmp(arg
, "-umbrella") == 0 ) {
2936 const char* name
= argv
[++i
];
2938 throw "-umbrella missing argument";
2939 fUmbrellaName
= name
;
2940 cannotBeUsedWithBitcode(arg
);
2942 else if ( strcmp(arg
, "-allowable_client") == 0 ) {
2943 const char* name
= argv
[++i
];
2946 throw "-allowable_client missing argument";
2948 fAllowableClients
.push_back(name
);
2949 cannotBeUsedWithBitcode(arg
);
2951 else if ( strcmp(arg
, "-client_name") == 0 ) {
2952 const char* name
= argv
[++i
];
2955 throw "-client_name missing argument";
2958 cannotBeUsedWithBitcode(arg
);
2960 else if ( strcmp(arg
, "-sub_umbrella") == 0 ) {
2961 const char* name
= argv
[++i
];
2963 throw "-sub_umbrella missing argument";
2964 fSubUmbellas
.push_back(name
);
2965 cannotBeUsedWithBitcode(arg
);
2967 else if ( strcmp(arg
, "-sub_library") == 0 ) {
2968 const char* name
= argv
[++i
];
2970 throw "-sub_library missing argument";
2971 fSubLibraries
.push_back(name
);
2972 cannotBeUsedWithBitcode(arg
);
2974 else if ( strcmp(arg
, "-init") == 0 ) {
2975 const char* name
= argv
[++i
];
2977 throw "-init missing argument";
2978 fInitFunctionName
= name
;
2979 cannotBeUsedWithBitcode(arg
);
2981 else if ( strcmp(arg
, "-dot") == 0 ) {
2982 const char* name
= argv
[++i
];
2984 throw "-dot missing argument";
2985 fDotOutputFile
= name
;
2986 cannotBeUsedWithBitcode(arg
);
2988 else if ( strcmp(arg
, "-warn_commons") == 0 ) {
2989 fWarnCommons
= true;
2991 else if ( strcmp(arg
, "-commons") == 0 ) {
2992 fCommonsMode
= parseCommonsTreatment(argv
[++i
]);
2994 else if ( strcmp(arg
, "-keep_relocs") == 0 ) {
2995 fKeepRelocations
= true;
2997 else if ( strcmp(arg
, "-warn_stabs") == 0 ) {
3000 else if ( strcmp(arg
, "-pause") == 0 ) {
3003 else if ( strcmp(arg
, "-print_statistics") == 0 ) {
3006 else if ( strcmp(arg
, "-d") == 0 ) {
3007 fMakeTentativeDefinitionsReal
= true;
3009 else if ( strcmp(arg
, "-v") == 0 ) {
3010 // previously handled by buildSearchPaths()
3012 else if ( strcmp(arg
, "-Z") == 0 ) {
3013 // previously handled by buildSearchPaths()
3015 else if ( strcmp(arg
, "-syslibroot") == 0 ) {
3016 snapshotArgCount
= 0;
3018 // previously handled by buildSearchPaths()
3020 else if ( strcmp(arg
, "-bitcode_bundle") == 0 ) {
3021 snapshotArgCount
= 0;
3022 // previously handled by buildSearchPaths()
3024 else if ( strcmp(arg
, "-no_uuid") == 0 ) {
3025 fUUIDMode
= kUUIDNone
;
3026 cannotBeUsedWithBitcode(arg
);
3028 else if ( strcmp(arg
, "-random_uuid") == 0 ) {
3029 fUUIDMode
= kUUIDRandom
;
3030 cannotBeUsedWithBitcode(arg
);
3032 else if ( strcmp(arg
, "-dtrace") == 0 ) {
3033 snapshotFileArgIndex
= 1;
3034 const char* name
= argv
[++i
];
3036 throw "-dtrace missing argument";
3037 fDtraceScriptName
= name
;
3038 cannotBeUsedWithBitcode(arg
);
3040 else if ( strcmp(arg
, "-root_safe") == 0 ) {
3043 else if ( strcmp(arg
, "-setuid_safe") == 0 ) {
3046 else if ( strcmp(arg
, "-alias") == 0 ) {
3047 Options::AliasPair pair
;
3048 pair
.realName
= argv
[++i
];
3049 if ( pair
.realName
== NULL
)
3050 throw "missing argument to -alias";
3051 pair
.alias
= argv
[++i
];
3052 if ( pair
.alias
== NULL
)
3053 throw "missing argument to -alias";
3054 fAliases
.push_back(pair
);
3055 cannotBeUsedWithBitcode(arg
);
3057 else if ( strcmp(arg
, "-alias_list") == 0 ) {
3058 snapshotFileArgIndex
= 1;
3059 parseAliasFile(argv
[++i
]);
3060 cannotBeUsedWithBitcode(arg
);
3062 else if ( strcmp(arg
, "-save-temps") == 0 ) {
3063 fSaveTempFiles
= true;
3065 else if ( strcmp(arg
, "-bitcode_hide_symbols") == 0 ) {
3066 fHideSymbols
= true;
3068 else if ( strcmp(arg
, "-bitcode_verify") == 0 ) {
3069 fVerifyBitcode
= true;
3071 else if ( strcmp(arg
, "-bitcode_symbol_map") == 0) {
3072 fReverseMapPath
= argv
[++i
];
3073 if ( fReverseMapPath
== NULL
)
3074 throw "missing argument to -bitcode_symbol_map";
3075 struct stat statbuf
;
3076 ::stat(fReverseMapPath
, &statbuf
);
3077 if (S_ISDIR(statbuf
.st_mode
)) {
3078 char tempPath
[PATH_MAX
];
3079 sprintf(tempPath
, "%s/XXXXXX", fReverseMapPath
);
3080 int tempFile
= ::mkstemp(tempPath
);
3082 throwf("could not write file to symbol map directory: %s", fReverseMapPath
);
3084 fReverseMapTempPath
= std::string(tempPath
);
3085 fReverseMapUUIDRename
= true;
3087 fReverseMapTempPath
= std::string(fReverseMapPath
);
3089 else if ( strcmp(argv
[i
], "-flto-codegen-only") == 0) {
3090 fLTOCodegenOnly
= true;
3092 else if ( strcmp(argv
[i
], "-ignore_auto_link") == 0) {
3093 fIgnoreAutoLink
= true;
3095 else if ( strcmp(argv
[i
], "-allow_dead_duplicates") == 0) {
3096 fAllowDeadDups
= true;
3098 else if ( strcmp(argv
[i
], "-bitcode_process_mode") == 0 ) {
3099 const char* bitcode_type
= argv
[++i
];
3100 if ( bitcode_type
== NULL
)
3101 throw "missing argument to -bitcode_process_mode";
3102 else if ( strcmp(bitcode_type
, "strip") == 0 )
3103 fBitcodeKind
= kBitcodeStrip
;
3104 else if ( strcmp(bitcode_type
, "marker") == 0 )
3105 fBitcodeKind
= kBitcodeMarker
;
3106 else if ( strcmp(bitcode_type
, "data") == 0 )
3107 fBitcodeKind
= kBitcodeAsData
;
3108 else if ( strcmp(bitcode_type
, "bitcode") == 0 )
3109 fBitcodeKind
= kBitcodeProcess
;
3111 throw "unknown argument to -bitcode_process_mode {strip,marker,data,bitcode}";
3113 else if ( strcmp(arg
, "-rpath") == 0 ) {
3114 const char* path
= argv
[++i
];
3116 throw "missing argument to -rpath";
3117 fRPaths
.push_back(path
);
3119 else if ( strcmp(arg
, "-read_only_stubs") == 0 ) {
3120 fReadOnlyx86Stubs
= true;
3122 else if ( strcmp(arg
, "-slow_stubs") == 0 ) {
3125 else if ( strcmp(arg
, "-map") == 0 ) {
3126 fMapPath
= argv
[++i
];
3127 if ( fMapPath
== NULL
)
3128 throw "missing argument to -map";
3130 else if ( strcmp(arg
, "-pie") == 0 ) {
3131 fPositionIndependentExecutable
= true;
3132 fPIEOnCommandLine
= true;
3134 else if ( strcmp(arg
, "-no_pie") == 0 ) {
3135 fDisablePositionIndependentExecutable
= true;
3136 cannotBeUsedWithBitcode(arg
);
3138 else if ( strncmp(arg
, "-reexport-l", 11) == 0 ) {
3139 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3140 snapshotArgCount
= 0;
3141 FileInfo info
= findLibrary(&arg
[11], true);
3142 info
.options
.fReExport
= true;
3143 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3145 cannotBeUsedWithBitcode(arg
);
3147 else if ( strcmp(arg
, "-reexport_library") == 0 ) {
3148 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3149 snapshotArgCount
= 0;
3150 FileInfo info
= findFile(argv
[++i
]);
3151 info
.options
.fReExport
= true;
3152 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3154 cannotBeUsedWithBitcode(arg
);
3156 else if ( strcmp(arg
, "-reexport_framework") == 0 ) {
3157 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3158 snapshotArgCount
= 0;
3159 FileInfo info
= findFramework(argv
[++i
]);
3160 info
.options
.fReExport
= true;
3161 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3163 cannotBeUsedWithBitcode(arg
);
3165 else if ( strncmp(arg
, "-upward-l", 9) == 0 ) {
3166 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3167 snapshotArgCount
= 0;
3168 FileInfo info
= findLibrary(&arg
[9], true);
3169 info
.options
.fUpward
= true;
3170 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3172 cannotBeUsedWithBitcode(arg
);
3174 else if ( strcmp(arg
, "-upward_library") == 0 ) {
3175 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3176 snapshotArgCount
= 0;
3177 FileInfo info
= findFile(argv
[++i
]);
3178 info
.options
.fUpward
= true;
3179 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3181 cannotBeUsedWithBitcode(arg
);
3183 else if ( strcmp(arg
, "-upward_framework") == 0 ) {
3184 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
3185 snapshotArgCount
= 0;
3186 FileInfo info
= findFramework(argv
[++i
]);
3187 info
.options
.fUpward
= true;
3188 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3190 cannotBeUsedWithBitcode(arg
);
3192 else if ( strcmp(arg
, "-dead_strip_dylibs") == 0 ) {
3193 fDeadStripDylibs
= true;
3194 cannotBeUsedWithBitcode(arg
);
3196 else if ( strcmp(arg
, "-no_implicit_dylibs") == 0 ) {
3197 fImplicitlyLinkPublicDylibs
= false;
3199 else if ( strcmp(arg
, "-new_linker") == 0 ) {
3202 else if ( strcmp(arg
, "-no_encryption") == 0 ) {
3203 fEncryptableForceOff
= true;
3204 cannotBeUsedWithBitcode(arg
);
3206 else if ( strcmp(arg
, "-encryptable") == 0 ) {
3207 fEncryptableForceOn
= true;
3208 cannotBeUsedWithBitcode(arg
);
3210 else if ( strcmp(arg
, "-no_compact_unwind") == 0 ) {
3211 fAddCompactUnwindEncoding
= false;
3212 cannotBeUsedWithBitcode(arg
);
3214 else if ( strcmp(arg
, "-mllvm") == 0 ) {
3215 const char* opts
= argv
[++i
];
3217 throw "missing argument to -mllvm";
3218 fLLVMOptions
.push_back(opts
);
3219 cannotBeUsedWithBitcode(arg
);
3221 else if ( strcmp(arg
, "-mcpu") == 0 ) {
3222 const char* cpu
= argv
[++i
];
3224 throw "missing argument to -mcpu";
3226 cannotBeUsedWithBitcode(arg
);
3228 else if ( strcmp(arg
, "-no_order_inits") == 0 ) {
3229 fAutoOrderInitializers
= false;
3230 cannotBeUsedWithBitcode(arg
);
3232 else if ( strcmp(arg
, "-no_order_data") == 0 ) {
3234 cannotBeUsedWithBitcode(arg
);
3236 else if ( strcmp(arg
, "-seg_page_size") == 0 ) {
3238 seg
.name
= argv
[++i
];
3239 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
3240 throw "-seg_page_size missing segName Adddress";
3241 seg
.size
= parseAddress(argv
[++i
]);
3242 uint64_t temp
= seg
.size
& (-4096); // page align
3243 if ( (seg
.size
!= temp
) )
3244 warning("-seg_page_size %s not 4K aligned, rounding down", seg
.name
);
3245 fCustomSegmentSizes
.push_back(seg
);
3246 cannotBeUsedWithBitcode(arg
);
3248 else if ( strcmp(arg
, "-mark_dead_strippable_dylib") == 0 ) {
3249 fMarkDeadStrippableDylib
= true;
3250 cannotBeUsedWithBitcode(arg
);
3252 else if ( strcmp(arg
, "-exported_symbols_order") == 0 ) {
3253 snapshotFileArgIndex
= 1;
3254 loadSymbolOrderFile(argv
[++i
], fExportSymbolsOrder
);
3255 cannotBeUsedWithBitcode(arg
);
3257 else if ( strcmp(arg
, "-no_compact_linkedit") == 0 ) {
3258 warnObsolete("-no_compact_linkedit");
3260 else if ( strcmp(arg
, "-no_eh_labels") == 0 ) {
3262 cannotBeUsedWithBitcode(arg
);
3264 else if ( strcmp(arg
, "-warn_compact_unwind") == 0 ) {
3265 fWarnCompactUnwind
= true;
3267 else if ( strcmp(arg
, "-allow_sub_type_mismatches") == 0 ) {
3268 fAllowCpuSubtypeMismatches
= true;
3269 cannotBeUsedWithBitcode(arg
);
3271 else if ( strcmp(arg
, "-no_zero_fill_sections") == 0 ) {
3272 fOptimizeZeroFill
= false;
3273 cannotBeUsedWithBitcode(arg
);
3275 else if ( strcmp(arg
, "-merge_zero_fill_sections") == 0 ) {
3276 fMergeZeroFill
= true;
3277 cannotBeUsedWithBitcode(arg
);
3279 else if ( strcmp(arg
, "-objc_abi_version") == 0 ) {
3280 const char* version
= argv
[++i
];
3281 if ( version
== NULL
)
3282 throw "-objc_abi_version missing version number";
3283 if ( strcmp(version
, "2") == 0 ) {
3284 fObjCABIVersion1Override
= false;
3285 fObjCABIVersion2Override
= true;
3287 else if ( strcmp(version
, "1") == 0 ) {
3288 fObjCABIVersion1Override
= true;
3289 fObjCABIVersion2Override
= false;
3292 warning("ignoring unrecognized argument (%s) to -objc_abi_version", version
);
3294 else if ( strcmp(arg
, "-warn_weak_exports") == 0 ) {
3295 fWarnWeakExports
= true;
3297 else if ( strcmp(arg
, "-objc_gc_compaction") == 0 ) {
3298 fObjcGcCompaction
= true;
3299 cannotBeUsedWithBitcode(arg
);
3301 else if ( strcmp(arg
, "-objc_gc") == 0 ) {
3303 if ( fObjCGcOnly
) {
3304 warning("-objc_gc overriding -objc_gc_only");
3305 fObjCGcOnly
= false;
3307 cannotBeUsedWithBitcode(arg
);
3309 else if ( strcmp(arg
, "-objc_gc_only") == 0 ) {
3312 warning("-objc_gc_only overriding -objc_gc");
3315 cannotBeUsedWithBitcode(arg
);
3317 else if ( strcmp(arg
, "-demangle") == 0 ) {
3320 else if ( strcmp(arg
, "-version_load_command") == 0 ) {
3321 fVersionLoadCommandForcedOn
= true;
3322 fVersionLoadCommandForcedOff
= false;
3324 else if ( strcmp(arg
, "-no_version_load_command") == 0 ) {
3325 fVersionLoadCommandForcedOff
= true;
3326 fVersionLoadCommandForcedOn
= false;
3327 cannotBeUsedWithBitcode(arg
);
3329 else if ( strcmp(arg
, "-function_starts") == 0 ) {
3330 fFunctionStartsForcedOn
= true;
3331 fFunctionStartsForcedOff
= false;
3333 else if ( strcmp(arg
, "-no_function_starts") == 0 ) {
3334 fFunctionStartsForcedOff
= true;
3335 fFunctionStartsForcedOn
= false;
3336 cannotBeUsedWithBitcode(arg
);
3338 else if ( strcmp(arg
, "-no_data_in_code_info") == 0 ) {
3339 fDataInCodeInfoLoadCommandForcedOff
= true;
3340 fDataInCodeInfoLoadCommandForcedOn
= false;
3341 cannotBeUsedWithBitcode(arg
);
3343 else if ( strcmp(arg
, "-data_in_code_info") == 0 ) {
3344 fDataInCodeInfoLoadCommandForcedOn
= true;
3345 fDataInCodeInfoLoadCommandForcedOff
= false;
3347 else if ( strcmp(arg
, "-object_path_lto") == 0 ) {
3348 fTempLtoObjectPath
= argv
[++i
];
3349 if ( fTempLtoObjectPath
== NULL
)
3350 throw "missing argument to -object_path_lto";
3352 else if ( strcmp(arg
, "-no_objc_category_merging") == 0 ) {
3353 fObjcCategoryMerging
= false;
3355 else if ( strcmp(arg
, "-force_symbols_weak_list") == 0 ) {
3356 snapshotFileArgIndex
= 1;
3357 loadExportFile(argv
[++i
], "-force_symbols_weak_list", fForceWeakSymbols
);
3358 cannotBeUsedWithBitcode(arg
);
3360 else if ( strcmp(arg
, "-force_symbols_not_weak_list") == 0 ) {
3361 snapshotFileArgIndex
= 1;
3362 loadExportFile(argv
[++i
], "-force_symbols_not_weak_list", fForceNotWeakSymbols
);
3363 cannotBeUsedWithBitcode(arg
);
3365 else if ( strcmp(arg
, "-force_symbol_weak") == 0 ) {
3366 const char* symbol
= argv
[++i
];
3367 if ( symbol
== NULL
)
3368 throw "-force_symbol_weak missing <symbol>";
3369 fForceWeakSymbols
.insert(symbol
);
3370 cannotBeUsedWithBitcode(arg
);
3372 else if ( strcmp(arg
, "-force_symbol_not_weak") == 0 ) {
3373 const char* symbol
= argv
[++i
];
3374 if ( symbol
== NULL
)
3375 throw "-force_symbol_not_weak missing <symbol>";
3376 fForceNotWeakSymbols
.insert(symbol
);
3377 cannotBeUsedWithBitcode(arg
);
3379 else if ( strcmp(arg
, "-reexported_symbols_list") == 0 ) {
3380 snapshotFileArgIndex
= 1;
3381 if ( fExportMode
== kExportSome
)
3382 throw "can't use -exported_symbols_list and -reexported_symbols_list";
3383 loadExportFile(argv
[++i
], "-reexported_symbols_list", fReExportSymbols
);
3385 else if ( strcmp(arg
, "-dyld_env") == 0 ) {
3386 const char* envarg
= argv
[++i
];
3387 if ( envarg
== NULL
)
3388 throw "-dyld_env missing ENV=VALUE";
3389 if ( strchr(envarg
, '=') == NULL
)
3390 throw "-dyld_env missing ENV=VALUE";
3391 fDyldEnvironExtras
.push_back(envarg
);
3392 cannotBeUsedWithBitcode(arg
);
3394 else if ( strcmp(arg
, "-page_align_data_atoms") == 0 ) {
3395 fPageAlignDataAtoms
= true;
3396 cannotBeUsedWithBitcode(arg
);
3398 else if (strcmp(arg
, "-debug_snapshot") == 0) {
3399 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3400 fSnapshotRequested
= true;
3401 cannotBeUsedWithBitcode(arg
);
3403 else if (strcmp(arg
, "-snapshot_dir") == 0) {
3404 const char* path
= argv
[++i
];
3406 throw "-snapshot_dir missing path";
3407 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3408 fLinkSnapshot
.setSnapshotPath(path
);
3409 fSnapshotRequested
= true;
3410 cannotBeUsedWithBitcode(arg
);
3412 else if ( strcmp(arg
, "-new_main") == 0 ) {
3413 fEntryPointLoadCommandForceOn
= true;
3414 cannotBeUsedWithBitcode(arg
);
3416 else if ( strcmp(arg
, "-no_new_main") == 0 ) {
3417 fEntryPointLoadCommandForceOff
= true;
3418 cannotBeUsedWithBitcode(arg
);
3420 else if ( strcmp(arg
, "-source_version") == 0 ) {
3421 const char* vers
= argv
[++i
];
3423 throw "-source_version missing <version>";
3424 fSourceVersion
= parseVersionNumber64(vers
);
3426 else if ( strcmp(arg
, "-add_source_version") == 0 ) {
3427 fSourceVersionLoadCommandForceOn
= true;
3429 else if ( strcmp(arg
, "-no_source_version") == 0 ) {
3430 fSourceVersionLoadCommandForceOff
= true;
3431 cannotBeUsedWithBitcode(arg
);
3433 else if ( strcmp(arg
, "-sdk_version") == 0 ) {
3434 const char* vers
= argv
[++i
];
3436 throw "-sdk_version missing <version>";
3437 fSDKVersion
= parseVersionNumber32(vers
);
3439 else if ( strcmp(arg
, "-dependent_dr_info") == 0 ) {
3442 else if ( strcmp(arg
, "-no_dependent_dr_info") == 0 ) {
3445 else if ( strcmp(arg
, "-kexts_use_stubs") == 0 ) {
3446 fKextsUseStubs
= true;
3447 cannotBeUsedWithBitcode(arg
);
3449 else if ( strcmp(argv
[i
], "-dependency_info") == 0 ) {
3450 snapshotArgCount
= 0;
3452 // previously handled by buildSearchPaths()
3454 else if ( strcmp(arg
, "-export_dynamic") == 0 ) {
3455 fExportDynamic
= true;
3457 else if ( strcmp(arg
, "-force_symbols_coalesce_list") == 0 ) {
3458 snapshotFileArgIndex
= 1;
3459 loadExportFile(argv
[++i
], "-force_symbols_coalesce_list", fForceCoalesceSymbols
);
3461 else if ( strcmp(arg
, "-add_linker_option") == 0 ) {
3462 // ex: -add_linker_option '-framework Foundation'
3463 const char* optString
= argv
[++i
];
3464 if ( optString
== NULL
)
3465 throw "-add_linker_option missing <option>";
3466 // break up into list of tokens at whitespace
3467 std::vector
<const char*> opts
;
3468 char* buffer
= strdup(optString
);
3469 char* start
= buffer
;
3470 for (char* s
= buffer
; ; ++s
) {
3471 if ( isspace(*s
) ) {
3473 opts
.push_back(start
);
3476 else if ( *s
== '\0' ) {
3477 opts
.push_back(start
);
3481 fLinkerOptions
.push_back(opts
);
3482 cannotBeUsedWithBitcode(arg
);
3484 else if ( strcmp(arg
, "-allow_simulator_linking_to_macosx_dylibs") == 0 ) {
3485 fAllowSimulatorToLinkWithMacOSX
= true;
3486 cannotBeUsedWithBitcode(arg
);
3488 else if ( strcmp(arg
, "-keep_dwarf_unwind") == 0 ) {
3489 fKeepDwarfUnwindForcedOn
= true;
3490 fKeepDwarfUnwindForcedOff
= false;
3491 cannotBeUsedWithBitcode(arg
);
3493 else if ( strcmp(arg
, "-no_keep_dwarf_unwind") == 0 ) {
3494 fKeepDwarfUnwindForcedOn
= false;
3495 fKeepDwarfUnwindForcedOff
= true;
3496 cannotBeUsedWithBitcode(arg
);
3498 else if ( strcmp(arg
, "-verbose_optimization_hints") == 0 ) {
3499 fVerboseOptimizationHints
= true;
3501 else if ( strcmp(arg
, "-ignore_optimization_hints") == 0 ) {
3502 fIgnoreOptimizationHints
= true;
3503 cannotBeUsedWithBitcode(arg
);
3505 else if ( strcmp(arg
, "-no_dtrace_dof") == 0 ) {
3506 fGenerateDtraceDOF
= false;
3508 else if ( strcmp(arg
, "-rename_section") == 0 ) {
3509 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) || (argv
[i
+4]==NULL
) )
3510 throw "-rename_section missing <segment> <section> <segment> <section>";
3511 addSectionRename(argv
[i
+1], argv
[i
+2], argv
[i
+3], argv
[i
+4]);
3513 cannotBeUsedWithBitcode(arg
);
3515 else if ( strcmp(arg
, "-rename_segment") == 0 ) {
3516 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3517 throw "-rename_segment missing <existing-segment> <new-segment>";
3518 addSegmentRename(argv
[i
+1], argv
[i
+2]);
3520 cannotBeUsedWithBitcode(arg
);
3522 else if ( strcmp(arg
, "-move_to_ro_segment") == 0 ) {
3523 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3524 throw "-move_to_ro_segment missing <segment> <symbol-list-file>";
3525 addSymbolMove(argv
[i
+1], argv
[i
+2], fSymbolsMovesCode
, "-move_to_ro_segment");
3527 cannotBeUsedWithBitcode(arg
);
3529 else if ( strcmp(arg
, "-move_to_rw_segment") == 0 ) {
3530 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3531 throw "-move_to_rw_segment missing <segment> <symbol-list-file>";
3532 addSymbolMove(argv
[i
+1], argv
[i
+2], fSymbolsMovesData
, "-move_to_rw_segment");
3534 cannotBeUsedWithBitcode(arg
);
3536 else if ( strcmp(arg
, "-trace_symbol_layout") == 0 ) {
3537 fTraceSymbolLayout
= true;
3539 else if ( strcmp(arg
, "-no_branch_islands") == 0 ) {
3540 fAllowBranchIslands
= false;
3541 cannotBeUsedWithBitcode(arg
);
3543 else if ( strcmp(arg
, "-segment_order") == 0 ) {
3544 // ex: -segment_order __TEXT:__DATA:__JUNK
3545 const char* optString
= argv
[++i
];
3546 if ( optString
== NULL
)
3547 throw "-segment_order missing colon separated <segment-list>";
3548 if ( !fSegmentOrder
.empty() )
3549 throw "-segment_order used more than once";
3550 // break up into list of tokens at colon
3551 char* buffer
= strdup(optString
);
3552 char* start
= buffer
;
3553 for (char* s
= buffer
; ; ++s
) {
3556 fSegmentOrder
.push_back(start
);
3559 else if ( *s
== '\0' ) {
3560 fSegmentOrder
.push_back(start
);
3564 cannotBeUsedWithBitcode(arg
);
3566 else if ( strcmp(arg
, "-section_order") == 0 ) {
3567 // ex: -section_order __DATA __data:__const:__nl_pointers
3568 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) )
3569 throw "-section_order missing <segment> <section-list>";
3570 const char* segName
= argv
[++i
];
3571 const char* optString
= argv
[++i
];
3572 if ( sectionOrder(segName
) != NULL
)
3573 throwf("-section_order %s ... used more than once", segName
);
3574 SectionOrderList dummy
;
3575 fSectionOrder
.push_back(dummy
);
3576 SectionOrderList
& entry
= fSectionOrder
.back();
3577 entry
.segmentName
= segName
;
3578 // break up into list of tokens at colon
3579 char* buffer
= strdup(optString
);
3580 char* start
= buffer
;
3581 for (char* s
= buffer
; ; ++s
) {
3584 entry
.sectionOrder
.push_back(start
);
3587 else if ( *s
== '\0' ) {
3588 entry
.sectionOrder
.push_back(start
);
3592 cannotBeUsedWithBitcode(arg
);
3594 else if ( strcmp(arg
, "-application_extension") == 0 ) {
3595 fMarkAppExtensionSafe
= true;
3596 fCheckAppExtensionSafe
= true;
3598 else if ( strcmp(arg
, "-no_application_extension") == 0 ) {
3599 fMarkAppExtensionSafe
= false;
3600 fCheckAppExtensionSafe
= false;
3602 else if ( strcmp(arg
, "-add_ast_path") == 0 ) {
3603 const char* path
= argv
[++i
];
3605 throw "-add_ast_path missing <option>";
3606 fASTFilePaths
.push_back(path
);
3608 else if ( strcmp(arg
, "-force_load_swift_libs") == 0 ) {
3609 fForceLoadSwiftLibs
= true;
3611 else if ( strcmp(arg
, "-not_for_dyld_shared_cache") == 0 ) {
3612 fSharedRegionEligibleForceOff
= true;
3613 cannotBeUsedWithBitcode(arg
);
3615 else if ( strcmp(arg
, "-dirty_data_list") == 0 ) {
3616 if ( argv
[i
+1] == NULL
)
3617 throw "-dirty_data_list missing <symbol-list-file>";
3618 addSymbolMove("__DATA_DIRTY", argv
[i
+1], fSymbolsMovesData
, "-dirty_data_list");
3620 cannotBeUsedWithBitcode(arg
);
3622 else if ( strcmp(arg
, "-data_const") == 0 ) {
3623 fUseDataConstSegmentForceOn
= true;
3624 cannotBeUsedWithBitcode(arg
);
3626 else if ( strcmp(arg
, "-no_data_const") == 0 ) {
3627 fUseDataConstSegmentForceOff
= true;
3628 cannotBeUsedWithBitcode(arg
);
3630 // put this last so that it does not interfer with other options starting with 'i'
3631 else if ( strncmp(arg
, "-i", 2) == 0 ) {
3632 const char* colon
= strchr(arg
, ':');
3633 if ( colon
== NULL
)
3634 throwf("unknown option: %s", arg
);
3635 Options::AliasPair pair
;
3636 char* temp
= new char[colon
-arg
];
3637 strlcpy(temp
, &arg
[2], colon
-arg
-1);
3638 pair
.realName
= &colon
[1];
3640 fAliases
.push_back(pair
);
3643 throwf("unknown option: %s", arg
);
3646 if (snapshotArgCount
== -1)
3647 snapshotArgCount
= i
-snapshotArgIndex
+1;
3648 if (snapshotArgCount
> 0)
3649 fLinkSnapshot
.addSnapshotLinkArg(snapshotArgIndex
, snapshotArgCount
, snapshotFileArgIndex
);
3652 FileInfo info
= findFile(arg
);
3653 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
3654 if ( strcmp(&info
.path
[strlen(info
.path
)-2], ".a") == 0 )
3657 fInputFiles
.push_back(info
);
3661 // if a -lazy option was used, implicitly link in lazydylib1.o
3662 if ( fUsingLazyDylibLinking
) {
3663 FileInfo info
= findLibrary("lazydylib1.o");
3664 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)argc
);
3668 if (fSnapshotRequested
)
3669 fLinkSnapshot
.createSnapshot();
3675 // -syslibroot <path> is used for SDK support.
3676 // The rule is that all search paths (both explicit and default) are
3677 // checked to see if they exist in the SDK. If so, that path is
3678 // replaced with the sdk prefixed path. If not, that search path
3679 // is used as is. If multiple -syslibroot options are specified
3680 // their directory structures are logically overlayed and files
3681 // from sdks specified earlier on the command line used before later ones.
3683 void Options::buildSearchPaths(int argc
, const char* argv
[])
3685 bool addStandardLibraryDirectories
= true;
3686 std::vector
<const char*> libraryPaths
;
3687 std::vector
<const char*> frameworkPaths
;
3688 libraryPaths
.reserve(10);
3689 frameworkPaths
.reserve(10);
3690 // scan through argv looking for -L, -F, -Z, and -syslibroot options
3691 for(int i
=0; i
< argc
; ++i
) {
3692 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') ) {
3693 const char* libSearchDir
= &argv
[i
][2];
3694 // Allow either "-L{path}" or "-L {path}".
3695 if (argv
[i
][2] == '\0') {
3696 // -L {path}. Make sure there is an argument following this.
3697 const char* path
= argv
[++i
];
3699 throw "-L missing argument";
3700 libSearchDir
= path
;
3702 if ( libSearchDir
[0] == '\0' )
3703 throw "-L must be immediately followed by a directory path (no space)";
3704 struct stat statbuf
;
3705 if ( stat(libSearchDir
, &statbuf
) == 0 ) {
3706 if ( statbuf
.st_mode
& S_IFDIR
)
3707 libraryPaths
.push_back(libSearchDir
);
3709 warning("path '%s' following -L not a directory", libSearchDir
);
3712 warning("directory not found for option '-L%s'", libSearchDir
);
3715 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') ) {
3716 const char* frameworkSearchDir
= &argv
[i
][2];
3717 // Allow either "-F{path}" or "-F {path}".
3718 if (argv
[i
][2] == '\0') {
3719 // -F {path}. Make sure there is an argument following this.
3720 const char* path
= argv
[++i
];
3722 throw "-F missing argument";
3723 frameworkSearchDir
= path
;
3725 if ( frameworkSearchDir
[0] == '\0' )
3726 throw "-F must be immediately followed by a directory path (no space)";
3727 struct stat statbuf
;
3728 if ( stat(frameworkSearchDir
, &statbuf
) == 0 ) {
3729 if ( statbuf
.st_mode
& S_IFDIR
)
3730 frameworkPaths
.push_back(frameworkSearchDir
);
3732 warning("path '%s' following -F not a directory", frameworkSearchDir
);
3735 warning("directory not found for option '-F%s'", frameworkSearchDir
);
3738 else if ( strcmp(argv
[i
], "-Z") == 0 )
3739 addStandardLibraryDirectories
= false;
3740 else if ( strcmp(argv
[i
], "-v") == 0 ) {
3742 extern const char ldVersionString
[];
3743 fprintf(stderr
, "%s", ldVersionString
);
3744 fprintf(stderr
, "configured to support archs: %s\n", ALL_SUPPORTED_ARCHS
);
3745 // if only -v specified, exit cleanly
3747 const char* ltoVers
= lto::version();
3748 if ( ltoVers
!= NULL
)
3749 fprintf(stderr
, "LTO support using: %s\n", ltoVers
);
3753 else if ( strcmp(argv
[i
], "-syslibroot") == 0 ) {
3754 const char* path
= argv
[++i
];
3756 throw "-syslibroot missing argument";
3757 fSDKPaths
.push_back(path
);
3759 else if ( strcmp(argv
[i
], "-search_paths_first") == 0 ) {
3760 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
3762 else if ( strcmp(argv
[i
], "-search_dylibs_first") == 0 ) {
3763 fLibrarySearchMode
= kSearchAllDirsForDylibsThenAllDirsForArchives
;
3765 else if ( strcmp(argv
[i
], "-w") == 0 ) {
3766 sEmitWarnings
= false;
3768 else if ( strcmp(argv
[i
], "-fatal_warnings") == 0 ) {
3769 sFatalWarnings
= true;
3771 else if ( strcmp(argv
[i
], "-dependency_info") == 0 ) {
3772 const char* path
= argv
[++i
];
3774 throw "-dependency_info missing <path>";
3775 fDependencyInfoPath
= path
;
3777 else if ( strcmp(argv
[i
], "-bitcode_bundle") == 0 ) {
3778 fBundleBitcode
= true;
3781 int standardLibraryPathsStartIndex
= libraryPaths
.size();
3782 int standardFrameworkPathsStartIndex
= frameworkPaths
.size();
3783 if ( addStandardLibraryDirectories
) {
3784 libraryPaths
.push_back("/usr/lib");
3785 libraryPaths
.push_back("/usr/local/lib");
3787 frameworkPaths
.push_back("/Library/Frameworks/");
3788 frameworkPaths
.push_back("/System/Library/Frameworks/");
3789 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
3792 // <rdar://problem/5829579> Support for configure based hacks
3793 // if last -syslibroot is /, then ignore all syslibroots
3794 if ( fSDKPaths
.size() > 0 ) {
3795 if ( strcmp(fSDKPaths
.back(), "/") == 0 ) {
3800 // now merge sdk and library paths to make real search paths
3801 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
3803 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); ++it
, ++libIndex
) {
3804 const char* libDir
= *it
;
3805 bool sdkOverride
= false;
3806 if ( libDir
[0] == '/' ) {
3807 char betterLibDir
[PATH_MAX
];
3808 if ( strstr(libDir
, "/..") != NULL
) {
3809 if ( realpath(libDir
, betterLibDir
) != NULL
)
3810 libDir
= strdup(betterLibDir
);
3812 const int libDirLen
= strlen(libDir
);
3813 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
3814 const char* sdkDir
= *sdkit
;
3815 const int sdkDirLen
= strlen(sdkDir
);
3816 char newPath
[libDirLen
+ sdkDirLen
+4];
3817 strcpy(newPath
, sdkDir
);
3818 if ( newPath
[sdkDirLen
-1] == '/' )
3819 newPath
[sdkDirLen
-1] = '\0';
3820 strcat(newPath
, libDir
);
3821 struct stat statBuffer
;
3822 if ( stat(newPath
, &statBuffer
) == 0 ) {
3823 fLibrarySearchPaths
.push_back(strdup(newPath
));
3828 if ( !sdkOverride
) {
3829 if ( (libIndex
>= standardLibraryPathsStartIndex
) && (fSDKPaths
.size() == 1) ) {
3830 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3831 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3834 fLibrarySearchPaths
.push_back(libDir
);
3839 // now merge sdk and framework paths to make real search paths
3840 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
3842 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); ++it
, ++frameIndex
) {
3843 const char* frameworkDir
= *it
;
3844 bool sdkOverride
= false;
3845 if ( frameworkDir
[0] == '/' ) {
3846 char betterFrameworkDir
[PATH_MAX
];
3847 if ( strstr(frameworkDir
, "/..") != NULL
) {
3848 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
3849 frameworkDir
= strdup(betterFrameworkDir
);
3851 const int frameworkDirLen
= strlen(frameworkDir
);
3852 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
3853 const char* sdkDir
= *sdkit
;
3854 const int sdkDirLen
= strlen(sdkDir
);
3855 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
3856 strcpy(newPath
, sdkDir
);
3857 if ( newPath
[sdkDirLen
-1] == '/' )
3858 newPath
[sdkDirLen
-1] = '\0';
3859 strcat(newPath
, frameworkDir
);
3860 struct stat statBuffer
;
3861 if ( stat(newPath
, &statBuffer
) == 0 ) {
3862 fFrameworkSearchPaths
.push_back(strdup(newPath
));
3867 if ( !sdkOverride
) {
3868 if ( (frameIndex
>= standardFrameworkPathsStartIndex
) && (fSDKPaths
.size() == 1) ) {
3869 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3870 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3873 fFrameworkSearchPaths
.push_back(frameworkDir
);
3879 fprintf(stderr
,"Library search paths:\n");
3880 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
3881 it
!= fLibrarySearchPaths
.end();
3883 fprintf(stderr
,"\t%s\n", *it
);
3884 fprintf(stderr
,"Framework search paths:\n");
3885 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
3886 it
!= fFrameworkSearchPaths
.end();
3888 fprintf(stderr
,"\t%s\n", *it
);
3892 // this is run before the command line is parsed
3893 void Options::parsePreCommandLineEnvironmentSettings()
3895 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
3896 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
3897 fTraceArchives
= true;
3899 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
3900 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
3901 fTraceDylibs
= true;
3902 fTraceIndirectDylibs
= true;
3905 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
3906 fTraceDylibSearching
= true;
3909 if (getenv("LD_PRINT_OPTIONS") != NULL
)
3910 fPrintOptions
= true;
3912 if (fTraceDylibs
|| fTraceArchives
)
3913 fTraceOutputFile
= getenv("LD_TRACE_FILE");
3915 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL
)
3916 fPrintOrderFileStatistics
= true;
3918 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL
)
3921 if (getenv("LD_NO_ENCRYPT") != NULL
) {
3922 fEncryptable
= false;
3923 fMarkAppExtensionSafe
= true; // temporary
3924 fCheckAppExtensionSafe
= false;
3927 if (getenv("LD_APPLICATION_EXTENSION_SAFE") != NULL
) {
3928 fMarkAppExtensionSafe
= true;
3929 fCheckAppExtensionSafe
= false;
3932 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL
)
3933 fAllowCpuSubtypeMismatches
= true;
3935 sWarningsSideFilePath
= getenv("LD_WARN_FILE");
3937 const char* customDyldPath
= getenv("LD_DYLD_PATH");
3938 if ( customDyldPath
!= NULL
)
3939 fDyldInstallPath
= customDyldPath
;
3941 const char* debugArchivePath
= getenv("LD_DEBUG_SNAPSHOT");
3942 if (debugArchivePath
!= NULL
) {
3943 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3944 if (strlen(debugArchivePath
) > 0)
3945 fLinkSnapshot
.setSnapshotPath(debugArchivePath
);
3946 fSnapshotRequested
= true;
3949 const char* pipeFdString
= getenv("LD_PIPELINE_FIFO");
3950 if (pipeFdString
!= NULL
) {
3951 fPipelineFifo
= pipeFdString
;
3956 // this is run after the command line is parsed
3957 void Options::parsePostCommandLineEnvironmentSettings()
3959 // when building a dynamic main executable, default any use of @executable_path to output path
3960 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
3961 fExecutablePath
= fOutputFile
;
3964 // allow build system to set default seg_addr_table
3965 if ( fSegAddrTablePath
== NULL
)
3966 fSegAddrTablePath
= getenv("LD_SEG_ADDR_TABLE");
3968 // allow build system to turn on prebinding
3970 fPrebind
= ( getenv("LD_PREBIND") != NULL
);
3973 // allow build system to force on dead-code-stripping
3974 if ( !fDeadStrip
) {
3975 if ( getenv("LD_DEAD_STRIP") != NULL
) {
3976 switch (fOutputKind
) {
3977 case Options::kDynamicLibrary
:
3978 case Options::kDynamicExecutable
:
3979 case Options::kDynamicBundle
:
3982 case Options::kPreload
:
3983 case Options::kObjectFile
:
3984 case Options::kDyld
:
3985 case Options::kStaticExecutable
:
3986 case Options::kKextBundle
:
3992 // allow build system to force on -warn_commons
3993 if ( getenv("LD_WARN_COMMONS") != NULL
)
3994 fWarnCommons
= true;
3996 // allow B&I to set default -source_version
3997 if ( fSourceVersion
== 0 ) {
3998 const char* vers
= getenv("RC_ProjectSourceVersion");
4000 fSourceVersion
= parseVersionNumber64(vers
);
4005 void Options::reconfigureDefaults()
4007 // sync reader options
4008 switch ( fOutputKind
) {
4009 case Options::kObjectFile
:
4010 fForFinalLinkedImage
= false;
4012 case Options::kDyld
:
4014 fForFinalLinkedImage
= true;
4017 case Options::kDynamicLibrary
:
4018 case Options::kDynamicBundle
:
4019 case Options::kKextBundle
:
4020 fForFinalLinkedImage
= true;
4023 case Options::kDynamicExecutable
:
4024 case Options::kStaticExecutable
:
4025 case Options::kPreload
:
4026 fLinkingMainExecutable
= true;
4027 fForFinalLinkedImage
= true;
4032 // set default min OS version
4033 if ( (fMacVersionMin
== ld::macVersionUnset
) && (fIOSVersionMin
== ld::iOSVersionUnset
) && (fWatchOSVersionMin
== ld::wOSVersionUnset
) ) {
4034 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
4035 const char* macVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
4036 const char* iPhoneVers
= getenv("IPHONEOS_DEPLOYMENT_TARGET");
4037 const char* iOSVers
= getenv("IOS_DEPLOYMENT_TARGET");
4038 const char* wOSVers
= getenv("WATCHOS_DEPLOYMENT_TARGET");
4039 if ( macVers
!= NULL
)
4040 setMacOSXVersionMin(macVers
);
4041 else if ( iPhoneVers
!= NULL
)
4042 setIOSVersionMin(iPhoneVers
);
4043 else if ( iOSVers
!= NULL
)
4044 setIOSVersionMin(iOSVers
);
4045 else if ( wOSVers
!= NULL
)
4046 setWatchOSVersionMin(wOSVers
);
4048 // if still nothing, set default based on architecture
4049 switch ( fArchitecture
) {
4051 case CPU_TYPE_X86_64
:
4052 if ( (fOutputKind
!= Options::kObjectFile
) && (fOutputKind
!= Options::kPreload
) ) {
4053 #ifdef DEFAULT_MACOSX_MIN_VERSION
4054 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
4055 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
4057 warning("-macosx_version_min not specified, assuming 10.6");
4058 setMacOSXVersionMin("10.6");
4063 if ( (fOutputKind
!= Options::kObjectFile
) && (fOutputKind
!= Options::kPreload
) ) {
4064 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
4065 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION
);
4066 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION
);
4068 if ( fSubArchitecture
== CPU_SUBTYPE_ARM_V7K
) {
4069 warning("-watchos_version_min not specified, assuming 2.0");
4070 setWatchOSVersionMin("2.0");
4073 warning("-ios_version_min not specified, assuming 6.0");
4074 setIOSVersionMin("6.0");
4080 // architecture will be infered later by examining .o files
4087 // adjust min based on architecture
4088 switch ( fArchitecture
) {
4090 if ( (fPlatform
== kPlatformOSX
) && (fMacVersionMin
< ld::mac10_4
) ) {
4091 //warning("-macosx_version_min should be 10.4 or later for i386");
4092 fMacVersionMin
= ld::mac10_4
;
4095 case CPU_TYPE_X86_64
:
4096 if ( (fPlatform
== kPlatformOSX
) && (fMacVersionMin
< ld::mac10_4
) ) {
4097 //warning("-macosx_version_min should be 10.4 or later for x86_64");
4098 fMacVersionMin
= ld::mac10_4
;
4101 case CPU_TYPE_ARM64
:
4102 if ( (fPlatform
== kPlatformiOS
) && (fIOSVersionMin
< ld::iOS_7_0
) ) {
4103 //warning("-mios_version_min should be 7.0 or later for arm64");
4104 fIOSVersionMin
= ld::iOS_7_0
;
4109 // default to adding functions start for dynamic code, static code must opt-in
4110 switch ( fOutputKind
) {
4111 case Options::kPreload
:
4112 case Options::kStaticExecutable
:
4113 case Options::kKextBundle
:
4114 if ( fDataInCodeInfoLoadCommandForcedOn
)
4115 fDataInCodeInfoLoadCommand
= true;
4116 if ( fFunctionStartsForcedOn
)
4117 fFunctionStartsLoadCommand
= true;
4119 case Options::kObjectFile
:
4120 if ( !fDataInCodeInfoLoadCommandForcedOff
)
4121 fDataInCodeInfoLoadCommand
= true;
4122 if ( fFunctionStartsForcedOn
)
4123 fFunctionStartsLoadCommand
= true;
4125 case Options::kDynamicExecutable
:
4126 case Options::kDyld
:
4127 case Options::kDynamicLibrary
:
4128 case Options::kDynamicBundle
:
4129 if ( !fDataInCodeInfoLoadCommandForcedOff
)
4130 fDataInCodeInfoLoadCommand
= true;
4131 if ( !fFunctionStartsForcedOff
)
4132 fFunctionStartsLoadCommand
= true;
4136 // adjust kext type based on architecture
4137 if ( fOutputKind
== kKextBundle
) {
4138 switch ( fArchitecture
) {
4139 case CPU_TYPE_X86_64
:
4140 // x86_64 uses new MH_KEXT_BUNDLE type
4141 fMakeCompressedDyldInfo
= false;
4142 fMakeCompressedDyldInfoForceOff
= true;
4143 fAllowTextRelocs
= true;
4144 fUndefinedTreatment
= kUndefinedDynamicLookup
;
4146 case CPU_TYPE_ARM64
:
4147 // arm64 uses new MH_KEXT_BUNDLE type
4148 fMakeCompressedDyldInfo
= false;
4149 fMakeCompressedDyldInfoForceOff
= true;
4150 fAllowTextRelocs
= false;
4151 fKextsUseStubs
= true;
4152 fUndefinedTreatment
= kUndefinedDynamicLookup
;
4155 if ( min_iOS(ld::iOS_5_0
) ) {
4156 // iOS 5.0 and later use new MH_KEXT_BUNDLE type
4157 fMakeCompressedDyldInfo
= false;
4158 fMakeCompressedDyldInfoForceOff
= true;
4159 // kexts are PIC in iOS 6.0 and later
4160 fAllowTextRelocs
= !min_iOS(ld::iOS_6_0
);
4161 fKextsUseStubs
= !fAllowTextRelocs
;
4162 fUndefinedTreatment
= kUndefinedDynamicLookup
;
4165 // else use object file
4168 fOutputKind
= kObjectFile
;
4173 // disable implicit dylibs when targeting 10.3
4174 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
4175 if ( !minOS(ld::mac10_4
, ld::iOS_2_0
) )
4176 fImplicitlyLinkPublicDylibs
= false;
4179 // allow build system to force linker to ignore -prebind
4180 if ( getenv("LD_FORCE_NO_PREBIND") != NULL
)
4183 // allow build system to force linker to ignore -seg_addr_table
4184 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL
)
4185 fSegAddrTablePath
= NULL
;
4187 // check for base address specified externally
4188 if ( (fSegAddrTablePath
!= NULL
) && (fOutputKind
== Options::kDynamicLibrary
) ) {
4189 parseSegAddrTable(fSegAddrTablePath
, this->installPath());
4190 // HACK to support seg_addr_table entries that are physical paths instead of install paths
4191 if ( fBaseAddress
== 0 ) {
4192 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
4193 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.4.dylib");
4194 if ( fBaseAddress
== 0 )
4195 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.9.dylib");
4198 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
4199 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libz.1.2.3.dylib");
4201 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
4202 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libutil1.0.dylib");
4206 // split segs only allowed for dylibs
4208 // split seg only supported for i386, and arm.
4209 switch ( fArchitecture
) {
4211 if ( fOutputKind
!= Options::kDynamicLibrary
)
4213 // make sure read and write segments are proper distance apart
4214 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x10000000) )
4215 fBaseWritableAddress
= fBaseAddress
+ 0x10000000;
4218 if ( fOutputKind
!= Options::kDynamicLibrary
) {
4222 // make sure read and write segments are proper distance apart
4223 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x08000000) )
4224 fBaseWritableAddress
= fBaseAddress
+ 0x08000000;
4230 fBaseWritableAddress
= 0;
4234 // set too-large size
4235 switch ( fArchitecture
) {
4237 fMaxAddress
= 0xFFFFFFFF;
4239 case CPU_TYPE_X86_64
:
4242 switch ( fOutputKind
) {
4243 case Options::kDynamicExecutable
:
4244 case Options::kDynamicLibrary
:
4245 case Options::kDynamicBundle
:
4246 // user land code is limited to low 1GB
4247 fMaxAddress
= 0x2FFFFFFF;
4249 case Options::kStaticExecutable
:
4250 case Options::kObjectFile
:
4251 case Options::kDyld
:
4252 case Options::kPreload
:
4253 case Options::kKextBundle
:
4254 fMaxAddress
= 0xFFFFFFFF;
4257 // range check -seg1addr for ARM
4258 if ( fBaseAddress
> fMaxAddress
) {
4259 warning("ignoring -seg1addr 0x%08llX. Address out of range.", fBaseAddress
);
4265 // <rdar://problem/6138961> -r implies no prebinding for all architectures
4266 if ( fOutputKind
== Options::kObjectFile
)
4269 // disable prebinding depending on arch and min OS version
4271 switch ( fArchitecture
) {
4273 if ( fMacVersionMin
== ld::mac10_4
) {
4274 // in 10.4 only split seg dylibs are prebound
4275 if ( (fOutputKind
!= Options::kDynamicLibrary
) || ! fSplitSegs
)
4278 else if ( fMacVersionMin
>= ld::mac10_5
) {
4279 // in 10.5 nothing is prebound
4282 else if ( fIOSVersionMin
!= ld::iOSVersionUnset
) {
4283 // nothing in simulator is prebound
4287 // in 10.3 and earlier only dylibs and main executables could be prebound
4288 switch ( fOutputKind
) {
4289 case Options::kDynamicExecutable
:
4290 case Options::kDynamicLibrary
:
4291 // only main executables and dylibs can be prebound
4293 case Options::kStaticExecutable
:
4294 case Options::kDynamicBundle
:
4295 case Options::kObjectFile
:
4296 case Options::kDyld
:
4297 case Options::kPreload
:
4298 case Options::kKextBundle
:
4299 // disable prebinding for everything else
4305 case CPU_TYPE_X86_64
:
4309 switch ( fOutputKind
) {
4310 case Options::kDynamicExecutable
:
4311 case Options::kDynamicLibrary
:
4312 // only main executables and dylibs can be prebound
4314 case Options::kStaticExecutable
:
4315 case Options::kDynamicBundle
:
4316 case Options::kObjectFile
:
4317 case Options::kDyld
:
4318 case Options::kPreload
:
4319 case Options::kKextBundle
:
4320 // disable prebinding for everything else
4328 // only prebound images can be split-seg
4329 if ( fSplitSegs
&& !fPrebind
)
4332 // determine if info for shared region should be added
4333 if ( fOutputKind
== Options::kDynamicLibrary
) {
4334 if ( minOS(ld::mac10_5
, ld::iOS_3_1
) )
4335 if ( !fPrebind
&& !fSharedRegionEligibleForceOff
)
4336 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
4337 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
4338 fSharedRegionEligible
= true;
4340 else if ( fOutputKind
== Options::kDyld
) {
4341 // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
4342 fSharedRegionEligible
= true;
4345 // <rdar://problem/18719327> warn if -rpath is used with OS dylibs
4346 if ( fSharedRegionEligible
&& !fRPaths
.empty() )
4347 warning("-rpath cannot be used with dylibs that will be in the dyld shared cache");
4349 // automatically use __DATA_CONST in iOS dylibs
4350 if ( fSharedRegionEligible
&& minOS(ld::mac10_Future
, ld::iOS_9_0
) && !fUseDataConstSegmentForceOff
) {
4351 fUseDataConstSegment
= true;
4353 if ( fUseDataConstSegmentForceOn
) {
4354 fUseDataConstSegment
= true;
4356 if ( fUseDataConstSegment
) {
4357 addSectionRename("__DATA", "__got", "__DATA_CONST", "__got");
4358 addSectionRename("__DATA", "__la_symbol_ptr", "__DATA_CONST", "__la_symbol_ptr");
4359 addSectionRename("__DATA", "__nl_symbol_ptr", "__DATA_CONST", "__nl_symbol_ptr");
4360 addSectionRename("__DATA", "__const", "__DATA_CONST", "__const");
4361 addSectionRename("__DATA", "__cfstring", "__DATA_CONST", "__cfstring");
4362 addSectionRename("__DATA", "__mod_init_func", "__DATA_CONST", "__mod_init_func");
4363 addSectionRename("__DATA", "__mod_term_func", "__DATA_CONST", "__mod_term_func");
4364 addSectionRename("__DATA", "__objc_classlist", "__DATA_CONST", "__objc_classlist");
4365 addSectionRename("__DATA", "__objc_nlclslist", "__DATA_CONST", "__objc_nlclslist");
4366 addSectionRename("__DATA", "__objc_catlist", "__DATA_CONST", "__objc_catlist");
4367 addSectionRename("__DATA", "__objc_nlcatlist", "__DATA_CONST", "__objc_nlcatlist");
4368 addSectionRename("__DATA", "__objc_protolist", "__DATA_CONST", "__objc_protolist");
4369 addSectionRename("__DATA", "__objc_imageinfo", "__DATA_CONST", "__objc_imageinfo");
4370 addSectionRename("__DATA", "__objc_const", "__DATA_CONST", "__objc_const");
4373 // Use V2 shared cache info when targetting newer OSs
4374 if ( fSharedRegionEligible
&& minOS(ld::mac10_Future
, ld::iOS_9_0
)) {
4375 fSharedRegionEncodingV2
= true;
4376 fIgnoreOptimizationHints
= true;
4379 // figure out if module table is needed for compatibility with old ld/dyld
4380 if ( fOutputKind
== Options::kDynamicLibrary
) {
4381 switch ( fArchitecture
) {
4383 if ( fIOSVersionMin
!= ld::iOSVersionUnset
) // simulator never needs modules
4387 fNeedsModuleTable
= true; // redo_prebinding requires a module table
4392 // <rdar://problem/5366363> -r -x implies -S
4393 if ( (fOutputKind
== Options::kObjectFile
) && (fLocalSymbolHandling
== kLocalSymbolsNone
) )
4394 fDebugInfoStripping
= Options::kDebugInfoNone
;
4396 // <rdar://problem/15252891> -r implies -no_uuid
4397 if ( fOutputKind
== Options::kObjectFile
)
4398 fUUIDMode
= kUUIDNone
;
4400 // choose how to process unwind info
4401 switch ( fArchitecture
) {
4403 case CPU_TYPE_X86_64
:
4404 case CPU_TYPE_ARM64
:
4405 switch ( fOutputKind
) {
4406 case Options::kObjectFile
:
4407 case Options::kStaticExecutable
:
4408 case Options::kPreload
:
4409 case Options::kKextBundle
:
4410 fAddCompactUnwindEncoding
= false;
4412 case Options::kDyld
:
4413 case Options::kDynamicLibrary
:
4414 case Options::kDynamicBundle
:
4415 case Options::kDynamicExecutable
:
4416 //if ( fAddCompactUnwindEncoding && (fVersionMin >= ld::mac10_6) )
4417 // fRemoveDwarfUnwindIfCompactExists = true;
4422 if ( armUsesZeroCostExceptions() ) {
4423 switch ( fOutputKind
) {
4424 case Options::kObjectFile
:
4425 case Options::kStaticExecutable
:
4426 case Options::kPreload
:
4427 case Options::kKextBundle
:
4428 fAddCompactUnwindEncoding
= false;
4430 case Options::kDyld
:
4431 case Options::kDynamicLibrary
:
4432 case Options::kDynamicBundle
:
4433 case Options::kDynamicExecutable
:
4434 fAddCompactUnwindEncoding
= true;
4439 fAddCompactUnwindEncoding
= false;
4440 fRemoveDwarfUnwindIfCompactExists
= false;
4444 // if -arch is missing, assume we don't want compact unwind info
4445 fAddCompactUnwindEncoding
= false;
4449 // only iOS executables should be encryptable
4450 switch ( fOutputKind
) {
4451 case Options::kObjectFile
:
4452 case Options::kDyld
:
4453 case Options::kStaticExecutable
:
4454 case Options::kPreload
:
4455 case Options::kKextBundle
:
4456 fEncryptable
= false;
4458 case Options::kDynamicExecutable
:
4460 case Options::kDynamicLibrary
:
4461 case Options::kDynamicBundle
:
4462 // <rdar://problem/16293398> Add LC_ENCRYPTION_INFO load command to bundled frameworks
4463 if ( !min_iOS(ld::iOS_7_0
) )
4464 fEncryptable
= false;
4467 if ( (fArchitecture
!= CPU_TYPE_ARM
) && (fArchitecture
!= CPU_TYPE_ARM64
) )
4468 fEncryptable
= false;
4469 if ( fEncryptableForceOn
)
4470 fEncryptable
= true;
4471 else if ( fEncryptableForceOff
)
4472 fEncryptable
= false;
4474 // don't move inits in dyld because dyld wants certain
4475 // entries point at stable locations at the start of __text
4476 if ( fOutputKind
== Options::kDyld
)
4477 fAutoOrderInitializers
= false;
4480 // disable __data ordering for some output kinds
4481 switch ( fOutputKind
) {
4482 case Options::kObjectFile
:
4483 case Options::kDyld
:
4484 case Options::kStaticExecutable
:
4485 case Options::kPreload
:
4486 case Options::kKextBundle
:
4489 case Options::kDynamicExecutable
:
4490 case Options::kDynamicLibrary
:
4491 case Options::kDynamicBundle
:
4495 // only use compressed LINKEDIT for final linked images
4496 switch ( fOutputKind
) {
4497 case Options::kDynamicExecutable
:
4498 case Options::kDynamicLibrary
:
4499 case Options::kDynamicBundle
:
4501 case Options::kPreload
:
4502 case Options::kStaticExecutable
:
4503 case Options::kObjectFile
:
4504 case Options::kDyld
:
4505 case Options::kKextBundle
:
4506 fMakeCompressedDyldInfoForceOff
= true;
4509 if ( fMakeCompressedDyldInfoForceOff
)
4510 fMakeCompressedDyldInfo
= false;
4513 // only use compressed LINKEDIT for:
4514 // Mac OS X 10.6 or later
4516 if ( fMakeCompressedDyldInfo
) {
4517 if ( !minOS(ld::mac10_6
, ld::iOS_3_1
) )
4518 fMakeCompressedDyldInfo
= false;
4521 // only ARM and x86_64 enforces that cpu-sub-types must match
4522 switch ( fArchitecture
) {
4524 case CPU_TYPE_X86_64
:
4527 case CPU_TYPE_ARM64
:
4528 fAllowCpuSubtypeMismatches
= true;
4533 // only final linked images can not optimize zero fill sections
4534 if ( fOutputKind
== Options::kObjectFile
)
4535 fOptimizeZeroFill
= true;
4537 // all undefines in -r mode
4538 // if ( fOutputKind == Options::kObjectFile )
4539 // fUndefinedTreatment = kUndefinedSuppress;
4541 // only dynamic final linked images should warn about use of commmons
4542 if ( fWarnCommons
) {
4543 switch ( fOutputKind
) {
4544 case Options::kDynamicExecutable
:
4545 case Options::kDynamicLibrary
:
4546 case Options::kDynamicBundle
:
4548 case Options::kPreload
:
4549 case Options::kStaticExecutable
:
4550 case Options::kObjectFile
:
4551 case Options::kDyld
:
4552 case Options::kKextBundle
:
4553 fWarnCommons
= false;
4558 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
4559 if ( minOS(ld::mac10_5
, ld::iOS_2_0
) )
4560 fUseSimplifiedDylibReExports
= true;
4562 // Mac OS X 10.7 and iOS 4.2 support LC_LOAD_UPWARD_DYLIB
4563 if ( minOS(ld::mac10_7
, ld::iOS_4_2
) && (fOutputKind
== kDynamicLibrary
) )
4564 fCanUseUpwardDylib
= true;
4566 // MacOSX 10.7 defaults to PIE
4567 if ( ((fArchitecture
== CPU_TYPE_X86_64
) || (fArchitecture
== CPU_TYPE_I386
))
4568 && (fOutputKind
== kDynamicExecutable
)
4569 && (fMacVersionMin
>= ld::mac10_7
) ) {
4570 fPositionIndependentExecutable
= true;
4573 // armv7 for iOS4.3 defaults to PIE
4574 if ( (fArchitecture
== CPU_TYPE_ARM
)
4575 && fArchSupportsThumb2
4576 && (fOutputKind
== kDynamicExecutable
)
4577 && min_iOS(ld::iOS_4_3
) ) {
4578 fPositionIndependentExecutable
= true;
4581 // Simulator defaults to PIE
4582 if ( fTargetIOSSimulator
&& (fOutputKind
== kDynamicExecutable
) )
4583 fPositionIndependentExecutable
= true;
4585 // -no_pie anywhere on command line disable PIE
4586 if ( fDisablePositionIndependentExecutable
)
4587 fPositionIndependentExecutable
= false;
4589 // arm64 is always PIE
4590 if ( (fArchitecture
== CPU_TYPE_ARM64
) && (fOutputKind
== kDynamicExecutable
) ) {
4591 fPositionIndependentExecutable
= true;
4594 // set fOutputSlidable
4595 switch ( fOutputKind
) {
4596 case Options::kObjectFile
:
4597 fOutputSlidable
= false;
4599 case Options::kStaticExecutable
:
4600 case Options::kDynamicExecutable
:
4601 fOutputSlidable
= fPositionIndependentExecutable
;
4603 case Options::kPreload
:
4604 fOutputSlidable
= fPIEOnCommandLine
;
4606 case Options::kDyld
:
4607 case Options::kDynamicLibrary
:
4608 case Options::kDynamicBundle
:
4609 case Options::kKextBundle
:
4610 fOutputSlidable
= true;
4614 // let linker know if thread local variables are supported
4615 if ( fMacVersionMin
>= ld::mac10_7
) {
4618 else if ( (fArchitecture
== CPU_TYPE_ARM64
) && min_iOS(ld::iOS_8_0
) ) {
4621 else if ( (fArchitecture
== CPU_TYPE_ARM
) && min_iOS(ld::iOS_9_0
) ) {
4625 // default to adding version load command for dynamic code, static code must opt-in
4626 switch ( fOutputKind
) {
4627 case Options::kObjectFile
:
4628 fVersionLoadCommand
= false;
4630 case Options::kStaticExecutable
:
4631 case Options::kPreload
:
4632 case Options::kKextBundle
:
4633 if ( fVersionLoadCommandForcedOn
)
4634 fVersionLoadCommand
= true;
4636 case Options::kDynamicExecutable
:
4637 case Options::kDyld
:
4638 case Options::kDynamicLibrary
:
4639 case Options::kDynamicBundle
:
4640 if ( !fVersionLoadCommandForcedOff
)
4641 fVersionLoadCommand
= true;
4645 // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
4646 if ( (fOutputKind
== kDynamicLibrary
) && minOS(ld::mac10_7
, ld::iOS_4_2
) )
4647 fCanReExportSymbols
= true;
4649 // ObjC optimization is only in dynamic final linked images
4650 switch ( fOutputKind
) {
4651 case Options::kObjectFile
:
4652 case Options::kStaticExecutable
:
4653 case Options::kPreload
:
4654 case Options::kKextBundle
:
4655 case Options::kDyld
:
4656 fObjcCategoryMerging
= false;
4658 case Options::kDynamicExecutable
:
4659 case Options::kDynamicLibrary
:
4660 case Options::kDynamicBundle
:
4664 // i386 main executables linked on Mac OS X 10.7 default to NX heap
4665 // regardless of target unless overriden with -allow_heap_execute anywhere
4666 // on the command line
4667 if ( (fArchitecture
== CPU_TYPE_I386
) && (fOutputKind
== kDynamicExecutable
) && !fDisableNonExecutableHeap
)
4668 fNonExecutableHeap
= true;
4670 // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
4671 switch ( fOutputKind
) {
4672 case Options::kDynamicExecutable
:
4673 if ( fEntryPointLoadCommandForceOn
) {
4674 fEntryPointLoadCommand
= true;
4675 if ( fEntryName
== NULL
)
4676 fEntryName
= "_main";
4678 else if ( fEntryPointLoadCommandForceOff
) {
4679 fNeedsThreadLoadCommand
= true;
4680 if ( fEntryName
== NULL
)
4681 fEntryName
= "start";
4684 // <rdar://problem/16310363> Linker should look for "_main" not "start" when building for sim regardless of min OS
4685 if ( minOS(ld::mac10_8
, ld::iOS_6_0
) || fTargetIOSSimulator
) {
4686 fEntryPointLoadCommand
= true;
4687 if ( fEntryName
== NULL
)
4688 fEntryName
= "_main";
4689 if ( strcmp(fEntryName
, "start") == 0 ) {
4690 warning("Ignoring '-e start' because entry point 'start' is not used for the targeted OS version");
4691 fEntryName
= "_main";
4695 fNeedsThreadLoadCommand
= true;
4696 if ( fEntryName
== NULL
)
4697 fEntryName
= "start";
4701 case Options::kObjectFile
:
4702 case Options::kKextBundle
:
4703 case Options::kDynamicLibrary
:
4704 case Options::kDynamicBundle
:
4707 case Options::kStaticExecutable
:
4708 case Options::kPreload
:
4709 case Options::kDyld
:
4710 fNeedsThreadLoadCommand
= true;
4711 if ( fEntryName
== NULL
)
4712 fEntryName
= "start"; // Perhaps these should have no default and require -e
4716 // add LC_SOURCE_VERSION
4717 switch ( fOutputKind
) {
4718 case Options::kDynamicExecutable
:
4719 case Options::kKextBundle
:
4720 case Options::kDynamicLibrary
:
4721 case Options::kDynamicBundle
:
4722 case Options::kDyld
:
4723 case Options::kStaticExecutable
:
4724 if ( fSourceVersionLoadCommandForceOn
) {
4725 fSourceVersionLoadCommand
= true;
4727 else if ( fSourceVersionLoadCommandForceOff
) {
4728 fSourceVersionLoadCommand
= false;
4731 if ( minOS(ld::mac10_8
, ld::iOS_6_0
) ) {
4732 fSourceVersionLoadCommand
= true;
4735 fSourceVersionLoadCommand
= false;
4738 case Options::kObjectFile
:
4739 case Options::kPreload
:
4740 fSourceVersionLoadCommand
= false;
4744 // if -sdk_version not on command line, infer from -syslibroot
4745 if ( (fSDKVersion
== 0) && (fSDKPaths
.size() > 0) ) {
4746 const char* sdkPath
= fSDKPaths
.front();
4747 const char* end
= &sdkPath
[strlen(sdkPath
)-1];
4748 while ( !isdigit(*end
) && (end
> sdkPath
) )
4750 const char* start
= end
-1;
4751 while ( (isdigit(*start
) || (*start
== '.')) && (start
> sdkPath
))
4753 char sdkVersionStr
[32];
4754 int len
= end
-start
+1;
4756 strlcpy(sdkVersionStr
, start
+1, len
);
4757 fSDKVersion
= parseVersionNumber32(sdkVersionStr
);
4761 // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
4762 if ( (fSDKVersion
== 0) && (fMacVersionMin
!= ld::macVersionUnset
) ) {
4763 // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
4764 if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
4765 fSDKVersion
= fMacVersionMin
;
4768 int mib
[2] = { CTL_KERN
, KERN_OSRELEASE
};
4769 char kernVersStr
[100];
4770 size_t strlen
= sizeof(kernVersStr
);
4771 if ( sysctl(mib
, 2, kernVersStr
, &strlen
, NULL
, 0) != -1 ) {
4772 uint32_t kernVers
= parseVersionNumber32(kernVersStr
);
4773 int minor
= (kernVers
>> 16) - 4; // kernel major version is 4 ahead of x in 10.x
4774 fSDKVersion
= 0x000A0000 + (minor
<< 8);
4779 // allow trie based absolute symbols if targeting new enough OS
4780 if ( fMakeCompressedDyldInfo
) {
4781 if ( minOS(ld::mac10_9
, ld::iOS_7_0
) ) {
4782 fAbsoluteSymbols
= true;
4786 // <rdar://problem/12959510> iOS main executables now default to 16KB page size
4787 if ( (fIOSVersionMin
!= ld::iOSVersionUnset
) && (fOutputKind
== Options::kDynamicExecutable
) ) {
4788 // <rdar://problem/13070042> Only third party apps should have 16KB page segments by default
4789 if ( fEncryptable
) {
4790 if ( fSegmentAlignment
== 4096 )
4791 fSegmentAlignment
= 4096*4;
4795 // <rdar://problem/12258065> ARM64 needs 16KB page size for user land code
4796 // <rdar://problem/15974532> make armv7[s] use 16KB pages in user land code for iOS 8 or later
4797 if ( fSegmentAlignment
== 4096 ) {
4798 switch ( fOutputKind
) {
4799 case Options::kDynamicExecutable
:
4800 case Options::kDynamicLibrary
:
4801 case Options::kDynamicBundle
:
4802 case Options::kDyld
:
4803 if ( (fArchitecture
== CPU_TYPE_ARM64
)
4804 || ((fArchitecture
== CPU_TYPE_ARM
) && min_iOS(ld::iOS_7_0
)) ) {
4805 fSegmentAlignment
= 4096*4;
4808 case Options::kStaticExecutable
:
4809 case Options::kKextBundle
:
4810 // <rdar://problem/14676611> 16KB segments for arm64 kexts
4811 if ( (fArchitecture
== CPU_TYPE_ARM64
) && min_iOS(ld::iOS_9_0
) ) {
4812 fSegmentAlignment
= 4096*4;
4815 case Options::kObjectFile
:
4816 case Options::kPreload
:
4823 // <rdar://problem/13624134> linker should not convert dwarf unwind if .o file has compact unwind section
4824 switch ( fOutputKind
) {
4825 case Options::kDynamicExecutable
:
4826 case Options::kDynamicLibrary
:
4827 case Options::kDynamicBundle
:
4828 case Options::kDyld
:
4829 if ( fKeepDwarfUnwindForcedOn
) {
4830 fKeepDwarfUnwind
= true;
4832 else if ( fKeepDwarfUnwindForcedOff
) {
4833 fKeepDwarfUnwind
= false;
4836 if ( minOS(ld::mac10_9
, ld::iOS_7_0
) )
4837 fKeepDwarfUnwind
= false;
4839 fKeepDwarfUnwind
= true;
4842 case Options::kKextBundle
:
4843 case Options::kStaticExecutable
:
4844 case Options::kObjectFile
:
4845 case Options::kPreload
:
4846 fKeepDwarfUnwind
= true;
4850 // Make sure -image_base matches alignment
4851 uint64_t alignedBaseAddress
= (fBaseAddress
+fSegmentAlignment
-1) & (-fSegmentAlignment
);
4852 if ( alignedBaseAddress
!= fBaseAddress
) {
4853 warning("base address 0x%llX is not properly aligned. Changing it to 0x%llX", fBaseAddress
, alignedBaseAddress
);
4854 fBaseAddress
= alignedBaseAddress
;
4857 // If -dirty_data_list not specified, look in $SDKROOT/AppleInternal/DirtyDataFiles/<dylib>.dirty for dirty data list
4858 if ( fSymbolsMovesData
.empty() && fUseDataConstSegment
&& ( fDylibInstallName
!= NULL
) && !fSDKPaths
.empty() ) {
4859 const char* dylibLeaf
= strrchr(fDylibInstallName
, '/');
4861 char path
[PATH_MAX
];
4862 strlcpy(path
, fSDKPaths
.front(), sizeof(path
));
4863 strlcat(path
, "/AppleInternal/DirtyDataFiles", sizeof(path
));
4864 strlcat(path
, dylibLeaf
, sizeof(path
));
4865 strlcat(path
, ".dirty", sizeof(path
));
4867 if ( info
.checkFileExists(*this, path
) )
4868 addSymbolMove("__DATA_DIRTY", path
, fSymbolsMovesData
, "-dirty_data_list");
4874 void Options::checkIllegalOptionCombinations()
4876 // check -undefined setting
4877 switch ( fUndefinedTreatment
) {
4878 case kUndefinedError
:
4879 case kUndefinedDynamicLookup
:
4882 case kUndefinedWarning
:
4883 case kUndefinedSuppress
:
4884 // requires flat namespace
4885 if ( fNameSpace
== kTwoLevelNameSpace
)
4886 throw "can't use -undefined warning or suppress with -twolevel_namespace";
4890 // unify -sub_umbrella with dylibs
4891 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
4892 const char* subUmbrella
= *it
;
4894 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
4895 Options::FileInfo
& info
= *fit
;
4896 const char* lastSlash
= strrchr(info
.path
, '/');
4897 if ( lastSlash
== NULL
)
4898 lastSlash
= info
.path
- 1;
4899 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
4900 info
.options
.fReExport
= true;
4902 fLinkSnapshot
.recordSubUmbrella(info
.path
);
4907 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella
);
4910 // unify -sub_library with dylibs
4911 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
4912 const char* subLibrary
= *it
;
4914 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
4915 Options::FileInfo
& info
= *fit
;
4916 const char* lastSlash
= strrchr(info
.path
, '/');
4917 if ( lastSlash
== NULL
)
4918 lastSlash
= info
.path
- 1;
4919 const char* dot
= strchr(&lastSlash
[1], '.');
4921 dot
= &lastSlash
[strlen(lastSlash
)];
4922 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
4923 info
.options
.fReExport
= true;
4925 fLinkSnapshot
.recordSubLibrary(info
.path
);
4930 warning("-sub_library %s does not match a supplied dylib", subLibrary
);
4933 // sync reader options
4934 if ( fNameSpace
!= kTwoLevelNameSpace
)
4935 fFlatNamespace
= true;
4937 // check -stack_addr
4938 if ( fStackAddr
!= 0 ) {
4939 switch (fArchitecture
) {
4942 if ( fStackAddr
> 0xFFFFFFFF )
4943 throw "-stack_addr must be < 4G for 32-bit processes";
4945 case CPU_TYPE_X86_64
:
4946 case CPU_TYPE_ARM64
:
4949 if ( (fStackAddr
& -4096) != fStackAddr
)
4950 throw "-stack_addr must be multiples of 4K";
4951 if ( fStackSize
== 0 )
4952 throw "-stack_addr must be used with -stack_size";
4955 // check -stack_size
4956 if ( fStackSize
!= 0 ) {
4957 switch (fArchitecture
) {
4959 if ( fStackSize
> 0xFFFFFFFF )
4960 throw "-stack_size must be < 4G for 32-bit processes";
4961 if ( fStackAddr
== 0 ) {
4962 fStackAddr
= 0xC0000000;
4964 if ( (fStackAddr
> 0xB0000000) && ((fStackAddr
-fStackSize
) < 0xB0000000) )
4965 warning("custom stack placement overlaps and will disable shared region");
4968 if ( fStackSize
> 0x2F000000 )
4969 throw "-stack_size must be < 752MB";
4970 if ( fStackAddr
== 0 )
4971 fStackAddr
= 0x2F000000;
4972 if ( fStackAddr
> 0x30000000)
4973 throw "-stack_addr must be < 0x30000000 for arm";
4975 case CPU_TYPE_X86_64
:
4976 if ( fStackAddr
== 0 ) {
4977 fStackAddr
= 0x00007FFF5C000000LL
;
4980 case CPU_TYPE_ARM64
:
4981 if ( fStackSize
> 0x20000000 )
4982 throw "-stack_size must be < 512MB";
4983 if ( fStackAddr
== 0 ) {
4984 fStackAddr
= 0x120000000;
4988 if ( (fStackSize
& -4096) != fStackSize
)
4989 throw "-stack_size must be multiples of 4K";
4990 switch ( fOutputKind
) {
4991 case Options::kDynamicExecutable
:
4992 case Options::kStaticExecutable
:
4993 // custom stack size only legal when building main executable
4995 case Options::kDynamicLibrary
:
4996 case Options::kDynamicBundle
:
4997 case Options::kObjectFile
:
4998 case Options::kDyld
:
4999 case Options::kPreload
:
5000 case Options::kKextBundle
:
5001 throw "-stack_size option can only be used when linking a main executable";
5003 if ( fStackSize
> fStackAddr
)
5004 throwf("-stack_size (0x%08llX) must be smaller than -stack_addr (0x%08llX)", fStackSize
, fStackAddr
);
5007 // check that -allow_stack_execute is only used with main executables
5008 if ( fExecutableStack
) {
5009 switch ( fOutputKind
) {
5010 case Options::kDynamicExecutable
:
5011 case Options::kStaticExecutable
:
5012 // -allow_stack_execute size only legal when building main executable
5014 case Options::kDynamicLibrary
:
5015 case Options::kDynamicBundle
:
5016 case Options::kObjectFile
:
5017 case Options::kDyld
:
5018 case Options::kPreload
:
5019 case Options::kKextBundle
:
5020 throw "-allow_stack_execute option can only be used when linking a main executable";
5024 // check that -allow_heap_execute is only used with i386 main executables
5025 if ( fDisableNonExecutableHeap
) {
5026 if ( fArchitecture
!= CPU_TYPE_I386
)
5027 throw "-allow_heap_execute option can only be used when linking for i386";
5028 switch ( fOutputKind
) {
5029 case Options::kDynamicExecutable
:
5030 // -allow_heap_execute only legal when building main executable
5032 case Options::kStaticExecutable
:
5033 case Options::kDynamicLibrary
:
5034 case Options::kDynamicBundle
:
5035 case Options::kObjectFile
:
5036 case Options::kDyld
:
5037 case Options::kPreload
:
5038 case Options::kKextBundle
:
5039 throw "-allow_heap_execute option can only be used when linking a main executable";
5043 // check -client_name is only used when making a bundle or main executable
5044 if ( fClientName
!= NULL
) {
5045 switch ( fOutputKind
) {
5046 case Options::kDynamicExecutable
:
5047 case Options::kDynamicBundle
:
5049 case Options::kStaticExecutable
:
5050 case Options::kDynamicLibrary
:
5051 case Options::kObjectFile
:
5052 case Options::kDyld
:
5053 case Options::kPreload
:
5054 case Options::kKextBundle
:
5055 throw "-client_name can only be used with -bundle";
5059 // check -init is only used when building a dylib
5060 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
5061 throw "-init can only be used with -dynamiclib";
5063 // check -bundle_loader only used with -bundle
5064 if ( (fBundleLoader
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
5065 throw "-bundle_loader can only be used with -bundle";
5067 // check -dtrace not used with -r
5068 if ( (fDtraceScriptName
!= NULL
) && (fOutputKind
== Options::kObjectFile
) )
5069 throw "-dtrace can only be used when creating final linked images";
5071 // check -d can only be used with -r
5072 if ( fMakeTentativeDefinitionsReal
&& (fOutputKind
!= Options::kObjectFile
) )
5073 throw "-d can only be used with -r";
5075 // check that -root_safe is not used with -r
5076 if ( fRootSafe
&& (fOutputKind
== Options::kObjectFile
) )
5077 throw "-root_safe cannot be used with -r";
5079 // check that -setuid_safe is not used with -r
5080 if ( fSetuidSafe
&& (fOutputKind
== Options::kObjectFile
) )
5081 throw "-setuid_safe cannot be used with -r";
5083 // <rdar://problem/12781832> compiler driver no longer uses -objc_abi_version, it uses -ios_simulator_version_min instead
5084 if ( !fObjCABIVersion1Override
&& !fObjCABIVersion2Override
&& fTargetIOSSimulator
)
5085 fObjCABIVersion2Override
= true;
5087 // rdar://problem/4718189 map ObjC class names to new runtime names
5088 bool alterObjC1ClassNamesToObjC2
= false;
5089 switch (fArchitecture
) {
5091 // i386 only uses new symbols when using objc2 ABI
5092 if ( fObjCABIVersion2Override
)
5093 alterObjC1ClassNamesToObjC2
= true;
5095 case CPU_TYPE_X86_64
:
5097 case CPU_TYPE_ARM64
:
5098 alterObjC1ClassNamesToObjC2
= true;
5102 // make sure all required exported symbols exist
5103 std::vector
<const char*> impliedExports
;
5104 for (NameSet::iterator it
=fExportSymbols
.regularBegin(); it
!= fExportSymbols
.regularEnd(); ++it
) {
5105 const char* name
= *it
;
5106 const int len
= strlen(name
);
5107 if ( (strcmp(&name
[len
-3], ".eh") == 0) || (strncmp(name
, ".objc_category_name_", 20) == 0) ) {
5108 // never export .eh symbols
5109 warning("ignoring %s in export list", name
);
5111 else if ( (fArchitecture
== CPU_TYPE_I386
) && !fObjCABIVersion2Override
&& (strncmp(name
, "_OBJC_CLASS_$", 13) == 0) ) {
5112 warning("ignoring Objc2 Class symbol %s in i386 export list", name
);
5113 fRemovedExports
.insert(name
);
5115 else if ( alterObjC1ClassNamesToObjC2
&& (strncmp(name
, ".objc_class_name_", 17) == 0) ) {
5116 // linking ObjC2 ABI, but have ObjC1 ABI name in export list. Change it to intended name
5117 fRemovedExports
.insert(name
);
5119 asprintf(&temp
, "_OBJC_CLASS_$_%s", &name
[17]);
5120 impliedExports
.push_back(temp
);
5121 asprintf(&temp
, "_OBJC_METACLASS_$_%s", &name
[17]);
5122 impliedExports
.push_back(temp
);
5125 fInitialUndefines
.push_back(name
);
5128 fExportSymbols
.remove(fRemovedExports
);
5129 for (std::vector
<const char*>::iterator it
=impliedExports
.begin(); it
!= impliedExports
.end(); ++it
) {
5130 const char* name
= *it
;
5131 fExportSymbols
.insert(name
);
5132 fInitialUndefines
.push_back(name
);
5135 // make sure all required re-exported symbols exist
5136 for (NameSet::iterator it
=fReExportSymbols
.regularBegin(); it
!= fReExportSymbols
.regularEnd(); ++it
) {
5137 fInitialUndefines
.push_back(*it
);
5140 // make sure that -init symbol exists
5141 if ( fInitFunctionName
!= NULL
)
5142 fInitialUndefines
.push_back(fInitFunctionName
);
5144 // make sure that entry symbol exists
5145 switch ( fOutputKind
) {
5146 case Options::kDynamicExecutable
:
5147 case Options::kStaticExecutable
:
5148 case Options::kDyld
:
5149 case Options::kPreload
:
5150 fInitialUndefines
.push_back(fEntryName
);
5152 case Options::kDynamicLibrary
:
5153 case Options::kDynamicBundle
:
5154 case Options::kObjectFile
:
5155 case Options::kKextBundle
:
5159 // make sure every alias base exists
5160 for (std::vector
<AliasPair
>::iterator it
=fAliases
.begin(); it
!= fAliases
.end(); ++it
) {
5161 fInitialUndefines
.push_back(it
->realName
);
5164 // check custom segments
5165 if ( fCustomSegmentAddresses
.size() != 0 ) {
5166 // verify no segment is in zero page
5167 if ( fZeroPageSize
!= ULLONG_MAX
) {
5168 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
5169 if ( it
->address
< fZeroPageSize
)
5170 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it
->name
, it
->address
);
5173 // verify no duplicates
5174 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
5175 for (std::vector
<SegmentStart
>::iterator it2
= fCustomSegmentAddresses
.begin(); it2
!= fCustomSegmentAddresses
.end(); ++it2
) {
5176 if ( (it
->address
== it2
->address
) && (it
!= it2
) )
5177 throwf("duplicate -segaddr addresses for %s and %s", it
->name
, it2
->name
);
5179 // a custom segment address of zero will disable the use of a zero page
5180 if ( it
->address
== 0 )
5185 if ( fZeroPageSize
== ULLONG_MAX
) {
5186 // zero page size not specified on command line, set default
5187 switch (fArchitecture
) {
5190 // first 4KB for 32-bit architectures
5191 fZeroPageSize
= 0x1000;
5193 case CPU_TYPE_ARM64
:
5194 case CPU_TYPE_X86_64
:
5195 // first 4GB for x86_64 on all OS's
5196 fZeroPageSize
= 0x100000000ULL
;
5199 // if -arch not used, default to 4K zero-page
5200 fZeroPageSize
= 0x1000;
5204 switch ( fOutputKind
) {
5205 case Options::kDynamicExecutable
:
5206 case Options::kStaticExecutable
:
5207 // -pagezero_size size only legal when building main executable
5209 case Options::kDynamicLibrary
:
5210 case Options::kDynamicBundle
:
5211 case Options::kObjectFile
:
5212 case Options::kDyld
:
5213 case Options::kPreload
:
5214 case Options::kKextBundle
:
5215 if ( fZeroPageSize
!= 0 )
5216 throw "-pagezero_size option can only be used when linking a main executable";
5220 // if main executable with custom base address, model zero page as custom segment
5221 if ( (fOutputKind
== Options::kDynamicExecutable
) && (fBaseAddress
!= 0) && (fZeroPageSize
!= 0) ) {
5223 seg
.name
= "__PAGEZERO";
5225 fCustomSegmentAddresses
.push_back(seg
);
5228 // -dead_strip and -r are incompatible
5229 if ( fDeadStrip
&& (fOutputKind
== Options::kObjectFile
) )
5230 throw "-r and -dead_strip cannot be used together";
5232 // can't use -rpath unless targeting 10.5 or later
5233 if ( fRPaths
.size() > 0 ) {
5234 if ( !minOS(ld::mac10_5
, ld::iOS_2_0
) )
5235 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
5236 switch ( fOutputKind
) {
5237 case Options::kDynamicExecutable
:
5238 case Options::kDynamicLibrary
:
5239 case Options::kDynamicBundle
:
5241 case Options::kStaticExecutable
:
5242 case Options::kObjectFile
:
5243 case Options::kDyld
:
5244 case Options::kPreload
:
5245 case Options::kKextBundle
:
5246 throw "-rpath can only be used when creating a dynamic final linked image";
5250 if ( fPositionIndependentExecutable
) {
5251 switch ( fOutputKind
) {
5252 case Options::kDynamicExecutable
:
5253 // check -pie is only used when building a dynamic main executable for 10.5
5254 if ( !minOS(ld::mac10_5
, ld::iOS_4_2
) ) {
5255 if ( fIOSVersionMin
== ld::iOSVersionUnset
)
5256 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
5258 throw "-pie can only be used when targeting iOS 4.2 or later";
5261 case Options::kStaticExecutable
:
5262 case Options::kPreload
:
5263 // -pie is ok with -static or -preload
5265 case Options::kDynamicLibrary
:
5266 case Options::kDynamicBundle
:
5267 warning("-pie being ignored. It is only used when linking a main executable");
5268 fPositionIndependentExecutable
= false;
5270 case Options::kObjectFile
:
5271 case Options::kDyld
:
5272 case Options::kKextBundle
:
5273 throw "-pie can only be used when linking a main executable";
5277 // check -read_only_relocs is not used with x86_64
5278 if ( fAllowTextRelocs
) {
5279 if ( (fArchitecture
== CPU_TYPE_X86_64
) && (fOutputKind
!= kKextBundle
) ) {
5280 warning("-read_only_relocs cannot be used with x86_64");
5281 fAllowTextRelocs
= false;
5285 // check -mark_auto_dead_strip is only used with dylibs
5286 if ( fMarkDeadStrippableDylib
) {
5287 if ( fOutputKind
!= Options::kDynamicLibrary
) {
5288 warning("-mark_auto_dead_strip can only be used when creating a dylib");
5289 fMarkDeadStrippableDylib
= false;
5293 // -force_cpusubtype_ALL is not supported for ARM
5294 if ( fForceSubtypeAll
) {
5295 if ( fArchitecture
== CPU_TYPE_ARM
) {
5296 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
5300 // -reexported_symbols_list can only be used with -dynamiclib
5301 if ( !fReExportSymbols
.empty() ) {
5302 if ( fOutputKind
!= Options::kDynamicLibrary
)
5303 throw "-reexported_symbols_list can only used used when created dynamic libraries";
5304 if ( !minOS(ld::mac10_7
, ld::iOS_4_2
) )
5305 throw "targeted OS version does not support -reexported_symbols_list";
5308 // -dyld_env can only be used with main executables
5309 if ( (fOutputKind
!= Options::kDynamicExecutable
) && (fDyldEnvironExtras
.size() != 0) )
5310 throw "-dyld_env can only used used when created main executables";
5312 // -segment_order can only be used with -preload
5313 if ( !fSegmentOrder
.empty() && (fOutputKind
!= Options::kPreload
) )
5314 throw "-segment_order can only used used with -preload output";
5316 if ( fBitcodeKind
!= kBitcodeProcess
&&
5317 fOutputKind
!= Options::kObjectFile
) {
5318 throw "-bitcode_process_mode can only be used together with -r";
5320 // auto fix up the process type for strip -S.
5321 // when there is only one input and output type is object file, downgrade kBitcodeProcess to kBitcodeAsData.
5322 if ( fOutputKind
== Options::kObjectFile
&& fInputFiles
.size() == 1 && fBitcodeKind
== Options::kBitcodeProcess
)
5323 fBitcodeKind
= Options::kBitcodeAsData
;
5325 // warn about bitcode option combinations
5326 if ( !fBundleBitcode
) {
5327 if ( fVerifyBitcode
)
5328 warning("-bitcode_verify is ignored without -bitcode_bundle");
5329 else if ( fHideSymbols
)
5330 warning("-bitcode_hide_symbols is ignored without -bitcode_bundle");
5332 if ( fReverseMapPath
!= NULL
&& !fHideSymbols
) {
5333 throw "-bitcode_symbol_map can only be used with -bitcode_hide_symbols";
5336 // <rdar://problem/17598404> warn if building an embedded iOS dylib for pre-iOS 8
5337 // <rdar://problem/18935714> How can we suppress "ld: warning: embedded dylibs/frameworks only run on iOS 8 or laterÓ when building XCTest?
5338 if ( (fOutputKind
== Options::kDynamicLibrary
) && (fIOSVersionMin
!= ld::iOSVersionUnset
) && (fDylibInstallName
!= NULL
) ) {
5339 if ( !min_iOS(ld::iOS_8_0
) && (fDylibInstallName
[0] == '@') && !fEncryptableForceOff
)
5340 warning("embedded dylibs/frameworks only run on iOS 8 or later");
5345 void Options::checkForClassic(int argc
, const char* argv
[])
5348 bool archFound
= false;
5349 bool staticFound
= false;
5350 bool dtraceFound
= false;
5351 bool kextFound
= false;
5352 bool rFound
= false;
5353 bool creatingMachKernel
= false;
5354 bool newLinker
= false;
5356 // build command line buffer in case ld crashes
5357 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
5358 CRSetCrashLogMessage(crashreporterBuffer
);
5360 const char* srcRoot
= getenv("SRCROOT");
5361 if ( srcRoot
!= NULL
) {
5362 strlcpy(crashreporterBuffer
, "SRCROOT=", crashreporterBufferSize
);
5363 strlcat(crashreporterBuffer
, srcRoot
, crashreporterBufferSize
);
5364 strlcat(crashreporterBuffer
, "\n", crashreporterBufferSize
);
5367 strlcat(crashreporterBuffer
, LD_VERS
, crashreporterBufferSize
);
5368 strlcat(crashreporterBuffer
, "\n", crashreporterBufferSize
);
5370 strlcat(crashreporterBuffer
, "ld ", crashreporterBufferSize
);
5371 for(int i
=1; i
< argc
; ++i
) {
5372 strlcat(crashreporterBuffer
, argv
[i
], crashreporterBufferSize
);
5373 strlcat(crashreporterBuffer
, " ", crashreporterBufferSize
);
5376 for(int i
=0; i
< argc
; ++i
) {
5377 const char* arg
= argv
[i
];
5378 if ( arg
[0] == '-' ) {
5379 if ( strcmp(arg
, "-arch") == 0 ) {
5380 parseArch(argv
[++i
]);
5383 else if ( strcmp(arg
, "-static") == 0 ) {
5386 else if ( strcmp(arg
, "-kext") == 0 ) {
5389 else if ( strcmp(arg
, "-dtrace") == 0 ) {
5392 else if ( strcmp(arg
, "-r") == 0 ) {
5395 else if ( strcmp(arg
, "-new_linker") == 0 ) {
5398 else if ( strcmp(arg
, "-classic_linker") == 0 ) {
5399 // ld_classic does not understand this option, so remove it
5400 for(int j
=i
; j
< argc
; ++j
)
5401 argv
[j
] = argv
[j
+1];
5402 warning("using ld_classic");
5403 this->gotoClassicLinker(argc
-1, argv
);
5405 else if ( strcmp(arg
, "-o") == 0 ) {
5406 const char* outfile
= argv
[++i
];
5407 if ( (outfile
!= NULL
) && (strstr(outfile
, "/mach_kernel") != NULL
) )
5408 creatingMachKernel
= true;
5414 void Options::gotoClassicLinker(int argc
, const char* argv
[])
5416 argv
[0] = "ld_classic";
5417 // ld_classic does not support -iphoneos_version_min, so change
5418 for(int j
=0; j
< argc
; ++j
) {
5419 if ( (strcmp(argv
[j
], "-iphoneos_version_min") == 0) || (strcmp(argv
[j
], "-ios_version_min") == 0) ) {
5420 argv
[j
] = "-macosx_version_min";
5426 // ld classic does not understand -kext (change to -static -r)
5427 for(int j
=0; j
< argc
; ++j
) {
5428 if ( strcmp(argv
[j
], "-kext") == 0)
5430 else if ( strcmp(argv
[j
], "-dynamic") == 0)
5431 argv
[j
] = "-static";
5433 // ld classic does not understand -demangle
5434 for(int j
=0; j
< argc
; ++j
) {
5435 if ( strcmp(argv
[j
], "-demangle") == 0)
5436 argv
[j
] = "-noprebind";
5438 // in -v mode, print command line passed to ld_classic
5439 for(int i
=0; i
< argc
; ++i
) {
5440 if ( strcmp(argv
[i
], "-v") == 0 ) {
5441 for(int j
=0; j
< argc
; ++j
)
5442 printf("%s ", argv
[j
]);
5447 char rawPath
[PATH_MAX
];
5448 char path
[PATH_MAX
];
5449 uint32_t bufSize
= PATH_MAX
;
5450 if ( _NSGetExecutablePath(rawPath
, &bufSize
) != -1 ) {
5451 if ( realpath(rawPath
, path
) != NULL
) {
5452 char* lastSlash
= strrchr(path
, '/');
5453 if ( lastSlash
!= NULL
) {
5454 strcpy(lastSlash
+1, "ld_classic");
5456 execvp(path
, (char**)argv
);
5460 // in case of error in above, try searching for ld_classic via PATH
5461 execvp(argv
[0], (char**)argv
);
5462 fprintf(stderr
, "can't exec ld_classic\n");
5467 // Note, returned string buffer is own by this function.
5468 // It should not be freed
5469 // It will be reused, so clients need to strdup() if they want
5470 // to use it long term.
5471 const char* Options::demangleSymbol(const char* sym
) const
5473 // only try to demangle symbols if -demangle on command line
5477 static size_t size
= 1024;
5478 static char* buff
= (char*)malloc(size
);
5481 // only try to demangle symbols that look like Swift symbols
5482 if ( strncmp(sym
, "__T", 3) == 0 ) {
5483 size_t demangledSize
= fnd_get_demangled_name(&sym
[1], buff
, size
);
5484 if ( demangledSize
> size
) {
5485 size
= demangledSize
+2;
5486 buff
= (char*)realloc(buff
, size
);
5487 demangledSize
= fnd_get_demangled_name(&sym
[1], buff
, size
);
5489 if ( demangledSize
!= 0 )
5494 // only try to demangle symbols that look like C++ symbols
5495 if ( strncmp(sym
, "__Z", 3) != 0 )
5499 char* result
= abi::__cxa_demangle(&sym
[1], buff
, &size
, &status
);
5500 if ( result
!= NULL
) {
5501 // if demangling successful, keep buffer for next demangle
5509 void Options::dumpDependency(uint8_t opcode
, const char* path
) const
5511 if ( !this->dumpDependencyInfo() )
5514 // one time open() of -dependency_info file
5515 if ( fDependencyFileDescriptor
== -1 ) {
5516 fDependencyFileDescriptor
= open(this->dependencyInfoPath(), O_WRONLY
| O_TRUNC
| O_CREAT
, 0666);
5517 if ( fDependencyFileDescriptor
== -1 )
5518 throwf("Could not open or create -dependency_info file: %s", this->dependencyInfoPath());
5521 uint8_t version
= depLinkerVersion
;
5522 if ( write(fDependencyFileDescriptor
, &version
, 1) == -1 )
5523 throwf("write() to -dependency_info failed, errno=%d", errno
);
5524 extern const char ldVersionString
[];
5525 if ( write(fDependencyFileDescriptor
, ldVersionString
, strlen(ldVersionString
)+1) == -1 )
5526 throwf("write() to -dependency_info failed, errno=%d", errno
);
5529 char realPath
[PATH_MAX
];
5530 if ( path
[0] != '/' ) {
5531 if ( realpath(path
, realPath
) != NULL
) {
5536 if ( write(fDependencyFileDescriptor
, &opcode
, 1) == -1 )
5537 throwf("write() to -dependency_info failed, errno=%d", errno
);
5538 if ( write(fDependencyFileDescriptor
, path
, strlen(path
)+1) == -1 )
5539 throwf("write() to -dependency_info failed, errno=%d", errno
);
5541 //fprintf(stderr, "0x%02X %s\n", opcode, path);