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;
2315 throwf("unknown option: %s", arg
);
2319 FileInfo info
= findFile(arg
);
2320 if ( strcmp(&info
.path
[strlen(info
.path
)-2], ".a") == 0 )
2323 fInputFiles
.push_back(info
);
2327 // if a -lazy option was used, implicitly link in lazydylib1.o
2328 if ( fUsingLazyDylibLinking
) {
2329 addLibrary(findLibrary("lazydylib1.o"));
2336 // -syslibroot <path> is used for SDK support.
2337 // The rule is that all search paths (both explicit and default) are
2338 // checked to see if they exist in the SDK. If so, that path is
2339 // replaced with the sdk prefixed path. If not, that search path
2340 // is used as is. If multiple -syslibroot options are specified
2341 // their directory structures are logically overlayed and files
2342 // from sdks specified earlier on the command line used before later ones.
2344 void Options::buildSearchPaths(int argc
, const char* argv
[])
2346 bool addStandardLibraryDirectories
= true;
2347 std::vector
<const char*> libraryPaths
;
2348 std::vector
<const char*> frameworkPaths
;
2349 libraryPaths
.reserve(10);
2350 frameworkPaths
.reserve(10);
2351 // scan through argv looking for -L, -F, -Z, and -syslibroot options
2352 for(int i
=0; i
< argc
; ++i
) {
2353 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') )
2354 libraryPaths
.push_back(&argv
[i
][2]);
2355 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') )
2356 frameworkPaths
.push_back(&argv
[i
][2]);
2357 else if ( strcmp(argv
[i
], "-Z") == 0 )
2358 addStandardLibraryDirectories
= false;
2359 else if ( strcmp(argv
[i
], "-v") == 0 ) {
2361 extern const char ldVersionString
[];
2362 fprintf(stderr
, "%s", ldVersionString
);
2363 // if only -v specified, exit cleanly
2366 printLTOVersion(*this);
2371 else if ( strcmp(argv
[i
], "-syslibroot") == 0 ) {
2372 const char* path
= argv
[++i
];
2374 throw "-syslibroot missing argument";
2375 fSDKPaths
.push_back(path
);
2377 else if ( strcmp(argv
[i
], "-search_paths_first") == 0 ) {
2378 // ??? Deprecate when we get -Bstatic/-Bdynamic.
2379 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
2381 else if ( strcmp(argv
[i
], "-w") == 0 ) {
2382 sEmitWarnings
= false;
2385 if ( addStandardLibraryDirectories
) {
2386 libraryPaths
.push_back("/usr/lib");
2387 libraryPaths
.push_back("/usr/local/lib");
2389 frameworkPaths
.push_back("/Library/Frameworks/");
2390 frameworkPaths
.push_back("/System/Library/Frameworks/");
2391 // <rdar://problem/5433882> remove /Network from default search path
2392 //frameworkPaths.push_back("/Network/Library/Frameworks/");
2395 // now merge sdk and library paths to make real search paths
2396 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
2397 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); it
++) {
2398 const char* libDir
= *it
;
2399 bool sdkOverride
= false;
2400 if ( libDir
[0] == '/' ) {
2401 char betterLibDir
[PATH_MAX
];
2402 if ( strstr(libDir
, "/..") != NULL
) {
2403 if ( realpath(libDir
, betterLibDir
) != NULL
)
2404 libDir
= strdup(betterLibDir
);
2406 const int libDirLen
= strlen(libDir
);
2407 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2408 // ??? Should be using string here.
2409 const char* sdkDir
= *sdkit
;
2410 const int sdkDirLen
= strlen(sdkDir
);
2411 char newPath
[libDirLen
+ sdkDirLen
+4];
2412 strcpy(newPath
, sdkDir
);
2413 if ( newPath
[sdkDirLen
-1] == '/' )
2414 newPath
[sdkDirLen
-1] = '\0';
2415 strcat(newPath
, libDir
);
2416 struct stat statBuffer
;
2417 if ( stat(newPath
, &statBuffer
) == 0 ) {
2418 fLibrarySearchPaths
.push_back(strdup(newPath
));
2424 fLibrarySearchPaths
.push_back(libDir
);
2427 // now merge sdk and framework paths to make real search paths
2428 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
2429 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); it
++) {
2430 const char* frameworkDir
= *it
;
2431 bool sdkOverride
= false;
2432 if ( frameworkDir
[0] == '/' ) {
2433 char betterFrameworkDir
[PATH_MAX
];
2434 if ( strstr(frameworkDir
, "/..") != NULL
) {
2435 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
2436 frameworkDir
= strdup(betterFrameworkDir
);
2438 const int frameworkDirLen
= strlen(frameworkDir
);
2439 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2440 // ??? Should be using string here
2441 const char* sdkDir
= *sdkit
;
2442 const int sdkDirLen
= strlen(sdkDir
);
2443 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
2444 strcpy(newPath
, sdkDir
);
2445 if ( newPath
[sdkDirLen
-1] == '/' )
2446 newPath
[sdkDirLen
-1] = '\0';
2447 strcat(newPath
, frameworkDir
);
2448 struct stat statBuffer
;
2449 if ( stat(newPath
, &statBuffer
) == 0 ) {
2450 fFrameworkSearchPaths
.push_back(strdup(newPath
));
2456 fFrameworkSearchPaths
.push_back(frameworkDir
);
2460 fprintf(stderr
,"Library search paths:\n");
2461 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
2462 it
!= fLibrarySearchPaths
.end();
2464 fprintf(stderr
,"\t%s\n", *it
);
2465 fprintf(stderr
,"Framework search paths:\n");
2466 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
2467 it
!= fFrameworkSearchPaths
.end();
2469 fprintf(stderr
,"\t%s\n", *it
);
2473 // this is run before the command line is parsed
2474 void Options::parsePreCommandLineEnvironmentSettings()
2476 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
2477 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
2478 fReaderOptions
.fTraceArchives
= true;
2480 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
2481 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
2482 fReaderOptions
.fTraceDylibs
= true;
2483 fReaderOptions
.fTraceIndirectDylibs
= true;
2486 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
2487 fTraceDylibSearching
= true;
2490 if (getenv("LD_PRINT_OPTIONS") != NULL
)
2491 fPrintOptions
= true;
2493 if (fReaderOptions
.fTraceDylibs
|| fReaderOptions
.fTraceArchives
)
2494 fReaderOptions
.fTraceOutputFile
= getenv("LD_TRACE_FILE");
2496 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL
)
2497 fPrintOrderFileStatistics
= true;
2499 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL
)
2502 if (getenv("LD_NO_ENCRYPT") != NULL
)
2503 fEncryptable
= false;
2505 sWarningsSideFilePath
= getenv("LD_WARN_FILE");
2509 // this is run after the command line is parsed
2510 void Options::parsePostCommandLineEnvironmentSettings()
2512 // when building a dynamic main executable, default any use of @executable_path to output path
2513 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
2514 fExecutablePath
= fOutputFile
;
2517 // allow build system to set default seg_addr_table
2518 if ( fSegAddrTablePath
== NULL
)
2519 fSegAddrTablePath
= getenv("LD_SEG_ADDR_TABLE");
2521 // allow build system to turn on prebinding
2523 fPrebind
= ( getenv("LD_PREBIND") != NULL
);
2526 // allow build system to force on dead-code-stripping
2527 if ( fDeadStrip
== kDeadStripOff
) {
2528 if ( getenv("LD_DEAD_STRIP") != NULL
) {
2529 switch (fOutputKind
) {
2530 case Options::kDynamicLibrary
:
2531 case Options::kDynamicExecutable
:
2532 case Options::kDynamicBundle
:
2533 fDeadStrip
= kDeadStripOn
;
2535 case Options::kObjectFile
:
2536 case Options::kDyld
:
2537 case Options::kStaticExecutable
:
2543 // allow build system to force on -warn_commons
2544 if ( getenv("LD_WARN_COMMONS") != NULL
)
2545 fWarnCommons
= true;
2548 void Options::reconfigureDefaults()
2550 // sync reader options
2551 switch ( fOutputKind
) {
2552 case Options::kObjectFile
:
2553 fReaderOptions
.fForFinalLinkedImage
= false;
2555 case Options::kDyld
:
2556 fReaderOptions
.fForDyld
= true;
2557 fReaderOptions
.fForFinalLinkedImage
= true;
2559 case Options::kDynamicLibrary
:
2560 case Options::kDynamicBundle
:
2561 fReaderOptions
.fForFinalLinkedImage
= true;
2563 case Options::kDynamicExecutable
:
2564 case Options::kStaticExecutable
:
2565 fReaderOptions
.fLinkingMainExecutable
= true;
2566 fReaderOptions
.fForFinalLinkedImage
= true;
2570 // set default min OS version
2571 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::kMinUnset
) {
2572 // if -macosx_version_min not used, try environment variable
2573 const char* envVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
2574 if ( envVers
!= NULL
)
2575 setMacOSXVersionMin(envVers
);
2576 // if -macosx_version_min and environment variable not used assume current OS version
2577 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::kMinUnset
)
2578 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_5
; // FIX FIX, this really should be a check of the OS version the linker is running on
2581 // adjust min based on architecture
2582 switch ( fArchitecture
) {
2584 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2585 //warning("-macosx_version_min should be 10.4 or later for i386");
2586 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2589 case CPU_TYPE_POWERPC64
:
2590 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2591 //warning("-macosx_version_min should be 10.4 or later for ppc64");
2592 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2595 case CPU_TYPE_X86_64
:
2596 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2597 //warning("-macosx_version_min should be 10.4 or later for x86_64");
2598 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2603 // disable implicit dylibs when targetting 10.3
2604 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
2605 if ( fReaderOptions
.fVersionMin
<= ObjectFile::ReaderOptions::k10_3
)
2606 fReaderOptions
.fImplicitlyLinkPublicDylibs
= false;
2609 // determine if info for shared region should be added
2610 if ( fOutputKind
== Options::kDynamicLibrary
) {
2611 if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
)
2612 if ( fArchitecture
!= CPU_TYPE_ARM
)
2613 fSharedRegionEligible
= true;
2616 // allow build system to force linker to ignore seg_addr_table
2617 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL
)
2618 fSegAddrTablePath
= NULL
;
2620 // check for base address specified externally
2621 if ( (fSegAddrTablePath
!= NULL
) && (fOutputKind
== Options::kDynamicLibrary
) ) {
2622 parseSegAddrTable(fSegAddrTablePath
, this->installPath());
2623 // HACK to support seg_addr_table entries that are physical paths instead of install paths
2624 if ( fBaseAddress
== 0 ) {
2625 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 )
2626 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.4.dylib");
2628 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
2629 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libz.1.2.3.dylib");
2631 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
2632 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libutil1.0.dylib");
2636 // split segs only allowed for dylibs
2638 // split seg only supported for ppc, i386, and arm.
2639 switch ( fArchitecture
) {
2640 case CPU_TYPE_POWERPC
:
2642 if ( fOutputKind
!= Options::kDynamicLibrary
)
2644 // make sure read and write segments are proper distance apart
2645 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x10000000) )
2646 fBaseWritableAddress
= fBaseAddress
+ 0x10000000;
2649 if ( fOutputKind
!= Options::kDynamicLibrary
) {
2653 // make sure read and write segments are proper distance apart
2654 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x08000000) )
2655 fBaseWritableAddress
= fBaseAddress
+ 0x08000000;
2661 fBaseWritableAddress
= 0;
2665 // disable prebinding depending on arch and min OS version
2667 switch ( fArchitecture
) {
2668 case CPU_TYPE_POWERPC
:
2670 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::k10_4
) {
2671 // in 10.4 only split seg dylibs are prebound
2672 if ( (fOutputKind
!= Options::kDynamicLibrary
) || ! fSplitSegs
)
2675 else if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
) {
2676 // in 10.5 nothing is prebound
2680 // in 10.3 and earlier only dylibs and main executables could be prebound
2681 switch ( fOutputKind
) {
2682 case Options::kDynamicExecutable
:
2683 case Options::kDynamicLibrary
:
2684 // only main executables and dylibs can be prebound
2686 case Options::kStaticExecutable
:
2687 case Options::kDynamicBundle
:
2688 case Options::kObjectFile
:
2689 case Options::kDyld
:
2690 // disable prebinding for everything else
2696 case CPU_TYPE_POWERPC64
:
2697 case CPU_TYPE_X86_64
:
2701 switch ( fOutputKind
) {
2702 case Options::kDynamicExecutable
:
2703 case Options::kDynamicLibrary
:
2704 // only main executables and dylibs can be prebound
2706 case Options::kStaticExecutable
:
2707 case Options::kDynamicBundle
:
2708 case Options::kObjectFile
:
2709 case Options::kDyld
:
2710 // disable prebinding for everything else
2718 // only prebound images can be split-seg
2719 if ( fSplitSegs
&& !fPrebind
)
2722 // figure out if module table is needed for compatibility with old ld/dyld
2723 if ( fOutputKind
== Options::kDynamicLibrary
) {
2724 switch ( fArchitecture
) {
2725 case CPU_TYPE_POWERPC
: // 10.3 and earlier dyld requires a module table
2726 case CPU_TYPE_I386
: // ld_classic for 10.4.x requires a module table
2727 if ( fReaderOptions
.fVersionMin
<= ObjectFile::ReaderOptions::k10_5
)
2728 fNeedsModuleTable
= true;
2731 fNeedsModuleTable
= true; // redo_prebinding requires a module table
2736 // <rdar://problem/5366363> -r -x implies -S
2737 if ( (fOutputKind
== Options::kObjectFile
) && (fLocalSymbolHandling
== kLocalSymbolsNone
) )
2738 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
2740 // only ARM main executables can be encrypted
2741 if ( fOutputKind
!= Options::kDynamicExecutable
)
2742 fEncryptable
= false;
2743 if ( fArchitecture
!= CPU_TYPE_ARM
)
2744 fEncryptable
= false;
2747 void Options::checkIllegalOptionCombinations()
2749 // check -undefined setting
2750 switch ( fUndefinedTreatment
) {
2751 case kUndefinedError
:
2752 case kUndefinedDynamicLookup
:
2755 case kUndefinedWarning
:
2756 case kUndefinedSuppress
:
2757 // requires flat namespace
2758 if ( fNameSpace
== kTwoLevelNameSpace
)
2759 throw "can't use -undefined warning or suppress with -twolevel_namespace";
2763 // unify -sub_umbrella with dylibs
2764 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
2765 const char* subUmbrella
= *it
;
2767 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
2768 Options::FileInfo
& info
= *fit
;
2769 const char* lastSlash
= strrchr(info
.path
, '/');
2770 if ( lastSlash
== NULL
)
2771 lastSlash
= info
.path
- 1;
2772 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
2773 info
.options
.fReExport
= true;
2779 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella
);
2782 // unify -sub_library with dylibs
2783 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
2784 const char* subLibrary
= *it
;
2786 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
2787 Options::FileInfo
& info
= *fit
;
2788 const char* lastSlash
= strrchr(info
.path
, '/');
2789 if ( lastSlash
== NULL
)
2790 lastSlash
= info
.path
- 1;
2791 const char* dot
= strchr(&lastSlash
[1], '.');
2793 dot
= &lastSlash
[strlen(lastSlash
)];
2794 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
2795 info
.options
.fReExport
= true;
2801 warning("-sub_library %s does not match a supplied dylib", subLibrary
);
2804 // sync reader options
2805 if ( fNameSpace
!= kTwoLevelNameSpace
)
2806 fReaderOptions
.fFlatNamespace
= true;
2808 // check -stack_addr
2809 if ( fStackAddr
!= 0 ) {
2810 switch (fArchitecture
) {
2812 case CPU_TYPE_POWERPC
:
2814 if ( fStackAddr
> 0xFFFFFFFF )
2815 throw "-stack_addr must be < 4G for 32-bit processes";
2817 case CPU_TYPE_POWERPC64
:
2818 case CPU_TYPE_X86_64
:
2821 if ( (fStackAddr
& -4096) != fStackAddr
)
2822 throw "-stack_addr must be multiples of 4K";
2823 if ( fStackSize
== 0 )
2824 throw "-stack_addr must be used with -stack_size";
2827 // check -stack_size
2828 if ( fStackSize
!= 0 ) {
2829 switch (fArchitecture
) {
2831 case CPU_TYPE_POWERPC
:
2832 if ( fStackSize
> 0xFFFFFFFF )
2833 throw "-stack_size must be < 4G for 32-bit processes";
2834 if ( fStackAddr
== 0 ) {
2835 fStackAddr
= 0xC0000000;
2837 if ( (fStackAddr
> 0xB0000000) && ((fStackAddr
-fStackSize
) < 0xB0000000) )
2838 warning("custom stack placement overlaps and will disable shared region");
2841 if ( fStackSize
> 0xFFFFFFFF )
2842 throw "-stack_size must be < 4G for 32-bit processes";
2843 if ( fStackAddr
== 0 )
2844 fStackAddr
= 0x30000000;
2845 if ( fStackAddr
> 0x40000000)
2846 throw "-stack_addr must be < 1G for arm";
2847 case CPU_TYPE_POWERPC64
:
2848 case CPU_TYPE_X86_64
:
2849 if ( fStackAddr
== 0 ) {
2850 fStackAddr
= 0x00007FFF5C000000LL
;
2854 if ( (fStackSize
& -4096) != fStackSize
)
2855 throw "-stack_size must be multiples of 4K";
2856 switch ( fOutputKind
) {
2857 case Options::kDynamicExecutable
:
2858 case Options::kStaticExecutable
:
2859 // custom stack size only legal when building main executable
2861 case Options::kDynamicLibrary
:
2862 case Options::kDynamicBundle
:
2863 case Options::kObjectFile
:
2864 case Options::kDyld
:
2865 throw "-stack_size option can only be used when linking a main executable";
2869 // check that -allow_stack_execute is only used with main executables
2870 if ( fExecutableStack
) {
2871 switch ( fOutputKind
) {
2872 case Options::kDynamicExecutable
:
2873 case Options::kStaticExecutable
:
2874 // -allow_stack_execute size only legal when building main executable
2876 case Options::kDynamicLibrary
:
2877 case Options::kDynamicBundle
:
2878 case Options::kObjectFile
:
2879 case Options::kDyld
:
2880 throw "-allow_stack_execute option can only be used when linking a main executable";
2884 // check -client_name is only used when making a bundle or main executable
2885 if ( fClientName
!= NULL
) {
2886 switch ( fOutputKind
) {
2887 case Options::kDynamicExecutable
:
2888 case Options::kDynamicBundle
:
2890 case Options::kStaticExecutable
:
2891 case Options::kDynamicLibrary
:
2892 case Options::kObjectFile
:
2893 case Options::kDyld
:
2894 throw "-client_name can only be used with -bundle";
2898 // check -init is only used when building a dylib
2899 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
2900 throw "-init can only be used with -dynamiclib";
2902 // check -bundle_loader only used with -bundle
2903 if ( (fBundleLoader
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
2904 throw "-bundle_loader can only be used with -bundle";
2906 // check -dtrace not used with -r
2907 if ( (fDtraceScriptName
!= NULL
) && (fOutputKind
== Options::kObjectFile
) )
2908 throw "-dtrace can only be used when creating final linked images";
2910 // check -d can only be used with -r
2911 if ( fReaderOptions
.fMakeTentativeDefinitionsReal
&& (fOutputKind
!= Options::kObjectFile
) )
2912 throw "-d can only be used with -r";
2914 // check that -root_safe is not used with -r
2915 if ( fReaderOptions
.fRootSafe
&& (fOutputKind
== Options::kObjectFile
) )
2916 throw "-root_safe cannot be used with -r";
2918 // check that -setuid_safe is not used with -r
2919 if ( fReaderOptions
.fSetuidSafe
&& (fOutputKind
== Options::kObjectFile
) )
2920 throw "-setuid_safe cannot be used with -r";
2922 // make sure all required exported symbols exist
2923 std::vector
<const char*> impliedExports
;
2924 for (NameSet::iterator it
=fExportSymbols
.regularBegin(); it
!= fExportSymbols
.regularEnd(); it
++) {
2925 const char* name
= *it
;
2926 // never export .eh symbols
2927 const int len
= strlen(name
);
2928 if ( (strcmp(&name
[len
-3], ".eh") == 0) || (strncmp(name
, ".objc_category_name_", 20) == 0) )
2929 warning("ignoring %s in export list", name
);
2931 fInitialUndefines
.push_back(name
);
2932 if ( strncmp(name
, ".objc_class_name_", 17) == 0 ) {
2933 // rdar://problem/4718189 map ObjC class names to new runtime names
2934 switch (fArchitecture
) {
2935 case CPU_TYPE_POWERPC64
:
2936 case CPU_TYPE_X86_64
:
2939 asprintf(&temp
, "_OBJC_CLASS_$_%s", &name
[17]);
2940 impliedExports
.push_back(temp
);
2941 asprintf(&temp
, "_OBJC_METACLASS_$_%s", &name
[17]);
2942 impliedExports
.push_back(temp
);
2947 for (std::vector
<const char*>::iterator it
=impliedExports
.begin(); it
!= impliedExports
.end(); it
++) {
2948 const char* name
= *it
;
2949 fExportSymbols
.insert(name
);
2950 fInitialUndefines
.push_back(name
);
2953 // make sure that -init symbol exist
2954 if ( fInitFunctionName
!= NULL
)
2955 fInitialUndefines
.push_back(fInitFunctionName
);
2957 // check custom segments
2958 if ( fCustomSegmentAddresses
.size() != 0 ) {
2959 // verify no segment is in zero page
2960 if ( fZeroPageSize
!= ULLONG_MAX
) {
2961 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
2962 if ( (it
->address
>= 0) && (it
->address
< fZeroPageSize
) )
2963 throwf("-segaddr %s 0x%X conflicts with -pagezero_size", it
->name
, it
->address
);
2966 // verify no duplicates
2967 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
2968 for (std::vector
<SegmentStart
>::iterator it2
= fCustomSegmentAddresses
.begin(); it2
!= fCustomSegmentAddresses
.end(); ++it2
) {
2969 if ( (it
->address
== it2
->address
) && (it
!= it2
) )
2970 throwf("duplicate -segaddr addresses for %s and %s", it
->name
, it2
->name
);
2972 // a custom segment address of zero will disable the use of a zero page
2973 if ( it
->address
== 0 )
2978 if ( fZeroPageSize
== ULLONG_MAX
) {
2979 // zero page size not specified on command line, set default
2980 switch (fArchitecture
) {
2982 case CPU_TYPE_POWERPC
:
2984 // first 4KB for 32-bit architectures
2985 fZeroPageSize
= 0x1000;
2987 case CPU_TYPE_POWERPC64
:
2988 // first 4GB for ppc64 on 10.5
2989 if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
)
2990 fZeroPageSize
= 0x100000000ULL
;
2992 fZeroPageSize
= 0x1000; // 10.4 dyld may not be able to handle >4GB zero page
2994 case CPU_TYPE_X86_64
:
2995 // first 4GB for x86_64 on all OS's
2996 fZeroPageSize
= 0x100000000ULL
;
2999 // if -arch not used, default to 4K zero-page
3000 fZeroPageSize
= 0x1000;
3004 switch ( fOutputKind
) {
3005 case Options::kDynamicExecutable
:
3006 case Options::kStaticExecutable
:
3007 // -pagezero_size size only legal when building main executable
3009 case Options::kDynamicLibrary
:
3010 case Options::kDynamicBundle
:
3011 case Options::kObjectFile
:
3012 case Options::kDyld
:
3013 if ( fZeroPageSize
!= 0 )
3014 throw "-pagezero_size option can only be used when linking a main executable";
3018 // -dead_strip and -r are incompatible
3019 if ( (fDeadStrip
!= kDeadStripOff
) && (fOutputKind
== Options::kObjectFile
) )
3020 throw "-r and -dead_strip cannot be used together";
3022 // can't use -rpath unless targeting 10.5 or later
3023 if ( fRPaths
.size() > 0 ) {
3024 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_5
)
3025 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
3026 switch ( fOutputKind
) {
3027 case Options::kDynamicExecutable
:
3028 case Options::kDynamicLibrary
:
3029 case Options::kDynamicBundle
:
3031 case Options::kStaticExecutable
:
3032 case Options::kObjectFile
:
3033 case Options::kDyld
:
3034 throw "-rpath can only be used when creating a dynamic final linked image";
3038 // check -pie is only used when building a dynamic main executable for 10.5
3039 if ( fPositionIndependentExecutable
) {
3040 if ( fOutputKind
!= Options::kDynamicExecutable
)
3041 throw "-pie can only be used when linking a main executable";
3042 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_5
)
3043 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
3049 void Options::checkForClassic(int argc
, const char* argv
[])
3052 bool archFound
= false;
3053 bool staticFound
= false;
3054 bool dtraceFound
= false;
3055 bool rFound
= false;
3056 bool creatingMachKernel
= false;
3057 bool newLinker
= false;
3059 for(int i
=0; i
< argc
; ++i
) {
3060 const char* arg
= argv
[i
];
3061 if ( arg
[0] == '-' ) {
3062 if ( strcmp(arg
, "-arch") == 0 ) {
3063 parseArch(argv
[++i
]);
3066 else if ( strcmp(arg
, "-static") == 0 ) {
3069 else if ( strcmp(arg
, "-dtrace") == 0 ) {
3072 else if ( strcmp(arg
, "-r") == 0 ) {
3075 else if ( strcmp(arg
, "-new_linker") == 0 ) {
3078 else if ( strcmp(arg
, "-classic_linker") == 0 ) {
3079 // ld_classic does not understand this option, so remove it
3080 for(int j
=i
; j
< argc
; ++j
)
3081 argv
[j
] = argv
[j
+1];
3082 this->gotoClassicLinker(argc
-1, argv
);
3084 else if ( strcmp(arg
, "-o") == 0 ) {
3085 const char* outfile
= argv
[++i
];
3086 if ( (outfile
!= NULL
) && (strstr(outfile
, "/mach_kernel") != NULL
) )
3087 creatingMachKernel
= true;
3092 // -dtrace only supported by new linker
3097 switch ( fArchitecture
) {
3098 case CPU_TYPE_POWERPC
:
3101 // if ( staticFound && (rFound || !creatingMachKernel) ) {
3102 if ( staticFound
&& !newLinker
) {
3103 // this environment variable will disable use of ld_classic for -static links
3104 if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL
) {
3105 // ld_classic does not support -aspen_version_min, so change
3106 for(int j
=0; j
< argc
; ++j
) {
3107 if ( (strcmp(argv
[j
], "-aspen_version_min") == 0)
3108 || (strcmp(argv
[j
], "-iphone_version_min") == 0)
3109 || (strcmp(argv
[j
], "-iphoneos_version_min") == 0) ) {
3110 argv
[j
] = "-macosx_version_min";
3116 this->gotoClassicLinker(argc
, argv
);
3123 // work around for VSPTool
3125 this->gotoClassicLinker(argc
, argv
);
3130 void Options::gotoClassicLinker(int argc
, const char* argv
[])
3132 argv
[0] = "ld_classic";
3133 execvp(argv
[0], (char**)argv
);
3134 fprintf(stderr
, "can't exec ld_classic\n");