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 // <rdar://problem/5829579> Support for configure based hacks
2396 // if last -syslibroot is /, then ignore all syslibroots
2397 if ( fSDKPaths
.size() > 0 ) {
2398 if ( strcmp(fSDKPaths
.back(), "/") == 0 ) {
2403 // now merge sdk and library paths to make real search paths
2404 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
2405 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); it
++) {
2406 const char* libDir
= *it
;
2407 bool sdkOverride
= false;
2408 if ( libDir
[0] == '/' ) {
2409 char betterLibDir
[PATH_MAX
];
2410 if ( strstr(libDir
, "/..") != NULL
) {
2411 if ( realpath(libDir
, betterLibDir
) != NULL
)
2412 libDir
= strdup(betterLibDir
);
2414 const int libDirLen
= strlen(libDir
);
2415 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2416 // ??? Should be using string here.
2417 const char* sdkDir
= *sdkit
;
2418 const int sdkDirLen
= strlen(sdkDir
);
2419 char newPath
[libDirLen
+ sdkDirLen
+4];
2420 strcpy(newPath
, sdkDir
);
2421 if ( newPath
[sdkDirLen
-1] == '/' )
2422 newPath
[sdkDirLen
-1] = '\0';
2423 strcat(newPath
, libDir
);
2424 struct stat statBuffer
;
2425 if ( stat(newPath
, &statBuffer
) == 0 ) {
2426 fLibrarySearchPaths
.push_back(strdup(newPath
));
2432 fLibrarySearchPaths
.push_back(libDir
);
2435 // now merge sdk and framework paths to make real search paths
2436 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
2437 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); it
++) {
2438 const char* frameworkDir
= *it
;
2439 bool sdkOverride
= false;
2440 if ( frameworkDir
[0] == '/' ) {
2441 char betterFrameworkDir
[PATH_MAX
];
2442 if ( strstr(frameworkDir
, "/..") != NULL
) {
2443 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
2444 frameworkDir
= strdup(betterFrameworkDir
);
2446 const int frameworkDirLen
= strlen(frameworkDir
);
2447 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
2448 // ??? Should be using string here
2449 const char* sdkDir
= *sdkit
;
2450 const int sdkDirLen
= strlen(sdkDir
);
2451 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
2452 strcpy(newPath
, sdkDir
);
2453 if ( newPath
[sdkDirLen
-1] == '/' )
2454 newPath
[sdkDirLen
-1] = '\0';
2455 strcat(newPath
, frameworkDir
);
2456 struct stat statBuffer
;
2457 if ( stat(newPath
, &statBuffer
) == 0 ) {
2458 fFrameworkSearchPaths
.push_back(strdup(newPath
));
2464 fFrameworkSearchPaths
.push_back(frameworkDir
);
2468 fprintf(stderr
,"Library search paths:\n");
2469 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
2470 it
!= fLibrarySearchPaths
.end();
2472 fprintf(stderr
,"\t%s\n", *it
);
2473 fprintf(stderr
,"Framework search paths:\n");
2474 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
2475 it
!= fFrameworkSearchPaths
.end();
2477 fprintf(stderr
,"\t%s\n", *it
);
2481 // this is run before the command line is parsed
2482 void Options::parsePreCommandLineEnvironmentSettings()
2484 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
2485 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
2486 fReaderOptions
.fTraceArchives
= true;
2488 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
2489 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
2490 fReaderOptions
.fTraceDylibs
= true;
2491 fReaderOptions
.fTraceIndirectDylibs
= true;
2494 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
2495 fTraceDylibSearching
= true;
2498 if (getenv("LD_PRINT_OPTIONS") != NULL
)
2499 fPrintOptions
= true;
2501 if (fReaderOptions
.fTraceDylibs
|| fReaderOptions
.fTraceArchives
)
2502 fReaderOptions
.fTraceOutputFile
= getenv("LD_TRACE_FILE");
2504 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL
)
2505 fPrintOrderFileStatistics
= true;
2507 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL
)
2510 if (getenv("LD_NO_ENCRYPT") != NULL
)
2511 fEncryptable
= false;
2513 sWarningsSideFilePath
= getenv("LD_WARN_FILE");
2517 // this is run after the command line is parsed
2518 void Options::parsePostCommandLineEnvironmentSettings()
2520 // when building a dynamic main executable, default any use of @executable_path to output path
2521 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
2522 fExecutablePath
= fOutputFile
;
2525 // allow build system to set default seg_addr_table
2526 if ( fSegAddrTablePath
== NULL
)
2527 fSegAddrTablePath
= getenv("LD_SEG_ADDR_TABLE");
2529 // allow build system to turn on prebinding
2531 fPrebind
= ( getenv("LD_PREBIND") != NULL
);
2534 // allow build system to force on dead-code-stripping
2535 if ( fDeadStrip
== kDeadStripOff
) {
2536 if ( getenv("LD_DEAD_STRIP") != NULL
) {
2537 switch (fOutputKind
) {
2538 case Options::kDynamicLibrary
:
2539 case Options::kDynamicExecutable
:
2540 case Options::kDynamicBundle
:
2541 fDeadStrip
= kDeadStripOn
;
2543 case Options::kObjectFile
:
2544 case Options::kDyld
:
2545 case Options::kStaticExecutable
:
2551 // allow build system to force on -warn_commons
2552 if ( getenv("LD_WARN_COMMONS") != NULL
)
2553 fWarnCommons
= true;
2556 void Options::reconfigureDefaults()
2558 // sync reader options
2559 switch ( fOutputKind
) {
2560 case Options::kObjectFile
:
2561 fReaderOptions
.fForFinalLinkedImage
= false;
2563 case Options::kDyld
:
2564 fReaderOptions
.fForDyld
= true;
2565 fReaderOptions
.fForFinalLinkedImage
= true;
2567 case Options::kDynamicLibrary
:
2568 case Options::kDynamicBundle
:
2569 fReaderOptions
.fForFinalLinkedImage
= true;
2571 case Options::kDynamicExecutable
:
2572 case Options::kStaticExecutable
:
2573 fReaderOptions
.fLinkingMainExecutable
= true;
2574 fReaderOptions
.fForFinalLinkedImage
= true;
2578 // set default min OS version
2579 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::kMinUnset
) {
2580 // if -macosx_version_min not used, try environment variable
2581 const char* envVers
= getenv("MACOSX_DEPLOYMENT_TARGET");
2582 if ( envVers
!= NULL
)
2583 setMacOSXVersionMin(envVers
);
2584 // if -macosx_version_min and environment variable not used assume current OS version
2585 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::kMinUnset
)
2586 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_5
; // FIX FIX, this really should be a check of the OS version the linker is running on
2589 // adjust min based on architecture
2590 switch ( fArchitecture
) {
2592 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2593 //warning("-macosx_version_min should be 10.4 or later for i386");
2594 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2597 case CPU_TYPE_POWERPC64
:
2598 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2599 //warning("-macosx_version_min should be 10.4 or later for ppc64");
2600 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2603 case CPU_TYPE_X86_64
:
2604 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_4
) {
2605 //warning("-macosx_version_min should be 10.4 or later for x86_64");
2606 fReaderOptions
.fVersionMin
= ObjectFile::ReaderOptions::k10_4
;
2611 // disable implicit dylibs when targetting 10.3
2612 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
2613 if ( fReaderOptions
.fVersionMin
<= ObjectFile::ReaderOptions::k10_3
)
2614 fReaderOptions
.fImplicitlyLinkPublicDylibs
= false;
2617 // determine if info for shared region should be added
2618 if ( fOutputKind
== Options::kDynamicLibrary
) {
2619 if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
)
2620 if ( fArchitecture
!= CPU_TYPE_ARM
)
2621 fSharedRegionEligible
= true;
2624 // allow build system to force linker to ignore seg_addr_table
2625 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL
)
2626 fSegAddrTablePath
= NULL
;
2628 // check for base address specified externally
2629 if ( (fSegAddrTablePath
!= NULL
) && (fOutputKind
== Options::kDynamicLibrary
) ) {
2630 parseSegAddrTable(fSegAddrTablePath
, this->installPath());
2631 // HACK to support seg_addr_table entries that are physical paths instead of install paths
2632 if ( fBaseAddress
== 0 ) {
2633 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 )
2634 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libstdc++.6.0.4.dylib");
2636 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
2637 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libz.1.2.3.dylib");
2639 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
2640 parseSegAddrTable(fSegAddrTablePath
, "/usr/lib/libutil1.0.dylib");
2644 // split segs only allowed for dylibs
2646 // split seg only supported for ppc, i386, and arm.
2647 switch ( fArchitecture
) {
2648 case CPU_TYPE_POWERPC
:
2650 if ( fOutputKind
!= Options::kDynamicLibrary
)
2652 // make sure read and write segments are proper distance apart
2653 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x10000000) )
2654 fBaseWritableAddress
= fBaseAddress
+ 0x10000000;
2657 if ( fOutputKind
!= Options::kDynamicLibrary
) {
2661 // make sure read and write segments are proper distance apart
2662 if ( fSplitSegs
&& (fBaseWritableAddress
-fBaseAddress
!= 0x08000000) )
2663 fBaseWritableAddress
= fBaseAddress
+ 0x08000000;
2669 fBaseWritableAddress
= 0;
2673 // disable prebinding depending on arch and min OS version
2675 switch ( fArchitecture
) {
2676 case CPU_TYPE_POWERPC
:
2678 if ( fReaderOptions
.fVersionMin
== ObjectFile::ReaderOptions::k10_4
) {
2679 // in 10.4 only split seg dylibs are prebound
2680 if ( (fOutputKind
!= Options::kDynamicLibrary
) || ! fSplitSegs
)
2683 else if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
) {
2684 // in 10.5 nothing is prebound
2688 // in 10.3 and earlier only dylibs and main executables could be prebound
2689 switch ( fOutputKind
) {
2690 case Options::kDynamicExecutable
:
2691 case Options::kDynamicLibrary
:
2692 // only main executables and dylibs can be prebound
2694 case Options::kStaticExecutable
:
2695 case Options::kDynamicBundle
:
2696 case Options::kObjectFile
:
2697 case Options::kDyld
:
2698 // disable prebinding for everything else
2704 case CPU_TYPE_POWERPC64
:
2705 case CPU_TYPE_X86_64
:
2709 switch ( fOutputKind
) {
2710 case Options::kDynamicExecutable
:
2711 case Options::kDynamicLibrary
:
2712 // only main executables and dylibs can be prebound
2714 case Options::kStaticExecutable
:
2715 case Options::kDynamicBundle
:
2716 case Options::kObjectFile
:
2717 case Options::kDyld
:
2718 // disable prebinding for everything else
2726 // only prebound images can be split-seg
2727 if ( fSplitSegs
&& !fPrebind
)
2730 // figure out if module table is needed for compatibility with old ld/dyld
2731 if ( fOutputKind
== Options::kDynamicLibrary
) {
2732 switch ( fArchitecture
) {
2733 case CPU_TYPE_POWERPC
: // 10.3 and earlier dyld requires a module table
2734 case CPU_TYPE_I386
: // ld_classic for 10.4.x requires a module table
2735 if ( fReaderOptions
.fVersionMin
<= ObjectFile::ReaderOptions::k10_5
)
2736 fNeedsModuleTable
= true;
2739 fNeedsModuleTable
= true; // redo_prebinding requires a module table
2744 // <rdar://problem/5366363> -r -x implies -S
2745 if ( (fOutputKind
== Options::kObjectFile
) && (fLocalSymbolHandling
== kLocalSymbolsNone
) )
2746 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
2748 // only ARM main executables can be encrypted
2749 if ( fOutputKind
!= Options::kDynamicExecutable
)
2750 fEncryptable
= false;
2751 if ( fArchitecture
!= CPU_TYPE_ARM
)
2752 fEncryptable
= false;
2755 void Options::checkIllegalOptionCombinations()
2757 // check -undefined setting
2758 switch ( fUndefinedTreatment
) {
2759 case kUndefinedError
:
2760 case kUndefinedDynamicLookup
:
2763 case kUndefinedWarning
:
2764 case kUndefinedSuppress
:
2765 // requires flat namespace
2766 if ( fNameSpace
== kTwoLevelNameSpace
)
2767 throw "can't use -undefined warning or suppress with -twolevel_namespace";
2771 // unify -sub_umbrella with dylibs
2772 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
2773 const char* subUmbrella
= *it
;
2775 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
2776 Options::FileInfo
& info
= *fit
;
2777 const char* lastSlash
= strrchr(info
.path
, '/');
2778 if ( lastSlash
== NULL
)
2779 lastSlash
= info
.path
- 1;
2780 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
2781 info
.options
.fReExport
= true;
2787 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella
);
2790 // unify -sub_library with dylibs
2791 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
2792 const char* subLibrary
= *it
;
2794 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
2795 Options::FileInfo
& info
= *fit
;
2796 const char* lastSlash
= strrchr(info
.path
, '/');
2797 if ( lastSlash
== NULL
)
2798 lastSlash
= info
.path
- 1;
2799 const char* dot
= strchr(&lastSlash
[1], '.');
2801 dot
= &lastSlash
[strlen(lastSlash
)];
2802 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
2803 info
.options
.fReExport
= true;
2809 warning("-sub_library %s does not match a supplied dylib", subLibrary
);
2812 // sync reader options
2813 if ( fNameSpace
!= kTwoLevelNameSpace
)
2814 fReaderOptions
.fFlatNamespace
= true;
2816 // check -stack_addr
2817 if ( fStackAddr
!= 0 ) {
2818 switch (fArchitecture
) {
2820 case CPU_TYPE_POWERPC
:
2822 if ( fStackAddr
> 0xFFFFFFFF )
2823 throw "-stack_addr must be < 4G for 32-bit processes";
2825 case CPU_TYPE_POWERPC64
:
2826 case CPU_TYPE_X86_64
:
2829 if ( (fStackAddr
& -4096) != fStackAddr
)
2830 throw "-stack_addr must be multiples of 4K";
2831 if ( fStackSize
== 0 )
2832 throw "-stack_addr must be used with -stack_size";
2835 // check -stack_size
2836 if ( fStackSize
!= 0 ) {
2837 switch (fArchitecture
) {
2839 case CPU_TYPE_POWERPC
:
2840 if ( fStackSize
> 0xFFFFFFFF )
2841 throw "-stack_size must be < 4G for 32-bit processes";
2842 if ( fStackAddr
== 0 ) {
2843 fStackAddr
= 0xC0000000;
2845 if ( (fStackAddr
> 0xB0000000) && ((fStackAddr
-fStackSize
) < 0xB0000000) )
2846 warning("custom stack placement overlaps and will disable shared region");
2849 if ( fStackSize
> 0xFFFFFFFF )
2850 throw "-stack_size must be < 4G for 32-bit processes";
2851 if ( fStackAddr
== 0 )
2852 fStackAddr
= 0x30000000;
2853 if ( fStackAddr
> 0x40000000)
2854 throw "-stack_addr must be < 1G for arm";
2855 case CPU_TYPE_POWERPC64
:
2856 case CPU_TYPE_X86_64
:
2857 if ( fStackAddr
== 0 ) {
2858 fStackAddr
= 0x00007FFF5C000000LL
;
2862 if ( (fStackSize
& -4096) != fStackSize
)
2863 throw "-stack_size must be multiples of 4K";
2864 switch ( fOutputKind
) {
2865 case Options::kDynamicExecutable
:
2866 case Options::kStaticExecutable
:
2867 // custom stack size only legal when building main executable
2869 case Options::kDynamicLibrary
:
2870 case Options::kDynamicBundle
:
2871 case Options::kObjectFile
:
2872 case Options::kDyld
:
2873 throw "-stack_size option can only be used when linking a main executable";
2877 // check that -allow_stack_execute is only used with main executables
2878 if ( fExecutableStack
) {
2879 switch ( fOutputKind
) {
2880 case Options::kDynamicExecutable
:
2881 case Options::kStaticExecutable
:
2882 // -allow_stack_execute size only legal when building main executable
2884 case Options::kDynamicLibrary
:
2885 case Options::kDynamicBundle
:
2886 case Options::kObjectFile
:
2887 case Options::kDyld
:
2888 throw "-allow_stack_execute option can only be used when linking a main executable";
2892 // check -client_name is only used when making a bundle or main executable
2893 if ( fClientName
!= NULL
) {
2894 switch ( fOutputKind
) {
2895 case Options::kDynamicExecutable
:
2896 case Options::kDynamicBundle
:
2898 case Options::kStaticExecutable
:
2899 case Options::kDynamicLibrary
:
2900 case Options::kObjectFile
:
2901 case Options::kDyld
:
2902 throw "-client_name can only be used with -bundle";
2906 // check -init is only used when building a dylib
2907 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
2908 throw "-init can only be used with -dynamiclib";
2910 // check -bundle_loader only used with -bundle
2911 if ( (fBundleLoader
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
2912 throw "-bundle_loader can only be used with -bundle";
2914 // check -dtrace not used with -r
2915 if ( (fDtraceScriptName
!= NULL
) && (fOutputKind
== Options::kObjectFile
) )
2916 throw "-dtrace can only be used when creating final linked images";
2918 // check -d can only be used with -r
2919 if ( fReaderOptions
.fMakeTentativeDefinitionsReal
&& (fOutputKind
!= Options::kObjectFile
) )
2920 throw "-d can only be used with -r";
2922 // check that -root_safe is not used with -r
2923 if ( fReaderOptions
.fRootSafe
&& (fOutputKind
== Options::kObjectFile
) )
2924 throw "-root_safe cannot be used with -r";
2926 // check that -setuid_safe is not used with -r
2927 if ( fReaderOptions
.fSetuidSafe
&& (fOutputKind
== Options::kObjectFile
) )
2928 throw "-setuid_safe cannot be used with -r";
2930 // make sure all required exported symbols exist
2931 std::vector
<const char*> impliedExports
;
2932 for (NameSet::iterator it
=fExportSymbols
.regularBegin(); it
!= fExportSymbols
.regularEnd(); it
++) {
2933 const char* name
= *it
;
2934 // never export .eh symbols
2935 const int len
= strlen(name
);
2936 if ( (strcmp(&name
[len
-3], ".eh") == 0) || (strncmp(name
, ".objc_category_name_", 20) == 0) )
2937 warning("ignoring %s in export list", name
);
2939 fInitialUndefines
.push_back(name
);
2940 if ( strncmp(name
, ".objc_class_name_", 17) == 0 ) {
2941 // rdar://problem/4718189 map ObjC class names to new runtime names
2942 switch (fArchitecture
) {
2943 case CPU_TYPE_POWERPC64
:
2944 case CPU_TYPE_X86_64
:
2947 asprintf(&temp
, "_OBJC_CLASS_$_%s", &name
[17]);
2948 impliedExports
.push_back(temp
);
2949 asprintf(&temp
, "_OBJC_METACLASS_$_%s", &name
[17]);
2950 impliedExports
.push_back(temp
);
2955 for (std::vector
<const char*>::iterator it
=impliedExports
.begin(); it
!= impliedExports
.end(); it
++) {
2956 const char* name
= *it
;
2957 fExportSymbols
.insert(name
);
2958 fInitialUndefines
.push_back(name
);
2961 // make sure that -init symbol exist
2962 if ( fInitFunctionName
!= NULL
)
2963 fInitialUndefines
.push_back(fInitFunctionName
);
2965 // check custom segments
2966 if ( fCustomSegmentAddresses
.size() != 0 ) {
2967 // verify no segment is in zero page
2968 if ( fZeroPageSize
!= ULLONG_MAX
) {
2969 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
2970 if ( (it
->address
>= 0) && (it
->address
< fZeroPageSize
) )
2971 throwf("-segaddr %s 0x%X conflicts with -pagezero_size", it
->name
, it
->address
);
2974 // verify no duplicates
2975 for (std::vector
<SegmentStart
>::iterator it
= fCustomSegmentAddresses
.begin(); it
!= fCustomSegmentAddresses
.end(); ++it
) {
2976 for (std::vector
<SegmentStart
>::iterator it2
= fCustomSegmentAddresses
.begin(); it2
!= fCustomSegmentAddresses
.end(); ++it2
) {
2977 if ( (it
->address
== it2
->address
) && (it
!= it2
) )
2978 throwf("duplicate -segaddr addresses for %s and %s", it
->name
, it2
->name
);
2980 // a custom segment address of zero will disable the use of a zero page
2981 if ( it
->address
== 0 )
2986 if ( fZeroPageSize
== ULLONG_MAX
) {
2987 // zero page size not specified on command line, set default
2988 switch (fArchitecture
) {
2990 case CPU_TYPE_POWERPC
:
2992 // first 4KB for 32-bit architectures
2993 fZeroPageSize
= 0x1000;
2995 case CPU_TYPE_POWERPC64
:
2996 // first 4GB for ppc64 on 10.5
2997 if ( fReaderOptions
.fVersionMin
>= ObjectFile::ReaderOptions::k10_5
)
2998 fZeroPageSize
= 0x100000000ULL
;
3000 fZeroPageSize
= 0x1000; // 10.4 dyld may not be able to handle >4GB zero page
3002 case CPU_TYPE_X86_64
:
3003 // first 4GB for x86_64 on all OS's
3004 fZeroPageSize
= 0x100000000ULL
;
3007 // if -arch not used, default to 4K zero-page
3008 fZeroPageSize
= 0x1000;
3012 switch ( fOutputKind
) {
3013 case Options::kDynamicExecutable
:
3014 case Options::kStaticExecutable
:
3015 // -pagezero_size size only legal when building main executable
3017 case Options::kDynamicLibrary
:
3018 case Options::kDynamicBundle
:
3019 case Options::kObjectFile
:
3020 case Options::kDyld
:
3021 if ( fZeroPageSize
!= 0 )
3022 throw "-pagezero_size option can only be used when linking a main executable";
3026 // -dead_strip and -r are incompatible
3027 if ( (fDeadStrip
!= kDeadStripOff
) && (fOutputKind
== Options::kObjectFile
) )
3028 throw "-r and -dead_strip cannot be used together";
3030 // can't use -rpath unless targeting 10.5 or later
3031 if ( fRPaths
.size() > 0 ) {
3032 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_5
)
3033 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
3034 switch ( fOutputKind
) {
3035 case Options::kDynamicExecutable
:
3036 case Options::kDynamicLibrary
:
3037 case Options::kDynamicBundle
:
3039 case Options::kStaticExecutable
:
3040 case Options::kObjectFile
:
3041 case Options::kDyld
:
3042 throw "-rpath can only be used when creating a dynamic final linked image";
3046 // check -pie is only used when building a dynamic main executable for 10.5
3047 if ( fPositionIndependentExecutable
) {
3048 if ( fOutputKind
!= Options::kDynamicExecutable
)
3049 throw "-pie can only be used when linking a main executable";
3050 if ( fReaderOptions
.fVersionMin
< ObjectFile::ReaderOptions::k10_5
)
3051 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
3057 void Options::checkForClassic(int argc
, const char* argv
[])
3060 bool archFound
= false;
3061 bool staticFound
= false;
3062 bool dtraceFound
= false;
3063 bool rFound
= false;
3064 bool creatingMachKernel
= false;
3065 bool newLinker
= false;
3067 for(int i
=0; i
< argc
; ++i
) {
3068 const char* arg
= argv
[i
];
3069 if ( arg
[0] == '-' ) {
3070 if ( strcmp(arg
, "-arch") == 0 ) {
3071 parseArch(argv
[++i
]);
3074 else if ( strcmp(arg
, "-static") == 0 ) {
3077 else if ( strcmp(arg
, "-dtrace") == 0 ) {
3080 else if ( strcmp(arg
, "-r") == 0 ) {
3083 else if ( strcmp(arg
, "-new_linker") == 0 ) {
3086 else if ( strcmp(arg
, "-classic_linker") == 0 ) {
3087 // ld_classic does not understand this option, so remove it
3088 for(int j
=i
; j
< argc
; ++j
)
3089 argv
[j
] = argv
[j
+1];
3090 this->gotoClassicLinker(argc
-1, argv
);
3092 else if ( strcmp(arg
, "-o") == 0 ) {
3093 const char* outfile
= argv
[++i
];
3094 if ( (outfile
!= NULL
) && (strstr(outfile
, "/mach_kernel") != NULL
) )
3095 creatingMachKernel
= true;
3100 // -dtrace only supported by new linker
3105 switch ( fArchitecture
) {
3106 case CPU_TYPE_POWERPC
:
3109 // if ( staticFound && (rFound || !creatingMachKernel) ) {
3110 if ( staticFound
&& !newLinker
) {
3111 // this environment variable will disable use of ld_classic for -static links
3112 if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL
) {
3113 // ld_classic does not support -aspen_version_min, so change
3114 for(int j
=0; j
< argc
; ++j
) {
3115 if ( (strcmp(argv
[j
], "-aspen_version_min") == 0)
3116 || (strcmp(argv
[j
], "-iphone_version_min") == 0)
3117 || (strcmp(argv
[j
], "-iphoneos_version_min") == 0) ) {
3118 argv
[j
] = "-macosx_version_min";
3124 this->gotoClassicLinker(argc
, argv
);
3131 // work around for VSPTool
3133 this->gotoClassicLinker(argc
, argv
);
3138 void Options::gotoClassicLinker(int argc
, const char* argv
[])
3140 argv
[0] = "ld_classic";
3141 execvp(argv
[0], (char**)argv
);
3142 fprintf(stderr
, "can't exec ld_classic\n");