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>
41 #include "Architectures.hpp"
42 #include "MachOFileAbstraction.hpp"
45 // upward dependency on lto::version()
47 extern const char* version();
50 // magic to place command line in crash reports
51 const int crashreporterBufferSize
= 2000;
52 static char crashreporterBuffer
[crashreporterBufferSize
];
53 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
54 #include <CrashReporterClient.h>
55 // hack until ld does not need to build on 10.6 anymore
56 struct crashreporter_annotations_t gCRAnnotations
57 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION
)))
58 = { CRASHREPORTER_ANNOTATIONS_VERSION
, 0, 0, 0, 0, 0, 0 };
60 extern "C" char* __crashreporter_info__
;
62 char* __crashreporter_info__
= crashreporterBuffer
;
66 static bool sEmitWarnings
= true;
67 static bool sFatalWarnings
= false;
68 static const char* sWarningsSideFilePath
= NULL
;
69 static FILE* sWarningsSideFile
= NULL
;
70 static int sWarningsCount
= 0;
72 void warning(const char* format
, ...)
75 if ( sEmitWarnings
) {
77 if ( sWarningsSideFilePath
!= NULL
) {
78 if ( sWarningsSideFile
== NULL
)
79 sWarningsSideFile
= fopen(sWarningsSideFilePath
, "a");
81 va_start(list
, format
);
82 fprintf(stderr
, "ld: warning: ");
83 vfprintf(stderr
, format
, list
);
84 fprintf(stderr
, "\n");
85 if ( sWarningsSideFile
!= NULL
) {
86 fprintf(sWarningsSideFile
, "ld: warning: ");
87 vfprintf(sWarningsSideFile
, format
, list
);
88 fprintf(sWarningsSideFile
, "\n");
89 fflush(sWarningsSideFile
);
95 void throwf(const char* format
, ...)
99 va_start(list
, format
);
100 vasprintf(&p
, format
, list
);
107 bool Options::FileInfo::checkFileExists(const char *p
)
109 struct stat statBuffer
;
110 if (p
== NULL
) p
= path
;
111 if ( stat(p
, &statBuffer
) == 0 ) {
112 if (p
!= path
) path
= strdup(p
);
113 fileLen
= statBuffer
.st_size
;
114 modTime
= statBuffer
.st_mtime
;
120 Options::Options(int argc
, const char* argv
[])
121 : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fArchitectureName("unknown"), fOutputKind(kDynamicExecutable
),
122 fHasPreferredSubType(false), fArchSupportsThumb2(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
123 fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fErrorOnOtherArchFiles(false), fForceSubtypeAll(false),
124 fInterposeMode(kInterposeNone
), fDeadStrip(false), fNameSpace(kTwoLevelNameSpace
),
125 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL
), fFinalName(NULL
), fEntryName("start"),
126 fBaseAddress(0), fMaxAddress(0x7FFFFFFFFFFFFFFFLL
),
127 fBaseWritableAddress(0), fSplitSegs(false),
128 fExportMode(kExportDefault
), fLibrarySearchMode(kSearchDylibAndArchiveInEachDir
),
129 fUndefinedTreatment(kUndefinedError
), fMessagesPrefixedWithArchitecture(true),
130 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchNonWeak
),
132 fUmbrellaName(NULL
), fInitFunctionName(NULL
), fDotOutputFile(NULL
), fExecutablePath(NULL
),
133 fBundleLoader(NULL
), fDtraceScriptName(NULL
), fSegAddrTablePath(NULL
), fMapPath(NULL
),
134 fDyldInstallPath("/usr/lib/dyld"), fTempLtoObjectPath(NULL
), fOverridePathlibLTO(NULL
),
135 fZeroPageSize(ULLONG_MAX
), fStackSize(0), fStackAddr(0), fSourceVersion(0), fSDKVersion(0), fExecutableStack(false),
136 fNonExecutableHeap(false), fDisableNonExecutableHeap(false),
137 fMinimumHeaderPad(32), fSegmentAlignment(4096),
138 fCommonsMode(kCommonsIgnoreDylibs
), fUUIDMode(kUUIDContent
), fLocalSymbolHandling(kLocalSymbolsAll
), fWarnCommons(false),
139 fVerbose(false), fKeepRelocations(false), fWarnStabs(false),
140 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
141 fSharedRegionEligible(false), fPrintOrderFileStatistics(false),
142 fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fPIEOnCommandLine(false),
143 fDisablePositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
144 fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false), fKextsUseStubs(false),
145 fUsingLazyDylibLinking(false), fEncryptable(true),
146 fOrderData(true), fMarkDeadStrippableDylib(false),
147 fMakeCompressedDyldInfo(true), fMakeCompressedDyldInfoForceOff(false), fNoEHLabels(false),
148 fAllowCpuSubtypeMismatches(false), fUseSimplifiedDylibReExports(false),
149 fObjCABIVersion2Override(false), fObjCABIVersion1Override(false), fCanUseUpwardDylib(false),
150 fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false),
151 fLinkingMainExecutable(false), fForFinalLinkedImage(false), fForStatic(false),
152 fForDyld(false), fMakeTentativeDefinitionsReal(false), fWhyLoad(false), fRootSafe(false),
153 fSetuidSafe(false), fImplicitlyLinkPublicDylibs(true), fAddCompactUnwindEncoding(true),
154 fWarnCompactUnwind(false), fRemoveDwarfUnwindIfCompactExists(false),
155 fAutoOrderInitializers(true), fOptimizeZeroFill(true), fMergeZeroFill(false), fLogObjectFiles(false),
156 fLogAllFiles(false), fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false),
157 fOutputSlidable(false), fWarnWeakExports(false),
158 fObjcGcCompaction(false), fObjCGc(false), fObjCGcOnly(false),
159 fDemangle(false), fTLVSupport(false),
160 fVersionLoadCommand(false), fVersionLoadCommandForcedOn(false),
161 fVersionLoadCommandForcedOff(false), fFunctionStartsLoadCommand(false),
162 fFunctionStartsForcedOn(false), fFunctionStartsForcedOff(false),
163 fDataInCodeInfoLoadCommand(false),
164 fCanReExportSymbols(false), fObjcCategoryMerging(true), fPageAlignDataAtoms(false),
165 fNeedsThreadLoadCommand(false), fEntryPointLoadCommand(false),
166 fEntryPointLoadCommandForceOn(false), fEntryPointLoadCommandForceOff(false),
167 fSourceVersionLoadCommand(false),
168 fSourceVersionLoadCommandForceOn(false), fSourceVersionLoadCommandForceOff(false),
169 fDependentDRInfo(false), fDependentDRInfoForcedOn(false), fDependentDRInfoForcedOff(false),
170 fDebugInfoStripping(kDebugInfoMinimal
), fTraceOutputFile(NULL
),
171 fMacVersionMin(ld::macVersionUnset
), fIOSVersionMin(ld::iOSVersionUnset
),
172 fSaveTempFiles(false), fSnapshotRequested(false), fPipelineFifo(NULL
)
174 this->checkForClassic(argc
, argv
);
175 this->parsePreCommandLineEnvironmentSettings();
176 this->parse(argc
, argv
);
177 this->parsePostCommandLineEnvironmentSettings();
178 this->reconfigureDefaults();
179 this->checkIllegalOptionCombinations();
186 bool Options::errorBecauseOfWarnings() const
188 return (sFatalWarnings
&& (sWarningsCount
> 0));
192 const char* Options::installPath() const
194 if ( fDylibInstallName
!= NULL
)
195 return fDylibInstallName
;
196 else if ( fFinalName
!= NULL
)
203 bool Options::interposable(const char* name
) const
205 switch ( fInterposeMode
) {
208 case kInterposeAllExternal
:
211 return fInterposeList
.contains(name
);
213 throw "internal error";
217 bool Options::printWhyLive(const char* symbolName
) const
219 return ( fWhyLive
.find(symbolName
) != fWhyLive
.end() );
223 const char* Options::dotOutputFile()
225 return fDotOutputFile
;
229 bool Options::hasWildCardExportRestrictList() const
231 // has -exported_symbols_list which contains some wildcards
232 return ((fExportMode
== kExportSome
) && fExportSymbols
.hasWildCards());
235 bool Options::hasWeakBitTweaks() const
237 // has -exported_symbols_list which contains some wildcards
238 return (!fForceWeakSymbols
.empty() || !fForceNotWeakSymbols
.empty());
241 bool Options::allGlobalsAreDeadStripRoots() const
243 // -exported_symbols_list means globals are not exported by default
244 if ( fExportMode
== kExportSome
)
247 switch ( fOutputKind
) {
248 case Options::kDynamicExecutable
:
249 case Options::kStaticExecutable
:
250 case Options::kPreload
:
251 // by default unused globals in a main executable are stripped
253 case Options::kDynamicLibrary
:
254 case Options::kDynamicBundle
:
255 case Options::kObjectFile
:
257 case Options::kKextBundle
:
264 bool Options::keepRelocations()
266 return fKeepRelocations
;
269 bool Options::warnStabs()
274 const char* Options::executablePath()
276 return fExecutablePath
;
280 uint32_t Options::initialSegProtection(const char* segName
) const
282 for(std::vector
<Options::SegmentProtect
>::const_iterator it
= fCustomSegmentProtections
.begin(); it
!= fCustomSegmentProtections
.end(); ++it
) {
283 if ( strcmp(it
->name
, segName
) == 0 ) {
287 if ( strcmp(segName
, "__PAGEZERO") == 0 ) {
290 else if ( strcmp(segName
, "__TEXT") == 0 ) {
291 return VM_PROT_READ
| VM_PROT_EXECUTE
;
293 else if ( strcmp(segName
, "__LINKEDIT") == 0 ) {
297 // all others default to read-write
298 return VM_PROT_READ
| VM_PROT_WRITE
;
301 uint32_t Options::maxSegProtection(const char* segName
) const
303 // iPhoneOS always uses same protection for max and initial
304 if ( fIOSVersionMin
!= ld::iOSVersionUnset
)
305 return initialSegProtection(segName
);
307 for(std::vector
<Options::SegmentProtect
>::const_iterator it
= fCustomSegmentProtections
.begin(); it
!= fCustomSegmentProtections
.end(); ++it
) {
308 if ( strcmp(it
->name
, segName
) == 0 ) {
312 if ( strcmp(segName
, "__PAGEZERO") == 0 ) {
315 // all others default to all
316 return VM_PROT_READ
| VM_PROT_WRITE
| VM_PROT_EXECUTE
;
319 uint64_t Options::segPageSize(const char* segName
) const
321 for(std::vector
<SegmentSize
>::const_iterator it
=fCustomSegmentSizes
.begin(); it
!= fCustomSegmentSizes
.end(); ++it
) {
322 if ( strcmp(it
->name
, segName
) == 0 )
325 return fSegmentAlignment
;
328 uint64_t Options::customSegmentAddress(const char* segName
) const
330 for(std::vector
<SegmentStart
>::const_iterator it
=fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
331 if ( strcmp(it
->name
, segName
) == 0 )
334 // if custom stack in use, model as segment with custom address
335 if ( (fStackSize
!= 0) && (strcmp("__UNIXSTACK", segName
) == 0) )
336 return fStackAddr
- fStackSize
;
340 bool Options::hasCustomSegmentAddress(const char* segName
) const
342 for(std::vector
<SegmentStart
>::const_iterator it
=fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
343 if ( strcmp(it
->name
, segName
) == 0 )
346 // if custom stack in use, model as segment with custom address
347 if ( (fStackSize
!= 0) && (strcmp("__UNIXSTACK", segName
) == 0) )
352 bool Options::hasCustomSectionAlignment(const char* segName
, const char* sectName
) const
354 for (std::vector
<SectionAlignment
>::const_iterator it
= fSectionAlignments
.begin(); it
!= fSectionAlignments
.end(); ++it
) {
355 if ( (strcmp(it
->segmentName
, segName
) == 0) && (strcmp(it
->sectionName
, sectName
) == 0) )
361 uint8_t Options::customSectionAlignment(const char* segName
, const char* sectName
) const
363 for (std::vector
<SectionAlignment
>::const_iterator it
= fSectionAlignments
.begin(); it
!= fSectionAlignments
.end(); ++it
) {
364 if ( (strcmp(it
->segmentName
, segName
) == 0) && (strcmp(it
->sectionName
, sectName
) == 0) )
365 return it
->alignment
;
371 bool Options::hasExportedSymbolOrder()
373 return (fExportSymbolsOrder
.size() > 0);
376 bool Options::exportedSymbolOrder(const char* sym
, unsigned int* order
) const
378 NameToOrder::const_iterator pos
= fExportSymbolsOrder
.find(sym
);
379 if ( pos
!= fExportSymbolsOrder
.end() ) {
380 *order
= pos
->second
;
389 void Options::loadSymbolOrderFile(const char* fileOfExports
, NameToOrder
& orderMapping
)
391 // read in whole file
392 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
394 throwf("can't open -exported_symbols_order file: %s", fileOfExports
);
395 struct stat stat_buf
;
396 ::fstat(fd
, &stat_buf
);
397 char* p
= (char*)malloc(stat_buf
.st_size
);
399 throwf("can't process -exported_symbols_order file: %s", fileOfExports
);
401 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
402 throwf("can't read -exported_symbols_order file: %s", fileOfExports
);
406 // parse into symbols and add to hash_set
407 unsigned int count
= 0;
408 char * const end
= &p
[stat_buf
.st_size
];
409 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
410 char* symbolStart
= NULL
;
411 for (char* s
= p
; s
< end
; ++s
) {
417 else if ( !isspace(*s
) ) {
423 if ( (*s
== '\n') || (*s
== '\r') ) {
425 // removing any trailing spaces
427 while ( isspace(*last
) ) {
431 orderMapping
[symbolStart
] = ++count
;
437 if ( (*s
== '\n') || (*s
== '\r') )
442 if ( state
== inSymbol
) {
443 warning("missing line-end at end of file \"%s\"", fileOfExports
);
444 int len
= end
-symbolStart
+1;
445 char* temp
= new char[len
];
446 strlcpy(temp
, symbolStart
, len
);
448 // remove any trailing spaces
449 char* last
= &temp
[len
-2];
450 while ( isspace(*last
) ) {
454 orderMapping
[temp
] = ++count
;
457 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
460 bool Options::forceWeak(const char* symbolName
) const
462 return fForceWeakSymbols
.contains(symbolName
);
465 bool Options::forceNotWeak(const char* symbolName
) const
467 return fForceNotWeakSymbols
.contains(symbolName
);
470 bool Options::forceWeakNonWildCard(const char* symbolName
) const
472 return fForceWeakSymbols
.containsNonWildcard(symbolName
);
475 bool Options::forceNotWeakNonWildcard(const char* symbolName
) const
477 return fForceNotWeakSymbols
.containsNonWildcard(symbolName
);
481 bool Options::shouldExport(const char* symbolName
) const
483 switch (fExportMode
) {
485 return fExportSymbols
.contains(symbolName
);
486 case kDontExportSome
:
487 return ! fDontExportSymbols
.contains(symbolName
);
491 throw "internal error";
494 bool Options::shouldReExport(const char* symbolName
) const
496 return fReExportSymbols
.contains(symbolName
);
499 bool Options::keepLocalSymbol(const char* symbolName
) const
501 switch (fLocalSymbolHandling
) {
502 case kLocalSymbolsAll
:
504 case kLocalSymbolsNone
:
506 case kLocalSymbolsSelectiveInclude
:
507 return fLocalSymbolsIncluded
.contains(symbolName
);
508 case kLocalSymbolsSelectiveExclude
:
509 return ! fLocalSymbolsExcluded
.contains(symbolName
);
511 throw "internal error";
514 void Options::setArchitecture(cpu_type_t type
, cpu_subtype_t subtype
)
516 for (const ArchInfo
* t
=archInfoArray
; t
->archName
!= NULL
; ++t
) {
517 if ( (type
== t
->cpuType
) && (subtype
== t
->cpuSubType
) ) {
518 fArchitecture
= type
;
519 fSubArchitecture
= subtype
;
520 fArchitectureName
= t
->archName
;
521 fHasPreferredSubType
= t
->isSubType
;
522 fArchSupportsThumb2
= t
->supportsThumb2
;
525 case CPU_TYPE_X86_64
:
526 if ( (fMacVersionMin
== ld::macVersionUnset
) && (fIOSVersionMin
== ld::iOSVersionUnset
) && (fOutputKind
!= Options::kObjectFile
) ) {
527 #ifdef DEFAULT_MACOSX_MIN_VERSION
528 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
529 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
531 warning("-macosx_version_min not specified, assuming 10.6");
532 fMacVersionMin
= ld::mac10_6
;
535 if ( !fMakeCompressedDyldInfo
&& minOS(ld::mac10_6
, ld::iOS_3_1
) && !fMakeCompressedDyldInfoForceOff
)
536 fMakeCompressedDyldInfo
= true;
539 if ( (fMacVersionMin
== ld::macVersionUnset
) && (fIOSVersionMin
== ld::iOSVersionUnset
) && (fOutputKind
!= Options::kObjectFile
) ) {
540 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
541 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION
);
542 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION
);
543 #elif defined(DEFAULT_MACOSX_MIN_VERSION)
544 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
545 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
547 warning("-macosx_version_min not specified, assuming 10.6");
548 fMacVersionMin
= ld::mac10_6
;
551 if ( !fMakeCompressedDyldInfo
&& minOS(ld::mac10_6
, ld::iOS_3_1
) && !fMakeCompressedDyldInfoForceOff
)
552 fMakeCompressedDyldInfo
= true;
555 fLinkSnapshot
.recordArch(fArchitectureName
);
559 fArchitectureName
= "unknown architecture";
562 void Options::parseArch(const char* arch
)
565 throw "-arch must be followed by an architecture string";
566 for (const ArchInfo
* t
=archInfoArray
; t
->archName
!= NULL
; ++t
) {
567 if ( strcmp(t
->archName
,arch
) == 0 ) {
568 fArchitectureName
= arch
;
569 fArchitecture
= t
->cpuType
;
570 fSubArchitecture
= t
->cpuSubType
;
571 fHasPreferredSubType
= t
->isSubType
;
572 fArchSupportsThumb2
= t
->supportsThumb2
;
576 throwf("unknown/unsupported architecture name for: -arch %s", arch
);
579 bool Options::checkForFile(const char* format
, const char* dir
, const char* rootName
, FileInfo
& result
) const
581 char possiblePath
[strlen(dir
)+strlen(rootName
)+strlen(format
)+8];
582 sprintf(possiblePath
, format
, dir
, rootName
);
583 bool found
= result
.checkFileExists(possiblePath
);
584 if ( fTraceDylibSearching
)
585 printf("[Logging for XBS]%sfound library: '%s'\n", (found
? " " : " not "), possiblePath
);
590 Options::FileInfo
Options::findLibrary(const char* rootName
, bool dylibsOnly
)
593 const int rootNameLen
= strlen(rootName
);
594 // if rootName ends in .o there is no .a vs .dylib choice
595 if ( (rootNameLen
> 3) && (strcmp(&rootName
[rootNameLen
-2], ".o") == 0) ) {
596 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
597 it
!= fLibrarySearchPaths
.end();
599 const char* dir
= *it
;
600 if ( checkForFile("%s/%s", dir
, rootName
, result
) )
605 bool lookForDylibs
= ( fOutputKind
!= Options::kDyld
);
606 switch ( fLibrarySearchMode
) {
607 case kSearchAllDirsForDylibsThenAllDirsForArchives
:
608 // first look in all directories for just for dylibs
609 if ( lookForDylibs
) {
610 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
611 it
!= fLibrarySearchPaths
.end();
613 const char* dir
= *it
;
614 if ( checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
617 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
618 it
!= fLibrarySearchPaths
.end();
620 const char* dir
= *it
;
621 if ( checkForFile("%s/lib%s.so", dir
, rootName
, result
) )
625 // next look in all directories for just for archives
627 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
628 it
!= fLibrarySearchPaths
.end();
630 const char* dir
= *it
;
631 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
637 case kSearchDylibAndArchiveInEachDir
:
638 // look in each directory for just for a dylib then for an archive
639 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
640 it
!= fLibrarySearchPaths
.end();
642 const char* dir
= *it
;
643 if ( lookForDylibs
&& checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
645 if ( lookForDylibs
&& checkForFile("%s/lib%s.so", dir
, rootName
, result
) )
647 if ( !dylibsOnly
&& checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
653 throwf("library not found for -l%s", rootName
);
656 Options::FileInfo
Options::findFramework(const char* frameworkName
)
658 if ( frameworkName
== NULL
)
659 throw "-framework missing next argument";
660 char temp
[strlen(frameworkName
)+1];
661 strcpy(temp
, frameworkName
);
662 const char* name
= temp
;
663 const char* suffix
= NULL
;
664 char* comma
= strchr(temp
, ',');
665 if ( comma
!= NULL
) {
669 return findFramework(name
, suffix
);
672 Options::FileInfo
Options::findFramework(const char* rootName
, const char* suffix
)
674 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
675 it
!= fFrameworkSearchPaths
.end();
677 // ??? Shouldn't we be using String here and just initializing it?
678 // ??? Use str.c_str () to pull out the string for the stat call.
679 const char* dir
= *it
;
680 char possiblePath
[PATH_MAX
];
681 strcpy(possiblePath
, dir
);
682 strcat(possiblePath
, "/");
683 strcat(possiblePath
, rootName
);
684 strcat(possiblePath
, ".framework/");
685 strcat(possiblePath
, rootName
);
686 if ( suffix
!= NULL
) {
687 char realPath
[PATH_MAX
];
688 // no symlink in framework to suffix variants, so follow main symlink
689 if ( realpath(possiblePath
, realPath
) != NULL
) {
690 strcpy(possiblePath
, realPath
);
691 strcat(possiblePath
, suffix
);
695 bool found
= result
.checkFileExists(possiblePath
);
696 if ( fTraceDylibSearching
)
697 printf("[Logging for XBS]%sfound framework: '%s'\n",
698 (found
? " " : " not "), possiblePath
);
703 // try without suffix
704 if ( suffix
!= NULL
)
705 return findFramework(rootName
, NULL
);
707 throwf("framework not found %s", rootName
);
710 Options::FileInfo
Options::findFile(const char* path
) const
714 // if absolute path and not a .o file, the use SDK prefix
715 if ( (path
[0] == '/') && (strcmp(&path
[strlen(path
)-2], ".o") != 0) ) {
716 const int pathLen
= strlen(path
);
717 for (std::vector
<const char*>::const_iterator it
= fSDKPaths
.begin(); it
!= fSDKPaths
.end(); it
++) {
718 // ??? Shouldn't we be using String here?
719 const char* sdkPathDir
= *it
;
720 const int sdkPathDirLen
= strlen(sdkPathDir
);
721 char possiblePath
[sdkPathDirLen
+pathLen
+4];
722 strcpy(possiblePath
, sdkPathDir
);
723 if ( possiblePath
[sdkPathDirLen
-1] == '/' )
724 possiblePath
[sdkPathDirLen
-1] = '\0';
725 strcat(possiblePath
, path
);
726 if ( result
.checkFileExists(possiblePath
) ) {
732 if ( result
.checkFileExists(path
) ) {
736 // try @executable_path substitution
737 if ( (strncmp(path
, "@executable_path/", 17) == 0) && (fExecutablePath
!= NULL
) ) {
738 char newPath
[strlen(fExecutablePath
) + strlen(path
)];
739 strcpy(newPath
, fExecutablePath
);
740 char* addPoint
= strrchr(newPath
,'/');
741 if ( addPoint
!= NULL
)
742 strcpy(&addPoint
[1], &path
[17]);
744 strcpy(newPath
, &path
[17]);
745 if ( result
.checkFileExists(newPath
) ) {
751 throwf("file not found: %s", path
);
754 Options::FileInfo
Options::findFileUsingPaths(const char* path
) const
758 const char* lastSlash
= strrchr(path
, '/');
759 const char* leafName
= (lastSlash
== NULL
) ? path
: &lastSlash
[1];
761 // Is this in a framework?
762 // /path/Foo.framework/Foo ==> true (Foo)
763 // /path/Foo.framework/Frameworks/Bar.framework/Bar ==> true (Bar)
764 // /path/Foo.framework/Resources/Bar ==> false
765 bool isFramework
= false;
766 if ( lastSlash
!= NULL
) {
767 char frameworkDir
[strlen(leafName
) + 20];
768 strcpy(frameworkDir
, "/");
769 strcat(frameworkDir
, leafName
);
770 strcat(frameworkDir
, ".framework/");
771 if ( strstr(path
, frameworkDir
) != NULL
)
775 // These are abbreviated versions of the routines findFramework and findLibrary above
776 // because we already know the final name of the file that we're looking for and so
777 // don't need to try variations, just paths. We do need to add the additional bits
778 // onto the framework path though.
780 for (std::vector
<const char*>::const_iterator it
= fFrameworkSearchPaths
.begin();
781 it
!= fFrameworkSearchPaths
.end();
783 const char* dir
= *it
;
784 char possiblePath
[PATH_MAX
];
785 strcpy(possiblePath
, dir
);
786 strcat(possiblePath
, "/");
787 strcat(possiblePath
, leafName
);
788 strcat(possiblePath
, ".framework");
790 //fprintf(stderr,"Finding Framework: %s/%s, leafName=%s\n", possiblePath, leafName, leafName);
791 if ( checkForFile("%s/%s", possiblePath
, leafName
, result
) )
796 // if this is a .dylib inside a framework, do not search -L paths
797 // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
798 int leafLen
= strlen(leafName
);
799 bool embeddedDylib
= ( (leafLen
> 6)
800 && (strcmp(&leafName
[leafLen
-6], ".dylib") == 0)
801 && (strstr(path
, ".framework/") != NULL
) );
802 if ( !embeddedDylib
) {
803 for (std::vector
<const char*>::const_iterator it
= fLibrarySearchPaths
.begin();
804 it
!= fLibrarySearchPaths
.end();
806 const char* dir
= *it
;
807 //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
808 if ( checkForFile("%s/%s", dir
, leafName
, result
) )
814 // If we didn't find it fall back to findFile.
815 return findFile(path
);
819 void Options::parseSegAddrTable(const char* segAddrPath
, const char* installPth
)
821 FILE* file
= fopen(segAddrPath
, "r");
822 if ( file
== NULL
) {
823 warning("-seg_addr_table file cannot be read: %s", segAddrPath
);
828 uint64_t firstColumAddress
= 0;
829 uint64_t secondColumAddress
= 0;
830 bool hasSecondColumn
= false;
831 while ( fgets(path
, PATH_MAX
, file
) != NULL
) {
832 path
[PATH_MAX
-1] = '\0';
833 char* eol
= strchr(path
, '\n');
836 // ignore lines not starting with 0x number
837 if ( (path
[0] == '0') && (path
[1] == 'x') ) {
839 firstColumAddress
= strtoull(path
, &p
, 16);
840 while ( isspace(*p
) )
842 // see if second column is a number
843 if ( (p
[0] == '0') && (p
[1] == 'x') ) {
844 secondColumAddress
= strtoull(p
, &p
, 16);
845 hasSecondColumn
= true;
846 while ( isspace(*p
) )
849 while ( isspace(*p
) )
852 // remove any trailing whitespace
853 for(char* end
= eol
-1; (end
> p
) && isspace(*end
); --end
)
855 // see if this line is for the dylib being linked
856 if ( strcmp(p
, installPth
) == 0 ) {
857 fBaseAddress
= firstColumAddress
;
858 if ( hasSecondColumn
) {
859 fBaseWritableAddress
= secondColumAddress
;
862 break; // out of while loop
871 void Options::loadFileList(const char* fileOfPaths
, ld::File::Ordinal baseOrdinal
)
874 const char* comma
= strrchr(fileOfPaths
, ',');
875 const char* prefix
= NULL
;
876 if ( comma
!= NULL
) {
877 // <rdar://problem/5907981> -filelist fails with comma in path
878 file
= fopen(fileOfPaths
, "r");
879 if ( file
== NULL
) {
881 int realFileOfPathsLen
= comma
-fileOfPaths
;
882 char realFileOfPaths
[realFileOfPathsLen
+1];
883 strncpy(realFileOfPaths
,fileOfPaths
, realFileOfPathsLen
);
884 realFileOfPaths
[realFileOfPathsLen
] = '\0';
885 file
= fopen(realFileOfPaths
, "r");
887 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", realFileOfPaths
, errno
, strerror(errno
));
891 file
= fopen(fileOfPaths
, "r");
893 throwf("-filelist file '%s' could not be opened, errno=%d (%s)\n", fileOfPaths
, errno
, strerror(errno
));
897 ld::File::Ordinal previousOrdinal
= baseOrdinal
;
898 while ( fgets(path
, PATH_MAX
, file
) != NULL
) {
899 path
[PATH_MAX
-1] = '\0';
900 char* eol
= strchr(path
, '\n');
903 if ( prefix
!= NULL
) {
904 char builtPath
[strlen(prefix
)+strlen(path
)+2];
905 strcpy(builtPath
, prefix
);
906 strcat(builtPath
, "/");
907 strcat(builtPath
, path
);
908 if (fPipelineFifo
!= NULL
) {
909 FileInfo info
= FileInfo(builtPath
);
910 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
911 previousOrdinal
= info
.ordinal
;
912 info
.fromFileList
= true;
913 fInputFiles
.push_back(info
);
915 FileInfo info
= findFile(builtPath
);
916 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
917 previousOrdinal
= info
.ordinal
;
918 info
.fromFileList
= true;
919 fInputFiles
.push_back(info
);
923 if (fPipelineFifo
!= NULL
) {
924 FileInfo info
= FileInfo(path
);
925 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
926 previousOrdinal
= info
.ordinal
;
927 info
.fromFileList
= true;
928 fInputFiles
.push_back(info
);
930 FileInfo info
= findFile(path
);
931 info
.ordinal
= previousOrdinal
.nextFileListOrdinal();
932 previousOrdinal
= info
.ordinal
;
933 info
.fromFileList
= true;
934 fInputFiles
.push_back(info
);
942 void Options::SetWithWildcards::remove(const NameSet
& toBeRemoved
)
944 for(NameSet::const_iterator it
=toBeRemoved
.begin(); it
!= toBeRemoved
.end(); ++it
) {
945 const char* symbolName
= *it
;
946 NameSet::iterator pos
= fRegular
.find(symbolName
);
947 if ( pos
!= fRegular
.end() )
952 bool Options::SetWithWildcards::hasWildCards(const char* symbol
)
954 // an exported symbol name containing *, ?, or [ requires wildcard matching
955 return ( strpbrk(symbol
, "*?[") != NULL
);
958 void Options::SetWithWildcards::insert(const char* symbol
)
960 if ( hasWildCards(symbol
) )
961 fWildCard
.push_back(symbol
);
963 fRegular
.insert(symbol
);
966 bool Options::SetWithWildcards::contains(const char* symbol
) const
968 // first look at hash table on non-wildcard symbols
969 if ( fRegular
.find(symbol
) != fRegular
.end() )
971 // next walk list of wild card symbols looking for a match
972 for(std::vector
<const char*>::const_iterator it
= fWildCard
.begin(); it
!= fWildCard
.end(); ++it
) {
973 if ( wildCardMatch(*it
, symbol
) )
979 bool Options::SetWithWildcards::containsNonWildcard(const char* symbol
) const
981 // look at hash table on non-wildcard symbols
982 return ( fRegular
.find(symbol
) != fRegular
.end() );
987 bool Options::SetWithWildcards::inCharRange(const char*& p
, unsigned char c
) const
991 while ( *p
!= '\0' ) {
994 // found beginining [ and ending ]
995 unsigned char last
= '\0';
996 for ( const char* s
= b
; s
< e
; ++s
) {
998 unsigned char next
= *(++s
);
999 if ( (last
<= c
) && (c
<= next
) )
1016 bool Options::SetWithWildcards::wildCardMatch(const char* pattern
, const char* symbol
) const
1018 const char* s
= symbol
;
1019 for (const char* p
= pattern
; *p
!= '\0'; ++p
) {
1024 for (const char* t
= s
; *t
!= '\0'; ++t
) {
1025 if ( wildCardMatch(&p
[1], t
) )
1035 if ( ! inCharRange(p
, *s
) )
1045 return (*s
== '\0');
1049 void Options::loadExportFile(const char* fileOfExports
, const char* option
, SetWithWildcards
& set
)
1051 if ( fileOfExports
== NULL
)
1052 throwf("missing file after %s", option
);
1053 // read in whole file
1054 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
1056 throwf("can't open %s file: %s", option
, fileOfExports
);
1057 struct stat stat_buf
;
1058 ::fstat(fd
, &stat_buf
);
1059 char* p
= (char*)malloc(stat_buf
.st_size
);
1061 throwf("can't process %s file: %s", option
, fileOfExports
);
1063 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1064 throwf("can't read %s file: %s", option
, fileOfExports
);
1068 // parse into symbols and add to hash_set
1069 char * const end
= &p
[stat_buf
.st_size
];
1070 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
1071 char* symbolStart
= NULL
;
1072 for (char* s
= p
; s
< end
; ++s
) {
1078 else if ( !isspace(*s
) ) {
1084 if ( (*s
== '\n') || (*s
== '\r') ) {
1086 // removing any trailing spaces
1088 while ( isspace(*last
) ) {
1092 set
.insert(symbolStart
);
1098 if ( (*s
== '\n') || (*s
== '\r') )
1103 if ( state
== inSymbol
) {
1104 warning("missing line-end at end of file \"%s\"", fileOfExports
);
1105 int len
= end
-symbolStart
+1;
1106 char* temp
= new char[len
];
1107 strlcpy(temp
, symbolStart
, len
);
1109 // remove any trailing spaces
1110 char* last
= &temp
[len
-2];
1111 while ( isspace(*last
) ) {
1118 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
1121 void Options::parseAliasFile(const char* fileOfAliases
)
1123 // read in whole file
1124 int fd
= ::open(fileOfAliases
, O_RDONLY
, 0);
1126 throwf("can't open alias file: %s", fileOfAliases
);
1127 struct stat stat_buf
;
1128 ::fstat(fd
, &stat_buf
);
1129 char* p
= (char*)malloc(stat_buf
.st_size
+1);
1131 throwf("can't process alias file: %s", fileOfAliases
);
1133 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1134 throwf("can't read alias file: %s", fileOfAliases
);
1135 p
[stat_buf
.st_size
] = '\n';
1138 // parse into symbols and add to fAliases
1140 char * const end
= &p
[stat_buf
.st_size
+1];
1141 enum { lineStart
, inRealName
, inBetween
, inAliasName
, inComment
} state
= lineStart
;
1143 for (char* s
= p
; s
< end
; ++s
) {
1149 else if ( !isspace(*s
) ) {
1156 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber
, fileOfAliases
);
1160 else if ( isspace(*s
) ) {
1167 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber
, fileOfAliases
);
1171 else if ( ! isspace(*s
) ) {
1172 state
= inAliasName
;
1179 // removing any trailing spaces
1181 while ( isspace(*last
) ) {
1185 fAliases
.push_back(pair
);
1188 else if ( *s
== '\n' ) {
1190 // removing any trailing spaces
1192 while ( isspace(*last
) ) {
1196 fAliases
.push_back(pair
);
1207 // Note: we do not free() the malloc buffer, because the strings therein are used by fAliases
1212 void Options::setUndefinedTreatment(const char* treatment
)
1214 if ( treatment
== NULL
)
1215 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
1217 if ( strcmp(treatment
, "warning") == 0 )
1218 fUndefinedTreatment
= kUndefinedWarning
;
1219 else if ( strcmp(treatment
, "error") == 0 )
1220 fUndefinedTreatment
= kUndefinedError
;
1221 else if ( strcmp(treatment
, "suppress") == 0 )
1222 fUndefinedTreatment
= kUndefinedSuppress
;
1223 else if ( strcmp(treatment
, "dynamic_lookup") == 0 )
1224 fUndefinedTreatment
= kUndefinedDynamicLookup
;
1226 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
1229 Options::Treatment
Options::parseTreatment(const char* treatment
)
1231 if ( treatment
== NULL
)
1234 if ( strcmp(treatment
, "warning") == 0 )
1236 else if ( strcmp(treatment
, "error") == 0 )
1238 else if ( strcmp(treatment
, "suppress") == 0 )
1244 void Options::setMacOSXVersionMin(const char* version
)
1246 if ( version
== NULL
)
1247 throw "-macosx_version_min argument missing";
1249 if ( (strncmp(version
, "10.", 3) == 0) && isdigit(version
[3]) ) {
1250 unsigned int minorVersion
= version
[3] - '0';
1251 fMacVersionMin
= (ld::MacVersionMin
)(0x000A0000 | (minorVersion
<< 8));
1254 warning("unknown option to -macosx_version_min, not 10.x");
1258 void Options::setIOSVersionMin(const char* version
)
1260 if ( version
== NULL
)
1261 throw "-ios_version_min argument missing";
1262 if ( ! isdigit(version
[0]) )
1263 throw "-ios_version_min argument is not a number";
1264 if ( version
[1] != '.' )
1265 throw "-ios_version_min argument is missing period as second character";
1266 if ( ! isdigit(version
[2]) )
1267 throw "-ios_version_min argument is not a number";
1269 unsigned int majorVersion
= version
[0] - '0';
1270 unsigned int minorVersion
= version
[2] - '0';
1271 fIOSVersionMin
= (ld::IOSVersionMin
)((majorVersion
<< 16) | (minorVersion
<< 8));
1274 bool Options::minOS(ld::MacVersionMin requiredMacMin
, ld::IOSVersionMin requirediPhoneOSMin
)
1276 if ( fMacVersionMin
!= ld::macVersionUnset
) {
1277 return ( fMacVersionMin
>= requiredMacMin
);
1280 return ( fIOSVersionMin
>= requirediPhoneOSMin
);
1285 void Options::setWeakReferenceMismatchTreatment(const char* treatment
)
1287 if ( treatment
== NULL
)
1288 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
1290 if ( strcmp(treatment
, "error") == 0 )
1291 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchError
;
1292 else if ( strcmp(treatment
, "weak") == 0 )
1293 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchWeak
;
1294 else if ( strcmp(treatment
, "non-weak") == 0 )
1295 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchNonWeak
;
1297 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
1300 Options::CommonsMode
Options::parseCommonsTreatment(const char* mode
)
1303 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
1305 if ( strcmp(mode
, "ignore_dylibs") == 0 )
1306 return kCommonsIgnoreDylibs
;
1307 else if ( strcmp(mode
, "use_dylibs") == 0 )
1308 return kCommonsOverriddenByDylibs
;
1309 else if ( strcmp(mode
, "error") == 0 )
1310 return kCommonsConflictsDylibsError
;
1312 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
1315 void Options::addDylibOverride(const char* paths
)
1317 if ( paths
== NULL
)
1318 throw "-dylib_file must followed by two colon separated paths";
1319 const char* colon
= strchr(paths
, ':');
1320 if ( colon
== NULL
)
1321 throw "-dylib_file must followed by two colon separated paths";
1322 int len
= colon
-paths
;
1323 char* target
= new char[len
+2];
1324 strncpy(target
, paths
, len
);
1326 DylibOverride entry
;
1327 entry
.installName
= target
;
1328 entry
.useInstead
= &colon
[1];
1329 fDylibOverrides
.push_back(entry
);
1332 uint64_t Options::parseAddress(const char* addr
)
1335 uint64_t result
= strtoull(addr
, &endptr
, 16);
1339 uint32_t Options::parseProtection(const char* prot
)
1341 uint32_t result
= 0;
1342 for(const char* p
= prot
; *p
!= '\0'; ++p
) {
1343 switch(tolower(*p
)) {
1345 result
|= VM_PROT_READ
;
1348 result
|= VM_PROT_WRITE
;
1351 result
|= VM_PROT_EXECUTE
;
1356 throwf("unknown -segprot lettter in %s", prot
);
1364 // Parses number of form A[.B[.B[.D[.E]]]] into a uint64_t where the bits are a24.b10.c10.d10.e10
1366 uint64_t Options::parseVersionNumber64(const char* versionString
)
1374 a
= strtoul(versionString
, &end
, 10);
1375 if ( *end
== '.' ) {
1376 b
= strtoul(&end
[1], &end
, 10);
1377 if ( *end
== '.' ) {
1378 c
= strtoul(&end
[1], &end
, 10);
1379 if ( *end
== '.' ) {
1380 d
= strtoul(&end
[1], &end
, 10);
1381 if ( *end
== '.' ) {
1382 e
= strtoul(&end
[1], &end
, 10);
1387 if ( (*end
!= '\0') || (a
> 0xFFFFFF) || (b
> 0x3FF) || (c
> 0x3FF) || (d
> 0x3FF) || (e
> 0x3FF) )
1388 throwf("malformed 64-bit a.b.c.d.e version number: %s", versionString
);
1390 return (a
<< 40) | ( b
<< 30 ) | ( c
<< 20 ) | ( d
<< 10 ) | e
;
1394 uint32_t Options::currentVersion32() const
1396 // warn if it does not fit into 32 bit vers number
1397 uint32_t a
= (fDylibCurrentVersion
>> 40) & 0xFFFF;
1398 uint32_t b
= (fDylibCurrentVersion
>> 30) & 0xFF;
1399 uint32_t c
= (fDylibCurrentVersion
>> 20) & 0xFF;
1400 uint64_t rep32
= ((uint64_t)a
<< 40) | ((uint64_t)b
<< 30) | ((uint64_t)c
<< 20);
1401 if ( rep32
!= fDylibCurrentVersion
) {
1402 warning("truncating -current_version to fit in 32-bit space used by old mach-o format");
1403 a
= (fDylibCurrentVersion
>> 40) & 0xFFFFFF;
1406 b
= (fDylibCurrentVersion
>> 30) & 0x3FF;
1409 c
= (fDylibCurrentVersion
>> 20) & 0x3FF;
1413 return (a
<< 16) | ( b
<< 8 ) | c
;
1417 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
1419 uint32_t Options::parseVersionNumber32(const char* versionString
)
1425 x
= strtoul(versionString
, &end
, 10);
1426 if ( *end
== '.' ) {
1427 y
= strtoul(&end
[1], &end
, 10);
1428 if ( *end
== '.' ) {
1429 z
= strtoul(&end
[1], &end
, 10);
1432 if ( (*end
!= '\0') || (x
> 0xffff) || (y
> 0xff) || (z
> 0xff) )
1433 throwf("malformed 32-bit x.y.z version number: %s", versionString
);
1435 return (x
<< 16) | ( y
<< 8 ) | z
;
1438 static const char* cstringSymbolName(const char* orderFileString
)
1441 asprintf(&result
, "cstring=%s", orderFileString
);
1442 // convert escaped characters
1444 for(const char* s
=result
; *s
!= '\0'; ++s
, ++d
) {
1482 // hexadecimal value of char
1486 while ( isxdigit(*s
) ) {
1491 value
+= ((toupper(*s
)-'A') + 10);
1498 if ( isdigit(*s
) ) {
1499 // octal value of char
1501 while ( isdigit(*s
) ) {
1502 value
= (value
<< 3) + (*s
-'0');
1517 void Options::parseOrderFile(const char* path
, bool cstring
)
1519 // order files override auto-ordering
1520 fAutoOrderInitializers
= false;
1522 // read in whole file
1523 int fd
= ::open(path
, O_RDONLY
, 0);
1525 throwf("can't open order file: %s", path
);
1526 struct stat stat_buf
;
1527 ::fstat(fd
, &stat_buf
);
1528 char* p
= (char*)malloc(stat_buf
.st_size
+1);
1530 throwf("can't process order file: %s", path
);
1531 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1532 throwf("can't read order file: %s", path
);
1534 p
[stat_buf
.st_size
] = '\n';
1536 // parse into vector of pairs
1537 char * const end
= &p
[stat_buf
.st_size
+1];
1538 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
1539 char* symbolStart
= NULL
;
1540 for (char* s
= p
; s
< end
; ++s
) {
1546 else if ( !isspace(*s
) || cstring
) {
1552 if ( (*s
== '\n') || (!cstring
&& (*s
== '#')) ) {
1553 bool wasComment
= (*s
== '#');
1555 // removing any trailing spaces
1557 while ( isspace(*last
) ) {
1561 // if there is an architecture prefix, only use this symbol it if matches current arch
1562 if ( strncmp(symbolStart
, "ppc:", 4) == 0 ) {
1565 else if ( strncmp(symbolStart
, "ppc64:", 6) == 0 ) {
1568 else if ( strncmp(symbolStart
, "i386:", 5) == 0 ) {
1569 if ( fArchitecture
== CPU_TYPE_I386
)
1570 symbolStart
= &symbolStart
[5];
1574 else if ( strncmp(symbolStart
, "x86_64:", 7) == 0 ) {
1575 if ( fArchitecture
== CPU_TYPE_X86_64
)
1576 symbolStart
= &symbolStart
[7];
1580 else if ( strncmp(symbolStart
, "arm:", 4) == 0 ) {
1581 if ( fArchitecture
== CPU_TYPE_ARM
)
1582 symbolStart
= &symbolStart
[4];
1586 if ( symbolStart
!= NULL
) {
1587 char* objFileName
= NULL
;
1588 char* colon
= strstr(symbolStart
, ".o:");
1589 if ( colon
!= NULL
) {
1591 objFileName
= symbolStart
;
1592 symbolStart
= &colon
[3];
1594 // trim leading spaces
1595 while ( isspace(*symbolStart
) )
1597 Options::OrderedSymbol pair
;
1599 pair
.symbolName
= cstringSymbolName(symbolStart
);
1601 pair
.symbolName
= symbolStart
;
1602 pair
.objectFileName
= objFileName
;
1603 fOrderedSymbols
.push_back(pair
);
1618 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1621 void Options::parseSectionOrderFile(const char* segment
, const char* section
, const char* path
)
1623 if ( (strcmp(section
, "__cstring") == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1624 parseOrderFile(path
, true);
1626 else if ( (strncmp(section
, "__literal",9) == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1627 warning("sorting of __literal[4,8,16] sections not supported");
1630 // ignore section information and append all symbol names to global order file
1631 parseOrderFile(path
, false);
1635 void Options::addSection(const char* segment
, const char* section
, const char* path
)
1637 if ( strlen(segment
) > 16 )
1638 throw "-seccreate segment name max 16 chars";
1639 if ( strlen(section
) > 16 ) {
1640 char* tmp
= strdup(section
);
1642 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section
, tmp
);
1646 // read in whole file
1647 int fd
= ::open(path
, O_RDONLY
, 0);
1649 throwf("can't open -sectcreate file: %s", path
);
1650 struct stat stat_buf
;
1651 ::fstat(fd
, &stat_buf
);
1652 char* p
= (char*)malloc(stat_buf
.st_size
);
1654 throwf("can't process -sectcreate file: %s", path
);
1655 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1656 throwf("can't read -sectcreate file: %s", path
);
1659 // record section to create
1660 ExtraSection info
= { segment
, section
, path
, (uint8_t*)p
, stat_buf
.st_size
};
1661 fExtraSections
.push_back(info
);
1664 void Options::addSectionAlignment(const char* segment
, const char* section
, const char* alignmentStr
)
1666 if ( strlen(segment
) > 16 )
1667 throw "-sectalign segment name max 16 chars";
1668 if ( strlen(section
) > 16 )
1669 throw "-sectalign section name max 16 chars";
1671 // argument to -sectalign is a hexadecimal number
1673 unsigned long value
= strtoul(alignmentStr
, &endptr
, 16);
1674 if ( *endptr
!= '\0')
1675 throw "argument for -sectalign is not a hexadecimal number";
1676 if ( value
> 0x8000 )
1677 throw "argument for -sectalign must be less than or equal to 0x8000";
1679 warning("zero is not a valid -sectalign");
1683 // alignment is power of 2 (e.g. page alignment = 12)
1684 uint8_t alignment
= (uint8_t)__builtin_ctz(value
);
1685 if ( (unsigned long)(1 << alignment
) != value
) {
1686 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1687 segment
, section
, 1 << alignment
);
1690 SectionAlignment info
= { segment
, section
, alignment
};
1691 fSectionAlignments
.push_back(info
);
1694 void Options::addLibrary(const FileInfo
& info
)
1696 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1697 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1698 if ( strcmp(info
.path
, fit
->path
) == 0 ) {
1699 // if dylib is specified again but weak, record that it should be weak
1700 if ( info
.options
.fWeakImport
)
1701 fit
->options
.fWeakImport
= true;
1706 fInputFiles
.push_back(info
);
1709 void Options::warnObsolete(const char* arg
)
1711 warning("option %s is obsolete and being ignored", arg
);
1718 // Process all command line arguments.
1720 // The only error checking done here is that each option is valid and if it has arguments
1721 // that they too are valid.
1723 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
1724 // whichever was last on the command line is used.
1726 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
1728 void Options::parse(int argc
, const char* argv
[])
1730 // Store the original args in the link snapshot.
1731 fLinkSnapshot
.recordRawArgs(argc
, argv
);
1733 // pass one builds search list from -L and -F options
1734 this->buildSearchPaths(argc
, argv
);
1736 // reduce re-allocations
1737 fInputFiles
.reserve(32);
1739 // pass two parse all other options
1740 for(int i
=1; i
< argc
; ++i
) {
1741 const char* arg
= argv
[i
];
1743 if ( arg
[0] == '-' ) {
1744 // by default, copy one arg to the snapshot link command, and do no file copying
1745 int snapshotArgIndex
= i
;
1746 int snapshotArgCount
= -1; // -1 means compute count based on change in index
1747 int snapshotFileArgIndex
= -1; // -1 means no data file parameter to arg
1749 // Since we don't care about the files passed, just the option names, we do this here.
1751 fprintf (stderr
, "[Logging ld64 options]\t%s\n", arg
);
1753 if ( (arg
[1] == 'L') || (arg
[1] == 'F') ) {
1754 snapshotArgCount
= 0; // stripped out of link snapshot
1757 // previously handled by buildSearchPaths()
1759 // The one gnu style option we have to keep compatibility
1760 // with gcc. Might as well have the single hyphen one as well.
1761 else if ( (strcmp(arg
, "--help") == 0)
1762 || (strcmp(arg
, "-help") == 0)) {
1763 fprintf (stdout
, "ld64: For information on command line options please use 'man ld'.\n");
1766 else if ( strcmp(arg
, "-arch") == 0 ) {
1767 parseArch(argv
[++i
]);
1769 else if ( strcmp(arg
, "-dynamic") == 0 ) {
1772 else if ( strcmp(arg
, "-static") == 0 ) {
1774 if ( (fOutputKind
!= kObjectFile
) && (fOutputKind
!= kKextBundle
) ) {
1775 fOutputKind
= kStaticExecutable
;
1778 else if ( strcmp(arg
, "-dylib") == 0 ) {
1779 fOutputKind
= kDynamicLibrary
;
1781 else if ( strcmp(arg
, "-bundle") == 0 ) {
1782 fOutputKind
= kDynamicBundle
;
1784 else if ( strcmp(arg
, "-dylinker") == 0 ) {
1785 fOutputKind
= kDyld
;
1787 else if ( strcmp(arg
, "-execute") == 0 ) {
1788 if ( fOutputKind
!= kStaticExecutable
)
1789 fOutputKind
= kDynamicExecutable
;
1791 else if ( strcmp(arg
, "-preload") == 0 ) {
1792 fOutputKind
= kPreload
;
1794 else if ( strcmp(arg
, "-r") == 0 ) {
1795 fOutputKind
= kObjectFile
;
1797 else if ( strcmp(arg
, "-kext") == 0 ) {
1798 fOutputKind
= kKextBundle
;
1800 else if ( strcmp(arg
, "-o") == 0 ) {
1801 snapshotArgCount
= 0;
1802 fOutputFile
= argv
[++i
];
1803 fLinkSnapshot
.setSnapshotName(fOutputFile
);
1805 else if ( strncmp(arg
, "-lazy-l", 7) == 0 ) {
1806 snapshotArgCount
= 0;
1807 FileInfo info
= findLibrary(&arg
[7], true);
1808 info
.options
.fLazyLoad
= true;
1809 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
1811 fUsingLazyDylibLinking
= true;
1813 else if ( strcmp(arg
, "-lto_library") == 0 ) {
1814 snapshotFileArgIndex
= 1;
1815 fOverridePathlibLTO
= argv
[++i
];
1816 if ( fOverridePathlibLTO
== NULL
)
1817 throw "missing argument to -lto_library";
1819 else if ( (arg
[1] == 'l') && (strncmp(arg
,"-lazy_",6) !=0) ) {
1820 snapshotArgCount
= 0;
1821 FileInfo info
= findLibrary(&arg
[2]);
1822 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
1825 // This causes a dylib to be weakly bound at
1826 // link time. This corresponds to weak_import.
1827 else if ( strncmp(arg
, "-weak-l", 7) == 0 ) {
1828 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
1829 snapshotArgCount
= 0;
1830 FileInfo info
= findLibrary(&arg
[7]);
1831 info
.options
.fWeakImport
= true;
1832 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
1835 // Avoid lazy binding.
1836 else if ( strcmp(arg
, "-bind_at_load") == 0 ) {
1839 else if ( strcmp(arg
, "-twolevel_namespace") == 0 ) {
1840 fNameSpace
= kTwoLevelNameSpace
;
1842 else if ( strcmp(arg
, "-flat_namespace") == 0 ) {
1843 fNameSpace
= kFlatNameSpace
;
1845 // Also sets a bit to ensure dyld causes everything
1846 // in the namespace to be flat.
1848 else if ( strcmp(arg
, "-force_flat_namespace") == 0 ) {
1849 fNameSpace
= kForceFlatNameSpace
;
1851 // Similar to --whole-archive.
1852 else if ( strcmp(arg
, "-all_load") == 0 ) {
1853 fFullyLoadArchives
= true;
1855 else if ( strcmp(arg
, "-noall_load") == 0) {
1858 // Similar to -all_load
1859 else if ( strcmp(arg
, "-ObjC") == 0 ) {
1860 fLoadAllObjcObjectsFromArchives
= true;
1862 // Similar to -all_load, but for the following archive only.
1863 else if ( strcmp(arg
, "-force_load") == 0 ) {
1864 FileInfo info
= findFile(argv
[++i
]);
1865 info
.options
.fForceLoad
= true;
1866 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
1869 // Library versioning.
1870 else if ( (strcmp(arg
, "-dylib_compatibility_version") == 0)
1871 || (strcmp(arg
, "-compatibility_version") == 0)) {
1872 const char* vers
= argv
[++i
];
1874 throw "-dylib_compatibility_version missing <version>";
1875 fDylibCompatVersion
= parseVersionNumber32(vers
);
1877 else if ( (strcmp(arg
, "-dylib_current_version") == 0)
1878 || (strcmp(arg
, "-current_version") == 0)) {
1879 const char* vers
= argv
[++i
];
1881 throw "-dylib_current_version missing <version>";
1882 fDylibCurrentVersion
= parseVersionNumber64(vers
);
1884 else if ( strcmp(arg
, "-sectorder") == 0 ) {
1885 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
1886 throw "-sectorder missing <segment> <section> <file-path>";
1887 snapshotFileArgIndex
= 3;
1888 parseSectionOrderFile(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
1891 else if ( strcmp(arg
, "-order_file") == 0 ) {
1892 snapshotFileArgIndex
= 1;
1893 parseOrderFile(argv
[++i
], false);
1895 else if ( strcmp(arg
, "-order_file_statistics") == 0 ) {
1896 fPrintOrderFileStatistics
= true;
1898 // ??? Deprecate segcreate.
1899 // -sectcreate puts whole files into a section in the output.
1900 else if ( (strcmp(arg
, "-sectcreate") == 0) || (strcmp(arg
, "-segcreate") == 0) ) {
1901 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
1902 throw "-sectcreate missing <segment> <section> <file-path>";
1903 snapshotFileArgIndex
= 3;
1904 addSection(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
1907 // Since we have a full path in binary/library names we need to be able to override it.
1908 else if ( (strcmp(arg
, "-dylib_install_name") == 0)
1909 || (strcmp(arg
, "-dylinker_install_name") == 0)
1910 || (strcmp(arg
, "-install_name") == 0)) {
1911 fDylibInstallName
= argv
[++i
];
1912 if ( fDylibInstallName
== NULL
)
1913 throw "-install_name missing <path>";
1915 // Sets the base address of the output.
1916 else if ( (strcmp(arg
, "-seg1addr") == 0) || (strcmp(arg
, "-image_base") == 0) ) {
1917 const char* address
= argv
[++i
];
1918 if ( address
== NULL
)
1919 throwf("%s missing <address>", arg
);
1920 fBaseAddress
= parseAddress(address
);
1921 uint64_t temp
= ((fBaseAddress
+fSegmentAlignment
-1) & (-fSegmentAlignment
));
1922 if ( fBaseAddress
!= temp
) {
1923 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment
);
1924 fBaseAddress
= temp
;
1927 else if ( strcmp(arg
, "-e") == 0 ) {
1928 fEntryName
= argv
[++i
];
1930 // Same as -@ from the FSF linker.
1931 else if ( strcmp(arg
, "-filelist") == 0 ) {
1932 snapshotArgCount
= 0;
1933 const char* path
= argv
[++i
];
1934 if ( (path
== NULL
) || (path
[0] == '-') )
1935 throw "-filelist missing <path>";
1936 ld::File::Ordinal baseOrdinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
1937 loadFileList(path
, baseOrdinal
);
1939 else if ( strcmp(arg
, "-keep_private_externs") == 0 ) {
1940 fKeepPrivateExterns
= true;
1942 else if ( strcmp(arg
, "-final_output") == 0 ) {
1943 fFinalName
= argv
[++i
];
1945 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
1946 // just ensures that this happens for cross object file boundaries.
1947 else if ( (strcmp(arg
, "-interposable") == 0) || (strcmp(arg
, "-multi_module") == 0)) {
1948 switch ( fInterposeMode
) {
1949 case kInterposeNone
:
1950 case kInterposeAllExternal
:
1951 fInterposeMode
= kInterposeAllExternal
;
1953 case kInterposeSome
:
1954 // do nothing, -interposable_list overrides -interposable"
1958 else if ( strcmp(arg
, "-interposable_list") == 0 ) {
1959 snapshotFileArgIndex
= 1;
1960 fInterposeMode
= kInterposeSome
;
1961 loadExportFile(argv
[++i
], "-interposable_list", fInterposeList
);
1963 // Default for -interposable/-multi_module/-single_module.
1964 else if ( strcmp(arg
, "-single_module") == 0 ) {
1965 fInterposeMode
= kInterposeNone
;
1967 else if ( strcmp(arg
, "-exported_symbols_list") == 0 ) {
1968 snapshotFileArgIndex
= 1;
1969 if ( fExportMode
== kDontExportSome
)
1970 throw "can't use -exported_symbols_list and -unexported_symbols_list";
1971 fExportMode
= kExportSome
;
1972 loadExportFile(argv
[++i
], "-exported_symbols_list", fExportSymbols
);
1974 else if ( strcmp(arg
, "-unexported_symbols_list") == 0 ) {
1975 snapshotFileArgIndex
= 1;
1976 if ( fExportMode
== kExportSome
)
1977 throw "can't use -unexported_symbols_list and -exported_symbols_list";
1978 fExportMode
= kDontExportSome
;
1979 loadExportFile(argv
[++i
], "-unexported_symbols_list", fDontExportSymbols
);
1981 else if ( strcmp(arg
, "-exported_symbol") == 0 ) {
1982 if ( fExportMode
== kDontExportSome
)
1983 throw "can't use -exported_symbol and -unexported_symbols";
1984 fExportMode
= kExportSome
;
1985 fExportSymbols
.insert(argv
[++i
]);
1987 else if ( strcmp(arg
, "-unexported_symbol") == 0 ) {
1988 if ( fExportMode
== kExportSome
)
1989 throw "can't use -unexported_symbol and -exported_symbol";
1990 fExportMode
= kDontExportSome
;
1991 fDontExportSymbols
.insert(argv
[++i
]);
1993 else if ( strcmp(arg
, "-non_global_symbols_no_strip_list") == 0 ) {
1994 snapshotFileArgIndex
= 1;
1995 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveExclude
)
1996 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
1997 fLocalSymbolHandling
= kLocalSymbolsSelectiveInclude
;
1998 loadExportFile(argv
[++i
], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded
);
2000 else if ( strcmp(arg
, "-non_global_symbols_strip_list") == 0 ) {
2001 snapshotFileArgIndex
= 1;
2002 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveInclude
)
2003 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
2004 fLocalSymbolHandling
= kLocalSymbolsSelectiveExclude
;
2005 loadExportFile(argv
[++i
], "-non_global_symbols_strip_list", fLocalSymbolsExcluded
);
2008 else if ( strcmp(arg
, "-no_arch_warnings") == 0 ) {
2009 fIgnoreOtherArchFiles
= true;
2011 else if ( strcmp(arg
, "-force_cpusubtype_ALL") == 0 ) {
2012 fForceSubtypeAll
= true;
2013 fAllowCpuSubtypeMismatches
= true;
2015 // Similar to -weak-l but uses the absolute path name to the library.
2016 else if ( strcmp(arg
, "-weak_library") == 0 ) {
2017 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2018 snapshotArgCount
= 0;
2019 FileInfo info
= findFile(argv
[++i
]);
2020 info
.options
.fWeakImport
= true;
2021 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2024 else if ( strcmp(arg
, "-lazy_library") == 0 ) {
2025 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2026 snapshotArgCount
= 0;
2027 FileInfo info
= findFile(argv
[++i
]);
2028 info
.options
.fLazyLoad
= true;
2029 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2031 fUsingLazyDylibLinking
= true;
2033 else if ( strcmp(arg
, "-framework") == 0 ) {
2034 snapshotArgCount
= 0;
2035 FileInfo info
= findFramework(argv
[++i
]);
2036 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2039 else if ( strcmp(arg
, "-weak_framework") == 0 ) {
2040 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2041 snapshotArgCount
= 0;
2042 FileInfo info
= findFramework(argv
[++i
]);
2043 info
.options
.fWeakImport
= true;
2044 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2047 else if ( strcmp(arg
, "-lazy_framework") == 0 ) {
2048 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2049 snapshotArgCount
= 0;
2050 FileInfo info
= findFramework(argv
[++i
]);
2051 info
.options
.fLazyLoad
= true;
2052 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2054 fUsingLazyDylibLinking
= true;
2056 else if ( strcmp(arg
, "-search_paths_first") == 0 ) {
2057 // previously handled by buildSearchPaths()
2059 else if ( strcmp(arg
, "-search_dylibs_first") == 0 ) {
2060 // previously handled by buildSearchPaths()
2062 else if ( strcmp(arg
, "-undefined") == 0 ) {
2063 setUndefinedTreatment(argv
[++i
]);
2065 // Debugging output flag.
2066 else if ( strcmp(arg
, "-arch_multiple") == 0 ) {
2067 fMessagesPrefixedWithArchitecture
= true;
2069 // Specify what to do with relocations in read only
2070 // sections like .text. Could be errors, warnings,
2071 // or suppressed. Currently we do nothing with the
2073 else if ( strcmp(arg
, "-read_only_relocs") == 0 ) {
2074 switch ( parseTreatment(argv
[++i
]) ) {
2077 throw "-read_only_relocs missing [ warning | error | suppress ]";
2079 fWarnTextRelocs
= true;
2080 fAllowTextRelocs
= true;
2083 fWarnTextRelocs
= false;
2084 fAllowTextRelocs
= true;
2087 fWarnTextRelocs
= false;
2088 fAllowTextRelocs
= false;
2092 else if ( strcmp(arg
, "-sect_diff_relocs") == 0 ) {
2096 // Warn, error or make strong a mismatch between weak
2097 // and non-weak references.
2098 else if ( strcmp(arg
, "-weak_reference_mismatches") == 0 ) {
2099 setWeakReferenceMismatchTreatment(argv
[++i
]);
2101 // For a deployment target of 10.3 and earlier ld64 will
2102 // prebind an executable with 0s in all addresses that
2103 // are prebound. This can then be fixed up by update_prebinding
2104 // later. Prebinding is less useful on 10.4 and greater.
2105 else if ( strcmp(arg
, "-prebind") == 0 ) {
2108 else if ( strcmp(arg
, "-noprebind") == 0 ) {
2112 else if ( strcmp(arg
, "-prebind_allow_overlap") == 0 ) {
2115 else if ( strcmp(arg
, "-prebind_all_twolevel_modules") == 0 ) {
2118 else if ( strcmp(arg
, "-noprebind_all_twolevel_modules") == 0 ) {
2121 else if ( strcmp(arg
, "-nofixprebinding") == 0 ) {
2124 // This should probably be deprecated when we respect -L and -F
2125 // when searching for libraries.
2126 else if ( strcmp(arg
, "-dylib_file") == 0 ) {
2127 // ignore for snapshot because a stub dylib will be created in the snapshot
2128 snapshotArgCount
= 0;
2129 addDylibOverride(argv
[++i
]);
2131 // What to expand @executable_path to if found in dependent dylibs
2132 else if ( strcmp(arg
, "-executable_path") == 0 ) {
2133 fExecutablePath
= argv
[++i
];
2134 if ( (fExecutablePath
== NULL
) || (fExecutablePath
[0] == '-') )
2135 throw "-executable_path missing <path>";
2136 // if a directory was passed, add / to end
2137 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2138 struct stat statBuffer
;
2139 if ( stat(fExecutablePath
, &statBuffer
) == 0 ) {
2140 if ( (statBuffer
.st_mode
& S_IFMT
) == S_IFDIR
) {
2141 char* pathWithSlash
= new char[strlen(fExecutablePath
)+2];
2142 strcpy(pathWithSlash
, fExecutablePath
);
2143 strcat(pathWithSlash
, "/");
2144 fExecutablePath
= pathWithSlash
;
2148 // Aligns all segments to the power of 2 boundary specified.
2149 else if ( strcmp(arg
, "-segalign") == 0 ) {
2150 const char* size
= argv
[++i
];
2152 throw "-segalign missing <size>";
2153 fSegmentAlignment
= parseAddress(size
);
2154 uint8_t alignment
= (uint8_t)__builtin_ctz(fSegmentAlignment
);
2155 uint32_t p2aligned
= (1 << alignment
);
2156 if ( p2aligned
!= fSegmentAlignment
) {
2157 warning("alignment for -segalign %s is not a power of two, using 0x%X", size
, p2aligned
);
2158 fSegmentAlignment
= p2aligned
;
2161 // Puts a specified segment at a particular address that must
2162 // be a multiple of the segment alignment.
2163 else if ( strcmp(arg
, "-segaddr") == 0 ) {
2165 seg
.name
= argv
[++i
];
2166 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
2167 throw "-segaddr missing segName Adddress";
2168 seg
.address
= parseAddress(argv
[++i
]);
2169 uint64_t temp
= ((seg
.address
+fSegmentAlignment
-1) & (-fSegmentAlignment
));
2170 if ( seg
.address
!= temp
)
2171 warning("-segaddr %s not %lld byte aligned", seg
.name
, fSegmentAlignment
);
2172 fCustomSegmentAddresses
.push_back(seg
);
2174 // ??? Deprecate when we deprecate split-seg.
2175 else if ( strcmp(arg
, "-segs_read_only_addr") == 0 ) {
2176 fBaseAddress
= parseAddress(argv
[++i
]);
2178 // ??? Deprecate when we deprecate split-seg.
2179 else if ( strcmp(arg
, "-segs_read_write_addr") == 0 ) {
2180 fBaseWritableAddress
= parseAddress(argv
[++i
]);
2183 // ??? Deprecate when we get rid of basing at build time.
2184 else if ( strcmp(arg
, "-seg_addr_table") == 0 ) {
2185 snapshotFileArgIndex
= 1;
2186 const char* name
= argv
[++i
];
2188 throw "-seg_addr_table missing argument";
2189 fSegAddrTablePath
= name
;
2191 else if ( strcmp(arg
, "-seg_addr_table_filename") == 0 ) {
2195 else if ( strcmp(arg
, "-segprot") == 0 ) {
2197 seg
.name
= argv
[++i
];
2198 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) || (argv
[i
+2] == NULL
) )
2199 throw "-segprot missing segName max-prot init-prot";
2200 seg
.max
= parseProtection(argv
[++i
]);
2201 seg
.init
= parseProtection(argv
[++i
]);
2202 fCustomSegmentProtections
.push_back(seg
);
2204 else if ( strcmp(arg
, "-pagezero_size") == 0 ) {
2205 const char* size
= argv
[++i
];
2207 throw "-pagezero_size missing <size>";
2208 fZeroPageSize
= parseAddress(size
);
2209 uint64_t temp
= fZeroPageSize
& (-4096); // page align
2210 if ( (fZeroPageSize
!= temp
) )
2211 warning("-pagezero_size not page aligned, rounding down");
2212 fZeroPageSize
= temp
;
2214 else if ( strcmp(arg
, "-stack_addr") == 0 ) {
2215 const char* address
= argv
[++i
];
2216 if ( address
== NULL
)
2217 throw "-stack_addr missing <address>";
2218 fStackAddr
= parseAddress(address
);
2220 else if ( strcmp(arg
, "-stack_size") == 0 ) {
2221 const char* size
= argv
[++i
];
2223 throw "-stack_size missing <address>";
2224 fStackSize
= parseAddress(size
);
2225 uint64_t temp
= fStackSize
& (-4096); // page align
2226 if ( (fStackSize
!= temp
) )
2227 warning("-stack_size not page aligned, rounding down");
2229 else if ( strcmp(arg
, "-allow_stack_execute") == 0 ) {
2230 fExecutableStack
= true;
2232 else if ( strcmp(arg
, "-allow_heap_execute") == 0 ) {
2233 fDisableNonExecutableHeap
= true;
2235 else if ( strcmp(arg
, "-sectalign") == 0 ) {
2236 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2237 throw "-sectalign missing <segment> <section> <file-path>";
2238 addSectionAlignment(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2241 else if ( strcmp(arg
, "-sectorder_detail") == 0 ) {
2244 else if ( strcmp(arg
, "-sectobjectsymbols") == 0 ) {
2248 else if ( strcmp(arg
, "-bundle_loader") == 0 ) {
2249 snapshotFileArgIndex
= 1;
2250 fBundleLoader
= argv
[++i
];
2251 if ( (fBundleLoader
== NULL
) || (fBundleLoader
[0] == '-') )
2252 throw "-bundle_loader missing <path>";
2253 FileInfo info
= findFile(fBundleLoader
);
2254 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2255 info
.options
.fBundleLoader
= true;
2256 fInputFiles
.push_back(info
);
2258 else if ( strcmp(arg
, "-private_bundle") == 0 ) {
2261 else if ( strcmp(arg
, "-twolevel_namespace_hints") == 0 ) {
2264 // Use this flag to set default behavior for deployement targets.
2265 else if ( strcmp(arg
, "-macosx_version_min") == 0 ) {
2266 setMacOSXVersionMin(argv
[++i
]);
2268 else if ( (strcmp(arg
, "-ios_version_min") == 0) || (strcmp(arg
, "-iphoneos_version_min") == 0) ) {
2269 setIOSVersionMin(argv
[++i
]);
2271 else if ( strcmp(arg
, "-ios_simulator_version_min") == 0 ) {
2272 setIOSVersionMin(argv
[++i
]);
2274 else if ( strcmp(arg
, "-multiply_defined") == 0 ) {
2275 //warnObsolete(arg);
2278 else if ( strcmp(arg
, "-multiply_defined_unused") == 0 ) {
2282 else if ( strcmp(arg
, "-nomultidefs") == 0 ) {
2285 // Display each file in which the argument symbol appears and whether
2286 // the file defines or references it. This option takes an argument
2287 // as -y<symbol> note that there is no space.
2288 else if ( strncmp(arg
, "-y", 2) == 0 ) {
2291 // Same output as -y, but output <arg> number of undefined symbols only.
2292 else if ( strcmp(arg
, "-Y") == 0 ) {
2293 //warnObsolete(arg);
2296 // This option affects all objects linked into the final result.
2297 else if ( strcmp(arg
, "-m") == 0 ) {
2300 else if ( (strcmp(arg
, "-why_load") == 0) || (strcmp(arg
, "-whyload") == 0) ) {
2303 else if ( strcmp(arg
, "-why_live") == 0 ) {
2304 const char* name
= argv
[++i
];
2306 throw "-why_live missing symbol name argument";
2307 fWhyLive
.insert(name
);
2309 else if ( strcmp(arg
, "-u") == 0 ) {
2310 const char* name
= argv
[++i
];
2312 throw "-u missing argument";
2313 fInitialUndefines
.push_back(name
);
2315 else if ( strcmp(arg
, "-U") == 0 ) {
2316 const char* name
= argv
[++i
];
2318 throw "-U missing argument";
2319 fAllowedUndefined
.insert(name
);
2321 else if ( strcmp(arg
, "-s") == 0 ) {
2323 fLocalSymbolHandling
= kLocalSymbolsNone
;
2324 fDebugInfoStripping
= Options::kDebugInfoNone
;
2326 else if ( strcmp(arg
, "-x") == 0 ) {
2327 fLocalSymbolHandling
= kLocalSymbolsNone
;
2329 else if ( strcmp(arg
, "-S") == 0 ) {
2330 fDebugInfoStripping
= Options::kDebugInfoNone
;
2332 else if ( strcmp(arg
, "-X") == 0 ) {
2335 else if ( strcmp(arg
, "-Si") == 0 ) {
2337 fDebugInfoStripping
= Options::kDebugInfoFull
;
2339 else if ( strcmp(arg
, "-b") == 0 ) {
2342 else if ( strcmp(arg
, "-Sn") == 0 ) {
2344 fDebugInfoStripping
= Options::kDebugInfoFull
;
2346 else if ( strcmp(arg
, "-Sp") == 0 ) {
2349 else if ( strcmp(arg
, "-dead_strip") == 0 ) {
2352 else if ( strcmp(arg
, "-no_dead_strip_inits_and_terms") == 0 ) {
2355 else if ( strcmp(arg
, "-w") == 0 ) {
2356 // previously handled by buildSearchPaths()
2358 else if ( strcmp(arg
, "-fatal_warnings") == 0 ) {
2359 // previously handled by buildSearchPaths()
2361 else if ( strcmp(arg
, "-arch_errors_fatal") == 0 ) {
2362 fErrorOnOtherArchFiles
= true;
2364 else if ( strcmp(arg
, "-M") == 0 ) {
2367 else if ( strcmp(arg
, "-headerpad") == 0 ) {
2368 const char* size
= argv
[++i
];
2370 throw "-headerpad missing argument";
2371 fMinimumHeaderPad
= parseAddress(size
);
2373 else if ( strcmp(arg
, "-headerpad_max_install_names") == 0 ) {
2374 fMaxMinimumHeaderPad
= true;
2376 else if ( strcmp(arg
, "-t") == 0 ) {
2377 fLogAllFiles
= true;
2379 else if ( strcmp(arg
, "-whatsloaded") == 0 ) {
2380 fLogObjectFiles
= true;
2382 else if ( strcmp(arg
, "-A") == 0 ) {
2386 else if ( strcmp(arg
, "-umbrella") == 0 ) {
2387 const char* name
= argv
[++i
];
2389 throw "-umbrella missing argument";
2390 fUmbrellaName
= name
;
2392 else if ( strcmp(arg
, "-allowable_client") == 0 ) {
2393 const char* name
= argv
[++i
];
2396 throw "-allowable_client missing argument";
2398 fAllowableClients
.push_back(name
);
2400 else if ( strcmp(arg
, "-client_name") == 0 ) {
2401 const char* name
= argv
[++i
];
2404 throw "-client_name missing argument";
2408 else if ( strcmp(arg
, "-sub_umbrella") == 0 ) {
2409 const char* name
= argv
[++i
];
2411 throw "-sub_umbrella missing argument";
2412 fSubUmbellas
.push_back(name
);
2414 else if ( strcmp(arg
, "-sub_library") == 0 ) {
2415 const char* name
= argv
[++i
];
2417 throw "-sub_library missing argument";
2418 fSubLibraries
.push_back(name
);
2420 else if ( strcmp(arg
, "-init") == 0 ) {
2421 const char* name
= argv
[++i
];
2423 throw "-init missing argument";
2424 fInitFunctionName
= name
;
2426 else if ( strcmp(arg
, "-dot") == 0 ) {
2427 const char* name
= argv
[++i
];
2429 throw "-dot missing argument";
2430 fDotOutputFile
= name
;
2432 else if ( strcmp(arg
, "-warn_commons") == 0 ) {
2433 fWarnCommons
= true;
2435 else if ( strcmp(arg
, "-commons") == 0 ) {
2436 fCommonsMode
= parseCommonsTreatment(argv
[++i
]);
2438 else if ( strcmp(arg
, "-keep_relocs") == 0 ) {
2439 fKeepRelocations
= true;
2441 else if ( strcmp(arg
, "-warn_stabs") == 0 ) {
2444 else if ( strcmp(arg
, "-pause") == 0 ) {
2447 else if ( strcmp(arg
, "-print_statistics") == 0 ) {
2450 else if ( strcmp(arg
, "-d") == 0 ) {
2451 fMakeTentativeDefinitionsReal
= true;
2453 else if ( strcmp(arg
, "-v") == 0 ) {
2454 // previously handled by buildSearchPaths()
2456 else if ( strcmp(arg
, "-Z") == 0 ) {
2457 // previously handled by buildSearchPaths()
2459 else if ( strcmp(arg
, "-syslibroot") == 0 ) {
2460 snapshotArgCount
= 0;
2462 // previously handled by buildSearchPaths()
2464 else if ( strcmp(arg
, "-no_uuid") == 0 ) {
2465 fUUIDMode
= kUUIDNone
;
2467 else if ( strcmp(arg
, "-random_uuid") == 0 ) {
2468 fUUIDMode
= kUUIDRandom
;
2470 else if ( strcmp(arg
, "-dtrace") == 0 ) {
2471 snapshotFileArgIndex
= 1;
2472 const char* name
= argv
[++i
];
2474 throw "-dtrace missing argument";
2475 fDtraceScriptName
= name
;
2477 else if ( strcmp(arg
, "-root_safe") == 0 ) {
2480 else if ( strcmp(arg
, "-setuid_safe") == 0 ) {
2483 else if ( strcmp(arg
, "-alias") == 0 ) {
2484 Options::AliasPair pair
;
2485 pair
.realName
= argv
[++i
];
2486 if ( pair
.realName
== NULL
)
2487 throw "missing argument to -alias";
2488 pair
.alias
= argv
[++i
];
2489 if ( pair
.alias
== NULL
)
2490 throw "missing argument to -alias";
2491 fAliases
.push_back(pair
);
2493 else if ( strcmp(arg
, "-alias_list") == 0 ) {
2494 snapshotFileArgIndex
= 1;
2495 parseAliasFile(argv
[++i
]);
2497 // put this last so that it does not interfer with other options starting with 'i'
2498 else if ( strncmp(arg
, "-i", 2) == 0 ) {
2499 const char* colon
= strchr(arg
, ':');
2500 if ( colon
== NULL
)
2501 throwf("unknown option: %s", arg
);
2502 Options::AliasPair pair
;
2503 char* temp
= new char[colon
-arg
];
2504 strlcpy(temp
, &arg
[2], colon
-arg
-1);
2505 pair
.realName
= &colon
[1];
2507 fAliases
.push_back(pair
);
2509 else if ( strcmp(arg
, "-save-temps") == 0 ) {
2510 fSaveTempFiles
= true;
2512 else if ( strcmp(arg
, "-rpath") == 0 ) {
2513 const char* path
= argv
[++i
];
2515 throw "missing argument to -rpath";
2516 fRPaths
.push_back(path
);
2518 else if ( strcmp(arg
, "-read_only_stubs") == 0 ) {
2519 fReadOnlyx86Stubs
= true;
2521 else if ( strcmp(arg
, "-slow_stubs") == 0 ) {
2524 else if ( strcmp(arg
, "-map") == 0 ) {
2525 fMapPath
= argv
[++i
];
2526 if ( fMapPath
== NULL
)
2527 throw "missing argument to -map";
2529 else if ( strcmp(arg
, "-pie") == 0 ) {
2530 fPositionIndependentExecutable
= true;
2531 fPIEOnCommandLine
= true;
2533 else if ( strcmp(arg
, "-no_pie") == 0 ) {
2534 fDisablePositionIndependentExecutable
= true;
2536 else if ( strncmp(arg
, "-reexport-l", 11) == 0 ) {
2537 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2538 snapshotArgCount
= 0;
2539 FileInfo info
= findLibrary(&arg
[11], true);
2540 info
.options
.fReExport
= true;
2541 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2544 else if ( strcmp(arg
, "-reexport_library") == 0 ) {
2545 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2546 snapshotArgCount
= 0;
2547 FileInfo info
= findFile(argv
[++i
]);
2548 info
.options
.fReExport
= true;
2549 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2552 else if ( strcmp(arg
, "-reexport_framework") == 0 ) {
2553 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2554 snapshotArgCount
= 0;
2555 FileInfo info
= findFramework(argv
[++i
]);
2556 info
.options
.fReExport
= true;
2557 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2560 else if ( strncmp(arg
, "-upward-l", 9) == 0 ) {
2561 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2562 snapshotArgCount
= 0;
2563 FileInfo info
= findLibrary(&arg
[9], true);
2564 info
.options
.fUpward
= true;
2565 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2568 else if ( strcmp(arg
, "-upward_library") == 0 ) {
2569 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2570 snapshotArgCount
= 0;
2571 FileInfo info
= findFile(argv
[++i
]);
2572 info
.options
.fUpward
= true;
2573 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2576 else if ( strcmp(arg
, "-upward_framework") == 0 ) {
2577 // SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
2578 snapshotArgCount
= 0;
2579 FileInfo info
= findFramework(argv
[++i
]);
2580 info
.options
.fUpward
= true;
2581 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2584 else if ( strcmp(arg
, "-dead_strip_dylibs") == 0 ) {
2585 fDeadStripDylibs
= true;
2587 else if ( strcmp(arg
, "-no_implicit_dylibs") == 0 ) {
2588 fImplicitlyLinkPublicDylibs
= false;
2590 else if ( strcmp(arg
, "-new_linker") == 0 ) {
2593 else if ( strcmp(arg
, "-no_encryption") == 0 ) {
2594 fEncryptable
= false;
2596 else if ( strcmp(arg
, "-no_compact_unwind") == 0 ) {
2597 fAddCompactUnwindEncoding
= false;
2599 else if ( strcmp(arg
, "-mllvm") == 0 ) {
2600 const char* opts
= argv
[++i
];
2602 throw "missing argument to -mllvm";
2603 fLLVMOptions
.push_back(opts
);
2605 else if ( strcmp(arg
, "-no_order_inits") == 0 ) {
2606 fAutoOrderInitializers
= false;
2608 else if ( strcmp(arg
, "-no_order_data") == 0 ) {
2611 else if ( strcmp(arg
, "-seg_page_size") == 0 ) {
2613 seg
.name
= argv
[++i
];
2614 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
2615 throw "-seg_page_size missing segName Adddress";
2616 seg
.size
= parseAddress(argv
[++i
]);
2617 uint64_t temp
= seg
.size
& (-4096); // page align
2618 if ( (seg
.size
!= temp
) )
2619 warning("-seg_page_size %s not 4K aligned, rounding down", seg
.name
);
2620 fCustomSegmentSizes
.push_back(seg
);
2622 else if ( strcmp(arg
, "-mark_dead_strippable_dylib") == 0 ) {
2623 fMarkDeadStrippableDylib
= true;
2625 else if ( strcmp(arg
, "-exported_symbols_order") == 0 ) {
2626 snapshotFileArgIndex
= 1;
2627 loadSymbolOrderFile(argv
[++i
], fExportSymbolsOrder
);
2629 else if ( strcmp(arg
, "-no_compact_linkedit") == 0 ) {
2630 warnObsolete("-no_compact_linkedit");
2632 else if ( strcmp(arg
, "-no_eh_labels") == 0 ) {
2635 else if ( strcmp(arg
, "-warn_compact_unwind") == 0 ) {
2636 fWarnCompactUnwind
= true;
2638 else if ( strcmp(arg
, "-allow_sub_type_mismatches") == 0 ) {
2639 fAllowCpuSubtypeMismatches
= true;
2641 else if ( strcmp(arg
, "-no_zero_fill_sections") == 0 ) {
2642 fOptimizeZeroFill
= false;
2644 else if ( strcmp(arg
, "-merge_zero_fill_sections") == 0 ) {
2645 fMergeZeroFill
= true;
2647 else if ( strcmp(arg
, "-objc_abi_version") == 0 ) {
2648 const char* version
= argv
[++i
];
2649 if ( version
== NULL
)
2650 throw "-objc_abi_version missing version number";
2651 if ( strcmp(version
, "2") == 0 ) {
2652 fObjCABIVersion1Override
= false;
2653 fObjCABIVersion2Override
= true;
2655 else if ( strcmp(version
, "1") == 0 ) {
2656 fObjCABIVersion1Override
= true;
2657 fObjCABIVersion2Override
= false;
2660 warning("ignoring unrecognized argument (%s) to -objc_abi_version", version
);
2662 else if ( strcmp(arg
, "-warn_weak_exports") == 0 ) {
2663 fWarnWeakExports
= true;
2665 else if ( strcmp(arg
, "-objc_gc_compaction") == 0 ) {
2666 fObjcGcCompaction
= true;
2668 else if ( strcmp(arg
, "-objc_gc") == 0 ) {
2670 if ( fObjCGcOnly
) {
2671 warning("-objc_gc overriding -objc_gc_only");
2672 fObjCGcOnly
= false;
2675 else if ( strcmp(arg
, "-objc_gc_only") == 0 ) {
2678 warning("-objc_gc_only overriding -objc_gc");
2682 else if ( strcmp(arg
, "-demangle") == 0 ) {
2685 else if ( strcmp(arg
, "-version_load_command") == 0 ) {
2686 fVersionLoadCommandForcedOn
= true;
2687 fVersionLoadCommandForcedOff
= false;
2689 else if ( strcmp(arg
, "-no_version_load_command") == 0 ) {
2690 fVersionLoadCommandForcedOff
= true;
2691 fVersionLoadCommandForcedOn
= false;
2693 else if ( strcmp(arg
, "-function_starts") == 0 ) {
2694 fFunctionStartsForcedOn
= true;
2695 fFunctionStartsForcedOff
= false;
2697 else if ( strcmp(arg
, "-no_function_starts") == 0 ) {
2698 fFunctionStartsForcedOff
= true;
2699 fFunctionStartsForcedOn
= false;
2701 else if ( strcmp(arg
, "-no_data_in_code_info") == 0 ) {
2702 fDataInCodeInfoLoadCommand
= false;
2704 else if ( strcmp(arg
, "-data_in_code_info") == 0 ) {
2705 fDataInCodeInfoLoadCommand
= true;
2707 else if ( strcmp(arg
, "-object_path_lto") == 0 ) {
2708 fTempLtoObjectPath
= argv
[++i
];
2709 if ( fTempLtoObjectPath
== NULL
)
2710 throw "missing argument to -object_path_lto";
2712 else if ( strcmp(arg
, "-no_objc_category_merging") == 0 ) {
2713 fObjcCategoryMerging
= false;
2715 else if ( strcmp(arg
, "-force_symbols_weak_list") == 0 ) {
2716 snapshotFileArgIndex
= 1;
2717 loadExportFile(argv
[++i
], "-force_symbols_weak_list", fForceWeakSymbols
);
2719 else if ( strcmp(arg
, "-force_symbols_not_weak_list") == 0 ) {
2720 snapshotFileArgIndex
= 1;
2721 loadExportFile(argv
[++i
], "-force_symbols_not_weak_list", fForceNotWeakSymbols
);
2723 else if ( strcmp(arg
, "-force_symbol_weak") == 0 ) {
2724 const char* symbol
= argv
[++i
];
2725 if ( symbol
== NULL
)
2726 throw "-force_symbol_weak missing <symbol>";
2727 fForceWeakSymbols
.insert(symbol
);
2729 else if ( strcmp(arg
, "-force_symbol_not_weak") == 0 ) {
2730 const char* symbol
= argv
[++i
];
2731 if ( symbol
== NULL
)
2732 throw "-force_symbol_not_weak missing <symbol>";
2733 fForceNotWeakSymbols
.insert(symbol
);
2735 else if ( strcmp(arg
, "-reexported_symbols_list") == 0 ) {
2736 snapshotFileArgIndex
= 1;
2737 if ( fExportMode
== kExportSome
)
2738 throw "can't use -exported_symbols_list and -reexported_symbols_list";
2739 loadExportFile(argv
[++i
], "-reexported_symbols_list", fReExportSymbols
);
2741 else if ( strcmp(arg
, "-dyld_env") == 0 ) {
2742 const char* envarg
= argv
[++i
];
2743 if ( envarg
== NULL
)
2744 throw "-dyld_env missing ENV=VALUE";
2745 if ( strchr(envarg
, '=') == NULL
)
2746 throw "-dyld_env missing ENV=VALUE";
2747 fDyldEnvironExtras
.push_back(envarg
);
2749 else if ( strcmp(arg
, "-page_align_data_atoms") == 0 ) {
2750 fPageAlignDataAtoms
= true;
2752 else if (strcmp(arg
, "-debug_snapshot") == 0) {
2753 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
2754 fSnapshotRequested
= true;
2756 else if ( strcmp(arg
, "-new_main") == 0 ) {
2757 fEntryPointLoadCommandForceOn
= true;
2759 else if ( strcmp(arg
, "-no_new_main") == 0 ) {
2760 fEntryPointLoadCommandForceOff
= true;
2762 else if ( strcmp(arg
, "-source_version") == 0 ) {
2763 const char* vers
= argv
[++i
];
2765 throw "-source_version missing <version>";
2766 fSourceVersion
= parseVersionNumber64(vers
);
2768 else if ( strcmp(arg
, "-add_source_version") == 0 ) {
2769 fSourceVersionLoadCommandForceOn
= true;
2771 else if ( strcmp(arg
, "-no_source_version") == 0 ) {
2772 fSourceVersionLoadCommandForceOff
= true;
2774 else if ( strcmp(arg
, "-sdk_version") == 0 ) {
2775 const char* vers
= argv
[++i
];
2777 throw "-sdk_version missing <version>";
2778 fSDKVersion
= parseVersionNumber32(vers
);
2780 else if ( strcmp(arg
, "-dependent_dr_info") == 0 ) {
2781 fDependentDRInfoForcedOn
= true;
2783 else if ( strcmp(arg
, "-no_dependent_dr_info") == 0 ) {
2784 fDependentDRInfoForcedOff
= true;
2786 else if ( strcmp(arg
, "-kexts_use_stubs") == 0 ) {
2787 fKextsUseStubs
= true;
2790 throwf("unknown option: %s", arg
);
2793 if (snapshotArgCount
== -1)
2794 snapshotArgCount
= i
-snapshotArgIndex
+1;
2795 if (snapshotArgCount
> 0)
2796 fLinkSnapshot
.addSnapshotLinkArg(snapshotArgIndex
, snapshotArgCount
, snapshotFileArgIndex
);
2799 FileInfo info
= findFile(arg
);
2800 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)i
);
2801 if ( strcmp(&info
.path
[strlen(info
.path
)-2], ".a") == 0 )
2804 fInputFiles
.push_back(info
);
2808 // if a -lazy option was used, implicitly link in lazydylib1.o
2809 if ( fUsingLazyDylibLinking
) {
2810 FileInfo info
= findLibrary("lazydylib1.o");
2811 info
.ordinal
= ld::File::Ordinal::makeArgOrdinal((uint16_t)argc
);
2815 if (fSnapshotRequested
)
2816 fLinkSnapshot
.createSnapshot();
2822 // -syslibroot <path> is used for SDK support.
2823 // The rule is that all search paths (both explicit and default) are
2824 // checked to see if they exist in the SDK. If so, that path is
2825 // replaced with the sdk prefixed path. If not, that search path
2826 // is used as is. If multiple -syslibroot options are specified
2827 // their directory structures are logically overlayed and files
2828 // from sdks specified earlier on the command line used before later ones.
2830 void Options::buildSearchPaths(int argc
, const char* argv
[])
2832 bool addStandardLibraryDirectories
= true;
2833 std::vector
<const char*> libraryPaths
;
2834 std::vector
<const char*> frameworkPaths
;
2835 libraryPaths
.reserve(10);
2836 frameworkPaths
.reserve(10);
2837 // scan through argv looking for -L, -F, -Z, and -syslibroot options
2838 for(int i
=0; i
< argc
; ++i
) {
2839 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') ) {
2840 const char* libSearchDir
= &argv
[i
][2];
2841 // Allow either "-L{path}" or "-L {path}".
2842 if (argv
[i
][2] == '\0') {
2843 // -L {path}. Make sure there is an argument following this.
2844 const char* path
= argv
[++i
];
2846 throw "-L missing argument";
2847 libSearchDir
= path
;
2849 if ( libSearchDir
[0] == '\0' )
2850 throw "-L must be immediately followed by a directory path (no space)";
2851 struct stat statbuf
;
2852 if ( stat(libSearchDir
, &statbuf
) == 0 ) {
2853 if ( statbuf
.st_mode
& S_IFDIR
)
2854 libraryPaths
.push_back(libSearchDir
);
2856 warning("path '%s' following -L not a directory", libSearchDir
);
2859 warning("directory not found for option '-L%s'", libSearchDir
);
2862 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') ) {
2863 const char* frameworkSearchDir
= &argv
[i
][2];
2864 // Allow either "-F{path}" or "-F {path}".
2865 if (argv
[i
][2] == '\0') {
2866 // -F {path}. Make sure there is an argument following this.
2867 const char* path
= argv
[++i
];
2869 throw "-F missing argument";
2870 frameworkSearchDir
= path
;
2872 if ( frameworkSearchDir
[0] == '\0' )
2873 throw "-F must be immediately followed by a directory path (no space)";
2874 struct stat statbuf
;
2875 if ( stat(frameworkSearchDir
, &statbuf
) == 0 ) {
2876 if ( statbuf
.st_mode
& S_IFDIR
)
2877 frameworkPaths
.push_back(frameworkSearchDir
);
2879 warning("path '%s' following -F not a directory", frameworkSearchDir
);
2882 warning("directory not found for option '-F%s'", frameworkSearchDir
);
2885 else if ( strcmp(argv
[i
], "-Z") == 0 )
2886 addStandardLibraryDirectories
= false;
2887 else if ( strcmp(argv
[i
], "-v") == 0 ) {
2889 extern const char ldVersionString
[];
2890 fprintf(stderr
, "%s", ldVersionString
);
2891 fprintf(stderr
, "configured to support archs: %s\n", ALL_SUPPORTED_ARCHS
);
2892 // if only -v specified, exit cleanly
2894 const char* ltoVers
= lto::version();
2895 if ( ltoVers
!= NULL
)
2896 fprintf(stderr
, "LTO support using: %s\n", ltoVers
);
2900 else if ( strcmp(argv
[i
], "-syslibroot") == 0 ) {
2901 const char* path
= argv
[++i
];
2903 throw "-syslibroot missing argument";
2904 fSDKPaths
.push_back(path
);
2906 else if ( strcmp(argv
[i
], "-search_paths_first") == 0 ) {
2907 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
2909 else if ( strcmp(argv
[i
], "-search_dylibs_first") == 0 ) {
2910 fLibrarySearchMode
= kSearchAllDirsForDylibsThenAllDirsForArchives
;
2912 else if ( strcmp(argv
[i
], "-w") == 0 ) {
2913 sEmitWarnings
= false;
2915 else if ( strcmp(argv
[i
], "-fatal_warnings") == 0 ) {
2916 sFatalWarnings
= true;
2919 int standardLibraryPathsStartIndex
= libraryPaths
.size();
2920 int standardFrameworkPathsStartIndex
= frameworkPaths
.size();
2921 if ( addStandardLibraryDirectories
) {
2922 libraryPaths
.push_back("/usr/lib");
2923 libraryPaths
.push_back("/usr/local/lib");
2925 frameworkPaths
.push_back("/Library/Frameworks/");
2926 frameworkPaths
.push_back("/System/Library/Frameworks/");
2927 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
2930 // <rdar://problem/5829579> Support for configure based hacks
2931 // if last -syslibroot is /, then ignore all syslibroots
2932 if ( fSDKPaths
.size() > 0 ) {
2933 if ( strcmp(fSDKPaths
.back(), "/") == 0 ) {
2938 // now merge sdk and library paths to make real search paths
2939 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
2941 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); ++it
, ++libIndex
) {
2942 const char* libDir
= *it
;
2943 bool sdkOverride
= false;
2944 if ( libDir
[0] == '/' ) {
2945 char betterLibDir
[PATH_MAX
];
2946 if ( strstr(libDir
, "/..") != NULL
) {
2947 if ( realpath(libDir
, betterLibDir
) != NULL
)
2948 libDir
= strdup(betterLibDir
);
2950 const int libDirLen
= strlen(libDir
);
2951 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2952 const char* sdkDir
= *sdkit
;
2953 const int sdkDirLen
= strlen(sdkDir
);
2954 char newPath
[libDirLen
+ sdkDirLen
+4];
2955 strcpy(newPath
, sdkDir
);
2956 if ( newPath
[sdkDirLen
-1] == '/' )
2957 newPath
[sdkDirLen
-1] = '\0';
2958 strcat(newPath
, libDir
);
2959 struct stat statBuffer
;
2960 if ( stat(newPath
, &statBuffer
) == 0 ) {
2961 fLibrarySearchPaths
.push_back(strdup(newPath
));
2966 if ( !sdkOverride
) {
2967 if ( (libIndex
>= standardLibraryPathsStartIndex
) && (fSDKPaths
.size() == 1) ) {
2968 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
2969 // if one SDK is specified and a standard library path is not in the SDK, don't use it
2972 fLibrarySearchPaths
.push_back(libDir
);
2977 // now merge sdk and framework paths to make real search paths
2978 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
2980 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); ++it
, ++frameIndex
) {
2981 const char* frameworkDir
= *it
;
2982 bool sdkOverride
= false;
2983 if ( frameworkDir
[0] == '/' ) {
2984 char betterFrameworkDir
[PATH_MAX
];
2985 if ( strstr(frameworkDir
, "/..") != NULL
) {
2986 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
2987 frameworkDir
= strdup(betterFrameworkDir
);
2989 const int frameworkDirLen
= strlen(frameworkDir
);
2990 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2991 const char* sdkDir
= *sdkit
;
2992 const int sdkDirLen
= strlen(sdkDir
);
2993 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
2994 strcpy(newPath
, sdkDir
);
2995 if ( newPath
[sdkDirLen
-1] == '/' )
2996 newPath
[sdkDirLen
-1] = '\0';
2997 strcat(newPath
, frameworkDir
);
2998 struct stat statBuffer
;
2999 if ( stat(newPath
, &statBuffer
) == 0 ) {
3000 fFrameworkSearchPaths
.push_back(strdup(newPath
));
3005 if ( !sdkOverride
) {
3006 if ( (frameIndex
>= standardFrameworkPathsStartIndex
) && (fSDKPaths
.size() == 1) ) {
3007 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
3008 // if one SDK is specified and a standard library path is not in the SDK, don't use it
3011 fFrameworkSearchPaths
.push_back(frameworkDir
);
3017 fprintf(stderr
,"Library search paths:\n");
3018 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
3019 it
!= fLibrarySearchPaths
.end();
3021 fprintf(stderr
,"\t%s\n", *it
);
3022 fprintf(stderr
,"Framework search paths:\n");
3023 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
3024 it
!= fFrameworkSearchPaths
.end();
3026 fprintf(stderr
,"\t%s\n", *it
);
3030 // this is run before the command line is parsed
3031 void Options::parsePreCommandLineEnvironmentSettings()
3033 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
3034 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
3035 fTraceArchives
= true;
3037 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
3038 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
3039 fTraceDylibs
= true;
3040 fTraceIndirectDylibs
= true;
3043 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
3044 fTraceDylibSearching
= true;
3047 if (getenv("LD_PRINT_OPTIONS") != NULL
)
3048 fPrintOptions
= true;
3050 if (fTraceDylibs
|| fTraceArchives
)
3051 fTraceOutputFile
= getenv("LD_TRACE_FILE");
3053 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL
)
3054 fPrintOrderFileStatistics
= true;
3056 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL
)
3059 if (getenv("LD_NO_ENCRYPT") != NULL
)
3060 fEncryptable
= false;
3062 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL
)
3063 fAllowCpuSubtypeMismatches
= true;
3065 sWarningsSideFilePath
= getenv("LD_WARN_FILE");
3067 const char* customDyldPath
= getenv("LD_DYLD_PATH");
3068 if ( customDyldPath
!= NULL
)
3069 fDyldInstallPath
= customDyldPath
;
3071 const char* debugArchivePath
= getenv("LD_DEBUG_SNAPSHOT");
3072 if (debugArchivePath
!= NULL
) {
3073 fLinkSnapshot
.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG
);
3074 if (strlen(debugArchivePath
) > 0)
3075 fLinkSnapshot
.setSnapshotPath(debugArchivePath
);
3076 fSnapshotRequested
= true;
3079 const char* pipeFdString
= getenv("LD_PIPELINE_FIFO");
3080 if (pipeFdString
!= NULL
) {
3081 fPipelineFifo
= pipeFdString
;
3086 // this is run after the command line is parsed
3087 void Options::parsePostCommandLineEnvironmentSettings()
3089 // when building a dynamic main executable, default any use of @executable_path to output path
3090 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
3091 fExecutablePath
= fOutputFile
;
3094 // allow build system to set default seg_addr_table
3095 if ( fSegAddrTablePath
== NULL
)
3096 fSegAddrTablePath
= getenv("LD_SEG_ADDR_TABLE");
3098 // allow build system to turn on prebinding
3100 fPrebind
= ( getenv("LD_PREBIND") != NULL
);
3103 // allow build system to force on dead-code-stripping
3104 if ( !fDeadStrip
) {
3105 if ( getenv("LD_DEAD_STRIP") != NULL
) {
3106 switch (fOutputKind
) {
3107 case Options::kDynamicLibrary
:
3108 case Options::kDynamicExecutable
:
3109 case Options::kDynamicBundle
:
3112 case Options::kPreload
:
3113 case Options::kObjectFile
:
3114 case Options::kDyld
:
3115 case Options::kStaticExecutable
:
3116 case Options::kKextBundle
:
3122 // allow build system to force on -warn_commons
3123 if ( getenv("LD_WARN_COMMONS") != NULL
)
3124 fWarnCommons
= true;
3126 // allow B&I to set default -source_version
3127 if ( fSourceVersion
== 0 ) {
3128 const char* vers
= getenv("RC_ProjectSourceVersion");
3130 fSourceVersion
= parseVersionNumber64(vers
);
3135 void Options::reconfigureDefaults()
3137 // sync reader options
3138 switch ( fOutputKind
) {
3139 case Options::kObjectFile
:
3140 fForFinalLinkedImage
= false;
3142 case Options::kDyld
:
3144 fForFinalLinkedImage
= true;
3147 case Options::kDynamicLibrary
:
3148 case Options::kDynamicBundle
:
3149 case Options::kKextBundle
:
3150 fForFinalLinkedImage
= true;
3153 case Options::kDynamicExecutable
:
3154 case Options::kStaticExecutable
:
3155 case Options::kPreload
:
3156 fLinkingMainExecutable
= true;
3157 fForFinalLinkedImage
= true;
3162 // set default min OS version
3163 if ( (fMacVersionMin
== ld::macVersionUnset
)
3164 && (fIOSVersionMin
== ld::iOSVersionUnset
) ) {
3165 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
3166 const char* macVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
3167 const char* iPhoneVers
= getenv("IPHONEOS_DEPLOYMENT_TARGET");
3168 const char* iOSVers
= getenv("IOS_DEPLOYMENT_TARGET");
3169 const char* iOSSimulatorVers
= getenv("IOS_SIMULATOR_DEPLOYMENT_TARGET");
3170 if ( macVers
!= NULL
)
3171 setMacOSXVersionMin(macVers
);
3172 else if ( iPhoneVers
!= NULL
)
3173 setIOSVersionMin(iPhoneVers
);
3174 else if ( iOSVers
!= NULL
)
3175 setIOSVersionMin(iOSVers
);
3176 else if ( iOSSimulatorVers
!= NULL
)
3177 setIOSVersionMin(iOSSimulatorVers
);
3179 // if still nothing, set default based on architecture
3180 switch ( fArchitecture
) {
3182 case CPU_TYPE_X86_64
:
3183 if ( (fOutputKind
!= Options::kObjectFile
) && (fOutputKind
!= Options::kPreload
) ) {
3184 #ifdef DEFAULT_MACOSX_MIN_VERSION
3185 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
3186 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
3188 warning("-macosx_version_min not specified, assuming 10.6");
3189 fMacVersionMin
= ld::mac10_6
;
3194 if ( (fOutputKind
!= Options::kObjectFile
) && (fOutputKind
!= Options::kPreload
) ) {
3195 #if defined(DEFAULT_IPHONEOS_MIN_VERSION)
3196 warning("-ios_version_min not specified, assuming " DEFAULT_IPHONEOS_MIN_VERSION
);
3197 setIOSVersionMin(DEFAULT_IPHONEOS_MIN_VERSION
);
3198 #elif defined(DEFAULT_MACOSX_MIN_VERSION)
3199 warning("-macosx_version_min not specified, assuming " DEFAULT_MACOSX_MIN_VERSION
);
3200 setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION
);
3202 warning("-macosx_version_min not specified, assuming 10.6");
3203 fMacVersionMin
= ld::mac10_6
;
3208 // architecture will be infered ;ater by examining .o files
3215 // adjust min based on architecture
3216 switch ( fArchitecture
) {
3218 if ( (fMacVersionMin
< ld::mac10_4
) && (fIOSVersionMin
== ld::iOSVersionUnset
) ) {
3219 //warning("-macosx_version_min should be 10.4 or later for i386");
3220 fMacVersionMin
= ld::mac10_4
;
3223 case CPU_TYPE_X86_64
:
3224 if ( (fMacVersionMin
< ld::mac10_4
) && (fIOSVersionMin
== ld::iOSVersionUnset
) ) {
3225 //warning("-macosx_version_min should be 10.4 or later for x86_64");
3226 fMacVersionMin
= ld::mac10_4
;
3231 // adjust kext type based on architecture
3232 if ( fOutputKind
== kKextBundle
) {
3233 switch ( fArchitecture
) {
3234 case CPU_TYPE_X86_64
:
3235 // x86_64 uses new MH_KEXT_BUNDLE type
3236 fMakeCompressedDyldInfo
= false;
3237 fMakeCompressedDyldInfoForceOff
= true;
3238 fAllowTextRelocs
= true;
3239 fUndefinedTreatment
= kUndefinedDynamicLookup
;
3242 if ( fIOSVersionMin
>= ld::iOS_5_0
) {
3243 // iOS 5.0 and later use new MH_KEXT_BUNDLE type
3244 fMakeCompressedDyldInfo
= false;
3245 fMakeCompressedDyldInfoForceOff
= true;
3246 fAllowTextRelocs
= true;
3247 fKextsUseStubs
= !fAllowTextRelocs
;
3248 fUndefinedTreatment
= kUndefinedDynamicLookup
;
3251 // else use object file
3254 fOutputKind
= kObjectFile
;
3259 // disable implicit dylibs when targeting 10.3
3260 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
3261 if ( !minOS(ld::mac10_4
, ld::iOS_2_0
) )
3262 fImplicitlyLinkPublicDylibs
= false;
3265 // allow build system to force linker to ignore -prebind
3266 if ( getenv("LD_FORCE_NO_PREBIND") != NULL
)
3269 // allow build system to force linker to ignore -seg_addr_table
3270 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL
)
3271 fSegAddrTablePath
= NULL
;
3273 // check for base address specified externally
3274 if ( (fSegAddrTablePath
!= NULL
) && (fOutputKind
== Options::kDynamicLibrary
) ) {
3275 parseSegAddrTable(fSegAddrTablePath
, this->installPath());
3276 // HACK to support seg_addr_table entries that are physical paths instead of install paths
3277 if ( fBaseAddress
== 0 ) {
3278 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
3279 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.4.dylib");
3280 if ( fBaseAddress
== 0 )
3281 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.9.dylib");
3284 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
3285 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libz.1.2.3.dylib");
3287 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
3288 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libutil1.0.dylib");
3292 // split segs only allowed for dylibs
3294 // split seg only supported for i386, and arm.
3295 switch ( fArchitecture
) {
3297 if ( fOutputKind
!= Options::kDynamicLibrary
)
3299 // make sure read and write segments are proper distance apart
3300 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x10000000) )
3301 fBaseWritableAddress
= fBaseAddress
+ 0x10000000;
3304 if ( fOutputKind
!= Options::kDynamicLibrary
) {
3308 // make sure read and write segments are proper distance apart
3309 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x08000000) )
3310 fBaseWritableAddress
= fBaseAddress
+ 0x08000000;
3316 fBaseWritableAddress
= 0;
3320 // set too-large size
3321 switch ( fArchitecture
) {
3323 fMaxAddress
= 0xFFFFFFFF;
3325 case CPU_TYPE_X86_64
:
3328 switch ( fOutputKind
) {
3329 case Options::kDynamicExecutable
:
3330 case Options::kDynamicLibrary
:
3331 case Options::kDynamicBundle
:
3332 // user land code is limited to low 1GB
3333 fMaxAddress
= 0x2FFFFFFF;
3335 case Options::kStaticExecutable
:
3336 case Options::kObjectFile
:
3337 case Options::kDyld
:
3338 case Options::kPreload
:
3339 case Options::kKextBundle
:
3340 fMaxAddress
= 0xFFFFFFFF;
3343 // range check -seg1addr for ARM
3344 if ( fBaseAddress
> fMaxAddress
) {
3345 warning("ignoring -seg1addr 0x%08llX. Address out of range.", fBaseAddress
);
3351 // <rdar://problem/6138961> -r implies no prebinding for all architectures
3352 if ( fOutputKind
== Options::kObjectFile
)
3355 // disable prebinding depending on arch and min OS version
3357 switch ( fArchitecture
) {
3359 if ( fMacVersionMin
== ld::mac10_4
) {
3360 // in 10.4 only split seg dylibs are prebound
3361 if ( (fOutputKind
!= Options::kDynamicLibrary
) || ! fSplitSegs
)
3364 else if ( fMacVersionMin
>= ld::mac10_5
) {
3365 // in 10.5 nothing is prebound
3368 else if ( fIOSVersionMin
!= ld::iOSVersionUnset
) {
3369 // nothing in simulator is prebound
3373 // in 10.3 and earlier only dylibs and main executables could be prebound
3374 switch ( fOutputKind
) {
3375 case Options::kDynamicExecutable
:
3376 case Options::kDynamicLibrary
:
3377 // only main executables and dylibs can be prebound
3379 case Options::kStaticExecutable
:
3380 case Options::kDynamicBundle
:
3381 case Options::kObjectFile
:
3382 case Options::kDyld
:
3383 case Options::kPreload
:
3384 case Options::kKextBundle
:
3385 // disable prebinding for everything else
3391 case CPU_TYPE_X86_64
:
3395 switch ( fOutputKind
) {
3396 case Options::kDynamicExecutable
:
3397 case Options::kDynamicLibrary
:
3398 // only main executables and dylibs can be prebound
3400 case Options::kStaticExecutable
:
3401 case Options::kDynamicBundle
:
3402 case Options::kObjectFile
:
3403 case Options::kDyld
:
3404 case Options::kPreload
:
3405 case Options::kKextBundle
:
3406 // disable prebinding for everything else
3414 // only prebound images can be split-seg
3415 if ( fSplitSegs
&& !fPrebind
)
3418 // determine if info for shared region should be added
3419 if ( fOutputKind
== Options::kDynamicLibrary
) {
3420 if ( minOS(ld::mac10_5
, ld::iOS_3_1
) )
3422 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
3423 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
3424 fSharedRegionEligible
= true;
3426 else if ( fOutputKind
== Options::kDyld
) {
3427 // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
3428 fSharedRegionEligible
= true;
3431 // figure out if module table is needed for compatibility with old ld/dyld
3432 if ( fOutputKind
== Options::kDynamicLibrary
) {
3433 switch ( fArchitecture
) {
3435 if ( fIOSVersionMin
!= ld::iOSVersionUnset
) // simulator never needs modules
3439 fNeedsModuleTable
= true; // redo_prebinding requires a module table
3444 // <rdar://problem/5366363> -r -x implies -S
3445 if ( (fOutputKind
== Options::kObjectFile
) && (fLocalSymbolHandling
== kLocalSymbolsNone
) )
3446 fDebugInfoStripping
= Options::kDebugInfoNone
;
3448 // choose how to process unwind info
3449 switch ( fArchitecture
) {
3451 case CPU_TYPE_X86_64
:
3452 switch ( fOutputKind
) {
3453 case Options::kObjectFile
:
3454 case Options::kStaticExecutable
:
3455 case Options::kPreload
:
3456 case Options::kKextBundle
:
3457 fAddCompactUnwindEncoding
= false;
3459 case Options::kDyld
:
3460 case Options::kDynamicLibrary
:
3461 case Options::kDynamicBundle
:
3462 case Options::kDynamicExecutable
:
3463 //if ( fAddCompactUnwindEncoding && (fVersionMin >= ld::mac10_6) )
3464 // fRemoveDwarfUnwindIfCompactExists = true;
3469 fAddCompactUnwindEncoding
= false;
3470 fRemoveDwarfUnwindIfCompactExists
= false;
3473 // if -arch is missing, assume we don't want compact unwind info
3474 fAddCompactUnwindEncoding
= false;
3478 // only ARM main executables can be encrypted
3479 if ( fOutputKind
!= Options::kDynamicExecutable
)
3480 fEncryptable
= false;
3481 if ( fArchitecture
!= CPU_TYPE_ARM
)
3482 fEncryptable
= false;
3484 // don't move inits in dyld because dyld wants certain
3485 // entries point at stable locations at the start of __text
3486 if ( fOutputKind
== Options::kDyld
)
3487 fAutoOrderInitializers
= false;
3490 // disable __data ordering for some output kinds
3491 switch ( fOutputKind
) {
3492 case Options::kObjectFile
:
3493 case Options::kDyld
:
3494 case Options::kStaticExecutable
:
3495 case Options::kPreload
:
3496 case Options::kKextBundle
:
3499 case Options::kDynamicExecutable
:
3500 case Options::kDynamicLibrary
:
3501 case Options::kDynamicBundle
:
3505 // only use compressed LINKEDIT for final linked images
3506 switch ( fOutputKind
) {
3507 case Options::kDynamicExecutable
:
3508 case Options::kDynamicLibrary
:
3509 case Options::kDynamicBundle
:
3511 case Options::kPreload
:
3512 case Options::kStaticExecutable
:
3513 case Options::kObjectFile
:
3514 case Options::kDyld
:
3515 case Options::kKextBundle
:
3516 fMakeCompressedDyldInfoForceOff
= true;
3519 if ( fMakeCompressedDyldInfoForceOff
)
3520 fMakeCompressedDyldInfo
= false;
3523 // only use compressed LINKEDIT for:
3524 // Mac OS X 10.6 or later
3526 if ( fMakeCompressedDyldInfo
) {
3527 if ( !minOS(ld::mac10_6
, ld::iOS_3_1
) )
3528 fMakeCompressedDyldInfo
= false;
3532 // only ARM enforces that cpu-sub-types must match
3533 if ( fArchitecture
!= CPU_TYPE_ARM
)
3534 fAllowCpuSubtypeMismatches
= true;
3536 // only final linked images can not optimize zero fill sections
3537 if ( fOutputKind
== Options::kObjectFile
)
3538 fOptimizeZeroFill
= true;
3540 // all undefines in -r mode
3541 // if ( fOutputKind == Options::kObjectFile )
3542 // fUndefinedTreatment = kUndefinedSuppress;
3544 // only dynamic final linked images should warn about use of commmons
3545 if ( fWarnCommons
) {
3546 switch ( fOutputKind
) {
3547 case Options::kDynamicExecutable
:
3548 case Options::kDynamicLibrary
:
3549 case Options::kDynamicBundle
:
3551 case Options::kPreload
:
3552 case Options::kStaticExecutable
:
3553 case Options::kObjectFile
:
3554 case Options::kDyld
:
3555 case Options::kKextBundle
:
3556 fWarnCommons
= false;
3561 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
3562 if ( minOS(ld::mac10_5
, ld::iOS_2_0
) )
3563 fUseSimplifiedDylibReExports
= true;
3565 // Mac OS X 10.7 and iOS 4.2 support LC_LOAD_UPWARD_DYLIB
3566 if ( minOS(ld::mac10_7
, ld::iOS_4_2
) && (fOutputKind
== kDynamicLibrary
) )
3567 fCanUseUpwardDylib
= true;
3569 // MacOSX 10.7 defaults to PIE
3570 if ( ((fArchitecture
== CPU_TYPE_X86_64
) || (fArchitecture
== CPU_TYPE_I386
))
3571 && (fOutputKind
== kDynamicExecutable
)
3572 && (fMacVersionMin
>= ld::mac10_7
) ) {
3573 fPositionIndependentExecutable
= true;
3576 // armv7 for iOS4.3 defaults to PIE
3577 if ( (fArchitecture
== CPU_TYPE_ARM
)
3578 && fArchSupportsThumb2
3579 && (fOutputKind
== kDynamicExecutable
)
3580 && (fIOSVersionMin
>= ld::iOS_4_3
) ) {
3581 fPositionIndependentExecutable
= true;
3584 // -no_pie anywhere on command line disable PIE
3585 if ( fDisablePositionIndependentExecutable
)
3586 fPositionIndependentExecutable
= false;
3588 // set fOutputSlidable
3589 switch ( fOutputKind
) {
3590 case Options::kObjectFile
:
3591 fOutputSlidable
= false;
3593 case Options::kStaticExecutable
:
3594 case Options::kDynamicExecutable
:
3595 fOutputSlidable
= fPositionIndependentExecutable
;
3597 case Options::kPreload
:
3598 fOutputSlidable
= fPIEOnCommandLine
;
3600 case Options::kDyld
:
3601 case Options::kDynamicLibrary
:
3602 case Options::kDynamicBundle
:
3603 case Options::kKextBundle
:
3604 fOutputSlidable
= true;
3608 // let linker know if thread local variables are supported
3609 if ( fMacVersionMin
>= ld::mac10_7
) {
3613 // default to adding version load command for dynamic code, static code must opt-in
3614 switch ( fOutputKind
) {
3615 case Options::kObjectFile
:
3616 fVersionLoadCommand
= false;
3618 case Options::kStaticExecutable
:
3619 case Options::kPreload
:
3620 case Options::kKextBundle
:
3621 if ( fVersionLoadCommandForcedOn
)
3622 fVersionLoadCommand
= true;
3624 case Options::kDynamicExecutable
:
3625 case Options::kDyld
:
3626 case Options::kDynamicLibrary
:
3627 case Options::kDynamicBundle
:
3628 if ( !fVersionLoadCommandForcedOff
)
3629 fVersionLoadCommand
= true;
3630 // <rdar://problem/9945513> for now, don't create version load commands for iOS simulator builds
3631 if ( fVersionLoadCommand
&& (fArchitecture
== CPU_TYPE_I386
) ) {
3632 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
3633 if ( strstr(*sdkit
, "/iPhoneSimulator.platform/") != NULL
)
3634 fVersionLoadCommand
= false;
3640 // default to adding functions start for dynamic code, static code must opt-in
3641 switch ( fOutputKind
) {
3642 case Options::kObjectFile
:
3643 fFunctionStartsLoadCommand
= false;
3644 fDataInCodeInfoLoadCommand
= false;
3646 case Options::kPreload
:
3647 case Options::kStaticExecutable
:
3648 case Options::kKextBundle
:
3649 fDataInCodeInfoLoadCommand
= false;
3650 if ( fFunctionStartsForcedOn
)
3651 fFunctionStartsLoadCommand
= true;
3653 case Options::kDynamicExecutable
:
3654 case Options::kDyld
:
3655 case Options::kDynamicLibrary
:
3656 case Options::kDynamicBundle
:
3657 if ( !fFunctionStartsForcedOff
)
3658 fFunctionStartsLoadCommand
= true;
3662 // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
3663 if ( (fOutputKind
== kDynamicLibrary
) && minOS(ld::mac10_7
, ld::iOS_4_2
) )
3664 fCanReExportSymbols
= true;
3666 // ObjC optimization is only in dynamic final linked images
3667 switch ( fOutputKind
) {
3668 case Options::kObjectFile
:
3669 case Options::kStaticExecutable
:
3670 case Options::kPreload
:
3671 case Options::kKextBundle
:
3672 case Options::kDyld
:
3673 fObjcCategoryMerging
= false;
3675 case Options::kDynamicExecutable
:
3676 case Options::kDynamicLibrary
:
3677 case Options::kDynamicBundle
:
3681 // i386 main executables linked on Mac OS X 10.7 default to NX heap
3682 // regardless of target unless overriden with -allow_heap_execute anywhere
3683 // on the command line
3684 if ( (fArchitecture
== CPU_TYPE_I386
) && (fOutputKind
== kDynamicExecutable
) && !fDisableNonExecutableHeap
)
3685 fNonExecutableHeap
= true;
3687 // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
3688 switch ( fOutputKind
) {
3689 case Options::kDynamicExecutable
:
3690 if ( fEntryPointLoadCommandForceOn
) {
3691 fEntryPointLoadCommand
= true;
3692 fEntryName
= "_main";
3694 else if ( fEntryPointLoadCommandForceOff
) {
3695 fNeedsThreadLoadCommand
= true;
3698 if ( minOS(ld::mac10_8
, ld::iOS_Future
) ) {
3699 fEntryPointLoadCommand
= true;
3700 fEntryName
= "_main";
3703 fNeedsThreadLoadCommand
= true;
3706 case Options::kObjectFile
:
3707 case Options::kKextBundle
:
3708 case Options::kDynamicLibrary
:
3709 case Options::kDynamicBundle
:
3712 case Options::kStaticExecutable
:
3713 case Options::kPreload
:
3714 case Options::kDyld
:
3715 fNeedsThreadLoadCommand
= true;
3719 // add LC_SOURCE_VERSION
3720 switch ( fOutputKind
) {
3721 case Options::kDynamicExecutable
:
3722 case Options::kKextBundle
:
3723 case Options::kDynamicLibrary
:
3724 case Options::kDynamicBundle
:
3725 case Options::kDyld
:
3726 case Options::kStaticExecutable
:
3727 if ( fSourceVersionLoadCommandForceOn
) {
3728 fSourceVersionLoadCommand
= true;
3730 else if ( fSourceVersionLoadCommandForceOff
) {
3731 fSourceVersionLoadCommand
= false;
3734 if ( minOS(ld::mac10_8
, ld::iOS_Future
) ) {
3735 fSourceVersionLoadCommand
= true;
3738 fSourceVersionLoadCommand
= false;
3741 case Options::kObjectFile
:
3742 case Options::kPreload
:
3743 fSourceVersionLoadCommand
= false;
3748 // add LC_DYLIB_CODE_SIGN_DRS
3749 switch ( fOutputKind
) {
3750 case Options::kDynamicExecutable
:
3751 case Options::kDynamicLibrary
:
3752 case Options::kDynamicBundle
:
3753 if ( fDependentDRInfoForcedOn
) {
3754 fDependentDRInfo
= true;
3756 else if ( fDependentDRInfoForcedOff
) {
3757 fDependentDRInfo
= false;
3760 if ( minOS(ld::mac10_8
, ld::iOS_Future
) )
3761 fDependentDRInfo
= true;
3763 fDependentDRInfo
= false;
3766 case Options::kKextBundle
:
3767 case Options::kDyld
:
3768 case Options::kStaticExecutable
:
3769 case Options::kObjectFile
:
3770 case Options::kPreload
:
3771 fDependentDRInfo
= false;
3775 // if -sdk_version not on command line, infer from -syslibroot
3776 if ( (fSDKVersion
== 0) && (fSDKPaths
.size() > 0) ) {
3777 const char* sdkPath
= fSDKPaths
.front();
3778 const char* end
= &sdkPath
[strlen(sdkPath
)-1];
3779 while ( !isdigit(*end
) && (end
> sdkPath
) )
3781 const char* start
= end
-1;
3782 while ( (isdigit(*start
) || (*start
== '.')) && (start
> sdkPath
))
3784 char sdkVersionStr
[32];
3785 int len
= end
-start
+1;
3787 strlcpy(sdkVersionStr
, start
+1, len
);
3788 fSDKVersion
= parseVersionNumber32(sdkVersionStr
);
3792 // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
3793 if ( (fSDKVersion
== 0) && (fMacVersionMin
!= ld::macVersionUnset
) ) {
3794 // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
3795 if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
3796 fSDKVersion
= fMacVersionMin
;
3799 int mib
[2] = { CTL_KERN
, KERN_OSRELEASE
};
3800 char kernVersStr
[100];
3801 size_t strlen
= sizeof(kernVersStr
);
3802 if ( sysctl(mib
, 2, kernVersStr
, &strlen
, NULL
, 0) != -1 ) {
3803 uint32_t kernVers
= parseVersionNumber32(kernVersStr
);
3804 int minor
= (kernVers
>> 16) - 4; // kernel major version is 4 ahead of x in 10.x
3805 fSDKVersion
= 0x000A0000 + (minor
<< 8);
3812 void Options::checkIllegalOptionCombinations()
3814 // check -undefined setting
3815 switch ( fUndefinedTreatment
) {
3816 case kUndefinedError
:
3817 case kUndefinedDynamicLookup
:
3820 case kUndefinedWarning
:
3821 case kUndefinedSuppress
:
3822 // requires flat namespace
3823 if ( fNameSpace
== kTwoLevelNameSpace
)
3824 throw "can't use -undefined warning or suppress with -twolevel_namespace";
3828 // unify -sub_umbrella with dylibs
3829 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
3830 const char* subUmbrella
= *it
;
3832 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
3833 Options::FileInfo
& info
= *fit
;
3834 const char* lastSlash
= strrchr(info
.path
, '/');
3835 if ( lastSlash
== NULL
)
3836 lastSlash
= info
.path
- 1;
3837 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
3838 info
.options
.fReExport
= true;
3840 fLinkSnapshot
.recordSubUmbrella(info
.path
);
3845 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella
);
3848 // unify -sub_library with dylibs
3849 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
3850 const char* subLibrary
= *it
;
3852 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
3853 Options::FileInfo
& info
= *fit
;
3854 const char* lastSlash
= strrchr(info
.path
, '/');
3855 if ( lastSlash
== NULL
)
3856 lastSlash
= info
.path
- 1;
3857 const char* dot
= strchr(&lastSlash
[1], '.');
3859 dot
= &lastSlash
[strlen(lastSlash
)];
3860 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
3861 info
.options
.fReExport
= true;
3863 fLinkSnapshot
.recordSubLibrary(info
.path
);
3868 warning("-sub_library %s does not match a supplied dylib", subLibrary
);
3871 // sync reader options
3872 if ( fNameSpace
!= kTwoLevelNameSpace
)
3873 fFlatNamespace
= true;
3875 // check -stack_addr
3876 if ( fStackAddr
!= 0 ) {
3877 switch (fArchitecture
) {
3880 if ( fStackAddr
> 0xFFFFFFFF )
3881 throw "-stack_addr must be < 4G for 32-bit processes";
3883 case CPU_TYPE_X86_64
:
3886 if ( (fStackAddr
& -4096) != fStackAddr
)
3887 throw "-stack_addr must be multiples of 4K";
3888 if ( fStackSize
== 0 )
3889 throw "-stack_addr must be used with -stack_size";
3892 // check -stack_size
3893 if ( fStackSize
!= 0 ) {
3894 switch (fArchitecture
) {
3896 if ( fStackSize
> 0xFFFFFFFF )
3897 throw "-stack_size must be < 4G for 32-bit processes";
3898 if ( fStackAddr
== 0 ) {
3899 fStackAddr
= 0xC0000000;
3901 if ( (fStackAddr
> 0xB0000000) && ((fStackAddr
-fStackSize
) < 0xB0000000) )
3902 warning("custom stack placement overlaps and will disable shared region");
3905 if ( fStackSize
> 0x2F000000 )
3906 throw "-stack_size must be < 752MB";
3907 if ( fStackAddr
== 0 )
3908 fStackAddr
= 0x2F000000;
3909 if ( fStackAddr
> 0x30000000)
3910 throw "-stack_addr must be < 0x30000000 for arm";
3911 case CPU_TYPE_X86_64
:
3912 if ( fStackAddr
== 0 ) {
3913 fStackAddr
= 0x00007FFF5C000000LL
;
3917 if ( (fStackSize
& -4096) != fStackSize
)
3918 throw "-stack_size must be multiples of 4K";
3919 switch ( fOutputKind
) {
3920 case Options::kDynamicExecutable
:
3921 case Options::kStaticExecutable
:
3922 // custom stack size only legal when building main executable
3924 case Options::kDynamicLibrary
:
3925 case Options::kDynamicBundle
:
3926 case Options::kObjectFile
:
3927 case Options::kDyld
:
3928 case Options::kPreload
:
3929 case Options::kKextBundle
:
3930 throw "-stack_size option can only be used when linking a main executable";
3932 if ( fStackSize
> fStackAddr
)
3933 throwf("-stack_size (0x%08llX) must be smaller than -stack_addr (0x%08llX)", fStackSize
, fStackAddr
);
3936 // check that -allow_stack_execute is only used with main executables
3937 if ( fExecutableStack
) {
3938 switch ( fOutputKind
) {
3939 case Options::kDynamicExecutable
:
3940 case Options::kStaticExecutable
:
3941 // -allow_stack_execute size only legal when building main executable
3943 case Options::kDynamicLibrary
:
3944 case Options::kDynamicBundle
:
3945 case Options::kObjectFile
:
3946 case Options::kDyld
:
3947 case Options::kPreload
:
3948 case Options::kKextBundle
:
3949 throw "-allow_stack_execute option can only be used when linking a main executable";
3953 // check that -allow_heap_execute is only used with i386 main executables
3954 if ( fDisableNonExecutableHeap
) {
3955 if ( fArchitecture
!= CPU_TYPE_I386
)
3956 throw "-allow_heap_execute option can only be used when linking for i386";
3957 switch ( fOutputKind
) {
3958 case Options::kDynamicExecutable
:
3959 // -allow_heap_execute only legal when building main executable
3961 case Options::kStaticExecutable
:
3962 case Options::kDynamicLibrary
:
3963 case Options::kDynamicBundle
:
3964 case Options::kObjectFile
:
3965 case Options::kDyld
:
3966 case Options::kPreload
:
3967 case Options::kKextBundle
:
3968 throw "-allow_heap_execute option can only be used when linking a main executable";
3972 // check -client_name is only used when making a bundle or main executable
3973 if ( fClientName
!= NULL
) {
3974 switch ( fOutputKind
) {
3975 case Options::kDynamicExecutable
:
3976 case Options::kDynamicBundle
:
3978 case Options::kStaticExecutable
:
3979 case Options::kDynamicLibrary
:
3980 case Options::kObjectFile
:
3981 case Options::kDyld
:
3982 case Options::kPreload
:
3983 case Options::kKextBundle
:
3984 throw "-client_name can only be used with -bundle";
3988 // check -init is only used when building a dylib
3989 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
3990 throw "-init can only be used with -dynamiclib";
3992 // check -bundle_loader only used with -bundle
3993 if ( (fBundleLoader
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
3994 throw "-bundle_loader can only be used with -bundle";
3996 // check -dtrace not used with -r
3997 if ( (fDtraceScriptName
!= NULL
) && (fOutputKind
== Options::kObjectFile
) )
3998 throw "-dtrace can only be used when creating final linked images";
4000 // check -d can only be used with -r
4001 if ( fMakeTentativeDefinitionsReal
&& (fOutputKind
!= Options::kObjectFile
) )
4002 throw "-d can only be used with -r";
4004 // check that -root_safe is not used with -r
4005 if ( fRootSafe
&& (fOutputKind
== Options::kObjectFile
) )
4006 throw "-root_safe cannot be used with -r";
4008 // check that -setuid_safe is not used with -r
4009 if ( fSetuidSafe
&& (fOutputKind
== Options::kObjectFile
) )
4010 throw "-setuid_safe cannot be used with -r";
4012 // rdar://problem/4718189 map ObjC class names to new runtime names
4013 bool alterObjC1ClassNamesToObjC2
= false;
4014 switch (fArchitecture
) {
4016 // i386 only uses new symbols when using objc2 ABI
4017 if ( fObjCABIVersion2Override
)
4018 alterObjC1ClassNamesToObjC2
= true;
4020 case CPU_TYPE_X86_64
:
4022 alterObjC1ClassNamesToObjC2
= true;
4026 // make sure all required exported symbols exist
4027 std::vector
<const char*> impliedExports
;
4028 for (NameSet::iterator it
=fExportSymbols
.regularBegin(); it
!= fExportSymbols
.regularEnd(); ++it
) {
4029 const char* name
= *it
;
4030 const int len
= strlen(name
);
4031 if ( (strcmp(&name
[len
-3], ".eh") == 0) || (strncmp(name
, ".objc_category_name_", 20) == 0) ) {
4032 // never export .eh symbols
4033 warning("ignoring %s in export list", name
);
4035 else if ( (fArchitecture
== CPU_TYPE_I386
) && !fObjCABIVersion2Override
&& (strncmp(name
, "_OBJC_CLASS_$", 13) == 0) ) {
4036 warning("ignoring Objc2 Class symbol %s in i386 export list", name
);
4037 fRemovedExports
.insert(name
);
4039 else if ( alterObjC1ClassNamesToObjC2
&& (strncmp(name
, ".objc_class_name_", 17) == 0) ) {
4040 // linking ObjC2 ABI, but have ObjC1 ABI name in export list. Change it to intended name
4041 fRemovedExports
.insert(name
);
4043 asprintf(&temp
, "_OBJC_CLASS_$_%s", &name
[17]);
4044 impliedExports
.push_back(temp
);
4045 asprintf(&temp
, "_OBJC_METACLASS_$_%s", &name
[17]);
4046 impliedExports
.push_back(temp
);
4049 fInitialUndefines
.push_back(name
);
4052 fExportSymbols
.remove(fRemovedExports
);
4053 for (std::vector
<const char*>::iterator it
=impliedExports
.begin(); it
!= impliedExports
.end(); ++it
) {
4054 const char* name
= *it
;
4055 fExportSymbols
.insert(name
);
4056 fInitialUndefines
.push_back(name
);
4059 // make sure all required re-exported symbols exist
4060 for (NameSet::iterator it
=fReExportSymbols
.regularBegin(); it
!= fReExportSymbols
.regularEnd(); ++it
) {
4061 fInitialUndefines
.push_back(*it
);
4064 // make sure that -init symbol exists
4065 if ( fInitFunctionName
!= NULL
)
4066 fInitialUndefines
.push_back(fInitFunctionName
);
4068 // make sure that entry symbol exists
4069 switch ( fOutputKind
) {
4070 case Options::kDynamicExecutable
:
4071 case Options::kStaticExecutable
:
4072 case Options::kDyld
:
4073 case Options::kPreload
:
4074 fInitialUndefines
.push_back(fEntryName
);
4076 case Options::kDynamicLibrary
:
4077 case Options::kDynamicBundle
:
4078 case Options::kObjectFile
:
4079 case Options::kKextBundle
:
4083 // make sure every alias base exists
4084 for (std::vector
<AliasPair
>::iterator it
=fAliases
.begin(); it
!= fAliases
.end(); ++it
) {
4085 fInitialUndefines
.push_back(it
->realName
);
4088 // check custom segments
4089 if ( fCustomSegmentAddresses
.size() != 0 ) {
4090 // verify no segment is in zero page
4091 if ( fZeroPageSize
!= ULLONG_MAX
) {
4092 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
4093 if ( it
->address
< fZeroPageSize
)
4094 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it
->name
, it
->address
);
4097 // verify no duplicates
4098 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
4099 for (std::vector
<SegmentStart
>::iterator it2
= fCustomSegmentAddresses
.begin(); it2
!= fCustomSegmentAddresses
.end(); ++it2
) {
4100 if ( (it
->address
== it2
->address
) && (it
!= it2
) )
4101 throwf("duplicate -segaddr addresses for %s and %s", it
->name
, it2
->name
);
4103 // a custom segment address of zero will disable the use of a zero page
4104 if ( it
->address
== 0 )
4109 if ( fZeroPageSize
== ULLONG_MAX
) {
4110 // zero page size not specified on command line, set default
4111 switch (fArchitecture
) {
4114 // first 4KB for 32-bit architectures
4115 fZeroPageSize
= 0x1000;
4117 case CPU_TYPE_X86_64
:
4118 // first 4GB for x86_64 on all OS's
4119 fZeroPageSize
= 0x100000000ULL
;
4122 // if -arch not used, default to 4K zero-page
4123 fZeroPageSize
= 0x1000;
4127 switch ( fOutputKind
) {
4128 case Options::kDynamicExecutable
:
4129 case Options::kStaticExecutable
:
4130 // -pagezero_size size only legal when building main executable
4132 case Options::kDynamicLibrary
:
4133 case Options::kDynamicBundle
:
4134 case Options::kObjectFile
:
4135 case Options::kDyld
:
4136 case Options::kPreload
:
4137 case Options::kKextBundle
:
4138 if ( fZeroPageSize
!= 0 )
4139 throw "-pagezero_size option can only be used when linking a main executable";
4143 // if main executable with custom base address, model zero page as custom segment
4144 if ( (fOutputKind
== Options::kDynamicExecutable
) && (fBaseAddress
!= 0) && (fZeroPageSize
!= 0) ) {
4146 seg
.name
= "__PAGEZERO";
4148 fCustomSegmentAddresses
.push_back(seg
);
4151 // -dead_strip and -r are incompatible
4152 if ( fDeadStrip
&& (fOutputKind
== Options::kObjectFile
) )
4153 throw "-r and -dead_strip cannot be used together";
4155 // can't use -rpath unless targeting 10.5 or later
4156 if ( fRPaths
.size() > 0 ) {
4157 if ( !minOS(ld::mac10_5
, ld::iOS_2_0
) )
4158 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
4159 switch ( fOutputKind
) {
4160 case Options::kDynamicExecutable
:
4161 case Options::kDynamicLibrary
:
4162 case Options::kDynamicBundle
:
4164 case Options::kStaticExecutable
:
4165 case Options::kObjectFile
:
4166 case Options::kDyld
:
4167 case Options::kPreload
:
4168 case Options::kKextBundle
:
4169 throw "-rpath can only be used when creating a dynamic final linked image";
4173 if ( fPositionIndependentExecutable
) {
4174 switch ( fOutputKind
) {
4175 case Options::kDynamicExecutable
:
4176 // check -pie is only used when building a dynamic main executable for 10.5
4177 if ( !minOS(ld::mac10_5
, ld::iOS_4_2
) ) {
4178 if ( fIOSVersionMin
== ld::iOSVersionUnset
)
4179 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
4181 throw "-pie can only be used when targeting iOS 4.2 or later";
4184 case Options::kStaticExecutable
:
4185 case Options::kPreload
:
4186 // -pie is ok with -static or -preload
4188 case Options::kDynamicLibrary
:
4189 case Options::kDynamicBundle
:
4190 warning("-pie being ignored. It is only used when linking a main executable");
4191 fPositionIndependentExecutable
= false;
4193 case Options::kObjectFile
:
4194 case Options::kDyld
:
4195 case Options::kKextBundle
:
4196 throw "-pie can only be used when linking a main executable";
4200 // check -read_only_relocs is not used with x86_64
4201 if ( fAllowTextRelocs
) {
4202 if ( (fArchitecture
== CPU_TYPE_X86_64
) && (fOutputKind
!= kKextBundle
) ) {
4203 warning("-read_only_relocs cannot be used with x86_64");
4204 fAllowTextRelocs
= false;
4208 // check -mark_auto_dead_strip is only used with dylibs
4209 if ( fMarkDeadStrippableDylib
) {
4210 if ( fOutputKind
!= Options::kDynamicLibrary
) {
4211 warning("-mark_auto_dead_strip can only be used when creating a dylib");
4212 fMarkDeadStrippableDylib
= false;
4216 // -force_cpusubtype_ALL is not supported for ARM
4217 if ( fForceSubtypeAll
) {
4218 if ( fArchitecture
== CPU_TYPE_ARM
) {
4219 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
4223 // -reexported_symbols_list can only be used with -dynamiclib
4224 if ( !fReExportSymbols
.empty() ) {
4225 if ( fOutputKind
!= Options::kDynamicLibrary
)
4226 throw "-reexported_symbols_list can only used used when created dynamic libraries";
4227 if ( !minOS(ld::mac10_7
, ld::iOS_4_2
) )
4228 throw "targeted OS version does not support -reexported_symbols_list";
4231 // -dyld_env can only be used with main executables
4232 if ( (fOutputKind
!= Options::kDynamicExecutable
) && (fDyldEnvironExtras
.size() != 0) )
4233 throw "-dyld_env can only used used when created main executables";
4237 void Options::checkForClassic(int argc
, const char* argv
[])
4240 bool archFound
= false;
4241 bool staticFound
= false;
4242 bool dtraceFound
= false;
4243 bool kextFound
= false;
4244 bool rFound
= false;
4245 bool creatingMachKernel
= false;
4246 bool newLinker
= false;
4248 // build command line buffer in case ld crashes
4249 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
4250 CRSetCrashLogMessage(crashreporterBuffer
);
4252 const char* srcRoot
= getenv("SRCROOT");
4253 if ( srcRoot
!= NULL
) {
4254 strlcpy(crashreporterBuffer
, "SRCROOT=", crashreporterBufferSize
);
4255 strlcat(crashreporterBuffer
, srcRoot
, crashreporterBufferSize
);
4256 strlcat(crashreporterBuffer
, "\n", crashreporterBufferSize
);
4259 strlcat(crashreporterBuffer
, LD_VERS
, crashreporterBufferSize
);
4260 strlcat(crashreporterBuffer
, "\n", crashreporterBufferSize
);
4262 strlcat(crashreporterBuffer
, "ld ", crashreporterBufferSize
);
4263 for(int i
=1; i
< argc
; ++i
) {
4264 strlcat(crashreporterBuffer
, argv
[i
], crashreporterBufferSize
);
4265 strlcat(crashreporterBuffer
, " ", crashreporterBufferSize
);
4268 for(int i
=0; i
< argc
; ++i
) {
4269 const char* arg
= argv
[i
];
4270 if ( arg
[0] == '-' ) {
4271 if ( strcmp(arg
, "-arch") == 0 ) {
4272 parseArch(argv
[++i
]);
4275 else if ( strcmp(arg
, "-static") == 0 ) {
4278 else if ( strcmp(arg
, "-kext") == 0 ) {
4281 else if ( strcmp(arg
, "-dtrace") == 0 ) {
4284 else if ( strcmp(arg
, "-r") == 0 ) {
4287 else if ( strcmp(arg
, "-new_linker") == 0 ) {
4290 else if ( strcmp(arg
, "-classic_linker") == 0 ) {
4291 // ld_classic does not understand this option, so remove it
4292 for(int j
=i
; j
< argc
; ++j
)
4293 argv
[j
] = argv
[j
+1];
4294 warning("using ld_classic");
4295 this->gotoClassicLinker(argc
-1, argv
);
4297 else if ( strcmp(arg
, "-o") == 0 ) {
4298 const char* outfile
= argv
[++i
];
4299 if ( (outfile
!= NULL
) && (strstr(outfile
, "/mach_kernel") != NULL
) )
4300 creatingMachKernel
= true;
4306 void Options::gotoClassicLinker(int argc
, const char* argv
[])
4308 argv
[0] = "ld_classic";
4309 // ld_classic does not support -iphoneos_version_min, so change
4310 for(int j
=0; j
< argc
; ++j
) {
4311 if ( (strcmp(argv
[j
], "-iphoneos_version_min") == 0) || (strcmp(argv
[j
], "-ios_version_min") == 0) ) {
4312 argv
[j
] = "-macosx_version_min";
4318 // ld classic does not understand -kext (change to -static -r)
4319 for(int j
=0; j
< argc
; ++j
) {
4320 if ( strcmp(argv
[j
], "-kext") == 0)
4322 else if ( strcmp(argv
[j
], "-dynamic") == 0)
4323 argv
[j
] = "-static";
4325 // ld classic does not understand -demangle
4326 for(int j
=0; j
< argc
; ++j
) {
4327 if ( strcmp(argv
[j
], "-demangle") == 0)
4328 argv
[j
] = "-noprebind";
4330 // in -v mode, print command line passed to ld_classic
4331 for(int i
=0; i
< argc
; ++i
) {
4332 if ( strcmp(argv
[i
], "-v") == 0 ) {
4333 for(int j
=0; j
< argc
; ++j
)
4334 printf("%s ", argv
[j
]);
4339 char rawPath
[PATH_MAX
];
4340 char path
[PATH_MAX
];
4341 uint32_t bufSize
= PATH_MAX
;
4342 if ( _NSGetExecutablePath(rawPath
, &bufSize
) != -1 ) {
4343 if ( realpath(rawPath
, path
) != NULL
) {
4344 char* lastSlash
= strrchr(path
, '/');
4345 if ( lastSlash
!= NULL
) {
4346 strcpy(lastSlash
+1, "ld_classic");
4348 execvp(path
, (char**)argv
);
4352 // in case of error in above, try searching for ld_classic via PATH
4353 execvp(argv
[0], (char**)argv
);
4354 fprintf(stderr
, "can't exec ld_classic\n");
4359 // Note, returned string buffer is own by this function.
4360 // It should not be freed
4361 // It will be reused, so clients need to strdup() if they want
4362 // to use it long term.
4363 const char* Options::demangleSymbol(const char* sym
) const
4365 // only try to demangle symbols if -demangle on command line
4369 // only try to demangle symbols that look like C++ symbols
4370 if ( strncmp(sym
, "__Z", 3) != 0 )
4373 static size_t size
= 1024;
4374 static char* buff
= (char*)malloc(size
);
4377 char* result
= abi::__cxa_demangle(&sym
[1], buff
, &size
, &status
);
4378 if ( result
!= NULL
) {
4379 // if demangling successful, keep buffer for next demangle