1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2005 Apple Computer, 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>
35 void throwf(const char* format
, ...)
39 va_start(list
, format
);
40 vasprintf(&p
, format
, list
);
47 Options::Options(int argc
, const char* argv
[])
48 : fOutputFile("a.out"), fArchitecture(0), fOutputKind(kDynamicExecutable
), fBindAtLoad(false),
49 fStripLocalSymbols(false), fKeepPrivateExterns(false),
50 fInterposable(false), fIgnoreOtherArchFiles(false), fForceSubtypeAll(false), fDeadStrip(kDeadStripOff
),
51 fVersionMin(k10_1
),fNameSpace(kTwoLevelNameSpace
),
52 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL
), fEntryName("start"), fBaseAddress(0),
53 fExportMode(kExportDefault
), fLibrarySearchMode(kSearchAllDirsForDylibsThenAllDirsForArchives
),
54 fUndefinedTreatment(kUndefinedError
), fMessagesPrefixedWithArchitecture(false), fPICTreatment(kError
),
55 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchError
), fMultiplyDefinedDynamic(kWarning
),
56 fMultiplyDefinedUnused(kSuppress
), fWarnOnMultiplyDefined(false), fClientName(NULL
),
57 fUmbrellaName(NULL
), fInitFunctionName(NULL
), fDotOutputFile(NULL
), fExecutablePath(NULL
),
58 fZeroPageSize(0x1000), fStackSize(0), fStackAddr(0), fExecutableStack(false), fMinimumHeaderPad(0),
59 fCommonsMode(kCommonsIgnoreDylibs
), fWarnCommons(false), fVerbose(false), fKeepRelocations(false),
60 fEmitUUID(true),fWarnStabs(false),
61 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false)
63 this->parsePreCommandLineEnvironmentSettings();
64 this->parse(argc
, argv
);
65 this->parsePostCommandLineEnvironmentSettings();
66 this->checkIllegalOptionCombinations();
73 const ObjectFile::ReaderOptions
& Options::readerOptions()
75 return fReaderOptions
;
78 cpu_type_t
Options::architecture()
83 const char* Options::getOutputFilePath()
88 std::vector
<Options::FileInfo
>& Options::getInputFiles()
93 Options::OutputKind
Options::outputKind()
98 bool Options::stripLocalSymbols()
100 return fStripLocalSymbols
;
103 bool Options::bindAtLoad()
108 bool Options::prebind()
113 bool Options::fullyLoadArchives()
115 return fReaderOptions
.fFullyLoadArchives
;
118 Options::NameSpace
Options::nameSpace()
123 const char* Options::installPath()
125 if ( fDylibInstallName
!= NULL
)
126 return fDylibInstallName
;
131 uint32_t Options::currentVersion()
133 return fDylibCurrentVersion
;
136 uint32_t Options::compatibilityVersion()
138 return fDylibCompatVersion
;
141 const char* Options::entryName()
146 uint64_t Options::baseAddress()
151 bool Options::keepPrivateExterns()
153 return fKeepPrivateExterns
;
156 bool Options::interposable()
158 return fInterposable
;
161 bool Options::ignoreOtherArchInputFiles()
163 return fIgnoreOtherArchFiles
;
166 bool Options::forceCpuSubtypeAll()
168 return fForceSubtypeAll
;
171 bool Options::traceDylibs()
173 return fReaderOptions
.fTraceDylibs
;
176 bool Options::traceArchives()
178 return fReaderOptions
.fTraceArchives
;
181 Options::UndefinedTreatment
Options::undefinedTreatment()
183 return fUndefinedTreatment
;
186 Options::VersionMin
Options::macosxVersionMin()
191 Options::WeakReferenceMismatchTreatment
Options::weakReferenceMismatchTreatment()
193 return fWeakReferenceMismatchTreatment
;
196 Options::Treatment
Options::multipleDefinitionsInDylibs()
198 return fMultiplyDefinedDynamic
;
201 Options::Treatment
Options::overridingDefinitionInDependentDylib()
203 return fMultiplyDefinedUnused
;
206 bool Options::warnOnMultipleDefinitionsInObjectFiles()
208 return fWarnOnMultiplyDefined
;
211 const char* Options::umbrellaName()
213 return fUmbrellaName
;
216 std::vector
<const char*>& Options::allowableClients()
218 return fAllowableClients
;
221 const char* Options::clientName()
226 uint64_t Options::zeroPageSize()
228 return fZeroPageSize
;
231 bool Options::hasCustomStack()
233 return (fStackSize
!= 0);
236 uint64_t Options::customStackSize()
241 uint64_t Options::customStackAddr()
246 bool Options::hasExecutableStack()
248 return fExecutableStack
;
251 std::vector
<const char*>& Options::initialUndefines()
253 return fInitialUndefines
;
256 std::vector
<const char*>& Options::traceSymbols()
258 return fTraceSymbols
;
261 const char* Options::initFunctionName()
263 return fInitFunctionName
;
266 const char* Options::dotOutputFile()
268 return fDotOutputFile
;
271 bool Options::hasExportRestrictList()
273 return (fExportMode
!= kExportDefault
);
276 uint32_t Options::minimumHeaderPad()
278 return fMinimumHeaderPad
;
281 std::vector
<Options::ExtraSection
>& Options::extraSections()
283 return fExtraSections
;
286 std::vector
<Options::SectionAlignment
>& Options::sectionAlignments()
288 return fSectionAlignments
;
291 Options::CommonsMode
Options::commonsMode()
296 bool Options::warnCommons()
301 bool Options::keepRelocations()
303 return fKeepRelocations
;
306 bool Options::emitUUID()
311 bool Options::warnStabs()
316 const char* Options::executablePath()
318 return fExecutablePath
;
321 Options::DeadStripMode
Options::deadStrip()
326 bool Options::shouldExport(const char* symbolName
)
328 switch (fExportMode
) {
330 return ( fExportSymbols
.find(symbolName
) != fExportSymbols
.end() );
331 case kDontExportSome
:
332 return ( fDontExportSymbols
.find(symbolName
) == fDontExportSymbols
.end() );
336 throw "internal error";
339 void Options::parseArch(const char* architecture
)
341 if ( architecture
== NULL
)
342 throw "-arch must be followed by an architecture string";
343 if ( strcmp(architecture
, "ppc") == 0 )
344 fArchitecture
= CPU_TYPE_POWERPC
;
345 else if ( strcmp(architecture
, "ppc64") == 0 )
346 fArchitecture
= CPU_TYPE_POWERPC64
;
347 else if ( strcmp(architecture
, "i386") == 0 )
348 fArchitecture
= CPU_TYPE_I386
;
350 throw "-arch followed by unknown architecture name";
353 bool Options::checkForFile(const char* format
, const char* dir
, const char* rootName
, FileInfo
& result
)
355 struct stat statBuffer
;
356 char possiblePath
[strlen(dir
)+strlen(rootName
)+strlen(format
)+8];
357 sprintf(possiblePath
, format
, dir
, rootName
);
358 bool found
= (stat(possiblePath
, &statBuffer
) == 0);
359 if ( fTraceDylibSearching
)
360 printf("[Logging for XBS]%sfound library: '%s'\n", (found
? " " : " not "), possiblePath
);
362 result
.path
= strdup(possiblePath
);
363 result
.fileLen
= statBuffer
.st_size
;
364 result
.modTime
= statBuffer
.st_mtime
;
371 Options::FileInfo
Options::findLibrary(const char* rootName
)
374 const int rootNameLen
= strlen(rootName
);
375 // if rootName ends in .o there is no .a vs .dylib choice
376 if ( (rootNameLen
> 3) && (strcmp(&rootName
[rootNameLen
-2], ".o") == 0) ) {
377 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
378 it
!= fLibrarySearchPaths
.end();
380 const char* dir
= *it
;
381 if ( checkForFile("%s/%s", dir
, rootName
, result
) )
386 bool lookForDylibs
= ( fOutputKind
!= Options::kDyld
);
387 switch ( fLibrarySearchMode
) {
388 case kSearchAllDirsForDylibsThenAllDirsForArchives
:
389 // first look in all directories for just for dylibs
390 if ( lookForDylibs
) {
391 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
392 it
!= fLibrarySearchPaths
.end();
394 const char* dir
= *it
;
395 if ( checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
399 // next look in all directories for just for archives
400 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
401 it
!= fLibrarySearchPaths
.end();
403 const char* dir
= *it
;
404 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
409 case kSearchDylibAndArchiveInEachDir
:
410 // look in each directory for just for a dylib then for an archive
411 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
412 it
!= fLibrarySearchPaths
.end();
414 const char* dir
= *it
;
415 if ( lookForDylibs
&& checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
417 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
423 throwf("library not found for -l%s", rootName
);
427 Options::FileInfo
Options::findFramework(const char* rootName
)
429 struct stat statBuffer
;
430 const int rootNameLen
= strlen(rootName
);
431 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
432 it
!= fFrameworkSearchPaths
.end();
434 // ??? Shouldn't we be using String here and just initializing it?
435 // ??? Use str.c_str () to pull out the string for the stat call.
436 const char* dir
= *it
;
437 char possiblePath
[strlen(dir
)+2*rootNameLen
+20];
438 strcpy(possiblePath
, dir
);
439 strcat(possiblePath
, "/");
440 strcat(possiblePath
, rootName
);
441 strcat(possiblePath
, ".framework/");
442 strcat(possiblePath
, rootName
);
443 bool found
= (stat(possiblePath
, &statBuffer
) == 0);
444 if ( fTraceDylibSearching
)
445 printf("[Logging for XBS]%sfound framework: '%s'\n",
446 (found
? " " : " not "), possiblePath
);
449 result
.path
= strdup(possiblePath
);
450 result
.fileLen
= statBuffer
.st_size
;
451 result
.modTime
= statBuffer
.st_mtime
;
455 throwf("framework not found %s", rootName
);
458 Options::FileInfo
Options::findFile(const char* path
)
461 struct stat statBuffer
;
463 // if absolute path and not a .o file, the use SDK prefix
464 if ( (path
[0] == '/') && (strcmp(&path
[strlen(path
)-2], ".o") != 0) ) {
465 const int pathLen
= strlen(path
);
466 for (std::vector
<const char*>::iterator it
= fSDKPaths
.begin(); it
!= fSDKPaths
.end(); it
++) {
467 // ??? Shouldn't we be using String here?
468 const char* sdkPathDir
= *it
;
469 const int sdkPathDirLen
= strlen(sdkPathDir
);
470 char possiblePath
[sdkPathDirLen
+pathLen
+4];
471 strcpy(possiblePath
, sdkPathDir
);
472 if ( possiblePath
[sdkPathDirLen
-1] == '/' )
473 possiblePath
[sdkPathDirLen
-1] = '\0';
474 strcat(possiblePath
, path
);
475 if ( stat(possiblePath
, &statBuffer
) == 0 ) {
476 result
.path
= strdup(possiblePath
);
477 result
.fileLen
= statBuffer
.st_size
;
478 result
.modTime
= statBuffer
.st_mtime
;
484 if ( stat(path
, &statBuffer
) == 0 ) {
485 result
.path
= strdup(path
);
486 result
.fileLen
= statBuffer
.st_size
;
487 result
.modTime
= statBuffer
.st_mtime
;
491 // try @executable_path substitution
492 if ( (strncmp(path
, "@executable_path/", 17) == 0) && (fExecutablePath
!= NULL
) ) {
493 char newPath
[strlen(fExecutablePath
) + strlen(path
)];
494 strcpy(newPath
, fExecutablePath
);
495 char* addPoint
= strrchr(newPath
,'/');
496 if ( addPoint
!= NULL
)
497 strcpy(&addPoint
[1], &path
[17]);
499 strcpy(newPath
, &path
[17]);
500 if ( stat(newPath
, &statBuffer
) == 0 ) {
501 result
.path
= strdup(newPath
);
502 result
.fileLen
= statBuffer
.st_size
;
503 result
.modTime
= statBuffer
.st_mtime
;
509 throwf("file not found: %s", path
);
513 void Options::loadFileList(const char* fileOfPaths
)
515 FILE* file
= fopen(fileOfPaths
, "r");
517 throwf("-filelist file not found: %s\n", fileOfPaths
);
520 while ( fgets(path
, 1024, file
) != NULL
) {
522 char* eol
= strchr(path
, '\n');
526 fInputFiles
.push_back(findFile(path
));
532 void Options::loadExportFile(const char* fileOfExports
, const char* option
, NameSet
& set
)
534 // read in whole file
535 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
537 throwf("can't open %s file: %s", option
, fileOfExports
);
538 struct stat stat_buf
;
539 ::fstat(fd
, &stat_buf
);
540 char* p
= (char*)malloc(stat_buf
.st_size
);
542 throwf("can't process %s file: %s", option
, fileOfExports
);
544 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
545 throwf("can't read %s file: %s", option
, fileOfExports
);
549 // parse into symbols and add to hash_set
550 char * const end
= &p
[stat_buf
.st_size
];
551 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
552 char* symbolStart
= NULL
;
553 for (char* s
= p
; s
< end
; ++s
) {
559 else if ( !isspace(*s
) ) {
567 // removing any trailing spaces
569 while ( isspace(*last
) ) {
573 set
.insert(symbolStart
);
584 if ( state
== inSymbol
) {
585 fprintf(stderr
, "ld64 warning: missing line-end at end of file \"%s\"\n", fileOfExports
);
586 int len
= end
-symbolStart
+1;
587 char* temp
= new char[len
];
588 strlcpy(temp
, symbolStart
, len
);
590 // remove any trailing spaces
591 char* last
= &temp
[len
-2];
592 while ( isspace(*last
) ) {
599 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
602 void Options::setUndefinedTreatment(const char* treatment
)
604 if ( treatment
== NULL
)
605 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
607 if ( strcmp(treatment
, "warning") == 0 )
608 fUndefinedTreatment
= kUndefinedWarning
;
609 else if ( strcmp(treatment
, "error") == 0 )
610 fUndefinedTreatment
= kUndefinedError
;
611 else if ( strcmp(treatment
, "suppress") == 0 )
612 fUndefinedTreatment
= kUndefinedSuppress
;
613 else if ( strcmp(treatment
, "dynamic_lookup") == 0 )
614 fUndefinedTreatment
= kUndefinedDynamicLookup
;
616 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
619 Options::Treatment
Options::parseTreatment(const char* treatment
)
621 if ( treatment
== NULL
)
624 if ( strcmp(treatment
, "warning") == 0 )
626 else if ( strcmp(treatment
, "error") == 0 )
628 else if ( strcmp(treatment
, "suppress") == 0 )
634 void Options::setVersionMin(const char* version
)
636 if ( version
== NULL
)
637 throw "-macosx_version_min argument missing";
639 if ( strcmp(version
, "10.1") == 0 )
641 else if ( strcmp(version
, "10.2") == 0)
643 else if ( strcmp(version
, "10.3") == 0)
645 else if ( strcmp(version
, "10.4") == 0)
647 else if ( strcmp(version
, "10.5") == 0)
650 fprintf(stderr
, "ld64: unknown option to -macosx_version_min");
653 void Options::setWeakReferenceMismatchTreatment(const char* treatment
)
655 if ( treatment
== NULL
)
656 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
658 if ( strcmp(treatment
, "error") == 0 )
659 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchError
;
660 else if ( strcmp(treatment
, "weak") == 0 )
661 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchWeak
;
662 else if ( strcmp(treatment
, "non-weak") == 0 )
663 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchNonWeak
;
665 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
668 Options::CommonsMode
Options::parseCommonsTreatment(const char* mode
)
671 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
673 if ( strcmp(mode
, "ignore_dylibs") == 0 )
674 return kCommonsIgnoreDylibs
;
675 else if ( strcmp(mode
, "use_dylibs") == 0 )
676 return kCommonsOverriddenByDylibs
;
677 else if ( strcmp(mode
, "error") == 0 )
678 return kCommonsConflictsDylibsError
;
680 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
683 void Options::setDylibInstallNameOverride(const char* paths
)
689 uint64_t Options::parseAddress(const char* addr
)
692 uint64_t result
= strtoull(addr
, &endptr
, 16);
697 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
700 uint32_t Options::parseVersionNumber(const char* versionString
)
706 x
= strtoul(versionString
, &end
, 10);
708 y
= strtoul(&end
[1], &end
, 10);
710 z
= strtoul(&end
[1], &end
, 10);
713 if ( (*end
!= '\0') || (x
> 0xffff) || (y
> 0xff) || (z
> 0xff) )
714 throwf("malformed version number: %s", versionString
);
716 return (x
<< 16) | ( y
<< 8 ) | z
;
719 void Options::parseSectionOrderFile(const char* segment
, const char* section
, const char* path
)
721 fprintf(stderr
, "ld64: warning -sectorder not yet supported for 64-bit code\n");
724 void Options::addSection(const char* segment
, const char* section
, const char* path
)
726 if ( strlen(segment
) > 16 )
727 throw "-seccreate segment name max 16 chars";
728 if ( strlen(section
) > 16 ) {
729 char* tmp
= strdup(section
);
731 fprintf(stderr
, "ld64 warning: -seccreate section name (%s) truncated to 16 chars (%s)\n", section
, tmp
);
735 // read in whole file
736 int fd
= ::open(path
, O_RDONLY
, 0);
738 throwf("can't open -sectcreate file: %s", path
);
739 struct stat stat_buf
;
740 ::fstat(fd
, &stat_buf
);
741 char* p
= (char*)malloc(stat_buf
.st_size
);
743 throwf("can't process -sectcreate file: %s", path
);
744 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
745 throwf("can't read -sectcreate file: %s", path
);
748 // record section to create
749 ExtraSection info
= { segment
, section
, path
, (uint8_t*)p
, stat_buf
.st_size
};
750 fExtraSections
.push_back(info
);
753 void Options::addSectionAlignment(const char* segment
, const char* section
, const char* alignmentStr
)
755 if ( strlen(segment
) > 16 )
756 throw "-sectalign segment name max 16 chars";
757 if ( strlen(section
) > 16 )
758 throw "-sectalign section name max 16 chars";
760 // argument to -sectalign is a hexadecimal number
762 unsigned long value
= strtoul(alignmentStr
, &endptr
, 16);
763 if ( *endptr
!= '\0')
764 throw "argument for -sectalign is not a hexadecimal number";
765 if ( value
> 0x8000 )
766 throw "argument for -sectalign must be less than or equal to 0x8000";
768 fprintf(stderr
, "ld64 warning: zero is not a valid -sectalign\n");
772 // alignment is power of 2 (e.g. page alignment = 12)
773 uint8_t alignment
= (uint8_t)log2(value
);
775 if ( (unsigned long)(1 << alignment
) != value
) {
776 fprintf(stderr
, "ld64 warning: alignment for -sectalign %s %s is not a power of two, using 0x%X\n",
777 segment
, section
, 1 << alignment
);
780 SectionAlignment info
= { segment
, section
, alignment
};
781 fSectionAlignments
.push_back(info
);
785 // Process all command line arguments.
787 // The only error checking done here is that each option is valid and if it has arguments
788 // that they too are valid.
790 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
791 // whichever was last on the command line is used.
793 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
795 void Options::parse(int argc
, const char* argv
[])
797 // pass one builds search list from -L and -F options
798 this->buildSearchPaths(argc
, argv
);
800 // reduce re-allocations
801 fInputFiles
.reserve(32);
803 // pass two parse all other options
804 for(int i
=1; i
< argc
; ++i
) {
805 const char* arg
= argv
[i
];
807 if ( arg
[0] == '-' ) {
809 // Since we don't care about the files passed, just the option names, we do this here.
811 fprintf (stderr
, "[Logging ld64 options]\t%s\n", arg
);
813 if ( (arg
[1] == 'L') || (arg
[1] == 'F') ) {
814 // previously handled by buildSearchPaths()
816 else if ( strcmp(arg
, "-arch") == 0 ) {
817 parseArch(argv
[++i
]);
819 else if ( strcmp(arg
, "-dynamic") == 0 ) {
822 else if ( strcmp(arg
, "-static") == 0 ) {
823 fOutputKind
= kStaticExecutable
;
825 else if ( strcmp(arg
, "-dylib") == 0 ) {
826 fOutputKind
= kDynamicLibrary
;
828 else if ( strcmp(arg
, "-bundle") == 0 ) {
829 fOutputKind
= kDynamicBundle
;
831 else if ( strcmp(arg
, "-dylinker") == 0 ) {
834 else if ( strcmp(arg
, "-execute") == 0 ) {
835 if ( fOutputKind
!= kStaticExecutable
)
836 fOutputKind
= kDynamicExecutable
;
838 else if ( strcmp(arg
, "-r") == 0 ) {
839 fOutputKind
= kObjectFile
;
841 else if ( strcmp(arg
, "-o") == 0 ) {
842 fOutputFile
= argv
[++i
];
844 else if ( arg
[1] == 'l' ) {
845 fInputFiles
.push_back(findLibrary(&arg
[2]));
847 // This causes a dylib to be weakly bound at
848 // link time. This corresponds to weak_import.
849 else if ( strncmp(arg
, "-weak-l", 7) == 0 ) {
850 FileInfo info
= findLibrary(&arg
[7]);
851 info
.options
.fWeakImport
= true;
852 fInputFiles
.push_back(info
);
854 // Avoid lazy binding.
856 else if ( strcmp(arg
, "-bind_at_load") == 0 ) {
859 else if ( strcmp(arg
, "-twolevel_namespace") == 0 ) {
860 fNameSpace
= kTwoLevelNameSpace
;
862 else if ( strcmp(arg
, "-flat_namespace") == 0 ) {
863 fNameSpace
= kFlatNameSpace
;
865 // Also sets a bit to ensure dyld causes everything
866 // in the namespace to be flat.
868 else if ( strcmp(arg
, "-force_flat_namespace") == 0 ) {
869 fNameSpace
= kForceFlatNameSpace
;
871 // Similar to --whole-archive.
872 else if ( strcmp(arg
, "-all_load") == 0 ) {
873 fReaderOptions
.fFullyLoadArchives
= true;
875 // Similar to --whole-archive, but for all ObjC classes.
876 else if ( strcmp(arg
, "-ObjC") == 0 ) {
877 fReaderOptions
.fLoadObjcClassesInArchives
= true;
879 // Library versioning.
880 else if ( strcmp(arg
, "-dylib_compatibility_version") == 0 ) {
881 fDylibCompatVersion
= parseVersionNumber(argv
[++i
]);
883 else if ( strcmp(arg
, "-dylib_current_version") == 0 ) {
884 fDylibCurrentVersion
= parseVersionNumber(argv
[++i
]);
886 else if ( strcmp(arg
, "-sectorder") == 0 ) {
887 parseSectionOrderFile(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
890 // ??? Deprecate segcreate.
891 // -sectcreate puts whole files into a section in the output.
892 else if ( (strcmp(arg
, "-sectcreate") == 0) || (strcmp(arg
, "-segcreate") == 0) ) {
893 addSection(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
896 // Since we have a full path in binary/library names we need to be able to override it.
897 else if ( (strcmp(arg
, "-dylib_install_name") == 0) || (strcmp(arg
, "-dylinker_install_name") == 0) ) {
898 fDylibInstallName
= argv
[++i
];
900 // Sets the base address of the output.
901 else if ( strcmp(arg
, "-seg1addr") == 0 ) {
902 fBaseAddress
= parseAddress(argv
[++i
]);
904 else if ( strcmp(arg
, "-e") == 0 ) {
905 fEntryName
= argv
[++i
];
907 // Same as -@ from the FSF linker.
908 else if ( strcmp(arg
, "-filelist") == 0 ) {
909 loadFileList(argv
[++i
]);
911 else if ( strcmp(arg
, "-keep_private_externs") == 0 ) {
912 fKeepPrivateExterns
= true;
915 else if ( strcmp(arg
, "-final_output") == 0 ) {
919 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
920 // just ensures that this happens for cross object file boundaries.
921 else if ( (strcmp(arg
, "-interposable") == 0) || (strcmp(arg
, "-multi_module") == 0)) {
922 fInterposable
= true;
924 // Default for -interposable/-multi_module/-single_module.
925 else if ( strcmp(arg
, "-single_module") == 0 ) {
926 fInterposable
= false;
928 else if ( strcmp(arg
, "-exported_symbols_list") == 0 ) {
929 if ( fExportMode
== kDontExportSome
)
930 throw "can't use -exported_symbols_list and -unexported_symbols_list";
931 fExportMode
= kExportSome
;
932 loadExportFile(argv
[++i
], "-exported_symbols_list", fExportSymbols
);
934 else if ( strcmp(arg
, "-unexported_symbols_list") == 0 ) {
935 if ( fExportMode
== kExportSome
)
936 throw "can't use -exported_symbols_list and -unexported_symbols_list";
937 fExportMode
= kDontExportSome
;
938 loadExportFile(argv
[++i
], "-unexported_symbols_list", fDontExportSymbols
);
941 else if ( strcmp(arg
, "-no_arch_warnings") == 0 ) {
942 fIgnoreOtherArchFiles
= true;
944 else if ( strcmp(arg
, "-force_cpusubtype_ALL") == 0 ) {
945 fForceSubtypeAll
= true;
947 // Similar to -weak-l but uses the absolute path name to the library.
948 else if ( strcmp(arg
, "-weak_library") == 0 ) {
949 FileInfo info
= findFile(argv
[++i
]);
950 info
.options
.fWeakImport
= true;
951 fInputFiles
.push_back(info
);
953 else if ( strcmp(arg
, "-framework") == 0 ) {
954 fInputFiles
.push_back(findFramework(argv
[++i
]));
956 else if ( strcmp(arg
, "-weak_framework") == 0 ) {
957 FileInfo info
= findFramework(argv
[++i
]);
958 info
.options
.fWeakImport
= true;
959 fInputFiles
.push_back(info
);
961 // ??? Deprecate when we get -Bstatic/-Bdynamic.
962 else if ( strcmp(arg
, "-search_paths_first") == 0 ) {
963 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
965 else if ( strcmp(arg
, "-undefined") == 0 ) {
966 setUndefinedTreatment(argv
[++i
]);
968 // Debugging output flag.
969 else if ( strcmp(arg
, "-arch_multiple") == 0 ) {
970 fMessagesPrefixedWithArchitecture
= true;
972 // Specify what to do with relocations in read only
973 // sections like .text. Could be errors, warnings,
974 // or suppressed. Currently we do nothing with the
976 else if ( strcmp(arg
, "-read_only_relocs") == 0 ) {
977 Treatment temp
= parseTreatment(argv
[++i
]);
980 throw "-read_only_relocs missing [ warning | error | suppress ]";
981 else if ( temp
== kInvalid
)
982 throw "invalid option to -read_only_relocs [ warning | error | suppress ]";
984 // Specifies whether or not there are intra section
985 // relocations and what to do when found. Could be
986 // errors, warnings, or suppressed.
987 else if ( strcmp(arg
, "-sect_diff_relocs") == 0 ) {
988 fPICTreatment
= parseTreatment(argv
[++i
]);
990 if ( fPICTreatment
== kNULL
)
991 throw "-sect_diff_relocs missing [ warning | error | suppress ]";
992 else if ( fPICTreatment
== kInvalid
)
993 throw "invalid option to -sect_diff_relocs [ warning | error | suppress ]";
995 // Warn, error or make strong a mismatch between weak
996 // and non-weak references.
997 else if ( strcmp(arg
, "-weak_reference_mismatches") == 0 ) {
998 setWeakReferenceMismatchTreatment(argv
[++i
]);
1000 // For a deployment target of 10.3 and earlier ld64 will
1001 // prebind an executable with 0s in all addresses that
1002 // are prebound. This can then be fixed up by update_prebinding
1003 // later. Prebinding is less useful on 10.4 and greater.
1004 else if ( strcmp(arg
, "-prebind") == 0 ) {
1007 else if ( strcmp(arg
, "-noprebind") == 0 ) {
1011 else if ( strcmp(arg
, "-prebind_allow_overlap") == 0 ) {
1012 // Do not handle and suppress warnings always.
1015 else if ( strcmp(arg
, "-prebind_all_twolevel_modules") == 0 ) {
1019 else if ( strcmp(arg
, "-noprebind_all_twolevel_modules") == 0 ) {
1022 // Sets a bit in the main executable only that causes fix_prebinding
1023 // not to run. This is always set.
1024 else if ( strcmp(arg
, "-nofixprebinding") == 0 ) {
1027 // This should probably be deprecated when we respect -L and -F
1028 // when searching for libraries.
1029 else if ( strcmp(arg
, "-dylib_file") == 0 ) {
1030 setDylibInstallNameOverride(argv
[++i
]);
1032 // Allows us to rewrite full paths to be relocatable based on
1033 // the path name of the executable.
1034 else if ( strcmp(arg
, "-executable_path") == 0 ) {
1035 fExecutablePath
= argv
[++i
];
1036 if ( (fExecutablePath
== NULL
) || (fExecutablePath
[0] == '-') )
1037 throw "-executable_path missing <path>";
1040 // Aligns all segments to the power of 2 boundary specified.
1041 else if ( strcmp(arg
, "-segalign") == 0 ) {
1045 // Puts a specified segment at a particular address that must
1046 // be a multiple of the segment alignment.
1047 else if ( strcmp(arg
, "-segaddr") == 0 ) {
1051 // ??? Deprecate when we deprecate split-seg.
1052 else if ( strcmp(arg
, "-segs_read_only_addr") == 0 ) {
1056 // ??? Deprecate when we deprecate split-seg.
1057 else if ( strcmp(arg
, "-segs_read_write_addr") == 0 ) {
1061 // ??? Deprecate when we get rid of basing at build time.
1062 else if ( strcmp(arg
, "-seg_addr_table") == 0 ) {
1067 else if ( strcmp(arg
, "-seg_addr_table_filename") == 0 ) {
1071 else if ( strcmp(arg
, "-segprot") == 0 ) {
1075 else if ( strcmp(arg
, "-pagezero_size") == 0 ) {
1076 fZeroPageSize
= parseAddress(argv
[++i
]);
1077 fZeroPageSize
&= (-4096); // page align
1079 else if ( strcmp(arg
, "-stack_addr") == 0 ) {
1080 fStackAddr
= parseAddress(argv
[++i
]);
1082 else if ( strcmp(arg
, "-stack_size") == 0 ) {
1083 fStackSize
= parseAddress(argv
[++i
]);
1085 else if ( strcmp(arg
, "-allow_stack_execute") == 0 ) {
1086 fExecutableStack
= true;
1088 else if ( strcmp(arg
, "-sectalign") == 0 ) {
1089 addSectionAlignment(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
1092 else if ( strcmp(arg
, "-sectorder_detail") == 0 ) {
1095 else if ( strcmp(arg
, "-sectobjectsymbols") == 0 ) {
1099 else if ( strcmp(arg
, "-bundle_loader") == 0 ) {
1103 else if ( strcmp(arg
, "-private_bundle") == 0 ) {
1106 else if ( strcmp(arg
, "-twolevel_namespace_hints") == 0 ) {
1109 // Use this flag to set default behavior for deployement targets.
1110 else if ( strcmp(arg
, "-macosx_version_min") == 0 ) {
1111 setVersionMin(argv
[++i
]);
1113 // This option (unlike -m below) only affects how we warn
1114 // on multiple definitions inside dynamic libraries.
1115 else if ( strcmp(arg
, "-multiply_defined") == 0 ) {
1116 fMultiplyDefinedDynamic
= parseTreatment(argv
[++i
]);
1118 if ( fMultiplyDefinedDynamic
== kNULL
)
1119 throw "-multiply_defined missing [ warning | error | suppress ]";
1120 else if ( fMultiplyDefinedDynamic
== kInvalid
)
1121 throw "invalid option to -multiply_defined [ warning | error | suppress ]";
1123 else if ( strcmp(arg
, "-multiply_defined_unused") == 0 ) {
1124 fMultiplyDefinedUnused
= parseTreatment(argv
[++i
]);
1126 if ( fMultiplyDefinedUnused
== kNULL
)
1127 throw "-multiply_defined_unused missing [ warning | error | suppress ]";
1128 else if ( fMultiplyDefinedUnused
== kInvalid
)
1129 throw "invalid option to -multiply_defined_unused [ warning | error | suppress ]";
1131 else if ( strcmp(arg
, "-nomultidefs") == 0 ) {
1134 // Display each file in which the argument symbol appears and whether
1135 // the file defines or references it. This option takes an argument
1136 // as -y<symbol> note that there is no space.
1137 else if ( strncmp(arg
, "-y", 2) == 0 ) {
1138 const char* name
= &arg
[2];
1141 throw "-y missing argument";
1143 fTraceSymbols
.push_back(name
);
1145 // Same output as -y, but output <arg> number of undefined symbols only.
1146 else if ( strcmp(arg
, "-Y") == 0 ) {
1148 fLimitUndefinedSymbols
= strtoul (argv
[++i
], &endptr
, 10);
1151 throw "invalid argument for -Y [decimal number]";
1153 // This option affects all objects linked into the final result.
1154 else if ( strcmp(arg
, "-m") == 0 ) {
1155 fWarnOnMultiplyDefined
= true;
1157 else if ( strcmp(arg
, "-whyload") == 0 ) {
1160 else if ( strcmp(arg
, "-u") == 0 ) {
1161 const char* name
= argv
[++i
];
1163 throw "-u missing argument";
1164 fInitialUndefines
.push_back(name
);
1166 else if ( strcmp(arg
, "-U") == 0 ) {
1170 else if ( strcmp(arg
, "-s") == 0 ) {
1171 fStripLocalSymbols
= true;
1172 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
1174 else if ( strcmp(arg
, "-x") == 0 ) {
1175 fStripLocalSymbols
= true;
1177 else if ( strcmp(arg
, "-S") == 0 ) {
1178 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoNone
;
1180 else if ( strcmp(arg
, "-X") == 0 ) {
1183 else if ( strcmp(arg
, "-Si") == 0 ) {
1184 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoFull
;
1186 else if ( strcmp(arg
, "-b") == 0 ) {
1189 else if ( strcmp(arg
, "-Sn") == 0 ) {
1190 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoFull
;
1192 else if ( strcmp(arg
, "-Sp") == 0 ) {
1193 fReaderOptions
.fDebugInfoStripping
= ObjectFile::ReaderOptions::kDebugInfoMinimal
;
1195 else if ( strcmp(arg
, "-dead_strip") == 0 ) {
1196 //fDeadStrip = kDeadStripOnPlusUnusedInits;
1197 fprintf(stderr
, "ld64: warning -dead_strip not yet supported in ld64\n");
1199 else if ( strcmp(arg
, "-no_dead_strip_inits_and_terms") == 0 ) {
1200 //fDeadStrip = kDeadStripOn;
1201 fprintf(stderr
, "ld64: warning -dead_strip not yet supported in ld64\n");
1203 else if ( strcmp(arg
, "-w") == 0 ) {
1206 else if ( strcmp(arg
, "-arch_errors_fatal") == 0 ) {
1209 else if ( strcmp(arg
, "-M") == 0 ) {
1212 else if ( strcmp(arg
, "-whatsloaded") == 0 ) {
1215 else if ( strcmp(arg
, "-headerpad") == 0 ) {
1216 const char* size
= argv
[++i
];
1218 throw "-headerpad missing argument";
1219 fMinimumHeaderPad
= parseAddress(size
);
1221 else if ( strcmp(arg
, "-headerpad_max_install_names") == 0 ) {
1224 else if ( strcmp(arg
, "-t") == 0 ) {
1227 else if ( strcmp(arg
, "-A") == 0 ) {
1231 else if ( strcmp(arg
, "-umbrella") == 0 ) {
1232 const char* name
= argv
[++i
];
1234 throw "-umbrella missing argument";
1235 fUmbrellaName
= name
;
1237 else if ( strcmp(arg
, "-allowable_client") == 0 ) {
1238 const char* name
= argv
[++i
];
1241 throw "-allowable_client missing argument";
1243 fAllowableClients
.push_back(name
);
1245 else if ( strcmp(arg
, "-client_name") == 0 ) {
1246 const char* name
= argv
[++i
];
1249 throw "-client_name missing argument";
1253 else if ( strcmp(arg
, "-sub_umbrella") == 0 ) {
1254 const char* name
= argv
[++i
];
1256 throw "-sub_umbrella missing argument";
1257 fSubUmbellas
.push_back(name
);
1259 else if ( strcmp(arg
, "-sub_library") == 0 ) {
1260 const char* name
= argv
[++i
];
1262 throw "-sub_library missing argument";
1263 fSubLibraries
.push_back(name
);
1265 else if ( strcmp(arg
, "-init") == 0 ) {
1266 const char* name
= argv
[++i
];
1268 throw "-init missing argument";
1269 fInitFunctionName
= name
;
1271 else if ( strcmp(arg
, "-dot") == 0 ) {
1272 const char* name
= argv
[++i
];
1274 throw "-dot missing argument";
1275 fDotOutputFile
= name
;
1277 else if ( strcmp(arg
, "-warn_commons") == 0 ) {
1278 fWarnCommons
= true;
1280 else if ( strcmp(arg
, "-commons") == 0 ) {
1281 fCommonsMode
= parseCommonsTreatment(argv
[++i
]);
1283 else if ( strcmp(arg
, "-keep_relocs") == 0 ) {
1284 fKeepRelocations
= true;
1286 else if ( strcmp(arg
, "-warn_stabs") == 0 ) {
1289 else if ( strcmp(arg
, "-pause") == 0 ) {
1292 else if ( strcmp(arg
, "-print_statistics") == 0 ) {
1295 else if ( strcmp(arg
, "-v") == 0 ) {
1296 // previously handled by buildSearchPaths()
1298 else if ( strcmp(arg
, "-Z") == 0 ) {
1299 // previously handled by buildSearchPaths()
1301 else if ( strcmp(arg
, "-syslibroot") == 0 ) {
1303 // previously handled by buildSearchPaths()
1305 else if ( strcmp(arg
, "-no_uuid") == 0 ) {
1308 // put this last so that it does not interfer with other options starting with 'i'
1309 else if ( strncmp(arg
, "-i", 2) == 0 ) {
1310 fprintf(stderr
, "ld64: -i option (indirect symbols) not supported\n");
1313 throwf("unknown option: %s", arg
);
1317 fInputFiles
.push_back(findFile(arg
));
1323 // -syslibroot <path> is used for SDK support.
1324 // The rule is that all search paths (both explicit and default) are
1325 // checked to see if they exist in the SDK. If so, that path is
1326 // replaced with the sdk prefixed path. If not, that search path
1327 // is used as is. If multiple -syslibroot options are specified
1328 // their directory structures are logically overlayed and files
1329 // from sdks specified earlier on the command line used before later ones.
1331 void Options::buildSearchPaths(int argc
, const char* argv
[])
1333 bool addStandardLibraryDirectories
= true;
1334 std::vector
<const char*> libraryPaths
;
1335 std::vector
<const char*> frameworkPaths
;
1336 libraryPaths
.reserve(10);
1337 frameworkPaths
.reserve(10);
1338 // scan through argv looking for -L, -F, -Z, and -syslibroot options
1339 for(int i
=0; i
< argc
; ++i
) {
1340 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') )
1341 libraryPaths
.push_back(&argv
[i
][2]);
1342 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') )
1343 frameworkPaths
.push_back(&argv
[i
][2]);
1344 else if ( strcmp(argv
[i
], "-Z") == 0 )
1345 addStandardLibraryDirectories
= false;
1346 else if ( strcmp(argv
[i
], "-v") == 0 ) {
1348 extern const char ld64VersionString
[];
1349 fprintf(stderr
, "%s", ld64VersionString
);
1350 // if only -v specified, exit cleanly
1354 else if ( strcmp(argv
[i
], "-syslibroot") == 0 ) {
1355 const char* path
= argv
[++i
];
1357 throw "-syslibroot missing argument";
1358 fSDKPaths
.push_back(path
);
1361 if ( addStandardLibraryDirectories
) {
1362 libraryPaths
.push_back("/usr/lib");
1363 libraryPaths
.push_back("/usr/local/lib");
1365 frameworkPaths
.push_back("/Library/Frameworks/");
1366 frameworkPaths
.push_back("/Network/Library/Frameworks/");
1367 frameworkPaths
.push_back("/System/Library/Frameworks/");
1370 // now merge sdk and library paths to make real search paths
1371 fLibrarySearchPaths
.reserve(libraryPaths
.size()*(fSDKPaths
.size()+1));
1372 for (std::vector
<const char*>::iterator it
= libraryPaths
.begin(); it
!= libraryPaths
.end(); it
++) {
1373 const char* libDir
= *it
;
1374 bool sdkOverride
= false;
1375 if ( libDir
[0] == '/' ) {
1376 char betterLibDir
[PATH_MAX
];
1377 if ( strstr(libDir
, "/..") != NULL
) {
1378 if ( realpath(libDir
, betterLibDir
) != NULL
)
1379 libDir
= strdup(betterLibDir
);
1381 const int libDirLen
= strlen(libDir
);
1382 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
1383 // ??? Should be using string here.
1384 const char* sdkDir
= *sdkit
;
1385 const int sdkDirLen
= strlen(sdkDir
);
1386 char newPath
[libDirLen
+ sdkDirLen
+4];
1387 strcpy(newPath
, sdkDir
);
1388 if ( newPath
[sdkDirLen
-1] == '/' )
1389 newPath
[sdkDirLen
-1] = '\0';
1390 strcat(newPath
, libDir
);
1391 struct stat statBuffer
;
1392 if ( stat(newPath
, &statBuffer
) == 0 ) {
1393 fLibrarySearchPaths
.push_back(strdup(newPath
));
1399 fLibrarySearchPaths
.push_back(libDir
);
1402 // now merge sdk and framework paths to make real search paths
1403 fFrameworkSearchPaths
.reserve(frameworkPaths
.size()*(fSDKPaths
.size()+1));
1404 for (std::vector
<const char*>::iterator it
= frameworkPaths
.begin(); it
!= frameworkPaths
.end(); it
++) {
1405 const char* frameworkDir
= *it
;
1406 bool sdkOverride
= false;
1407 if ( frameworkDir
[0] == '/' ) {
1408 char betterFrameworkDir
[PATH_MAX
];
1409 if ( strstr(frameworkDir
, "/..") != NULL
) {
1410 if ( realpath(frameworkDir
, betterFrameworkDir
) != NULL
)
1411 frameworkDir
= strdup(betterFrameworkDir
);
1413 const int frameworkDirLen
= strlen(frameworkDir
);
1414 for (std::vector
<const char*>::iterator sdkit
= fSDKPaths
.begin(); sdkit
!= fSDKPaths
.end(); sdkit
++) {
1415 // ??? Should be using string here
1416 const char* sdkDir
= *sdkit
;
1417 const int sdkDirLen
= strlen(sdkDir
);
1418 char newPath
[frameworkDirLen
+ sdkDirLen
+4];
1419 strcpy(newPath
, sdkDir
);
1420 if ( newPath
[sdkDirLen
-1] == '/' )
1421 newPath
[sdkDirLen
-1] = '\0';
1422 strcat(newPath
, frameworkDir
);
1423 struct stat statBuffer
;
1424 if ( stat(newPath
, &statBuffer
) == 0 ) {
1425 fFrameworkSearchPaths
.push_back(strdup(newPath
));
1431 fFrameworkSearchPaths
.push_back(frameworkDir
);
1435 fprintf(stderr
,"Library search paths:\n");
1436 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin();
1437 it
!= fLibrarySearchPaths
.end();
1439 fprintf(stderr
,"\t%s\n", *it
);
1440 fprintf(stderr
,"Framework search paths:\n");
1441 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin();
1442 it
!= fFrameworkSearchPaths
.end();
1444 fprintf(stderr
,"\t%s\n", *it
);
1448 // this is run before the command line is parsed
1449 void Options::parsePreCommandLineEnvironmentSettings()
1451 if ((getenv("LD_TRACE_ARCHIVES") != NULL
)
1452 || (getenv("RC_TRACE_ARCHIVES") != NULL
))
1453 fReaderOptions
.fTraceArchives
= true;
1455 if ((getenv("LD_TRACE_DYLIBS") != NULL
)
1456 || (getenv("RC_TRACE_DYLIBS") != NULL
)) {
1457 fReaderOptions
.fTraceDylibs
= true;
1458 fReaderOptions
.fTraceIndirectDylibs
= true;
1461 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL
) {
1462 fTraceDylibSearching
= true;
1465 if (getenv("LD_PRINT_OPTIONS") != NULL
)
1466 fPrintOptions
= true;
1468 if (fReaderOptions
.fTraceDylibs
|| fReaderOptions
.fTraceArchives
)
1469 fReaderOptions
.fTraceOutputFile
= getenv("LD_TRACE_FILE");
1472 // this is run after the command line is parsed
1473 void Options::parsePostCommandLineEnvironmentSettings()
1475 // when building a dynamic main executable, default any use of @executable_path to output path
1476 if ( fExecutablePath
== NULL
&& (fOutputKind
== kDynamicExecutable
) ) {
1477 fExecutablePath
= fOutputFile
;
1481 void Options::checkIllegalOptionCombinations()
1483 // check -undefined setting
1484 switch ( fUndefinedTreatment
) {
1485 case kUndefinedError
:
1486 case kUndefinedDynamicLookup
:
1489 case kUndefinedWarning
:
1490 case kUndefinedSuppress
:
1491 // requires flat namespace
1492 if ( fNameSpace
== kTwoLevelNameSpace
)
1493 throw "can't use -undefined warning or suppress with -twolevel_namespace";
1497 // unify -sub_umbrella with dylibs
1498 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
1499 const char* subUmbrella
= *it
;
1501 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1502 Options::FileInfo
& info
= *fit
;
1503 const char* lastSlash
= strrchr(info
.path
, '/');
1504 if ( lastSlash
== NULL
)
1505 lastSlash
= info
.path
- 1;
1506 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
1507 info
.options
.fReExport
= true;
1513 fprintf(stderr
, "ld64 warning: -sub_umbrella %s does not match a supplied dylib\n", subUmbrella
);
1516 // unify -sub_library with dylibs
1517 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
1518 const char* subLibrary
= *it
;
1520 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1521 Options::FileInfo
& info
= *fit
;
1522 const char* lastSlash
= strrchr(info
.path
, '/');
1523 if ( lastSlash
== NULL
)
1524 lastSlash
= info
.path
- 1;
1525 const char* dot
= strchr(lastSlash
, '.');
1527 dot
= &lastSlash
[strlen(lastSlash
)];
1528 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
1529 info
.options
.fReExport
= true;
1535 fprintf(stderr
, "ld64 warning: -sub_library %s does not match a supplied dylib\n", subLibrary
);
1538 // sync reader options
1539 if ( fNameSpace
!= kTwoLevelNameSpace
)
1540 fReaderOptions
.fFlatNamespace
= true;
1542 // check -stack_addr
1543 if ( fStackAddr
!= 0 ) {
1544 switch (fArchitecture
) {
1546 case CPU_TYPE_POWERPC
:
1547 if ( fStackAddr
> 0xFFFFFFFF )
1548 throw "-stack_addr must be < 4G for 32-bit processes";
1550 case CPU_TYPE_POWERPC64
:
1553 if ( (fStackAddr
& -4096) != fStackAddr
)
1554 throw "-stack_addr must be multiples of 4K";
1555 if ( fStackSize
== 0 )
1556 throw "-stack_addr must be used with -stack_size";
1559 // check -stack_size
1560 if ( fStackSize
!= 0 ) {
1561 switch (fArchitecture
) {
1563 case CPU_TYPE_POWERPC
:
1564 if ( fStackSize
> 0xFFFFFFFF )
1565 throw "-stack_size must be < 4G for 32-bit processes";
1566 if ( fStackAddr
== 0 ) {
1567 fprintf(stderr
, "ld64 warning: -stack_addr not specified, using the default 0xC0000000\n");
1568 fStackAddr
= 0xC0000000;
1571 case CPU_TYPE_POWERPC64
:
1572 if ( fStackAddr
== 0 ) {
1573 fprintf(stderr
, "ld64 warning: -stack_addr not specified, using the default 0x0008000000000000\n");
1574 fStackAddr
= 0x0008000000000000LL
;
1578 if ( (fStackSize
& -4096) != fStackSize
)
1579 throw "-stack_size must be multiples of 4K";
1580 switch ( fOutputKind
) {
1581 case Options::kDynamicExecutable
:
1582 case Options::kStaticExecutable
:
1583 // custom stack size only legal when building main executable
1585 case Options::kDynamicLibrary
:
1586 case Options::kDynamicBundle
:
1587 case Options::kObjectFile
:
1588 case Options::kDyld
:
1589 throw "-stack_size option can only be used when linking a main executable";
1593 // check that -allow_stack_execute is only used with main executables
1594 if ( fExecutableStack
) {
1595 switch ( fOutputKind
) {
1596 case Options::kDynamicExecutable
:
1597 case Options::kStaticExecutable
:
1598 // -allow_stack_execute size only legal when building main executable
1600 case Options::kDynamicLibrary
:
1601 case Options::kDynamicBundle
:
1602 case Options::kObjectFile
:
1603 case Options::kDyld
:
1604 throw "-allow_stack_execute option can only be used when linking a main executable";
1608 // check -client_name is only used when -bundle is specified
1609 if ( (fClientName
!= NULL
) && (fOutputKind
!= Options::kDynamicBundle
) )
1610 throw "-client_name can only be used with -bundle";
1612 // check -init is only used when building a dylib
1613 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
1614 throw "-init can only be used with -dynamiclib";
1616 // make sure all required exported symbols exist
1617 for (NameSet::iterator it
=fExportSymbols
.begin(); it
!= fExportSymbols
.end(); it
++) {
1618 const char* name
= *it
;
1619 // never export .eh symbols
1620 if ( strcmp(&name
[strlen(name
)-3], ".eh") != 0 )
1621 fInitialUndefines
.push_back(name
);