2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <sys/types.h>
32 __attribute__((noreturn
))
33 void throwf(const char* format
, ...)
37 va_start(list
, format
);
38 vasprintf(&p
, format
, list
);
46 Options::Options(int argc
, const char* argv
[])
47 : fOutputFile("a.out"), fArchitecture(CPU_TYPE_POWERPC64
), fOutputKind(kDynamicExecutable
), fBindAtLoad(false),
48 fStripLocalSymbols(false), fKeepPrivateExterns(false),
49 fInterposable(false), fIgnoreOtherArchFiles(false), fForceSubtypeAll(false), fNameSpace(kTwoLevelNameSpace
),
50 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL
), fEntryName("start"), fBaseAddress(0),
51 fExportMode(kExportDefault
), fLibrarySearchMode(kSearchAllDirsForDylibsThenAllDirsForArchives
),
52 fUndefinedTreatment(kUndefinedError
), fMessagesPrefixedWithArchitecture(false), fPICTreatment(kPICError
),
53 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchError
),
54 fUmbrellaName(NULL
), fInitFunctionName(NULL
), fZeroPageSize(0x1000), fStackSize(0), fStackAddr(0), fMinimumHeaderPad(0),
55 fCommonsMode(kCommonsIgnoreDylibs
), fWarnCommons(false)
57 this->parsePreCommandLineEnvironmentSettings();
58 this->parse(argc
, argv
);
59 this->parsePostCommandLineEnvironmentSettings();
60 this->checkIllegalOptionCombinations();
68 ObjectFile::ReaderOptions
& Options::readerOptions()
70 return fReaderOptions
;
73 cpu_type_t
Options::architecture()
79 const char* Options::getOutputFilePath()
85 std::vector
<Options::FileInfo
>& Options::getInputFiles()
90 Options::OutputKind
Options::outputKind()
95 bool Options::stripLocalSymbols()
97 return fStripLocalSymbols
;
100 bool Options::stripDebugInfo()
102 return fReaderOptions
.fStripDebugInfo
;
105 bool Options::bindAtLoad()
110 bool Options::fullyLoadArchives()
112 return fReaderOptions
.fFullyLoadArchives
;
115 Options::NameSpace
Options::nameSpace()
120 const char* Options::installPath()
122 if ( fDylibInstallName
!= NULL
)
123 return fDylibInstallName
;
128 uint32_t Options::currentVersion()
130 return fDylibCurrentVersion
;
133 uint32_t Options::compatibilityVersion()
135 return fDylibCompatVersion
;
138 const char* Options::entryName()
143 uint64_t Options::baseAddress()
148 bool Options::keepPrivateExterns()
150 return fKeepPrivateExterns
;
153 bool Options::interposable()
155 return fInterposable
;
158 bool Options::ignoreOtherArchInputFiles()
160 return fIgnoreOtherArchFiles
;
163 bool Options::forceCpuSubtypeAll()
165 return fForceSubtypeAll
;
168 bool Options::traceDylibs()
170 return fReaderOptions
.fTraceDylibs
;
173 bool Options::traceArchives()
175 return fReaderOptions
.fTraceArchives
;
178 Options::UndefinedTreatment
Options::undefinedTreatment()
180 return fUndefinedTreatment
;
183 Options::WeakReferenceMismatchTreatment
Options::weakReferenceMismatchTreatment()
185 return fWeakReferenceMismatchTreatment
;
188 const char* Options::umbrellaName()
190 return fUmbrellaName
;
193 uint64_t Options::zeroPageSize()
195 return fZeroPageSize
;
198 bool Options::hasCustomStack()
200 return (fStackSize
!= 0);
203 uint64_t Options::customStackSize()
208 uint64_t Options::customStackAddr()
213 std::vector
<const char*>& Options::initialUndefines()
215 return fInitialUndefines
;
218 const char* Options::initFunctionName()
220 return fInitFunctionName
;
223 bool Options::hasExportRestrictList()
225 return (fExportMode
!= kExportDefault
);
228 uint32_t Options::minimumHeaderPad()
230 return fMinimumHeaderPad
;
233 std::vector
<Options::ExtraSection
>& Options::extraSections()
235 return fExtraSections
;
238 std::vector
<Options::SectionAlignment
>& Options::sectionAlignments()
240 return fSectionAlignments
;
244 Options::CommonsMode
Options::commonsMode()
249 bool Options::warnCommons()
255 bool Options::shouldExport(const char* symbolName
)
257 switch (fExportMode
) {
259 return ( fExportSymbols
.find(symbolName
) != fExportSymbols
.end() );
260 case kDontExportSome
:
261 return ( fDontExportSymbols
.find(symbolName
) == fDontExportSymbols
.end() );
265 throw "internal error";
269 void Options::parseArch(const char* architecture
)
271 if ( architecture
== NULL
)
272 throw "-arch must be followed by an architecture string";
273 if ( strcmp(architecture
, "ppc") == 0 )
274 fArchitecture
= CPU_TYPE_POWERPC
;
275 else if ( strcmp(architecture
, "ppc64") == 0 )
276 fArchitecture
= CPU_TYPE_POWERPC64
;
277 else if ( strcmp(architecture
, "i386") == 0 )
278 fArchitecture
= CPU_TYPE_I386
;
280 throw "-arch followed by unknown architecture name";
283 bool Options::checkForFile(const char* format
, const char* dir
, const char* rootName
, FileInfo
& result
)
285 struct stat statBuffer
;
286 char possiblePath
[strlen(dir
)+strlen(rootName
)+20];
287 sprintf(possiblePath
, format
, dir
, rootName
);
288 if ( stat(possiblePath
, &statBuffer
) == 0 ) {
289 result
.path
= strdup(possiblePath
);
290 result
.fileLen
= statBuffer
.st_size
;
297 Options::FileInfo
Options::findLibrary(const char* rootName
)
300 const int rootNameLen
= strlen(rootName
);
301 // if rootName ends in .o there is no .a vs .dylib choice
302 if ( (rootNameLen
> 3) && (strcmp(&rootName
[rootNameLen
-2], ".o") == 0) ) {
303 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin(); it
!= fLibrarySearchPaths
.end(); it
++) {
304 const char* dir
= *it
;
305 if ( checkForFile("%s/%s", dir
, rootName
, result
) )
310 bool lookForDylibs
= ( fOutputKind
!= Options::kDyld
);
311 switch ( fLibrarySearchMode
) {
312 case kSearchAllDirsForDylibsThenAllDirsForArchives
:
313 // first look in all directories for just for dylibs
314 if ( lookForDylibs
) {
315 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin(); it
!= fLibrarySearchPaths
.end(); it
++) {
316 const char* dir
= *it
;
317 if ( checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
321 // next look in all directories for just for archives
322 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin(); it
!= fLibrarySearchPaths
.end(); it
++) {
323 const char* dir
= *it
;
324 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
329 case kSearchDylibAndArchiveInEachDir
:
330 // look in each directory for just for a dylib then for an archive
331 for (std::vector
<const char*>::iterator it
= fLibrarySearchPaths
.begin(); it
!= fLibrarySearchPaths
.end(); it
++) {
332 const char* dir
= *it
;
333 if ( lookForDylibs
&& checkForFile("%s/lib%s.dylib", dir
, rootName
, result
) )
335 if ( checkForFile("%s/lib%s.a", dir
, rootName
, result
) )
341 throwf("library not found for -l%s", rootName
);
345 Options::FileInfo
Options::findFramework(const char* rootName
)
347 struct stat statBuffer
;
348 const int rootNameLen
= strlen(rootName
);
349 for (std::vector
<const char*>::iterator it
= fFrameworkSearchPaths
.begin(); it
!= fFrameworkSearchPaths
.end(); it
++) {
350 const char* dir
= *it
;
351 char possiblePath
[strlen(dir
)+2*rootNameLen
+20];
352 strcpy(possiblePath
, dir
);
353 strcat(possiblePath
, "/");
354 strcat(possiblePath
, rootName
);
355 strcat(possiblePath
, ".framework/");
356 strcat(possiblePath
, rootName
);
357 if ( stat(possiblePath
, &statBuffer
) == 0 ) {
359 result
.path
= strdup(possiblePath
);
360 result
.fileLen
= statBuffer
.st_size
;
364 throwf("framework not found %s", rootName
);
368 Options::FileInfo
Options::makeFileInfo(const char* path
)
370 struct stat statBuffer
;
371 if ( stat(path
, &statBuffer
) == 0 ) {
373 result
.path
= strdup(path
);
374 result
.fileLen
= statBuffer
.st_size
;
378 throwf("file not found: %s", path
);
382 void Options::loadFileList(const char* fileOfPaths
)
384 FILE* file
= fopen(fileOfPaths
, "r");
386 throwf("-filelist file not found: %s\n", fileOfPaths
);
389 while ( fgets(path
, 1024, file
) != NULL
) {
391 char* eol
= strchr(path
, '\n');
395 fInputFiles
.push_back(makeFileInfo(path
));
401 void Options::loadExportFile(const char* fileOfExports
, const char* option
, NameSet
& set
)
403 // read in whole file
404 int fd
= ::open(fileOfExports
, O_RDONLY
, 0);
406 throwf("can't open %s file: %s", option
, fileOfExports
);
407 struct stat stat_buf
;
408 ::fstat(fd
, &stat_buf
);
409 char* p
= (char*)malloc(stat_buf
.st_size
);
411 throwf("can't process %s file: %s", option
, fileOfExports
);
413 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
414 throwf("can't read %s file: %s", option
, fileOfExports
);
418 // parse into symbols and add to hash_set
419 char * const end
= &p
[stat_buf
.st_size
];
420 enum { lineStart
, inSymbol
, inComment
} state
= lineStart
;
421 char* symbolStart
= NULL
;
422 for (char* s
= p
; s
< end
; ++s
) {
428 else if ( !isspace(*s
) ) {
436 // removing any trailing spaces
438 while ( isspace(*last
) ) {
442 set
.insert(symbolStart
);
453 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
456 void Options::setUndefinedTreatment(const char* treatment
)
458 if ( treatment
== NULL
)
459 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
461 if ( strcmp(treatment
, "warning") == 0 )
462 fUndefinedTreatment
= kUndefinedWarning
;
463 else if ( strcmp(treatment
, "error") == 0 )
464 fUndefinedTreatment
= kUndefinedError
;
465 else if ( strcmp(treatment
, "suppress") == 0 )
466 fUndefinedTreatment
= kUndefinedSuppress
;
467 else if ( strcmp(treatment
, "dynamic_lookup") == 0 )
468 fUndefinedTreatment
= kUndefinedDynamicLookup
;
470 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
473 void Options::setReadOnlyRelocTreatment(const char* treatment
)
475 if ( treatment
== NULL
)
476 throw "-read_only_relocs missing [ warning | error | suppress ]";
478 if ( strcmp(treatment
, "warning") == 0 )
479 throw "-read_only_relocs warning not supported";
480 else if ( strcmp(treatment
, "suppress") == 0 )
481 throw "-read_only_relocs suppress not supported";
482 else if ( strcmp(treatment
, "error") != 0 )
483 throw "invalid option to -read_only_relocs [ warning | error | suppress | dynamic_lookup ]";
486 void Options::setPICTreatment(const char* treatment
)
488 if ( treatment
== NULL
)
489 throw "-sect_diff_relocs missing [ warning | error | suppress ]";
491 if ( strcmp(treatment
, "warning") == 0 )
492 fPICTreatment
= kPICWarning
;
493 else if ( strcmp(treatment
, "error") == 0 )
494 fPICTreatment
= kPICError
;
495 else if ( strcmp(treatment
, "suppress") == 0 )
496 fPICTreatment
= kPICSuppress
;
498 throw "invalid option to -sect_diff_relocs [ warning | error | suppress ]";
501 void Options::setWeakReferenceMismatchTreatment(const char* treatment
)
503 if ( treatment
== NULL
)
504 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
506 if ( strcmp(treatment
, "error") == 0 )
507 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchError
;
508 else if ( strcmp(treatment
, "weak") == 0 )
509 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchWeak
;
510 else if ( strcmp(treatment
, "non-weak") == 0 )
511 fWeakReferenceMismatchTreatment
= kWeakReferenceMismatchNonWeak
;
513 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
516 Options::CommonsMode
Options::parseCommonsTreatment(const char* mode
)
519 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
521 if ( strcmp(mode
, "ignore_dylibs") == 0 )
522 return kCommonsIgnoreDylibs
;
523 else if ( strcmp(mode
, "use_dylibs") == 0 )
524 return kCommonsOverriddenByDylibs
;
525 else if ( strcmp(mode
, "error") == 0 )
526 return kCommonsConflictsDylibsError
;
528 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
532 void Options::setDylibInstallNameOverride(const char* paths
)
538 void Options::setExecutablePath(const char* path
)
547 uint64_t Options::parseAddress(const char* addr
)
550 uint64_t result
= strtoull(addr
, &endptr
, 16);
557 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
560 uint32_t Options::parseVersionNumber(const char* versionString
)
566 x
= strtoul(versionString
, &end
, 10);
568 y
= strtoul(&end
[1], &end
, 10);
570 z
= strtoul(&end
[1], &end
, 10);
573 if ( (*end
!= '\0') || (x
> 0xffff) || (y
> 0xff) || (z
> 0xff) )
574 throwf("malformed version number: %s", versionString
);
576 return (x
<< 16) | ( y
<< 8 ) | z
;
579 void Options::parseSectionOrderFile(const char* segment
, const char* section
, const char* path
)
581 fprintf(stderr
, "ld64: warning -sectorder not yet supported for 64-bit code\n");
584 void Options::addSection(const char* segment
, const char* section
, const char* path
)
586 if ( strlen(segment
) > 16 )
587 throw "-seccreate segment name max 16 chars";
588 if ( strlen(section
) > 16 )
589 throw "-seccreate section name max 16 chars";
591 // read in whole file
592 int fd
= ::open(path
, O_RDONLY
, 0);
594 throwf("can't open -sectcreate file: %s", path
);
595 struct stat stat_buf
;
596 ::fstat(fd
, &stat_buf
);
597 char* p
= (char*)malloc(stat_buf
.st_size
);
599 throwf("can't process -sectcreate file: %s", path
);
600 if ( read(fd
, p
, stat_buf
.st_size
) != stat_buf
.st_size
)
601 throwf("can't read -sectcreate file: %s", path
);
604 // record section to create
605 ExtraSection info
= { segment
, section
, path
, (uint8_t*)p
, stat_buf
.st_size
};
606 fExtraSections
.push_back(info
);
609 void Options::addSectionAlignment(const char* segment
, const char* section
, const char* alignmentStr
)
611 if ( strlen(segment
) > 16 )
612 throw "-sectalign segment name max 16 chars";
613 if ( strlen(section
) > 16 )
614 throw "-sectalign section name max 16 chars";
617 unsigned long value
= strtoul(alignmentStr
, &endptr
, 16);
618 if ( *endptr
!= '\0')
619 throw "argument for -sectalign is not a hexadecimal number";
620 if ( value
> 0x8000 )
621 throw "argument for -sectalign must be less than or equal to 0x8000";
622 uint8_t alignment
= 0;
623 for(unsigned long x
=value
; x
!= 1; x
>>= 1)
625 if ( (unsigned long)(1 << alignment
) != value
)
626 throw "argument for -sectalign is not a power of two";
628 SectionAlignment info
= { segment
, section
, alignment
};
629 fSectionAlignments
.push_back(info
);
633 void Options::parse(int argc
, const char* argv
[])
635 // pass one builds search list from -L and -F options
636 this->buildSearchPaths(argc
, argv
);
638 // pass two parse all other options
639 for(int i
=1; i
< argc
; ++i
) {
640 const char* arg
= argv
[i
];
642 if ( arg
[0] == '-' ) {
643 if ( (arg
[1] == 'L') || (arg
[1] == 'F') ) {
644 // previously handled
646 else if ( strcmp(arg
, "-arch") == 0 ) {
647 parseArch(argv
[++i
]);
649 else if ( strcmp(arg
, "-dynamic") == 0 ) {
652 else if ( strcmp(arg
, "-static") == 0 ) {
653 fOutputKind
= kStaticExecutable
;
655 else if ( strcmp(arg
, "-dylib") == 0 ) {
656 fOutputKind
= kDynamicLibrary
;
658 else if ( strcmp(arg
, "-bundle") == 0 ) {
659 fOutputKind
= kDynamicBundle
;
661 else if ( strcmp(arg
, "-dylinker") == 0 ) {
664 else if ( strcmp(arg
, "-execute") == 0 ) {
665 if ( fOutputKind
!= kStaticExecutable
)
666 fOutputKind
= kDynamicExecutable
;
668 else if ( strcmp(arg
, "-r") == 0 ) {
669 fOutputKind
= kObjectFile
;
671 else if ( strcmp(arg
, "-o") == 0 ) {
672 fOutputFile
= argv
[++i
];
674 else if ( arg
[1] == 'l' ) {
675 fInputFiles
.push_back(findLibrary(&arg
[2]));
677 else if ( strcmp(arg
, "-weak-l") == 0 ) {
678 FileInfo info
= findLibrary(&arg
[2]);
679 info
.options
.fWeakImport
= true;
680 fInputFiles
.push_back(info
);
682 else if ( strcmp(arg
, "-bind_at_load") == 0 ) {
685 else if ( strcmp(arg
, "-twolevel_namespace") == 0 ) {
686 fNameSpace
= kTwoLevelNameSpace
;
688 else if ( strcmp(arg
, "-flat_namespace") == 0 ) {
689 fNameSpace
= kFlatNameSpace
;
691 else if ( strcmp(arg
, "-force_flat_namespace") == 0 ) {
692 fNameSpace
= kForceFlatNameSpace
;
694 else if ( strcmp(arg
, "-all_load") == 0 ) {
695 fReaderOptions
.fFullyLoadArchives
= true;
697 else if ( strcmp(arg
, "-ObjC") == 0 ) {
698 fReaderOptions
.fLoadObjcClassesInArchives
= true;
700 else if ( strcmp(arg
, "-dylib_compatibility_version") == 0 ) {
701 fDylibCompatVersion
= parseVersionNumber(argv
[++i
]);
703 else if ( strcmp(arg
, "-dylib_current_version") == 0 ) {
704 fDylibCurrentVersion
= parseVersionNumber(argv
[++i
]);
706 else if ( strcmp(arg
, "-sectorder") == 0 ) {
707 parseSectionOrderFile(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
710 else if ( (strcmp(arg
, "-sectcreate") == 0) || (strcmp(arg
, "-segcreate") == 0) ) {
711 addSection(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
714 else if ( (strcmp(arg
, "-dylib_install_name") == 0) || (strcmp(arg
, "-dylinker_install_name") == 0) ) {
715 fDylibInstallName
= argv
[++i
];
717 else if ( strcmp(arg
, "-seg1addr") == 0 ) {
718 fBaseAddress
= parseAddress(argv
[++i
]);
720 else if ( strcmp(arg
, "-e") == 0 ) {
721 fEntryName
= argv
[++i
];
723 else if ( strcmp(arg
, "-filelist") == 0 ) {
724 loadFileList(argv
[++i
]);
726 else if ( strcmp(arg
, "-keep_private_externs") == 0 ) {
727 fKeepPrivateExterns
= true;
729 else if ( strcmp(arg
, "-final_output") == 0 ) {
733 else if ( (strcmp(arg
, "-interposable") == 0) || (strcmp(arg
, "-multi_module") == 0)) {
734 fInterposable
= true;
736 else if ( strcmp(arg
, "-single_module") == 0 ) {
737 fInterposable
= false;
739 else if ( strcmp(arg
, "-exported_symbols_list") == 0 ) {
740 if ( fExportMode
== kDontExportSome
)
741 throw "can't use -exported_symbols_list and -unexported_symbols_list";
742 fExportMode
= kExportSome
;
743 loadExportFile(argv
[++i
], "-exported_symbols_list", fExportSymbols
);
745 else if ( strcmp(arg
, "-unexported_symbols_list") == 0 ) {
746 if ( fExportMode
== kExportSome
)
747 throw "can't use -exported_symbols_list and -unexported_symbols_list";
748 fExportMode
= kDontExportSome
;
749 loadExportFile(argv
[++i
], "-unexported_symbols_list", fDontExportSymbols
);
751 else if ( strcmp(arg
, "-no_arch_warnings") == 0 ) {
752 fIgnoreOtherArchFiles
= true;
754 else if ( strcmp(arg
, "-force_cpusubtype_ALL") == 0 ) {
755 fForceSubtypeAll
= true;
757 else if ( strcmp(arg
, "-weak_library") == 0 ) {
758 FileInfo info
= makeFileInfo(argv
[++i
]);
759 info
.options
.fWeakImport
= true;
760 fInputFiles
.push_back(info
);
762 else if ( strcmp(arg
, "-framework") == 0 ) {
763 fInputFiles
.push_back(findFramework(argv
[++i
]));
765 else if ( strcmp(arg
, "-weak_framework") == 0 ) {
766 FileInfo info
= findFramework(argv
[++i
]);
767 info
.options
.fWeakImport
= true;
768 fInputFiles
.push_back(info
);
770 else if ( strcmp(arg
, "-search_paths_first") == 0 ) {
771 fLibrarySearchMode
= kSearchDylibAndArchiveInEachDir
;
773 else if ( strcmp(arg
, "-undefined") == 0 ) {
774 setUndefinedTreatment(argv
[++i
]);
776 else if ( strcmp(arg
, "-arch_multiple") == 0 ) {
777 fMessagesPrefixedWithArchitecture
= true;
779 else if ( strcmp(arg
, "-read_only_relocs") == 0 ) {
780 setReadOnlyRelocTreatment(argv
[++i
]);
782 else if ( strcmp(arg
, "-sect_diff_relocs") == 0 ) {
783 setPICTreatment(argv
[++i
]);
785 else if ( strcmp(arg
, "-weak_reference_mismatches") == 0 ) {
786 setWeakReferenceMismatchTreatment(argv
[++i
]);
788 else if ( strcmp(arg
, "-prebind") == 0 ) {
791 else if ( strcmp(arg
, "-noprebind") == 0 ) {
794 else if ( strcmp(arg
, "-prebind_allow_overlap") == 0 ) {
797 else if ( strcmp(arg
, "-prebind_all_twolevel_modules") == 0 ) {
800 else if ( strcmp(arg
, "-noprebind_all_twolevel_modules") == 0 ) {
803 else if ( strcmp(arg
, "-nofixprebinding") == 0 ) {
806 else if ( strcmp(arg
, "-dylib_file") == 0 ) {
807 setDylibInstallNameOverride(argv
[++i
]);
809 else if ( strcmp(arg
, "-executable_path") == 0 ) {
810 setExecutablePath(argv
[++i
]);
812 else if ( strcmp(arg
, "-segalign") == 0 ) {
816 else if ( strcmp(arg
, "-segaddr") == 0 ) {
820 else if ( strcmp(arg
, "-segs_read_only_addr") == 0 ) {
824 else if ( strcmp(arg
, "-segs_read_write_addr") == 0 ) {
828 else if ( strcmp(arg
, "-seg_addr_table") == 0 ) {
832 else if ( strcmp(arg
, "-seg_addr_table_filename") == 0 ) {
836 else if ( strcmp(arg
, "-segprot") == 0 ) {
840 else if ( strcmp(arg
, "-pagezero_size") == 0 ) {
841 fZeroPageSize
= parseAddress(argv
[++i
]);
842 fZeroPageSize
&= (-4096); // page align
844 else if ( strcmp(arg
, "-stack_addr") == 0 ) {
845 fStackAddr
= parseAddress(argv
[++i
]);
847 else if ( strcmp(arg
, "-stack_size") == 0 ) {
848 fStackSize
= parseAddress(argv
[++i
]);
850 else if ( strcmp(arg
, "-sectalign") == 0 ) {
851 addSectionAlignment(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
854 else if ( strcmp(arg
, "-sectorder_detail") == 0 ) {
857 else if ( strcmp(arg
, "-sectobjectsymbols") == 0 ) {
861 else if ( strcmp(arg
, "-bundle_loader") == 0 ) {
865 else if ( strcmp(arg
, "-private_bundle") == 0 ) {
868 else if ( strcmp(arg
, "-twolevel_namespace_hints") == 0 ) {
871 else if ( strcmp(arg
, "-multiply_defined") == 0 ) {
875 else if ( strcmp(arg
, "-multiply_defined_unused") == 0 ) {
879 else if ( strcmp(arg
, "-nomultidefs") == 0 ) {
882 else if ( arg
[1] == 'y' ) {
885 else if ( strcmp(arg
, "-Y") == 0 ) {
889 else if ( strcmp(arg
, "-m") == 0 ) {
892 else if ( strcmp(arg
, "-whyload") == 0 ) {
895 else if ( strcmp(arg
, "-u") == 0 ) {
896 const char* name
= argv
[++i
];
898 throw "-u missing argument";
899 fInitialUndefines
.push_back(name
);
901 else if ( strcmp(arg
, "-i") == 0 ) {
904 else if ( strcmp(arg
, "-U") == 0 ) {
908 else if ( strcmp(arg
, "-s") == 0 ) {
911 else if ( strcmp(arg
, "-x") == 0 ) {
914 else if ( strcmp(arg
, "-S") == 0 ) {
917 else if ( strcmp(arg
, "-X") == 0 ) {
920 else if ( strcmp(arg
, "-Si") == 0 ) {
923 else if ( strcmp(arg
, "-b") == 0 ) {
926 else if ( strcmp(arg
, "-Sn") == 0 ) {
929 else if ( strcmp(arg
, "-dead_strip") == 0 ) {
931 fprintf(stderr
, "ld64: warning -dead_strip not yet supported for 64-bit code\n");
933 else if ( strcmp(arg
, "-v") == 0 ) {
934 extern const char ld64VersionString
[];
935 fprintf(stderr
, "%s", ld64VersionString
);
936 // if only -v specified, exit cleanly
940 else if ( strcmp(arg
, "-w") == 0 ) {
943 else if ( strcmp(arg
, "-arch_errors_fatal") == 0 ) {
946 else if ( strcmp(arg
, "-M") == 0 ) {
949 else if ( strcmp(arg
, "-whatsloaded") == 0 ) {
952 else if ( strcmp(arg
, "-headerpad") == 0 ) {
953 const char* size
= argv
[++i
];
955 throw "-headerpad missing argument";
956 fMinimumHeaderPad
= parseAddress(size
);
958 else if ( strcmp(arg
, "-headerpad_max_install_names") == 0 ) {
961 else if ( strcmp(arg
, "-t") == 0 ) {
964 else if ( strcmp(arg
, "-A") == 0 ) {
968 else if ( strcmp(arg
, "-umbrella") == 0 ) {
969 const char* name
= argv
[++i
];
971 throw "-umbrella missing argument";
972 fUmbrellaName
= name
;
974 else if ( strcmp(arg
, "-allowable_client") == 0 ) {
978 else if ( strcmp(arg
, "-client_name") == 0 ) {
982 else if ( strcmp(arg
, "-sub_umbrella") == 0 ) {
983 const char* name
= argv
[++i
];
985 throw "-sub_umbrella missing argument";
986 fSubUmbellas
.push_back(name
);
988 else if ( strcmp(arg
, "-sub_library") == 0 ) {
989 const char* name
= argv
[++i
];
991 throw "-sub_library missing argument";
992 fSubLibraries
.push_back(name
);
994 else if ( strcmp(arg
, "-init") == 0 ) {
995 const char* name
= argv
[++i
];
997 throw "-init missing argument";
998 fInitFunctionName
= name
;
1000 else if ( strcmp(arg
, "-warn_commons") == 0 ) {
1001 fWarnCommons
= true;
1003 else if ( strcmp(arg
, "-commons") == 0 ) {
1004 fCommonsMode
= parseCommonsTreatment(argv
[++i
]);
1008 fprintf(stderr
, "unknown option: %s\n", arg
);
1012 fInputFiles
.push_back(makeFileInfo(arg
));
1017 void Options::buildSearchPaths(int argc
, const char* argv
[])
1019 bool addStandardLibraryDirectories
= true;
1020 // scan through argv looking for -L and -F options
1021 for(int i
=0; i
< argc
; ++i
) {
1022 if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'L') )
1023 fLibrarySearchPaths
.push_back(&argv
[i
][2]);
1024 else if ( (argv
[i
][0] == '-') && (argv
[i
][1] == 'F') )
1025 fFrameworkSearchPaths
.push_back(&argv
[i
][2]);
1026 else if ( strcmp(argv
[i
], "-Z") == 0 )
1027 addStandardLibraryDirectories
= false;
1029 if ( addStandardLibraryDirectories
) {
1030 fLibrarySearchPaths
.push_back("/usr/lib");
1031 fLibrarySearchPaths
.push_back("/usr/local/lib");
1033 fFrameworkSearchPaths
.push_back("/Library/Frameworks/");
1034 fFrameworkSearchPaths
.push_back("/Network/Library/Frameworks/");
1035 fFrameworkSearchPaths
.push_back("/System/Library/Frameworks/");
1039 // this is run before the command line is parsed
1040 void Options::parsePreCommandLineEnvironmentSettings()
1042 if ( getenv("RC_TRACE_ARCHIVES") != NULL
)
1043 fReaderOptions
.fTraceArchives
= true;
1045 if ( getenv("RC_TRACE_DYLIBS") != NULL
) {
1046 fReaderOptions
.fTraceDylibs
= true;
1047 fReaderOptions
.fTraceIndirectDylibs
= true;
1051 // this is run after the command line is parsed
1052 void Options::parsePostCommandLineEnvironmentSettings()
1057 void Options::checkIllegalOptionCombinations()
1059 // check -undefined setting
1060 switch ( fUndefinedTreatment
) {
1061 case kUndefinedError
:
1062 case kUndefinedDynamicLookup
:
1065 case kUndefinedWarning
:
1066 case kUndefinedSuppress
:
1067 // requires flat namespace
1068 if ( fNameSpace
== kTwoLevelNameSpace
)
1069 throw "can't use -undefined warning or suppress with -twolevel_namespace";
1073 // unify -sub_umbrella with dylibs
1074 for (std::vector
<const char*>::iterator it
= fSubUmbellas
.begin(); it
!= fSubUmbellas
.end(); it
++) {
1075 const char* subUmbrella
= *it
;
1077 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1078 Options::FileInfo
& info
= *fit
;
1079 const char* lastSlash
= strrchr(info
.path
, '/');
1080 if ( lastSlash
== NULL
)
1081 lastSlash
= info
.path
- 1;
1082 if ( strcmp(&lastSlash
[1], subUmbrella
) == 0 ) {
1083 info
.options
.fReExport
= true;
1089 fprintf(stderr
, "ld64 warning: -sub_umbrella %s does not match a supplied dylib\n", subUmbrella
);
1092 // unify -sub_library with dylibs
1093 for (std::vector
<const char*>::iterator it
= fSubLibraries
.begin(); it
!= fSubLibraries
.end(); it
++) {
1094 const char* subLibrary
= *it
;
1096 for (std::vector
<Options::FileInfo
>::iterator fit
= fInputFiles
.begin(); fit
!= fInputFiles
.end(); fit
++) {
1097 Options::FileInfo
& info
= *fit
;
1098 const char* lastSlash
= strrchr(info
.path
, '/');
1099 if ( lastSlash
== NULL
)
1100 lastSlash
= info
.path
- 1;
1101 const char* dot
= strchr(lastSlash
, '.');
1103 dot
= &lastSlash
[strlen(lastSlash
)];
1104 if ( strncmp(&lastSlash
[1], subLibrary
, dot
-lastSlash
-1) == 0 ) {
1105 info
.options
.fReExport
= true;
1111 fprintf(stderr
, "ld64 warning: -sub_library %s does not match a supplied dylib\n", subLibrary
);
1114 // sync reader options
1115 if ( fNameSpace
!= kTwoLevelNameSpace
)
1116 fReaderOptions
.fFlatNamespace
= true;
1118 // check -stack_addr
1119 if ( fStackAddr
!= 0 ) {
1120 switch (fArchitecture
) {
1122 case CPU_TYPE_POWERPC
:
1123 if ( fStackAddr
> 0xFFFFFFFF )
1124 throw "-stack_addr must be < 4G for 32-bit processes";
1126 case CPU_TYPE_POWERPC64
:
1129 if ( (fStackAddr
& -4096) != fStackAddr
)
1130 throw "-stack_addr must be multiples of 4K";
1131 if ( fStackSize
== 0 )
1132 throw "-stack_addr must be used with -stack_size";
1135 // check -stack_size
1136 if ( fStackSize
!= 0 ) {
1137 switch (fArchitecture
) {
1139 case CPU_TYPE_POWERPC
:
1140 if ( fStackSize
> 0xFFFFFFFF )
1141 throw "-stack_size must be < 4G for 32-bit processes";
1142 if ( fStackAddr
== 0 ) {
1143 fprintf(stderr
, "ld64 warning: -stack_addr not specified, using the default 0xC0000000\n");
1144 fStackAddr
= 0xC0000000;
1147 case CPU_TYPE_POWERPC64
:
1148 if ( fStackAddr
== 0 ) {
1149 fprintf(stderr
, "ld64 warning: -stack_addr not specified, using the default 0x0008000000000000\n");
1150 fStackAddr
= 0x0008000000000000LL
;
1154 if ( (fStackSize
& -4096) != fStackSize
)
1155 throw "-stack_size must be multiples of 4K";
1156 switch ( fOutputKind
) {
1157 case Options::kDynamicExecutable
:
1158 case Options::kStaticExecutable
:
1159 // custom stack size only legeal when building main executable
1161 case Options::kDynamicLibrary
:
1162 case Options::kDynamicBundle
:
1163 case Options::kObjectFile
:
1164 case Options::kDyld
:
1165 throw "-stack_size option can only be used when linking a main executable";
1169 // check -init is only used when building a dylib
1170 if ( (fInitFunctionName
!= NULL
) && (fOutputKind
!= Options::kDynamicLibrary
) )
1171 throw "-init can only be used with -dynamiclib";