1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2005-2008 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>
32 #include "configure.h"
34 #include "Architectures.hpp"
35 #include "MachOFileAbstraction.hpp"
37 extern void printLTOVersion(Options
&opts
);
40 static bool sEmitWarnings
= true;
41 static const char* sWarningsSideFilePath
= NULL
;
42 static FILE* sWarningsSideFile
= NULL
;
44 void warning(const char* format
, ...)
46 if ( sEmitWarnings
) {
48 if ( sWarningsSideFilePath
!= NULL
) {
49 if ( sWarningsSideFile
== NULL
)
50 sWarningsSideFile
= fopen(sWarningsSideFilePath
, "a");
52 va_start(list
, format
);
53 fprintf(stderr
, "ld warning: ");
54 vfprintf(stderr
, format
, list
);
55 fprintf(stderr
, "\n");
56 if ( sWarningsSideFile
!= NULL
) {
57 fprintf(sWarningsSideFile
, "ld warning: ");
58 vfprintf(sWarningsSideFile
, format
, list
);
59 fprintf(sWarningsSideFile
, "\n");
60 fflush(sWarningsSideFile
);
66 void throwf(const char* format
, ...)
70 va_start(list
, format
);
71 vasprintf(&p
, format
, list
);
78 Options::Options(int argc
, const char* argv
[])
79 : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fOutputKind(kDynamicExecutable
),
80 fHasPreferredSubType(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
81 fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fForceSubtypeAll(false),
82 fInterposeMode(kInterposeNone
), fDeadStrip(kDeadStripOff
), fNameSpace(kTwoLevelNameSpace
),
83 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL
), fFinalName(NULL
), fEntryName("start"), fBaseAddress(0),
84 fBaseWritableAddress(0), fSplitSegs(false),
85 fExportMode(kExportDefault
), fLibrarySearchMode(kSearchAllDirsForDylibsThenAllDirsForArchives
),
86 fUndefinedTreatment(kUndefinedError
), fMessagesPrefixedWithArchitecture(false),
87 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchNonWeak
),
89 fUmbrellaName(NULL
), fInitFunctionName(NULL
), fDotOutputFile(NULL
), fExecutablePath(NULL
),
90 fBundleLoader(NULL
), fDtraceScriptName(NULL
), fSegAddrTablePath(NULL
), fMapPath(NULL
),
91 fZeroPageSize(ULLONG_MAX
), fStackSize(0), fStackAddr(0), fExecutableStack(false), fMinimumHeaderPad(32),
92 fCommonsMode(kCommonsIgnoreDylibs
), fUUIDMode(kUUIDContent
), fLocalSymbolHandling(kLocalSymbolsAll
), fWarnCommons(false),
93 fVerbose(false), fKeepRelocations(false), fWarnStabs(false),
94 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
95 fSharedRegionEligible(false), fPrintOrderFileStatistics(false),
96 fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
97 fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false),
98 fUsingLazyDylibLinking(false), fEncryptable(true), fSaveTempFiles(false)
100 this->checkForClassic(argc
, argv
);
101 this->parsePreCommandLineEnvironmentSettings();
102 this->parse(argc
, argv
);
103 this->parsePostCommandLineEnvironmentSettings();
104 this->reconfigureDefaults();
105 this->checkIllegalOptionCombinations();
112 const ObjectFile::ReaderOptions
& Options::readerOptions()
114 return fReaderOptions
;
118 const char* Options::getOutputFilePath()
123 std::vector
<Options::FileInfo
>& Options::getInputFiles()
128 Options::OutputKind
Options::outputKind()
133 bool Options::bindAtLoad()
138 bool Options::prebind()
143 bool Options::fullyLoadArchives()
145 return fReaderOptions
.fFullyLoadArchives
;
148 Options::NameSpace
Options::nameSpace()
153 const char* Options::installPath()
155 if ( fDylibInstallName
!= NULL
)
156 return fDylibInstallName
;
157 else if ( fFinalName
!= NULL
)
163 uint32_t Options::currentVersion()
165 return fDylibCurrentVersion
;
168 uint32_t Options::compatibilityVersion()
170 return fDylibCompatVersion
;
173 const char* Options::entryName()
178 uint64_t Options::baseAddress()
183 bool Options::keepPrivateExterns()
185 return fKeepPrivateExterns
;
188 bool Options::interposable(const char* name
)
190 switch ( fInterposeMode
) {
193 case kInterposeAllExternal
:
196 return fInterposeList
.contains(name
);
198 throw "internal error";
201 bool Options::needsModuleTable()
203 return fNeedsModuleTable
;
206 bool Options::ignoreOtherArchInputFiles()
208 return fIgnoreOtherArchFiles
;
211 bool Options::forceCpuSubtypeAll()
213 return fForceSubtypeAll
;
216 bool Options::traceDylibs()
218 return fReaderOptions
.fTraceDylibs
;
221 bool Options::traceArchives()
223 return fReaderOptions
.fTraceArchives
;
226 Options::UndefinedTreatment
Options::undefinedTreatment()
228 return fUndefinedTreatment
;
231 ObjectFile::ReaderOptions::VersionMin
Options::macosxVersionMin()
233 return fReaderOptions
.fVersionMin
;
236 Options::WeakReferenceMismatchTreatment
Options::weakReferenceMismatchTreatment()
238 return fWeakReferenceMismatchTreatment
;
241 const char* Options::umbrellaName()
243 return fUmbrellaName
;
246 std::vector
<const char*>& Options::allowableClients()
248 return fAllowableClients
;
251 const char* Options::clientName()
256 uint64_t Options::zeroPageSize()
258 return fZeroPageSize
;
261 bool Options::hasCustomStack()
263 return (fStackSize
!= 0);
266 uint64_t Options::customStackSize()
271 uint64_t Options::customStackAddr()
276 bool Options::hasExecutableStack()
278 return fExecutableStack
;
281 std::vector
<const char*>& Options::initialUndefines()
283 return fInitialUndefines
;
286 bool Options::printWhyLive(const char* symbolName
)
288 return ( fWhyLive
.find(symbolName
) != fWhyLive
.end() );
292 const char* Options::initFunctionName()
294 return fInitFunctionName
;
297 const char* Options::dotOutputFile()
299 return fDotOutputFile
;
302 bool Options::hasExportRestrictList()
304 return (fExportMode
!= kExportDefault
);
307 bool Options::hasExportMaskList()
309 return (fExportMode
== kExportSome
);
313 bool Options::hasWildCardExportRestrictList()
315 // has -exported_symbols_list which contains some wildcards
316 return ((fExportMode
== kExportSome
) && fExportSymbols
.hasWildCards());
320 bool Options::allGlobalsAreDeadStripRoots()
322 // -exported_symbols_list means globals are not exported by default
323 if ( fExportMode
== kExportSome
)
326 switch ( fOutputKind
) {
327 case Options::kDynamicExecutable
:
328 case Options::kStaticExecutable
:
329 // by default unused globals in a main executable are stripped
331 case Options::kDynamicLibrary
:
332 case Options::kDynamicBundle
:
333 case Options::kObjectFile
:
340 uint32_t Options::minimumHeaderPad()
342 return fMinimumHeaderPad
;
345 std::vector
<Options::ExtraSection
>& Options::extraSections()
347 return fExtraSections
;
350 std::vector
<Options::SectionAlignment
>& Options::sectionAlignments()
352 return fSectionAlignments
;
355 Options::CommonsMode
Options::commonsMode()
360 bool Options::warnCommons()
365 bool Options::keepRelocations()
367 return fKeepRelocations
;
370 bool Options::warnStabs()
375 const char* Options::executablePath()
377 return fExecutablePath
;
380 Options::DeadStripMode
Options::deadStrip()
385 bool Options::shouldExport(const char* symbolName
)
387 switch (fExportMode
) {
389 return fExportSymbols
.contains(symbolName
);
390 case kDontExportSome
:
391 return ! fDontExportSymbols
.contains(symbolName
);
395 throw "internal error";
398 bool Options::keepLocalSymbol(const char* symbolName
)
400 switch (fLocalSymbolHandling
) {
401 case kLocalSymbolsAll
:
403 case kLocalSymbolsNone
:
405 case kLocalSymbolsSelectiveInclude
:
406 return fLocalSymbolsIncluded
.contains(symbolName
);
407 case kLocalSymbolsSelectiveExclude
:
408 return ! fLocalSymbolsExcluded
.contains(symbolName
);
410 throw "internal error";
413 void Options::parseArch(const char* architecture
)
415 if ( architecture
== NULL
)
416 throw "-arch must be followed by an architecture string";
417 if ( strcmp(architecture
, "ppc") == 0 ) {
418 fArchitecture
= CPU_TYPE_POWERPC
;
419 fSubArchitecture
= CPU_SUBTYPE_POWERPC_ALL
;
421 else if ( strcmp(architecture
, "ppc64") == 0 ) {
422 fArchitecture
= CPU_TYPE_POWERPC64
;
423 fSubArchitecture
= CPU_SUBTYPE_POWERPC_ALL
;
425 else if ( strcmp(architecture
, "i386") == 0 ) {
426 fArchitecture
= CPU_TYPE_I386
;
427 fSubArchitecture
= CPU_SUBTYPE_I386_ALL
;
429 else if ( strcmp(architecture
, "x86_64") == 0 ) {
430 fArchitecture
= CPU_TYPE_X86_64
;
431 fSubArchitecture
= CPU_SUBTYPE_X86_64_ALL
;
433 else if ( strcmp(architecture
, "arm") == 0 ) {
434 fArchitecture
= CPU_TYPE_ARM
;
435 fSubArchitecture
= CPU_SUBTYPE_ARM_ALL
;
437 // compatibility support for cpu-sub-types
438 else if ( strcmp(architecture
, "ppc750") == 0 ) {
439 fArchitecture
= CPU_TYPE_POWERPC
;
440 fSubArchitecture
= CPU_SUBTYPE_POWERPC_750
;
441 fHasPreferredSubType
= true;
443 else if ( strcmp(architecture
, "ppc7400") == 0 ) {
444 fArchitecture
= CPU_TYPE_POWERPC
;
445 fSubArchitecture
= CPU_SUBTYPE_POWERPC_7400
;
446 fHasPreferredSubType
= true;
448 else if ( strcmp(architecture
, "ppc7450") == 0 ) {
449 fArchitecture
= CPU_TYPE_POWERPC
;
450 fSubArchitecture
= CPU_SUBTYPE_POWERPC_7450
;
451 fHasPreferredSubType
= true;
453 else if ( strcmp(architecture
, "ppc970") == 0 ) {
454 fArchitecture
= CPU_TYPE_POWERPC
;
455 fSubArchitecture
= CPU_SUBTYPE_POWERPC_970
;
456 fHasPreferredSubType
= true;
458 else if ( strcmp(architecture
, "armv6") == 0 ) {
459 fArchitecture
= CPU_TYPE_ARM
;
460 fSubArchitecture
= CPU_SUBTYPE_ARM_V6
;
461 fHasPreferredSubType
= true;
463 else if ( strcmp(architecture
, "armv5") == 0 ) {
464 fArchitecture
= CPU_TYPE_ARM
;
465 fSubArchitecture
= CPU_SUBTYPE_ARM_V5TEJ
;
466 fHasPreferredSubType
= true;
468 else if ( strcmp(architecture
, "armv4t") == 0 ) {
469 fArchitecture
= CPU_TYPE_ARM
;
470 fSubArchitecture
= CPU_SUBTYPE_ARM_V4T
;
471 fHasPreferredSubType
= true;
473 else if ( strcmp(architecture
, "xscale") == 0 ) {
474 fArchitecture
= CPU_TYPE_ARM
;
475 fSubArchitecture
= CPU_SUBTYPE_ARM_XSCALE
;
476 fHasPreferredSubType
= true;
478 else if ( strcmp(architecture
, "armv7") == 0 ) {
479 fArchitecture
= CPU_TYPE_ARM
;
480 fSubArchitecture
= CPU_SUBTYPE_ARM_V7
;
481 fHasPreferredSubType
= true;
484 throwf("unknown/unsupported architecture name for: -arch %s", architecture
);
487 bool Options::checkForFile(const char* format
, const char* dir
, const char* rootName
, FileInfo
& result
)
489 struct stat statBuffer
;
490 char possiblePath
[strlen(dir
)+strlen(rootName
)+strlen(format
)+8];
491 sprintf(possiblePath
, format
, dir
, rootName
);
492 bool found
= (stat(possiblePath
, &statBuffer
) == 0);
493 if ( fTraceDylibSearching
)
494 printf("[Logging for XBS]%sfound library: '%s'\n", (found
? " " : " not "), possiblePath
);
496 result
.path
= strdup(possiblePath
);
497 result
.fileLen
= statBuffer
.st_size
;
498 result
.modTime
= statBuffer
.st_mtime
;
505 Options::FileInfo
Options::findLibrary(const char* rootName
, bool dylibsOnly
)
508 const int rootNameLen
= strlen(rootName
);
509 // if rootName ends in .o there is no .a vs .dylib choice
510 if ( (rootNameLen
> 3) && (strcmp(&rootName
[rootNameLen
-2], ".o") == 0) ) {
511 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
512 it
!= fLibrarySearchPaths
.end();
514 const char* dir
= *it
;
515 if ( checkForFile("%s/%s", dir
, rootName
, result
) )
520 bool lookForDylibs
= ( fOutputKind
!= Options::kDyld
);
521 switch ( fLibrarySearchMode
) {
522 case kSearchAllDirsForDylibsThenAllDirsForArchives
:
523 // first look in all directories for just for dylibs
524 if ( lookForDylibs
) {
525 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
526 it
!= fLibrarySearchPaths
.end();
528 const char* dir
= *it
;
529 if ( checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
532 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
533 it
!= fLibrarySearchPaths
.end();
535 const char* dir
= *it
;
536 if ( checkForFile("%s/lib%s.so", dir
, rootName
, result
) )
540 // next look in all directories for just for archives
542 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
543 it
!= fLibrarySearchPaths
.end();
545 const char* dir
= *it
;
546 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
552 case kSearchDylibAndArchiveInEachDir
:
553 // look in each directory for just for a dylib then for an archive
554 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
555 it
!= fLibrarySearchPaths
.end();
557 const char* dir
= *it
;
558 if ( lookForDylibs
&& checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
560 if ( lookForDylibs
&& checkForFile("%s/lib%s.so", dir
, rootName
, result
) )
562 if ( !dylibsOnly
&& checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
568 throwf("library not found for -l%s", rootName
);
571 Options::FileInfo
Options::findFramework(const char* frameworkName
)
573 if ( frameworkName
== NULL
)
574 throw "-framework missing next argument";
575 char temp
[strlen(frameworkName
)+1];
576 strcpy(temp
, frameworkName
);
577 const char* name
= temp
;
578 const char* suffix
= NULL
;
579 char* comma
= strchr(temp
, ',');
580 if ( comma
!= NULL
) {
584 return findFramework(name
, suffix
);
587 Options::FileInfo
Options::findFramework(const char* rootName
, const char* suffix
)
589 struct stat statBuffer
;
590 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
591 it
!= fFrameworkSearchPaths
.end();
593 // ??? Shouldn't we be using String here and just initializing it?
594 // ??? Use str.c_str () to pull out the string for the stat call.
595 const char* dir
= *it
;
596 char possiblePath
[PATH_MAX
];
597 strcpy(possiblePath
, dir
);
598 strcat(possiblePath
, "/");
599 strcat(possiblePath
, rootName
);
600 strcat(possiblePath
, ".framework/");
601 strcat(possiblePath
, rootName
);
602 if ( suffix
!= NULL
) {
603 char realPath
[PATH_MAX
];
604 // no symlink in framework to suffix variants, so follow main symlink
605 if ( realpath(possiblePath
, realPath
) != NULL
) {
606 strcpy(possiblePath
, realPath
);
607 strcat(possiblePath
, suffix
);
610 bool found
= (stat(possiblePath
, &statBuffer
) == 0);
611 if ( fTraceDylibSearching
)
612 printf("[Logging for XBS]%sfound framework: '%s'\n",
613 (found
? " " : " not "), possiblePath
);
616 result
.path
= strdup(possiblePath
);
617 result
.fileLen
= statBuffer
.st_size
;
618 result
.modTime
= statBuffer
.st_mtime
;
622 // try without suffix
623 if ( suffix
!= NULL
)
624 return findFramework(rootName
, NULL
);
626 throwf("framework not found %s", rootName
);
629 Options::FileInfo
Options::findFile(const char* path
)
632 struct stat statBuffer
;
634 // if absolute path and not a .o file, the use SDK prefix
635 if ( (path
[0] == '/') && (strcmp(&path
[strlen(path
)-2], ".o") != 0) ) {
636 const int pathLen
= strlen(path
);
637 for (std::vector
<const char*>::iterator it
= fSDKPaths
.begin(); it
!= fSDKPaths
.end(); it
++) {
638 // ??? Shouldn't we be using String here?
639 const char* sdkPathDir
= *it
;
640 const int sdkPathDirLen
= strlen(sdkPathDir
);
641 char possiblePath
[sdkPathDirLen
+pathLen
+4];
642 strcpy(possiblePath
, sdkPathDir
);
643 if ( possiblePath
[sdkPathDirLen
-1] == '/' )
644 possiblePath
[sdkPathDirLen
-1] = '\0';
645 strcat(possiblePath
, path
);
646 if ( stat(possiblePath
, &statBuffer
) == 0 ) {
647 result
.path
= strdup(possiblePath
);
648 result
.fileLen
= statBuffer
.st_size
;
649 result
.modTime
= statBuffer
.st_mtime
;
655 if ( stat(path
, &statBuffer
) == 0 ) {
656 result
.path
= strdup(path
);
657 result
.fileLen
= statBuffer
.st_size
;
658 result
.modTime
= statBuffer
.st_mtime
;
662 // try @executable_path substitution
663 if ( (strncmp(path
, "@executable_path/", 17) == 0) && (fExecutablePath
!= NULL
) ) {
664 char newPath
[strlen(fExecutablePath
) + strlen(path
)];
665 strcpy(newPath
, fExecutablePath
);
666 char* addPoint
= strrchr(newPath
,'/');
667 if ( addPoint
!= NULL
)
668 strcpy(&addPoint
[1], &path
[17]);
670 strcpy(newPath
, &path
[17]);
671 if ( stat(newPath
, &statBuffer
) == 0 ) {
672 result
.path
= strdup(newPath
);
673 result
.fileLen
= statBuffer
.st_size
;
674 result
.modTime
= statBuffer
.st_mtime
;
680 throwf("file not found: %s", path
);
683 Options::FileInfo
Options::findFileUsingPaths(const char* path
)
687 const char* lastSlash
= strrchr(path
, '/');
688 const char* leafName
= (lastSlash
== NULL
) ? path
: &lastSlash
[1];
690 // Is this in a framework?
691 // /path/Foo.framework/Foo ==> true (Foo)
692 // /path/Foo.framework/Frameworks/Bar.framework/Bar ==> true (Bar)
693 // /path/Foo.framework/Resources/Bar ==> false
694 bool isFramework
= false;
695 if ( lastSlash
!= NULL
) {
696 char frameworkDir
[strlen(leafName
) + 20];
697 strcpy(frameworkDir
, "/");
698 strcat(frameworkDir
, leafName
);
699 strcat(frameworkDir
, ".framework/");
700 if ( strstr(path
, frameworkDir
) != NULL
)
704 // These are abbreviated versions of the routines findFramework and findLibrary above
705 // because we already know the final name of the file that we're looking for and so
706 // don't need to try variations, just paths. We do need to add the additional bits
707 // onto the framework path though.
709 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
710 it
!= fFrameworkSearchPaths
.end();
712 const char* dir
= *it
;
713 char possiblePath
[PATH_MAX
];
714 strcpy(possiblePath
, dir
);
715 strcat(possiblePath
, "/");
716 strcat(possiblePath
, leafName
);
717 strcat(possiblePath
, ".framework");
719 //fprintf(stderr,"Finding Framework: %s/%s, leafName=%s\n", possiblePath, leafName, leafName);
720 if ( checkForFile("%s/%s", possiblePath
, leafName
, result
) )
725 // if this is a .dylib inside a framework, do not search -L paths
726 // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
727 int leafLen
= strlen(leafName
);
728 bool embeddedDylib
= ( (leafLen
> 6)
729 && (strcmp(&leafName
[leafLen
-6], ".dylib") == 0)
730 && (strstr(path
, ".framework/") != NULL
) );
731 if ( !embeddedDylib
) {
732 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
733 it
!= fLibrarySearchPaths
.end();
735 const char* dir
= *it
;
736 //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
737 if ( checkForFile("%s/%s", dir
, leafName
, result
) )
743 // If we didn't find it fall back to findFile.
744 return findFile(path
);
748 void Options::parseSegAddrTable(const char* segAddrPath
, const char* installPath
)
750 FILE* file
= fopen(segAddrPath
, "r");
751 if ( file
== NULL
) {
752 warning("-seg_addr_table file cannot be read: %s", segAddrPath
);
757 uint64_t firstColumAddress
= 0;
758 uint64_t secondColumAddress
= 0;
759 bool hasSecondColumn
= false;
760 while ( fgets(path
, PATH_MAX
, file
) != NULL
) {
761 path
[PATH_MAX
-1] = '\0';
762 char* eol
= strchr(path
, '\n');
765 // ignore lines not starting with 0x number
766 if ( (path
[0] == '0') && (path
[1] == 'x') ) {
768 firstColumAddress
= strtoull(path
, &p
, 16);
769 while ( isspace(*p
) )
771 // see if second column is a number
772 if ( (p
[0] == '0') && (p
[1] == 'x') ) {
773 secondColumAddress
= strtoull(p
, &p
, 16);
774 hasSecondColumn
= true;
775 while ( isspace(*p
) )
778 while ( isspace(*p
) )
781 // remove any trailing whitespace
782 for(char* end
= eol
-1; (end
> p
) && isspace(*end
); --end
)
784 // see if this line is for the dylib being linked
785 if ( strcmp(p
, installPath
) == 0 ) {
786 fBaseAddress
= firstColumAddress
;
787 if ( hasSecondColumn
) {
788 fBaseWritableAddress
= secondColumAddress
;
791 break; // out of while loop
800 void Options::loadFileList(const char* fileOfPaths
)
803 const char* comma
= strrchr(fileOfPaths
, ',');
804 const char* prefix
= NULL
;
805 if ( comma
!= NULL
) {
807 int realFileOfPathsLen
= comma
-fileOfPaths
;
808 char realFileOfPaths
[realFileOfPathsLen
+1];
809 strncpy(realFileOfPaths
,fileOfPaths
, realFileOfPathsLen
);
810 realFileOfPaths
[realFileOfPathsLen
] = '\0';
811 file
= fopen(realFileOfPaths
, "r");
813 throwf("-filelist file not found: %s\n", realFileOfPaths
);
816 file
= fopen(fileOfPaths
, "r");
818 throwf("-filelist file not found: %s\n", fileOfPaths
);
822 while ( fgets(path
, PATH_MAX
, file
) != NULL
) {
823 path
[PATH_MAX
-1] = '\0';
824 char* eol
= strchr(path
, '\n');
827 if ( prefix
!= NULL
) {
828 char builtPath
[strlen(prefix
)+strlen(path
)+2];
829 strcpy(builtPath
, prefix
);
830 strcat(builtPath
, "/");
831 strcat(builtPath
, path
);
832 fInputFiles
.push_back(findFile(builtPath
));
835 fInputFiles
.push_back(findFile(path
));
841 bool Options::SetWithWildcards::hasWildCards(const char* symbol
)
843 // an exported symbol name containing *, ?, or [ requires wildcard matching
844 return ( strpbrk(symbol
, "*?[") != NULL
);
847 void Options::SetWithWildcards::insert(const char* symbol
)
849 if ( hasWildCards(symbol
) )
850 fWildCard
.push_back(symbol
);
852 fRegular
.insert(symbol
);
855 bool Options::SetWithWildcards::contains(const char* symbol
)
857 // first look at hash table on non-wildcard symbols
858 if ( fRegular
.find(symbol
) != fRegular
.end() )
860 // next walk list of wild card symbols looking for a match
861 for(std::vector
<const char*>::iterator it
= fWildCard
.begin(); it
!= fWildCard
.end(); ++it
) {
862 if ( wildCardMatch(*it
, symbol
) )
869 bool Options::SetWithWildcards::inCharRange(const char*& p
, unsigned char c
)
873 while ( *p
!= '\0' ) {
876 // found beginining [ and ending ]
877 unsigned char last
= '\0';
878 for ( const char* s
= b
; s
< e
; ++s
) {
880 unsigned char next
= *(++s
);
881 if ( (last
<= c
) && (c
<= next
) )
898 bool Options::SetWithWildcards::wildCardMatch(const char* pattern
, const char* symbol
)
900 const char* s
= symbol
;
901 for (const char* p
= pattern
; *p
!= '\0'; ++p
) {
906 for (const char* t
= s
; *t
!= '\0'; ++t
) {
907 if ( wildCardMatch(&p
[1], t
) )
917 if ( ! inCharRange(p
, *s
) )
931 void Options::loadExportFile(const char* fileOfExports
, const char* option
, SetWithWildcards
& set
)
933 // read in whole file
934 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
936 throwf("can't open %s file: %s", option
, fileOfExports
);
937 struct stat stat_buf
;
938 ::fstat(fd
, &stat_buf
);
939 char* p
= (char*)malloc(stat_buf
.st_size
);
941 throwf("can't process %s file: %s", option
, fileOfExports
);
943 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
944 throwf("can't read %s file: %s", option
, fileOfExports
);
948 // parse into symbols and add to hash_set
949 char * const end
= &p
[stat_buf
.st_size
];
950 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
951 char* symbolStart
= NULL
;
952 for (char* s
= p
; s
< end
; ++s
) {
958 else if ( !isspace(*s
) ) {
964 if ( (*s
== '\n') || (*s
== '\r') ) {
966 // removing any trailing spaces
968 while ( isspace(*last
) ) {
972 set
.insert(symbolStart
);
978 if ( (*s
== '\n') || (*s
== '\r') )
983 if ( state
== inSymbol
) {
984 warning("missing line-end at end of file \"%s\"", fileOfExports
);
985 int len
= end
-symbolStart
+1;
986 char* temp
= new char[len
];
987 strlcpy(temp
, symbolStart
, len
);
989 // remove any trailing spaces
990 char* last
= &temp
[len
-2];
991 while ( isspace(*last
) ) {
998 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
1001 void Options::parseAliasFile(const char* fileOfAliases
)
1003 // read in whole file
1004 int fd
= ::open(fileOfAliases
, O_RDONLY
, 0);
1006 throwf("can't open alias file: %s", fileOfAliases
);
1007 struct stat stat_buf
;
1008 ::fstat(fd
, &stat_buf
);
1009 char* p
= (char*)malloc(stat_buf
.st_size
+1);
1011 throwf("can't process alias file: %s", fileOfAliases
);
1013 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1014 throwf("can't read alias file: %s", fileOfAliases
);
1015 p
[stat_buf
.st_size
] = '\n';
1018 // parse into symbols and add to fAliases
1019 ObjectFile::ReaderOptions::AliasPair pair
;
1020 char * const end
= &p
[stat_buf
.st_size
+1];
1021 enum { lineStart
, inRealName
, inBetween
, inAliasName
, inComment
} state
= lineStart
;
1023 for (char* s
= p
; s
< end
; ++s
) {
1029 else if ( !isspace(*s
) ) {
1036 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber
, fileOfAliases
);
1040 else if ( isspace(*s
) ) {
1047 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber
, fileOfAliases
);
1051 else if ( ! isspace(*s
) ) {
1052 state
= inAliasName
;
1059 // removing any trailing spaces
1061 while ( isspace(*last
) ) {
1065 fReaderOptions
.fAliases
.push_back(pair
);
1068 else if ( *s
== '\n' ) {
1070 // removing any trailing spaces
1072 while ( isspace(*last
) ) {
1076 fReaderOptions
.fAliases
.push_back(pair
);
1087 // Note: we do not free() the malloc buffer, because the strings therein are used by fAliases
1092 void Options::setUndefinedTreatment(const char* treatment
)
1094 if ( treatment
== NULL
)
1095 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
1097 if ( strcmp(treatment
, "warning") == 0 )
1098 fUndefinedTreatment
= kUndefinedWarning
;
1099 else if ( strcmp(treatment
, "error") == 0 )
1100 fUndefinedTreatment
= kUndefinedError
;
1101 else if ( strcmp(treatment
, "suppress") == 0 )
1102 fUndefinedTreatment
= kUndefinedSuppress
;
1103 else if ( strcmp(treatment
, "dynamic_lookup") == 0 )
1104 fUndefinedTreatment
= kUndefinedDynamicLookup
;
1106 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
1109 Options::Treatment
Options::parseTreatment(const char* treatment
)
1111 if ( treatment
== NULL
)
1114 if ( strcmp(treatment
, "warning") == 0 )
1116 else if ( strcmp(treatment
, "error") == 0 )
1118 else if ( strcmp(treatment
, "suppress") == 0 )
1124 void Options::setMacOSXVersionMin(const char* version
)
1126 if ( version
== NULL
)
1127 throw "-macosx_version_min argument missing";
1129 if ( (strncmp(version
, "10.", 3) == 0) && isdigit(version
[3]) ) {
1130 int num
= version
[3] - '0';
1134 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_1
;
1137 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_2
;
1140 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_3
;
1143 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
1146 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_5
;
1149 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_6
;
1152 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_6
;
1157 warning("unknown option to -macosx_version_min, not 10.x");
1161 void Options::setIPhoneVersionMin(const char* version
)
1163 if ( version
== NULL
)
1164 throw "-iphoneos_version_min argument missing";
1166 if ( ((strncmp(version
, "1.", 2) == 0) || (strncmp(version
, "2.", 2) == 0)) && isdigit(version
[2]) ) {
1167 int num
= version
[2] - '0';
1170 // TODO: store deployment version
1177 warning("unknown option to -iphoneos_version_min, not 1.x or 2.x");
1181 void Options::setWeakReferenceMismatchTreatment(const char* treatment
)
1183 if ( treatment
== NULL
)
1184 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
1186 if ( strcmp(treatment
, "error") == 0 )
1187 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchError
;
1188 else if ( strcmp(treatment
, "weak") == 0 )
1189 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchWeak
;
1190 else if ( strcmp(treatment
, "non-weak") == 0 )
1191 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchNonWeak
;
1193 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
1196 Options::CommonsMode
Options::parseCommonsTreatment(const char* mode
)
1199 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
1201 if ( strcmp(mode
, "ignore_dylibs") == 0 )
1202 return kCommonsIgnoreDylibs
;
1203 else if ( strcmp(mode
, "use_dylibs") == 0 )
1204 return kCommonsOverriddenByDylibs
;
1205 else if ( strcmp(mode
, "error") == 0 )
1206 return kCommonsConflictsDylibsError
;
1208 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
1211 void Options::addDylibOverride(const char* paths
)
1213 if ( paths
== NULL
)
1214 throw "-dylib_file must followed by two colon separated paths";
1215 const char* colon
= strchr(paths
, ':');
1216 if ( colon
== NULL
)
1217 throw "-dylib_file must followed by two colon separated paths";
1218 int len
= colon
-paths
;
1219 char* target
= new char[len
+2];
1220 strncpy(target
, paths
, len
);
1222 DylibOverride entry
;
1223 entry
.installName
= target
;
1224 entry
.useInstead
= &colon
[1];
1225 fDylibOverrides
.push_back(entry
);
1228 uint64_t Options::parseAddress(const char* addr
)
1231 uint64_t result
= strtoull(addr
, &endptr
, 16);
1235 uint32_t Options::parseProtection(const char* prot
)
1237 uint32_t result
= 0;
1238 for(const char* p
= prot
; *p
!= '\0'; ++p
) {
1239 switch(tolower(*p
)) {
1241 result
|= VM_PROT_READ
;
1244 result
|= VM_PROT_WRITE
;
1247 result
|= VM_PROT_EXECUTE
;
1252 throwf("unknown -segprot lettter in %s", prot
);
1261 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
1264 uint32_t Options::parseVersionNumber(const char* versionString
)
1266 unsigned long x
= 0;
1267 unsigned long y
= 0;
1268 unsigned long z
= 0;
1270 x
= strtoul(versionString
, &end
, 10);
1271 if ( *end
== '.' ) {
1272 y
= strtoul(&end
[1], &end
, 10);
1273 if ( *end
== '.' ) {
1274 z
= strtoul(&end
[1], &end
, 10);
1277 if ( (*end
!= '\0') || (x
> 0xffff) || (y
> 0xff) || (z
> 0xff) )
1278 throwf("malformed version number: %s", versionString
);
1280 return (x
<< 16) | ( y
<< 8 ) | z
;
1283 static const char* cstringSymbolName(const char* orderFileString
)
1286 asprintf(&result
, "cstring=%s", orderFileString
);
1287 // convert escaped characters
1289 for(const char* s
=result
; *s
!= '\0'; ++s
, ++d
) {
1327 // hexadecimal value of char
1331 while ( isxdigit(*s
) ) {
1336 value
+= ((toupper(*s
)-'A') + 10);
1343 if ( isdigit(*s
) ) {
1344 // octal value of char
1346 while ( isdigit(*s
) ) {
1347 value
= (value
<< 3) + (*s
-'0');
1362 void Options::parseOrderFile(const char* path
, bool cstring
)
1364 // read in whole file
1365 int fd
= ::open(path
, O_RDONLY
, 0);
1367 throwf("can't open order file: %s", path
);
1368 struct stat stat_buf
;
1369 ::fstat(fd
, &stat_buf
);
1370 char* p
= (char*)malloc(stat_buf
.st_size
+1);
1372 throwf("can't process order file: %s", path
);
1373 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1374 throwf("can't read order file: %s", path
);
1376 p
[stat_buf
.st_size
] = '\n';
1378 // parse into vector of pairs
1379 char * const end
= &p
[stat_buf
.st_size
+1];
1380 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
1381 char* symbolStart
= NULL
;
1382 for (char* s
= p
; s
< end
; ++s
) {
1388 else if ( !isspace(*s
) || cstring
) {
1394 if ( (*s
== '\n') || (!cstring
&& (*s
== '#')) ) {
1395 bool wasComment
= (*s
== '#');
1397 // removing any trailing spaces
1399 while ( isspace(*last
) ) {
1403 if ( strncmp(symbolStart
, "ppc:", 4) == 0 ) {
1404 if ( fArchitecture
== CPU_TYPE_POWERPC
)
1405 symbolStart
= &symbolStart
[4];
1409 // if there is an architecture prefix, only use this symbol it if matches current arch
1410 else if ( strncmp(symbolStart
, "ppc64:", 6) == 0 ) {
1411 if ( fArchitecture
== CPU_TYPE_POWERPC64
)
1412 symbolStart
= &symbolStart
[6];
1416 else if ( strncmp(symbolStart
, "i386:", 5) == 0 ) {
1417 if ( fArchitecture
== CPU_TYPE_I386
)
1418 symbolStart
= &symbolStart
[5];
1422 else if ( strncmp(symbolStart
, "x86_64:", 7) == 0 ) {
1423 if ( fArchitecture
== CPU_TYPE_X86_64
)
1424 symbolStart
= &symbolStart
[7];
1428 else if ( strncmp(symbolStart
, "arm:", 4) == 0 ) {
1429 if ( fArchitecture
== CPU_TYPE_ARM
)
1430 symbolStart
= &symbolStart
[4];
1434 if ( symbolStart
!= NULL
) {
1435 char* objFileName
= NULL
;
1436 char* colon
= strstr(symbolStart
, ".o:");
1437 if ( colon
!= NULL
) {
1439 objFileName
= symbolStart
;
1440 symbolStart
= &colon
[3];
1442 // trim leading spaces
1443 while ( isspace(*symbolStart
) )
1445 Options::OrderedSymbol pair
;
1447 pair
.symbolName
= cstringSymbolName(symbolStart
);
1449 pair
.symbolName
= symbolStart
;
1450 pair
.objectFileName
= objFileName
;
1451 fOrderedSymbols
.push_back(pair
);
1466 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1469 void Options::parseSectionOrderFile(const char* segment
, const char* section
, const char* path
)
1471 if ( (strcmp(section
, "__cstring") == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1472 parseOrderFile(path
, true);
1474 else if ( (strncmp(section
, "__literal",9) == 0) && (strcmp(segment
, "__TEXT") == 0) ) {
1475 warning("sorting of __literal[4,8,16] sections not supported");
1478 // ignore section information and append all symbol names to global order file
1479 parseOrderFile(path
, false);
1483 void Options::addSection(const char* segment
, const char* section
, const char* path
)
1485 if ( strlen(segment
) > 16 )
1486 throw "-seccreate segment name max 16 chars";
1487 if ( strlen(section
) > 16 ) {
1488 char* tmp
= strdup(section
);
1490 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section
, tmp
);
1494 // read in whole file
1495 int fd
= ::open(path
, O_RDONLY
, 0);
1497 throwf("can't open -sectcreate file: %s", path
);
1498 struct stat stat_buf
;
1499 ::fstat(fd
, &stat_buf
);
1500 char* p
= (char*)malloc(stat_buf
.st_size
);
1502 throwf("can't process -sectcreate file: %s", path
);
1503 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
1504 throwf("can't read -sectcreate file: %s", path
);
1507 // record section to create
1508 ExtraSection info
= { segment
, section
, path
, (uint8_t*)p
, stat_buf
.st_size
};
1509 fExtraSections
.push_back(info
);
1512 void Options::addSectionAlignment(const char* segment
, const char* section
, const char* alignmentStr
)
1514 if ( strlen(segment
) > 16 )
1515 throw "-sectalign segment name max 16 chars";
1516 if ( strlen(section
) > 16 )
1517 throw "-sectalign section name max 16 chars";
1519 // argument to -sectalign is a hexadecimal number
1521 unsigned long value
= strtoul(alignmentStr
, &endptr
, 16);
1522 if ( *endptr
!= '\0')
1523 throw "argument for -sectalign is not a hexadecimal number";
1524 if ( value
> 0x8000 )
1525 throw "argument for -sectalign must be less than or equal to 0x8000";
1527 warning("zero is not a valid -sectalign");
1531 // alignment is power of 2 (e.g. page alignment = 12)
1532 uint8_t alignment
= (uint8_t)__builtin_ctz(value
);
1533 if ( (unsigned long)(1 << alignment
) != value
) {
1534 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1535 segment
, section
, 1 << alignment
);
1538 SectionAlignment info
= { segment
, section
, alignment
};
1539 fSectionAlignments
.push_back(info
);
1542 void Options::addLibrary(const FileInfo
& info
)
1544 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1545 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1546 if ( strcmp(info
.path
, fit
->path
) == 0 ) {
1547 // if dylib is specified again but weak, record that it should be weak
1548 if ( info
.options
.fWeakImport
)
1549 fit
->options
.fWeakImport
= true;
1554 fInputFiles
.push_back(info
);
1557 void Options::warnObsolete(const char* arg
)
1559 warning("option %s is obsolete and being ignored", arg
);
1566 // Process all command line arguments.
1568 // The only error checking done here is that each option is valid and if it has arguments
1569 // that they too are valid.
1571 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
1572 // whichever was last on the command line is used.
1574 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
1576 void Options::parse(int argc
, const char* argv
[])
1578 // pass one builds search list from -L and -F options
1579 this->buildSearchPaths(argc
, argv
);
1581 // reduce re-allocations
1582 fInputFiles
.reserve(32);
1584 // pass two parse all other options
1585 for(int i
=1; i
< argc
; ++i
) {
1586 const char* arg
= argv
[i
];
1588 if ( arg
[0] == '-' ) {
1590 // Since we don't care about the files passed, just the option names, we do this here.
1592 fprintf (stderr
, "[Logging ld64 options]\t%s\n", arg
);
1594 if ( (arg
[1] == 'L') || (arg
[1] == 'F') ) {
1595 // previously handled by buildSearchPaths()
1597 // The one gnu style option we have to keep compatibility
1598 // with gcc. Might as well have the single hyphen one as well.
1599 else if ( (strcmp(arg
, "--help") == 0)
1600 || (strcmp(arg
, "-help") == 0)) {
1601 fprintf (stdout
, "ld64: For information on command line options please use 'man ld'.\n");
1604 else if ( strcmp(arg
, "-arch") == 0 ) {
1605 parseArch(argv
[++i
]);
1607 else if ( strcmp(arg
, "-dynamic") == 0 ) {
1610 else if ( strcmp(arg
, "-static") == 0 ) {
1611 if ( fOutputKind
!= kObjectFile
)
1612 fOutputKind
= kStaticExecutable
;
1613 fReaderOptions
.fForStatic
= true;
1615 else if ( strcmp(arg
, "-dylib") == 0 ) {
1616 fOutputKind
= kDynamicLibrary
;
1618 else if ( strcmp(arg
, "-bundle") == 0 ) {
1619 fOutputKind
= kDynamicBundle
;
1621 else if ( strcmp(arg
, "-dylinker") == 0 ) {
1622 fOutputKind
= kDyld
;
1624 else if ( strcmp(arg
, "-execute") == 0 ) {
1625 if ( fOutputKind
!= kStaticExecutable
)
1626 fOutputKind
= kDynamicExecutable
;
1628 else if ( strcmp(arg
, "-r") == 0 ) {
1629 fOutputKind
= kObjectFile
;
1631 else if ( strcmp(arg
, "-o") == 0 ) {
1632 fOutputFile
= argv
[++i
];
1634 else if ( (arg
[1] == 'l') && (strncmp(arg
,"-lazy_",6) !=0) ) {
1635 addLibrary(findLibrary(&arg
[2]));
1637 // This causes a dylib to be weakly bound at
1638 // link time. This corresponds to weak_import.
1639 else if ( strncmp(arg
, "-weak-l", 7) == 0 ) {
1640 FileInfo info
= findLibrary(&arg
[7]);
1641 info
.options
.fWeakImport
= true;
1644 else if ( strncmp(arg
, "-lazy-l", 7) == 0 ) {
1645 FileInfo info
= findLibrary(&arg
[7], true);
1646 info
.options
.fLazyLoad
= true;
1648 fUsingLazyDylibLinking
= true;
1650 // Avoid lazy binding.
1652 else if ( strcmp(arg
, "-bind_at_load") == 0 ) {
1655 else if ( strcmp(arg
, "-twolevel_namespace") == 0 ) {
1656 fNameSpace
= kTwoLevelNameSpace
;
1658 else if ( strcmp(arg
, "-flat_namespace") == 0 ) {
1659 fNameSpace
= kFlatNameSpace
;
1661 // Also sets a bit to ensure dyld causes everything
1662 // in the namespace to be flat.
1664 else if ( strcmp(arg
, "-force_flat_namespace") == 0 ) {
1665 fNameSpace
= kForceFlatNameSpace
;
1667 // Similar to --whole-archive.
1668 else if ( strcmp(arg
, "-all_load") == 0 ) {
1669 fReaderOptions
.fFullyLoadArchives
= true;
1671 else if ( strcmp(arg
, "-noall_load") == 0) {
1674 // Similar to -all_load
1675 else if ( strcmp(arg
, "-ObjC") == 0 ) {
1676 fReaderOptions
.fLoadAllObjcObjectsFromArchives
= true;
1678 // Library versioning.
1679 else if ( (strcmp(arg
, "-dylib_compatibility_version") == 0)
1680 || (strcmp(arg
, "-compatibility_version") == 0)) {
1681 const char* vers
= argv
[++i
];
1683 throw "-dylib_compatibility_version missing <version>";
1684 fDylibCompatVersion
= parseVersionNumber(vers
);
1686 else if ( (strcmp(arg
, "-dylib_current_version") == 0)
1687 || (strcmp(arg
, "-current_version") == 0)) {
1688 const char* vers
= argv
[++i
];
1690 throw "-dylib_current_version missing <version>";
1691 fDylibCurrentVersion
= parseVersionNumber(vers
);
1693 else if ( strcmp(arg
, "-sectorder") == 0 ) {
1694 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
1695 throw "-sectorder missing <segment> <section> <file-path>";
1696 parseSectionOrderFile(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
1699 else if ( strcmp(arg
, "-order_file") == 0 ) {
1700 parseOrderFile(argv
[++i
], false);
1702 else if ( strcmp(arg
, "-order_file_statistics") == 0 ) {
1703 fPrintOrderFileStatistics
= true;
1705 // ??? Deprecate segcreate.
1706 // -sectcreate puts whole files into a section in the output.
1707 else if ( (strcmp(arg
, "-sectcreate") == 0) || (strcmp(arg
, "-segcreate") == 0) ) {
1708 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
1709 throw "-sectcreate missing <segment> <section> <file-path>";
1710 addSection(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
1713 // Since we have a full path in binary/library names we need to be able to override it.
1714 else if ( (strcmp(arg
, "-dylib_install_name") == 0)
1715 || (strcmp(arg
, "-dylinker_install_name") == 0)
1716 || (strcmp(arg
, "-install_name") == 0)) {
1717 fDylibInstallName
= argv
[++i
];
1718 if ( fDylibInstallName
== NULL
)
1719 throw "-install_name missing <path>";
1721 // Sets the base address of the output.
1722 else if ( (strcmp(arg
, "-seg1addr") == 0) || (strcmp(arg
, "-image_base") == 0) ) {
1723 const char* address
= argv
[++i
];
1724 if ( address
== NULL
)
1725 throwf("%s missing <address>", arg
);
1726 fBaseAddress
= parseAddress(address
);
1727 uint64_t temp
= (fBaseAddress
+4095) & (-4096); // page align
1728 if ( fBaseAddress
!= temp
) {
1729 warning("-seg1addr not page aligned, rounding up");
1730 fBaseAddress
= temp
;
1733 else if ( strcmp(arg
, "-e") == 0 ) {
1734 fEntryName
= argv
[++i
];
1736 // Same as -@ from the FSF linker.
1737 else if ( strcmp(arg
, "-filelist") == 0 ) {
1738 const char* path
= argv
[++i
];
1739 if ( (path
== NULL
) || (path
[0] == '-') )
1740 throw "-filelist missing <path>";
1743 else if ( strcmp(arg
, "-keep_private_externs") == 0 ) {
1744 fKeepPrivateExterns
= true;
1746 else if ( strcmp(arg
, "-final_output") == 0 ) {
1747 fFinalName
= argv
[++i
];
1749 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
1750 // just ensures that this happens for cross object file boundaries.
1751 else if ( (strcmp(arg
, "-interposable") == 0) || (strcmp(arg
, "-multi_module") == 0)) {
1752 switch ( fInterposeMode
) {
1753 case kInterposeNone
:
1754 case kInterposeAllExternal
:
1755 fInterposeMode
= kInterposeAllExternal
;
1757 case kInterposeSome
:
1758 // do nothing, -interposable_list overrides -interposable"
1762 else if ( strcmp(arg
, "-interposable_list") == 0 ) {
1763 fInterposeMode
= kInterposeSome
;
1764 loadExportFile(argv
[++i
], "-interposable_list", fInterposeList
);
1766 // Default for -interposable/-multi_module/-single_module.
1767 else if ( strcmp(arg
, "-single_module") == 0 ) {
1768 fInterposeMode
= kInterposeNone
;
1770 else if ( strcmp(arg
, "-exported_symbols_list") == 0 ) {
1771 if ( fExportMode
== kDontExportSome
)
1772 throw "can't use -exported_symbols_list and -unexported_symbols_list";
1773 fExportMode
= kExportSome
;
1774 loadExportFile(argv
[++i
], "-exported_symbols_list", fExportSymbols
);
1776 else if ( strcmp(arg
, "-unexported_symbols_list") == 0 ) {
1777 if ( fExportMode
== kExportSome
)
1778 throw "can't use -unexported_symbols_list and -exported_symbols_list";
1779 fExportMode
= kDontExportSome
;
1780 loadExportFile(argv
[++i
], "-unexported_symbols_list", fDontExportSymbols
);
1782 else if ( strcmp(arg
, "-exported_symbol") == 0 ) {
1783 if ( fExportMode
== kDontExportSome
)
1784 throw "can't use -exported_symbol and -unexported_symbols";
1785 fExportMode
= kExportSome
;
1786 fExportSymbols
.insert(argv
[++i
]);
1788 else if ( strcmp(arg
, "-unexported_symbol") == 0 ) {
1789 if ( fExportMode
== kExportSome
)
1790 throw "can't use -unexported_symbol and -exported_symbol";
1791 fExportMode
= kDontExportSome
;
1792 fDontExportSymbols
.insert(argv
[++i
]);
1794 else if ( strcmp(arg
, "-non_global_symbols_no_strip_list") == 0 ) {
1795 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveExclude
)
1796 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
1797 fLocalSymbolHandling
= kLocalSymbolsSelectiveInclude
;
1798 loadExportFile(argv
[++i
], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded
);
1800 else if ( strcmp(arg
, "-non_global_symbols_strip_list") == 0 ) {
1801 if ( fLocalSymbolHandling
== kLocalSymbolsSelectiveInclude
)
1802 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
1803 fLocalSymbolHandling
= kLocalSymbolsSelectiveExclude
;
1804 loadExportFile(argv
[++i
], "-non_global_symbols_strip_list", fLocalSymbolsExcluded
);
1807 else if ( strcmp(arg
, "-no_arch_warnings") == 0 ) {
1808 fIgnoreOtherArchFiles
= true;
1810 else if ( strcmp(arg
, "-force_cpusubtype_ALL") == 0 ) {
1811 fForceSubtypeAll
= true;
1813 // Similar to -weak-l but uses the absolute path name to the library.
1814 else if ( strcmp(arg
, "-weak_library") == 0 ) {
1815 FileInfo info
= findFile(argv
[++i
]);
1816 info
.options
.fWeakImport
= true;
1819 else if ( strcmp(arg
, "-lazy_library") == 0 ) {
1820 FileInfo info
= findFile(argv
[++i
]);
1821 info
.options
.fLazyLoad
= true;
1823 fUsingLazyDylibLinking
= true;
1825 else if ( strcmp(arg
, "-framework") == 0 ) {
1826 addLibrary(findFramework(argv
[++i
]));
1828 else if ( strcmp(arg
, "-weak_framework") == 0 ) {
1829 FileInfo info
= findFramework(argv
[++i
]);
1830 info
.options
.fWeakImport
= true;
1833 else if ( strcmp(arg
, "-lazy_framework") == 0 ) {
1834 FileInfo info
= findFramework(argv
[++i
]);
1835 info
.options
.fLazyLoad
= true;
1837 fUsingLazyDylibLinking
= true;
1839 else if ( strcmp(arg
, "-search_paths_first") == 0 ) {
1840 // previously handled by buildSearchPaths()
1842 else if ( strcmp(arg
, "-undefined") == 0 ) {
1843 setUndefinedTreatment(argv
[++i
]);
1845 // Debugging output flag.
1846 else if ( strcmp(arg
, "-arch_multiple") == 0 ) {
1847 fMessagesPrefixedWithArchitecture
= true;
1849 // Specify what to do with relocations in read only
1850 // sections like .text. Could be errors, warnings,
1851 // or suppressed. Currently we do nothing with the
1853 else if ( strcmp(arg
, "-read_only_relocs") == 0 ) {
1854 switch ( parseTreatment(argv
[++i
]) ) {
1857 throw "-read_only_relocs missing [ warning | error | suppress ]";
1859 fWarnTextRelocs
= true;
1860 fAllowTextRelocs
= true;
1863 fWarnTextRelocs
= false;
1864 fAllowTextRelocs
= true;
1867 fWarnTextRelocs
= false;
1868 fAllowTextRelocs
= false;
1872 else if ( strcmp(arg
, "-sect_diff_relocs") == 0 ) {
1876 // Warn, error or make strong a mismatch between weak
1877 // and non-weak references.
1878 else if ( strcmp(arg
, "-weak_reference_mismatches") == 0 ) {
1879 setWeakReferenceMismatchTreatment(argv
[++i
]);
1881 // For a deployment target of 10.3 and earlier ld64 will
1882 // prebind an executable with 0s in all addresses that
1883 // are prebound. This can then be fixed up by update_prebinding
1884 // later. Prebinding is less useful on 10.4 and greater.
1885 else if ( strcmp(arg
, "-prebind") == 0 ) {
1888 else if ( strcmp(arg
, "-noprebind") == 0 ) {
1892 else if ( strcmp(arg
, "-prebind_allow_overlap") == 0 ) {
1895 else if ( strcmp(arg
, "-prebind_all_twolevel_modules") == 0 ) {
1898 else if ( strcmp(arg
, "-noprebind_all_twolevel_modules") == 0 ) {
1901 else if ( strcmp(arg
, "-nofixprebinding") == 0 ) {
1904 // This should probably be deprecated when we respect -L and -F
1905 // when searching for libraries.
1906 else if ( strcmp(arg
, "-dylib_file") == 0 ) {
1907 addDylibOverride(argv
[++i
]);
1909 // What to expand @executable_path to if found in dependent dylibs
1910 else if ( strcmp(arg
, "-executable_path") == 0 ) {
1911 fExecutablePath
= argv
[++i
];
1912 if ( (fExecutablePath
== NULL
) || (fExecutablePath
[0] == '-') )
1913 throw "-executable_path missing <path>";
1914 // if a directory was passed, add / to end
1915 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
1916 struct stat statBuffer
;
1917 if ( stat(fExecutablePath
, &statBuffer
) == 0 ) {
1918 if ( (statBuffer
.st_mode
& S_IFMT
) == S_IFDIR
) {
1919 char* pathWithSlash
= new char[strlen(fExecutablePath
)+2];
1920 strcpy(pathWithSlash
, fExecutablePath
);
1921 strcat(pathWithSlash
, "/");
1922 fExecutablePath
= pathWithSlash
;
1926 // Aligns all segments to the power of 2 boundary specified.
1927 else if ( strcmp(arg
, "-segalign") == 0 ) {
1931 // Puts a specified segment at a particular address that must
1932 // be a multiple of the segment alignment.
1933 else if ( strcmp(arg
, "-segaddr") == 0 ) {
1935 seg
.name
= argv
[++i
];
1936 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) )
1937 throw "-segaddr missing segName Adddress";
1938 seg
.address
= parseAddress(argv
[++i
]);
1939 uint64_t temp
= seg
.address
& (-4096); // page align
1940 if ( (seg
.address
!= temp
) )
1941 warning("-segaddr %s not page aligned, rounding down", seg
.name
);
1942 fCustomSegmentAddresses
.push_back(seg
);
1944 // ??? Deprecate when we deprecate split-seg.
1945 else if ( strcmp(arg
, "-segs_read_only_addr") == 0 ) {
1946 fBaseAddress
= parseAddress(argv
[++i
]);
1948 // ??? Deprecate when we deprecate split-seg.
1949 else if ( strcmp(arg
, "-segs_read_write_addr") == 0 ) {
1950 fBaseWritableAddress
= parseAddress(argv
[++i
]);
1953 // ??? Deprecate when we get rid of basing at build time.
1954 else if ( strcmp(arg
, "-seg_addr_table") == 0 ) {
1955 const char* name
= argv
[++i
];
1957 throw "-seg_addr_table missing argument";
1958 fSegAddrTablePath
= name
;
1960 else if ( strcmp(arg
, "-seg_addr_table_filename") == 0 ) {
1964 else if ( strcmp(arg
, "-segprot") == 0 ) {
1966 seg
.name
= argv
[++i
];
1967 if ( (seg
.name
== NULL
) || (argv
[i
+1] == NULL
) || (argv
[i
+2] == NULL
) )
1968 throw "-segprot missing segName max-prot init-prot";
1969 seg
.max
= parseProtection(argv
[++i
]);
1970 seg
.init
= parseProtection(argv
[++i
]);
1971 fCustomSegmentProtections
.push_back(seg
);
1973 else if ( strcmp(arg
, "-pagezero_size") == 0 ) {
1974 const char* size
= argv
[++i
];
1976 throw "-pagezero_size missing <size>";
1977 fZeroPageSize
= parseAddress(size
);
1978 uint64_t temp
= fZeroPageSize
& (-4096); // page align
1979 if ( (fZeroPageSize
!= temp
) )
1980 warning("-pagezero_size not page aligned, rounding down");
1981 fZeroPageSize
= temp
;
1983 else if ( strcmp(arg
, "-stack_addr") == 0 ) {
1984 const char* address
= argv
[++i
];
1985 if ( address
== NULL
)
1986 throw "-stack_addr missing <address>";
1987 fStackAddr
= parseAddress(address
);
1989 else if ( strcmp(arg
, "-stack_size") == 0 ) {
1990 const char* size
= argv
[++i
];
1992 throw "-stack_size missing <address>";
1993 fStackSize
= parseAddress(size
);
1994 uint64_t temp
= fStackSize
& (-4096); // page align
1995 if ( (fStackSize
!= temp
) )
1996 warning("-stack_size not page aligned, rounding down");
1998 else if ( strcmp(arg
, "-allow_stack_execute") == 0 ) {
1999 fExecutableStack
= true;
2001 else if ( strcmp(arg
, "-sectalign") == 0 ) {
2002 if ( (argv
[i
+1]==NULL
) || (argv
[i
+2]==NULL
) || (argv
[i
+3]==NULL
) )
2003 throw "-sectalign missing <segment> <section> <file-path>";
2004 addSectionAlignment(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
2007 else if ( strcmp(arg
, "-sectorder_detail") == 0 ) {
2010 else if ( strcmp(arg
, "-sectobjectsymbols") == 0 ) {
2014 else if ( strcmp(arg
, "-bundle_loader") == 0 ) {
2015 fBundleLoader
= argv
[++i
];
2016 if ( (fBundleLoader
== NULL
) || (fBundleLoader
[0] == '-') )
2017 throw "-bundle_loader missing <path>";
2018 FileInfo info
= findFile(fBundleLoader
);
2019 info
.options
.fBundleLoader
= true;
2020 fInputFiles
.push_back(info
);
2022 else if ( strcmp(arg
, "-private_bundle") == 0 ) {
2025 else if ( strcmp(arg
, "-twolevel_namespace_hints") == 0 ) {
2028 // Use this flag to set default behavior for deployement targets.
2029 else if ( strcmp(arg
, "-macosx_version_min") == 0 ) {
2030 setMacOSXVersionMin(argv
[++i
]);
2032 else if ( (strcmp(arg
, "-aspen_version_min") == 0) || (strcmp(arg
, "-iphone_version_min") == 0) || (strcmp(arg
, "-iphoneos_version_min") == 0) ) {
2033 setIPhoneVersionMin(argv
[++i
]);
2035 else if ( strcmp(arg
, "-multiply_defined") == 0 ) {
2036 //warnObsolete(arg);
2039 else if ( strcmp(arg
, "-multiply_defined_unused") == 0 ) {
2043 else if ( strcmp(arg
, "-nomultidefs") == 0 ) {
2046 // Display each file in which the argument symbol appears and whether
2047 // the file defines or references it. This option takes an argument
2048 // as -y<symbol> note that there is no space.
2049 else if ( strncmp(arg
, "-y", 2) == 0 ) {
2052 // Same output as -y, but output <arg> number of undefined symbols only.
2053 else if ( strcmp(arg
, "-Y") == 0 ) {
2054 //warnObsolete(arg);
2057 // This option affects all objects linked into the final result.
2058 else if ( strcmp(arg
, "-m") == 0 ) {
2061 else if ( (strcmp(arg
, "-why_load") == 0) || (strcmp(arg
, "-whyload") == 0) ) {
2062 fReaderOptions
.fWhyLoad
= true;
2064 else if ( strcmp(arg
, "-why_live") == 0 ) {
2065 const char* name
= argv
[++i
];
2067 throw "-why_live missing symbol name argument";
2068 fWhyLive
.insert(name
);
2070 else if ( strcmp(arg
, "-u") == 0 ) {
2071 const char* name
= argv
[++i
];
2073 throw "-u missing argument";
2074 fInitialUndefines
.push_back(name
);
2076 else if ( strcmp(arg
, "-U") == 0 ) {
2077 const char* name
= argv
[++i
];
2079 throw "-U missing argument";
2080 fAllowedUndefined
.insert(name
);
2082 else if ( strcmp(arg
, "-s") == 0 ) {
2084 fLocalSymbolHandling
= kLocalSymbolsNone
;
2085 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
2087 else if ( strcmp(arg
, "-x") == 0 ) {
2088 fLocalSymbolHandling
= kLocalSymbolsNone
;
2090 else if ( strcmp(arg
, "-S") == 0 ) {
2091 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
2093 else if ( strcmp(arg
, "-X") == 0 ) {
2096 else if ( strcmp(arg
, "-Si") == 0 ) {
2098 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoFull
;
2100 else if ( strcmp(arg
, "-b") == 0 ) {
2103 else if ( strcmp(arg
, "-Sn") == 0 ) {
2105 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoFull
;
2107 else if ( strcmp(arg
, "-Sp") == 0 ) {
2110 else if ( strcmp(arg
, "-dead_strip") == 0 ) {
2111 fDeadStrip
= kDeadStripOnPlusUnusedInits
;
2113 else if ( strcmp(arg
, "-no_dead_strip_inits_and_terms") == 0 ) {
2114 fDeadStrip
= kDeadStripOn
;
2116 else if ( strcmp(arg
, "-w") == 0 ) {
2117 // previously handled by buildSearchPaths()
2119 else if ( strcmp(arg
, "-arch_errors_fatal") == 0 ) {
2122 else if ( strcmp(arg
, "-M") == 0 ) {
2125 else if ( strcmp(arg
, "-headerpad") == 0 ) {
2126 const char* size
= argv
[++i
];
2128 throw "-headerpad missing argument";
2129 fMinimumHeaderPad
= parseAddress(size
);
2131 else if ( strcmp(arg
, "-headerpad_max_install_names") == 0 ) {
2132 fMaxMinimumHeaderPad
= true;
2134 else if ( strcmp(arg
, "-t") == 0 ) {
2135 fReaderOptions
.fLogAllFiles
= true;
2137 else if ( strcmp(arg
, "-whatsloaded") == 0 ) {
2138 fReaderOptions
.fLogObjectFiles
= true;
2140 else if ( strcmp(arg
, "-A") == 0 ) {
2144 else if ( strcmp(arg
, "-umbrella") == 0 ) {
2145 const char* name
= argv
[++i
];
2147 throw "-umbrella missing argument";
2148 fUmbrellaName
= name
;
2150 else if ( strcmp(arg
, "-allowable_client") == 0 ) {
2151 const char* name
= argv
[++i
];
2154 throw "-allowable_client missing argument";
2156 fAllowableClients
.push_back(name
);
2158 else if ( strcmp(arg
, "-client_name") == 0 ) {
2159 const char* name
= argv
[++i
];
2162 throw "-client_name missing argument";
2166 else if ( strcmp(arg
, "-sub_umbrella") == 0 ) {
2167 const char* name
= argv
[++i
];
2169 throw "-sub_umbrella missing argument";
2170 fSubUmbellas
.push_back(name
);
2172 else if ( strcmp(arg
, "-sub_library") == 0 ) {
2173 const char* name
= argv
[++i
];
2175 throw "-sub_library missing argument";
2176 fSubLibraries
.push_back(name
);
2178 else if ( strcmp(arg
, "-init") == 0 ) {
2179 const char* name
= argv
[++i
];
2181 throw "-init missing argument";
2182 fInitFunctionName
= name
;
2184 else if ( strcmp(arg
, "-dot") == 0 ) {
2185 const char* name
= argv
[++i
];
2187 throw "-dot missing argument";
2188 fDotOutputFile
= name
;
2190 else if ( strcmp(arg
, "-warn_commons") == 0 ) {
2191 fWarnCommons
= true;
2193 else if ( strcmp(arg
, "-commons") == 0 ) {
2194 fCommonsMode
= parseCommonsTreatment(argv
[++i
]);
2196 else if ( strcmp(arg
, "-keep_relocs") == 0 ) {
2197 fKeepRelocations
= true;
2199 else if ( strcmp(arg
, "-warn_stabs") == 0 ) {
2202 else if ( strcmp(arg
, "-pause") == 0 ) {
2205 else if ( strcmp(arg
, "-print_statistics") == 0 ) {
2208 else if ( strcmp(arg
, "-d") == 0 ) {
2209 fReaderOptions
.fMakeTentativeDefinitionsReal
= true;
2211 else if ( strcmp(arg
, "-v") == 0 ) {
2212 // previously handled by buildSearchPaths()
2214 else if ( strcmp(arg
, "-Z") == 0 ) {
2215 // previously handled by buildSearchPaths()
2217 else if ( strcmp(arg
, "-syslibroot") == 0 ) {
2219 // previously handled by buildSearchPaths()
2221 else if ( strcmp(arg
, "-no_uuid") == 0 ) {
2222 fUUIDMode
= kUUIDNone
;
2224 else if ( strcmp(arg
, "-random_uuid") == 0 ) {
2225 fUUIDMode
= kUUIDRandom
;
2227 else if ( strcmp(arg
, "-dtrace") == 0 ) {
2228 const char* name
= argv
[++i
];
2230 throw "-dtrace missing argument";
2231 fDtraceScriptName
= name
;
2233 else if ( strcmp(arg
, "-root_safe") == 0 ) {
2234 fReaderOptions
.fRootSafe
= true;
2236 else if ( strcmp(arg
, "-setuid_safe") == 0 ) {
2237 fReaderOptions
.fSetuidSafe
= true;
2239 else if ( strcmp(arg
, "-alias") == 0 ) {
2240 ObjectFile::ReaderOptions::AliasPair pair
;
2241 pair
.realName
= argv
[++i
];
2242 if ( pair
.realName
== NULL
)
2243 throw "missing argument to -alias";
2244 pair
.alias
= argv
[++i
];
2245 if ( pair
.alias
== NULL
)
2246 throw "missing argument to -alias";
2247 fReaderOptions
.fAliases
.push_back(pair
);
2249 else if ( strcmp(arg
, "-alias_list") == 0 ) {
2250 parseAliasFile(argv
[++i
]);
2252 // put this last so that it does not interfer with other options starting with 'i'
2253 else if ( strncmp(arg
, "-i", 2) == 0 ) {
2254 const char* colon
= strchr(arg
, ':');
2255 if ( colon
== NULL
)
2256 throwf("unknown option: %s", arg
);
2257 ObjectFile::ReaderOptions::AliasPair pair
;
2258 char* temp
= new char[colon
-arg
];
2259 strlcpy(temp
, &arg
[2], colon
-arg
-1);
2260 pair
.realName
= &colon
[1];
2262 fReaderOptions
.fAliases
.push_back(pair
);
2264 else if ( strcmp(arg
, "-save-temps") == 0 ) {
2265 fSaveTempFiles
= true;
2267 else if ( strcmp(arg
, "-rpath") == 0 ) {
2268 const char* path
= argv
[++i
];
2270 throw "missing argument to -rpath";
2271 fRPaths
.push_back(path
);
2273 else if ( strcmp(arg
, "-read_only_stubs") == 0 ) {
2274 fReadOnlyx86Stubs
= true;
2276 else if ( strcmp(arg
, "-slow_stubs") == 0 ) {
2277 fReaderOptions
.fSlowx86Stubs
= true;
2279 else if ( strcmp(arg
, "-map") == 0 ) {
2280 fMapPath
= argv
[++i
];
2281 if ( fMapPath
== NULL
)
2282 throw "missing argument to -map";
2284 else if ( strcmp(arg
, "-pie") == 0 ) {
2285 fPositionIndependentExecutable
= true;
2287 else if ( strncmp(arg
, "-reexport-l", 11) == 0 ) {
2288 FileInfo info
= findLibrary(&arg
[11], true);
2289 info
.options
.fReExport
= true;
2292 else if ( strcmp(arg
, "-reexport_library") == 0 ) {
2293 FileInfo info
= findFile(argv
[++i
]);
2294 info
.options
.fReExport
= true;
2297 else if ( strcmp(arg
, "-reexport_framework") == 0 ) {
2298 FileInfo info
= findFramework(argv
[++i
]);
2299 info
.options
.fReExport
= true;
2302 else if ( strcmp(arg
, "-dead_strip_dylibs") == 0 ) {
2303 fDeadStripDylibs
= true;
2305 else if ( strcmp(arg
, "-no_implicit_dylibs") == 0 ) {
2306 fReaderOptions
.fImplicitlyLinkPublicDylibs
= false;
2308 else if ( strcmp(arg
, "-new_linker") == 0 ) {
2311 else if ( strcmp(arg
, "-no_encryption") == 0 ) {
2312 fEncryptable
= false;
2314 else if ( strcmp(arg
, "-mllvm") == 0 ) {
2315 const char* opts
= argv
[++i
];
2317 throw "missing argument to -mllvm";
2318 fLLVMOptions
.push_back(opts
);
2321 throwf("unknown option: %s", arg
);
2325 FileInfo info
= findFile(arg
);
2326 if ( strcmp(&info
.path
[strlen(info
.path
)-2], ".a") == 0 )
2329 fInputFiles
.push_back(info
);
2333 // if a -lazy option was used, implicitly link in lazydylib1.o
2334 if ( fUsingLazyDylibLinking
) {
2335 addLibrary(findLibrary("lazydylib1.o"));
2342 // -syslibroot <path> is used for SDK support.
2343 // The rule is that all search paths (both explicit and default) are
2344 // checked to see if they exist in the SDK. If so, that path is
2345 // replaced with the sdk prefixed path. If not, that search path
2346 // is used as is. If multiple -syslibroot options are specified
2347 // their directory structures are logically overlayed and files
2348 // from sdks specified earlier on the command line used before later ones.
2350 void Options::buildSearchPaths(int argc
, const char* argv
[])
2352 bool addStandardLibraryDirectories
= true;
2353 std::vector
<const char*> libraryPaths
;
2354 std::vector
<const char*> frameworkPaths
;
2355 libraryPaths
.reserve(10);
2356 frameworkPaths
.reserve(10);
2357 // scan through argv looking for -L, -F, -Z, and -syslibroot options
2358 for(int i
=0; i
< argc
; ++i
) {
2359 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') )
2360 libraryPaths
.push_back(&argv
[i
][2]);
2361 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') )
2362 frameworkPaths
.push_back(&argv
[i
][2]);
2363 else if ( strcmp(argv
[i
], "-Z") == 0 )
2364 addStandardLibraryDirectories
= false;
2365 else if ( strcmp(argv
[i
], "-v") == 0 ) {
2367 extern const char ldVersionString
[];
2368 fprintf(stderr
, "%s", ldVersionString
);
2369 // if only -v specified, exit cleanly
2372 printLTOVersion(*this);
2377 else if ( strcmp(argv
[i
], "-syslibroot") == 0 ) {
2378 const char* path
= argv
[++i
];
2380 throw "-syslibroot missing argument";
2381 fSDKPaths
.push_back(path
);
2383 else if ( strcmp(argv
[i
], "-search_paths_first") == 0 ) {
2384 // ??? Deprecate when we get -Bstatic/-Bdynamic.
2385 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
2387 else if ( strcmp(argv
[i
], "-w") == 0 ) {
2388 sEmitWarnings
= false;
2391 if ( addStandardLibraryDirectories
) {
2392 libraryPaths
.push_back("/usr/lib");
2393 libraryPaths
.push_back("/usr/local/lib");
2395 frameworkPaths
.push_back("/Library/Frameworks/");
2396 frameworkPaths
.push_back("/System/Library/Frameworks/");
2397 // <rdar://problem/5433882> remove /Network from default search path
2398 //frameworkPaths.push_back("/Network/Library/Frameworks/");
2401 // <rdar://problem/5829579> Support for configure based hacks
2402 // if last -syslibroot is /, then ignore all syslibroots
2403 if ( fSDKPaths
.size() > 0 ) {
2404 if ( strcmp(fSDKPaths
.back(), "/") == 0 ) {
2409 // now merge sdk and library paths to make real search paths
2410 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
2411 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); it
++) {
2412 const char* libDir
= *it
;
2413 bool sdkOverride
= false;
2414 if ( libDir
[0] == '/' ) {
2415 char betterLibDir
[PATH_MAX
];
2416 if ( strstr(libDir
, "/..") != NULL
) {
2417 if ( realpath(libDir
, betterLibDir
) != NULL
)
2418 libDir
= strdup(betterLibDir
);
2420 const int libDirLen
= strlen(libDir
);
2421 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2422 // ??? Should be using string here.
2423 const char* sdkDir
= *sdkit
;
2424 const int sdkDirLen
= strlen(sdkDir
);
2425 char newPath
[libDirLen
+ sdkDirLen
+4];
2426 strcpy(newPath
, sdkDir
);
2427 if ( newPath
[sdkDirLen
-1] == '/' )
2428 newPath
[sdkDirLen
-1] = '\0';
2429 strcat(newPath
, libDir
);
2430 struct stat statBuffer
;
2431 if ( stat(newPath
, &statBuffer
) == 0 ) {
2432 fLibrarySearchPaths
.push_back(strdup(newPath
));
2438 fLibrarySearchPaths
.push_back(libDir
);
2441 // now merge sdk and framework paths to make real search paths
2442 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
2443 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); it
++) {
2444 const char* frameworkDir
= *it
;
2445 bool sdkOverride
= false;
2446 if ( frameworkDir
[0] == '/' ) {
2447 char betterFrameworkDir
[PATH_MAX
];
2448 if ( strstr(frameworkDir
, "/..") != NULL
) {
2449 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
2450 frameworkDir
= strdup(betterFrameworkDir
);
2452 const int frameworkDirLen
= strlen(frameworkDir
);
2453 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2454 // ??? Should be using string here
2455 const char* sdkDir
= *sdkit
;
2456 const int sdkDirLen
= strlen(sdkDir
);
2457 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
2458 strcpy(newPath
, sdkDir
);
2459 if ( newPath
[sdkDirLen
-1] == '/' )
2460 newPath
[sdkDirLen
-1] = '\0';
2461 strcat(newPath
, frameworkDir
);
2462 struct stat statBuffer
;
2463 if ( stat(newPath
, &statBuffer
) == 0 ) {
2464 fFrameworkSearchPaths
.push_back(strdup(newPath
));
2470 fFrameworkSearchPaths
.push_back(frameworkDir
);
2474 fprintf(stderr
,"Library search paths:\n");
2475 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
2476 it
!= fLibrarySearchPaths
.end();
2478 fprintf(stderr
,"\t%s\n", *it
);
2479 fprintf(stderr
,"Framework search paths:\n");
2480 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
2481 it
!= fFrameworkSearchPaths
.end();
2483 fprintf(stderr
,"\t%s\n", *it
);
2487 // this is run before the command line is parsed
2488 void Options::parsePreCommandLineEnvironmentSettings()
2490 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
2491 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
2492 fReaderOptions
.fTraceArchives
= true;
2494 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
2495 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
2496 fReaderOptions
.fTraceDylibs
= true;
2497 fReaderOptions
.fTraceIndirectDylibs
= true;
2500 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
2501 fTraceDylibSearching
= true;
2504 if (getenv("LD_PRINT_OPTIONS") != NULL
)
2505 fPrintOptions
= true;
2507 if (fReaderOptions
.fTraceDylibs
|| fReaderOptions
.fTraceArchives
)
2508 fReaderOptions
.fTraceOutputFile
= getenv("LD_TRACE_FILE");
2510 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL
)
2511 fPrintOrderFileStatistics
= true;
2513 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL
)
2516 if (getenv("LD_NO_ENCRYPT") != NULL
)
2517 fEncryptable
= false;
2519 sWarningsSideFilePath
= getenv("LD_WARN_FILE");
2523 // this is run after the command line is parsed
2524 void Options::parsePostCommandLineEnvironmentSettings()
2526 // when building a dynamic main executable, default any use of @executable_path to output path
2527 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
2528 fExecutablePath
= fOutputFile
;
2531 // allow build system to set default seg_addr_table
2532 if ( fSegAddrTablePath
== NULL
)
2533 fSegAddrTablePath
= getenv("LD_SEG_ADDR_TABLE");
2535 // allow build system to turn on prebinding
2537 fPrebind
= ( getenv("LD_PREBIND") != NULL
);
2540 // allow build system to force on dead-code-stripping
2541 if ( fDeadStrip
== kDeadStripOff
) {
2542 if ( getenv("LD_DEAD_STRIP") != NULL
) {
2543 switch (fOutputKind
) {
2544 case Options::kDynamicLibrary
:
2545 case Options::kDynamicExecutable
:
2546 case Options::kDynamicBundle
:
2547 fDeadStrip
= kDeadStripOn
;
2549 case Options::kObjectFile
:
2550 case Options::kDyld
:
2551 case Options::kStaticExecutable
:
2557 // allow build system to force on -warn_commons
2558 if ( getenv("LD_WARN_COMMONS") != NULL
)
2559 fWarnCommons
= true;
2562 void Options::reconfigureDefaults()
2564 // sync reader options
2565 switch ( fOutputKind
) {
2566 case Options::kObjectFile
:
2567 fReaderOptions
.fForFinalLinkedImage
= false;
2569 case Options::kDyld
:
2570 fReaderOptions
.fForDyld
= true;
2571 fReaderOptions
.fForFinalLinkedImage
= true;
2573 case Options::kDynamicLibrary
:
2574 case Options::kDynamicBundle
:
2575 fReaderOptions
.fForFinalLinkedImage
= true;
2577 case Options::kDynamicExecutable
:
2578 case Options::kStaticExecutable
:
2579 fReaderOptions
.fLinkingMainExecutable
= true;
2580 fReaderOptions
.fForFinalLinkedImage
= true;
2584 // set default min OS version
2585 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::kMinUnset
) {
2586 // if -macosx_version_min not used, try environment variable
2587 const char* envVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
2588 if ( envVers
!= NULL
)
2589 setMacOSXVersionMin(envVers
);
2590 // if -macosx_version_min and environment variable not used assume current OS version
2591 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::kMinUnset
)
2592 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_5
; // FIX FIX, this really should be a check of the OS version the linker is running on
2595 // adjust min based on architecture
2596 switch ( fArchitecture
) {
2598 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2599 //warning("-macosx_version_min should be 10.4 or later for i386");
2600 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2603 case CPU_TYPE_POWERPC64
:
2604 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2605 //warning("-macosx_version_min should be 10.4 or later for ppc64");
2606 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2609 case CPU_TYPE_X86_64
:
2610 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2611 //warning("-macosx_version_min should be 10.4 or later for x86_64");
2612 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2617 // disable implicit dylibs when targetting 10.3
2618 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
2619 if ( fReaderOptions
.fVersionMin
<= ObjectFile::ReaderOptions::k10_3
)
2620 fReaderOptions
.fImplicitlyLinkPublicDylibs
= false;
2623 // determine if info for shared region should be added
2624 if ( fOutputKind
== Options::kDynamicLibrary
) {
2625 if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
)
2626 if ( fArchitecture
!= CPU_TYPE_ARM
)
2627 fSharedRegionEligible
= true;
2630 // allow build system to force linker to ignore seg_addr_table
2631 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL
)
2632 fSegAddrTablePath
= NULL
;
2634 // check for base address specified externally
2635 if ( (fSegAddrTablePath
!= NULL
) && (fOutputKind
== Options::kDynamicLibrary
) ) {
2636 parseSegAddrTable(fSegAddrTablePath
, this->installPath());
2637 // HACK to support seg_addr_table entries that are physical paths instead of install paths
2638 if ( fBaseAddress
== 0 ) {
2639 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 )
2640 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.4.dylib");
2642 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
2643 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libz.1.2.3.dylib");
2645 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
2646 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libutil1.0.dylib");
2650 // split segs only allowed for dylibs
2652 // split seg only supported for ppc, i386, and arm.
2653 switch ( fArchitecture
) {
2654 case CPU_TYPE_POWERPC
:
2656 if ( fOutputKind
!= Options::kDynamicLibrary
)
2658 // make sure read and write segments are proper distance apart
2659 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x10000000) )
2660 fBaseWritableAddress
= fBaseAddress
+ 0x10000000;
2663 if ( fOutputKind
!= Options::kDynamicLibrary
) {
2667 // make sure read and write segments are proper distance apart
2668 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x08000000) )
2669 fBaseWritableAddress
= fBaseAddress
+ 0x08000000;
2675 fBaseWritableAddress
= 0;
2679 // disable prebinding depending on arch and min OS version
2681 switch ( fArchitecture
) {
2682 case CPU_TYPE_POWERPC
:
2684 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::k10_4
) {
2685 // in 10.4 only split seg dylibs are prebound
2686 if ( (fOutputKind
!= Options::kDynamicLibrary
) || ! fSplitSegs
)
2689 else if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
) {
2690 // in 10.5 nothing is prebound
2694 // in 10.3 and earlier only dylibs and main executables could be prebound
2695 switch ( fOutputKind
) {
2696 case Options::kDynamicExecutable
:
2697 case Options::kDynamicLibrary
:
2698 // only main executables and dylibs can be prebound
2700 case Options::kStaticExecutable
:
2701 case Options::kDynamicBundle
:
2702 case Options::kObjectFile
:
2703 case Options::kDyld
:
2704 // disable prebinding for everything else
2710 case CPU_TYPE_POWERPC64
:
2711 case CPU_TYPE_X86_64
:
2715 switch ( fOutputKind
) {
2716 case Options::kDynamicExecutable
:
2717 case Options::kDynamicLibrary
:
2718 // only main executables and dylibs can be prebound
2720 case Options::kStaticExecutable
:
2721 case Options::kDynamicBundle
:
2722 case Options::kObjectFile
:
2723 case Options::kDyld
:
2724 // disable prebinding for everything else
2732 // only prebound images can be split-seg
2733 if ( fSplitSegs
&& !fPrebind
)
2736 // figure out if module table is needed for compatibility with old ld/dyld
2737 if ( fOutputKind
== Options::kDynamicLibrary
) {
2738 switch ( fArchitecture
) {
2739 case CPU_TYPE_POWERPC
: // 10.3 and earlier dyld requires a module table
2740 case CPU_TYPE_I386
: // ld_classic for 10.4.x requires a module table
2741 if ( fReaderOptions
.fVersionMin
<= ObjectFile::ReaderOptions::k10_5
)
2742 fNeedsModuleTable
= true;
2745 fNeedsModuleTable
= true; // redo_prebinding requires a module table
2750 // <rdar://problem/5366363> -r -x implies -S
2751 if ( (fOutputKind
== Options::kObjectFile
) && (fLocalSymbolHandling
== kLocalSymbolsNone
) )
2752 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
2754 // only ARM main executables can be encrypted
2755 if ( fOutputKind
!= Options::kDynamicExecutable
)
2756 fEncryptable
= false;
2757 if ( fArchitecture
!= CPU_TYPE_ARM
)
2758 fEncryptable
= false;
2761 void Options::checkIllegalOptionCombinations()
2763 // check -undefined setting
2764 switch ( fUndefinedTreatment
) {
2765 case kUndefinedError
:
2766 case kUndefinedDynamicLookup
:
2769 case kUndefinedWarning
:
2770 case kUndefinedSuppress
:
2771 // requires flat namespace
2772 if ( fNameSpace
== kTwoLevelNameSpace
)
2773 throw "can't use -undefined warning or suppress with -twolevel_namespace";
2777 // unify -sub_umbrella with dylibs
2778 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
2779 const char* subUmbrella
= *it
;
2781 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
2782 Options::FileInfo
& info
= *fit
;
2783 const char* lastSlash
= strrchr(info
.path
, '/');
2784 if ( lastSlash
== NULL
)
2785 lastSlash
= info
.path
- 1;
2786 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
2787 info
.options
.fReExport
= true;
2793 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella
);
2796 // unify -sub_library with dylibs
2797 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
2798 const char* subLibrary
= *it
;
2800 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
2801 Options::FileInfo
& info
= *fit
;
2802 const char* lastSlash
= strrchr(info
.path
, '/');
2803 if ( lastSlash
== NULL
)
2804 lastSlash
= info
.path
- 1;
2805 const char* dot
= strchr(&lastSlash
[1], '.');
2807 dot
= &lastSlash
[strlen(lastSlash
)];
2808 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
2809 info
.options
.fReExport
= true;
2815 warning("-sub_library %s does not match a supplied dylib", subLibrary
);
2818 // sync reader options
2819 if ( fNameSpace
!= kTwoLevelNameSpace
)
2820 fReaderOptions
.fFlatNamespace
= true;
2822 // check -stack_addr
2823 if ( fStackAddr
!= 0 ) {
2824 switch (fArchitecture
) {
2826 case CPU_TYPE_POWERPC
:
2828 if ( fStackAddr
> 0xFFFFFFFF )
2829 throw "-stack_addr must be < 4G for 32-bit processes";
2831 case CPU_TYPE_POWERPC64
:
2832 case CPU_TYPE_X86_64
:
2835 if ( (fStackAddr
& -4096) != fStackAddr
)
2836 throw "-stack_addr must be multiples of 4K";
2837 if ( fStackSize
== 0 )
2838 throw "-stack_addr must be used with -stack_size";
2841 // check -stack_size
2842 if ( fStackSize
!= 0 ) {
2843 switch (fArchitecture
) {
2845 case CPU_TYPE_POWERPC
:
2846 if ( fStackSize
> 0xFFFFFFFF )
2847 throw "-stack_size must be < 4G for 32-bit processes";
2848 if ( fStackAddr
== 0 ) {
2849 fStackAddr
= 0xC0000000;
2851 if ( (fStackAddr
> 0xB0000000) && ((fStackAddr
-fStackSize
) < 0xB0000000) )
2852 warning("custom stack placement overlaps and will disable shared region");
2855 if ( fStackSize
> 0xFFFFFFFF )
2856 throw "-stack_size must be < 4G for 32-bit processes";
2857 if ( fStackAddr
== 0 )
2858 fStackAddr
= 0x30000000;
2859 if ( fStackAddr
> 0x40000000)
2860 throw "-stack_addr must be < 1G for arm";
2861 case CPU_TYPE_POWERPC64
:
2862 case CPU_TYPE_X86_64
:
2863 if ( fStackAddr
== 0 ) {
2864 fStackAddr
= 0x00007FFF5C000000LL
;
2868 if ( (fStackSize
& -4096) != fStackSize
)
2869 throw "-stack_size must be multiples of 4K";
2870 switch ( fOutputKind
) {
2871 case Options::kDynamicExecutable
:
2872 case Options::kStaticExecutable
:
2873 // custom stack size only legal when building main executable
2875 case Options::kDynamicLibrary
:
2876 case Options::kDynamicBundle
:
2877 case Options::kObjectFile
:
2878 case Options::kDyld
:
2879 throw "-stack_size option can only be used when linking a main executable";
2883 // check that -allow_stack_execute is only used with main executables
2884 if ( fExecutableStack
) {
2885 switch ( fOutputKind
) {
2886 case Options::kDynamicExecutable
:
2887 case Options::kStaticExecutable
:
2888 // -allow_stack_execute size only legal when building main executable
2890 case Options::kDynamicLibrary
:
2891 case Options::kDynamicBundle
:
2892 case Options::kObjectFile
:
2893 case Options::kDyld
:
2894 throw "-allow_stack_execute option can only be used when linking a main executable";
2898 // check -client_name is only used when making a bundle or main executable
2899 if ( fClientName
!= NULL
) {
2900 switch ( fOutputKind
) {
2901 case Options::kDynamicExecutable
:
2902 case Options::kDynamicBundle
:
2904 case Options::kStaticExecutable
:
2905 case Options::kDynamicLibrary
:
2906 case Options::kObjectFile
:
2907 case Options::kDyld
:
2908 throw "-client_name can only be used with -bundle";
2912 // check -init is only used when building a dylib
2913 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
2914 throw "-init can only be used with -dynamiclib";
2916 // check -bundle_loader only used with -bundle
2917 if ( (fBundleLoader
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
2918 throw "-bundle_loader can only be used with -bundle";
2920 // check -dtrace not used with -r
2921 if ( (fDtraceScriptName
!= NULL
) && (fOutputKind
== Options::kObjectFile
) )
2922 throw "-dtrace can only be used when creating final linked images";
2924 // check -d can only be used with -r
2925 if ( fReaderOptions
.fMakeTentativeDefinitionsReal
&& (fOutputKind
!= Options::kObjectFile
) )
2926 throw "-d can only be used with -r";
2928 // check that -root_safe is not used with -r
2929 if ( fReaderOptions
.fRootSafe
&& (fOutputKind
== Options::kObjectFile
) )
2930 throw "-root_safe cannot be used with -r";
2932 // check that -setuid_safe is not used with -r
2933 if ( fReaderOptions
.fSetuidSafe
&& (fOutputKind
== Options::kObjectFile
) )
2934 throw "-setuid_safe cannot be used with -r";
2936 // make sure all required exported symbols exist
2937 std::vector
<const char*> impliedExports
;
2938 for (NameSet::iterator it
=fExportSymbols
.regularBegin(); it
!= fExportSymbols
.regularEnd(); it
++) {
2939 const char* name
= *it
;
2940 // never export .eh symbols
2941 const int len
= strlen(name
);
2942 if ( (strcmp(&name
[len
-3], ".eh") == 0) || (strncmp(name
, ".objc_category_name_", 20) == 0) )
2943 warning("ignoring %s in export list", name
);
2945 fInitialUndefines
.push_back(name
);
2946 if ( strncmp(name
, ".objc_class_name_", 17) == 0 ) {
2947 // rdar://problem/4718189 map ObjC class names to new runtime names
2948 switch (fArchitecture
) {
2949 case CPU_TYPE_POWERPC64
:
2950 case CPU_TYPE_X86_64
:
2953 asprintf(&temp
, "_OBJC_CLASS_$_%s", &name
[17]);
2954 impliedExports
.push_back(temp
);
2955 asprintf(&temp
, "_OBJC_METACLASS_$_%s", &name
[17]);
2956 impliedExports
.push_back(temp
);
2961 for (std::vector
<const char*>::iterator it
=impliedExports
.begin(); it
!= impliedExports
.end(); it
++) {
2962 const char* name
= *it
;
2963 fExportSymbols
.insert(name
);
2964 fInitialUndefines
.push_back(name
);
2967 // make sure that -init symbol exist
2968 if ( fInitFunctionName
!= NULL
)
2969 fInitialUndefines
.push_back(fInitFunctionName
);
2971 // check custom segments
2972 if ( fCustomSegmentAddresses
.size() != 0 ) {
2973 // verify no segment is in zero page
2974 if ( fZeroPageSize
!= ULLONG_MAX
) {
2975 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
2976 if ( (it
->address
>= 0) && (it
->address
< fZeroPageSize
) )
2977 throwf("-segaddr %s 0x%X conflicts with -pagezero_size", it
->name
, it
->address
);
2980 // verify no duplicates
2981 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
2982 for (std::vector
<SegmentStart
>::iterator it2
= fCustomSegmentAddresses
.begin(); it2
!= fCustomSegmentAddresses
.end(); ++it2
) {
2983 if ( (it
->address
== it2
->address
) && (it
!= it2
) )
2984 throwf("duplicate -segaddr addresses for %s and %s", it
->name
, it2
->name
);
2986 // a custom segment address of zero will disable the use of a zero page
2987 if ( it
->address
== 0 )
2992 if ( fZeroPageSize
== ULLONG_MAX
) {
2993 // zero page size not specified on command line, set default
2994 switch (fArchitecture
) {
2996 case CPU_TYPE_POWERPC
:
2998 // first 4KB for 32-bit architectures
2999 fZeroPageSize
= 0x1000;
3001 case CPU_TYPE_POWERPC64
:
3002 // first 4GB for ppc64 on 10.5
3003 if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
)
3004 fZeroPageSize
= 0x100000000ULL
;
3006 fZeroPageSize
= 0x1000; // 10.4 dyld may not be able to handle >4GB zero page
3008 case CPU_TYPE_X86_64
:
3009 // first 4GB for x86_64 on all OS's
3010 fZeroPageSize
= 0x100000000ULL
;
3013 // if -arch not used, default to 4K zero-page
3014 fZeroPageSize
= 0x1000;
3018 switch ( fOutputKind
) {
3019 case Options::kDynamicExecutable
:
3020 case Options::kStaticExecutable
:
3021 // -pagezero_size size only legal when building main executable
3023 case Options::kDynamicLibrary
:
3024 case Options::kDynamicBundle
:
3025 case Options::kObjectFile
:
3026 case Options::kDyld
:
3027 if ( fZeroPageSize
!= 0 )
3028 throw "-pagezero_size option can only be used when linking a main executable";
3032 // -dead_strip and -r are incompatible
3033 if ( (fDeadStrip
!= kDeadStripOff
) && (fOutputKind
== Options::kObjectFile
) )
3034 throw "-r and -dead_strip cannot be used together";
3036 // can't use -rpath unless targeting 10.5 or later
3037 if ( fRPaths
.size() > 0 ) {
3038 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_5
)
3039 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
3040 switch ( fOutputKind
) {
3041 case Options::kDynamicExecutable
:
3042 case Options::kDynamicLibrary
:
3043 case Options::kDynamicBundle
:
3045 case Options::kStaticExecutable
:
3046 case Options::kObjectFile
:
3047 case Options::kDyld
:
3048 throw "-rpath can only be used when creating a dynamic final linked image";
3052 // check -pie is only used when building a dynamic main executable for 10.5
3053 if ( fPositionIndependentExecutable
) {
3054 if ( fOutputKind
!= Options::kDynamicExecutable
)
3055 throw "-pie can only be used when linking a main executable";
3056 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_5
)
3057 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
3063 void Options::checkForClassic(int argc
, const char* argv
[])
3066 bool archFound
= false;
3067 bool staticFound
= false;
3068 bool dtraceFound
= false;
3069 bool rFound
= false;
3070 bool creatingMachKernel
= false;
3071 bool newLinker
= false;
3073 for(int i
=0; i
< argc
; ++i
) {
3074 const char* arg
= argv
[i
];
3075 if ( arg
[0] == '-' ) {
3076 if ( strcmp(arg
, "-arch") == 0 ) {
3077 parseArch(argv
[++i
]);
3080 else if ( strcmp(arg
, "-static") == 0 ) {
3083 else if ( strcmp(arg
, "-dtrace") == 0 ) {
3086 else if ( strcmp(arg
, "-r") == 0 ) {
3089 else if ( strcmp(arg
, "-new_linker") == 0 ) {
3092 else if ( strcmp(arg
, "-classic_linker") == 0 ) {
3093 // ld_classic does not understand this option, so remove it
3094 for(int j
=i
; j
< argc
; ++j
)
3095 argv
[j
] = argv
[j
+1];
3096 this->gotoClassicLinker(argc
-1, argv
);
3098 else if ( strcmp(arg
, "-o") == 0 ) {
3099 const char* outfile
= argv
[++i
];
3100 if ( (outfile
!= NULL
) && (strstr(outfile
, "/mach_kernel") != NULL
) )
3101 creatingMachKernel
= true;
3106 // -dtrace only supported by new linker
3111 switch ( fArchitecture
) {
3112 case CPU_TYPE_POWERPC
:
3115 // if ( staticFound && (rFound || !creatingMachKernel) ) {
3116 if ( staticFound
&& !newLinker
) {
3117 // this environment variable will disable use of ld_classic for -static links
3118 if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL
) {
3119 // ld_classic does not support -aspen_version_min, so change
3120 for(int j
=0; j
< argc
; ++j
) {
3121 if ( (strcmp(argv
[j
], "-aspen_version_min") == 0)
3122 || (strcmp(argv
[j
], "-iphone_version_min") == 0)
3123 || (strcmp(argv
[j
], "-iphoneos_version_min") == 0) ) {
3124 argv
[j
] = "-macosx_version_min";
3130 this->gotoClassicLinker(argc
, argv
);
3137 // work around for VSPTool
3139 this->gotoClassicLinker(argc
, argv
);
3144 void Options::gotoClassicLinker(int argc
, const char* argv
[])
3146 argv
[0] = "ld_classic";
3147 execvp(argv
[0], (char**)argv
);
3148 fprintf(stderr
, "can't exec ld_classic\n");