]> git.saurik.com Git - apple/ld64.git/blob - src/ld/Options.cpp
ld64-96.5.tar.gz
[apple/ld64.git] / src / ld / Options.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2005-2008 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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
12 * file.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <mach/vm_prot.h>
29 #include <mach-o/dyld.h>
30 #include <fcntl.h>
31 #include <vector>
32
33 #include "configure.h"
34 #include "Options.h"
35 #include "Architectures.hpp"
36 #include "MachOFileAbstraction.hpp"
37
38 extern void printLTOVersion(Options &opts);
39
40 // magic to place command line in crash reports
41 extern "C" char* __crashreporter_info__;
42 static char crashreporterBuffer[1000];
43 char* __crashreporter_info__ = crashreporterBuffer;
44
45 static bool sEmitWarnings = true;
46 static const char* sWarningsSideFilePath = NULL;
47 static FILE* sWarningsSideFile = NULL;
48
49 void warning(const char* format, ...)
50 {
51 if ( sEmitWarnings ) {
52 va_list list;
53 if ( sWarningsSideFilePath != NULL ) {
54 if ( sWarningsSideFile == NULL )
55 sWarningsSideFile = fopen(sWarningsSideFilePath, "a");
56 }
57 va_start(list, format);
58 fprintf(stderr, "ld: warning: ");
59 vfprintf(stderr, format, list);
60 fprintf(stderr, "\n");
61 if ( sWarningsSideFile != NULL ) {
62 fprintf(sWarningsSideFile, "ld: warning: ");
63 vfprintf(sWarningsSideFile, format, list);
64 fprintf(sWarningsSideFile, "\n");
65 fflush(sWarningsSideFile);
66 }
67 va_end(list);
68 }
69 }
70
71 void throwf(const char* format, ...)
72 {
73 va_list list;
74 char* p;
75 va_start(list, format);
76 vasprintf(&p, format, list);
77 va_end(list);
78
79 const char* t = p;
80 throw t;
81 }
82
83 Options::Options(int argc, const char* argv[])
84 : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fOutputKind(kDynamicExecutable),
85 fHasPreferredSubType(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
86 fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fErrorOnOtherArchFiles(false), fForceSubtypeAll(false),
87 fInterposeMode(kInterposeNone), fDeadStrip(kDeadStripOff), fNameSpace(kTwoLevelNameSpace),
88 fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL), fFinalName(NULL), fEntryName("start"), fBaseAddress(0),
89 fBaseWritableAddress(0), fSplitSegs(false),
90 fExportMode(kExportDefault), fLibrarySearchMode(kSearchAllDirsForDylibsThenAllDirsForArchives),
91 fUndefinedTreatment(kUndefinedError), fMessagesPrefixedWithArchitecture(false),
92 fWeakReferenceMismatchTreatment(kWeakReferenceMismatchNonWeak),
93 fClientName(NULL),
94 fUmbrellaName(NULL), fInitFunctionName(NULL), fDotOutputFile(NULL), fExecutablePath(NULL),
95 fBundleLoader(NULL), fDtraceScriptName(NULL), fSegAddrTablePath(NULL), fMapPath(NULL),
96 fZeroPageSize(ULLONG_MAX), fStackSize(0), fStackAddr(0), fExecutableStack(false),
97 fMinimumHeaderPad(32), fSegmentAlignment(4096),
98 fCommonsMode(kCommonsIgnoreDylibs), fUUIDMode(kUUIDContent), fLocalSymbolHandling(kLocalSymbolsAll), fWarnCommons(false),
99 fVerbose(false), fKeepRelocations(false), fWarnStabs(false),
100 fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
101 fSharedRegionEligible(false), fPrintOrderFileStatistics(false),
102 fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
103 fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false),
104 fUsingLazyDylibLinking(false), fEncryptable(true),
105 fOrderData(true), fMarkDeadStrippableDylib(false),
106 fMakeClassicDyldInfo(true), fMakeCompressedDyldInfo(true), fAllowCpuSubtypeMismatches(false),
107 fUseSimplifiedDylibReExports(false), fSaveTempFiles(false)
108 {
109 this->checkForClassic(argc, argv);
110 this->parsePreCommandLineEnvironmentSettings();
111 this->parse(argc, argv);
112 this->parsePostCommandLineEnvironmentSettings();
113 this->reconfigureDefaults();
114 this->checkIllegalOptionCombinations();
115 }
116
117 Options::~Options()
118 {
119 }
120
121 const ObjectFile::ReaderOptions& Options::readerOptions()
122 {
123 return fReaderOptions;
124 }
125
126
127 const char* Options::getOutputFilePath()
128 {
129 return fOutputFile;
130 }
131
132 std::vector<Options::FileInfo>& Options::getInputFiles()
133 {
134 return fInputFiles;
135 }
136
137 Options::OutputKind Options::outputKind()
138 {
139 return fOutputKind;
140 }
141
142 bool Options::bindAtLoad()
143 {
144 return fBindAtLoad;
145 }
146
147 bool Options::prebind()
148 {
149 return fPrebind;
150 }
151
152 bool Options::fullyLoadArchives()
153 {
154 return fReaderOptions.fFullyLoadArchives;
155 }
156
157 Options::NameSpace Options::nameSpace()
158 {
159 return fNameSpace;
160 }
161
162 const char* Options::installPath()
163 {
164 if ( fDylibInstallName != NULL )
165 return fDylibInstallName;
166 else if ( fFinalName != NULL )
167 return fFinalName;
168 else
169 return fOutputFile;
170 }
171
172 uint32_t Options::currentVersion()
173 {
174 return fDylibCurrentVersion;
175 }
176
177 uint32_t Options::compatibilityVersion()
178 {
179 return fDylibCompatVersion;
180 }
181
182 const char* Options::entryName()
183 {
184 return fEntryName;
185 }
186
187 uint64_t Options::baseAddress()
188 {
189 return fBaseAddress;
190 }
191
192 bool Options::keepPrivateExterns()
193 {
194 return fKeepPrivateExterns;
195 }
196
197 bool Options::interposable(const char* name)
198 {
199 switch ( fInterposeMode ) {
200 case kInterposeNone:
201 return false;
202 case kInterposeAllExternal:
203 return true;
204 case kInterposeSome:
205 return fInterposeList.contains(name);
206 }
207 throw "internal error";
208 }
209
210 bool Options::needsModuleTable()
211 {
212 return fNeedsModuleTable;
213 }
214
215 bool Options::ignoreOtherArchInputFiles()
216 {
217 return fIgnoreOtherArchFiles;
218 }
219
220 bool Options::forceCpuSubtypeAll()
221 {
222 return fForceSubtypeAll;
223 }
224
225 bool Options::traceDylibs()
226 {
227 return fReaderOptions.fTraceDylibs;
228 }
229
230 bool Options::traceArchives()
231 {
232 return fReaderOptions.fTraceArchives;
233 }
234
235 Options::UndefinedTreatment Options::undefinedTreatment()
236 {
237 return fUndefinedTreatment;
238 }
239
240 Options::WeakReferenceMismatchTreatment Options::weakReferenceMismatchTreatment()
241 {
242 return fWeakReferenceMismatchTreatment;
243 }
244
245 const char* Options::umbrellaName()
246 {
247 return fUmbrellaName;
248 }
249
250 std::vector<const char*>& Options::allowableClients()
251 {
252 return fAllowableClients;
253 }
254
255 const char* Options::clientName()
256 {
257 return fClientName;
258 }
259
260 uint64_t Options::zeroPageSize()
261 {
262 return fZeroPageSize;
263 }
264
265 bool Options::hasCustomStack()
266 {
267 return (fStackSize != 0);
268 }
269
270 uint64_t Options::customStackSize()
271 {
272 return fStackSize;
273 }
274
275 uint64_t Options::customStackAddr()
276 {
277 return fStackAddr;
278 }
279
280 bool Options::hasExecutableStack()
281 {
282 return fExecutableStack;
283 }
284
285 std::vector<const char*>& Options::initialUndefines()
286 {
287 return fInitialUndefines;
288 }
289
290 bool Options::printWhyLive(const char* symbolName)
291 {
292 return ( fWhyLive.find(symbolName) != fWhyLive.end() );
293 }
294
295
296 const char* Options::initFunctionName()
297 {
298 return fInitFunctionName;
299 }
300
301 const char* Options::dotOutputFile()
302 {
303 return fDotOutputFile;
304 }
305
306 bool Options::hasExportRestrictList()
307 {
308 return (fExportMode != kExportDefault);
309 }
310
311 bool Options::hasExportMaskList()
312 {
313 return (fExportMode == kExportSome);
314 }
315
316
317 bool Options::hasWildCardExportRestrictList()
318 {
319 // has -exported_symbols_list which contains some wildcards
320 return ((fExportMode == kExportSome) && fExportSymbols.hasWildCards());
321 }
322
323
324 bool Options::allGlobalsAreDeadStripRoots()
325 {
326 // -exported_symbols_list means globals are not exported by default
327 if ( fExportMode == kExportSome )
328 return false;
329 //
330 switch ( fOutputKind ) {
331 case Options::kDynamicExecutable:
332 case Options::kStaticExecutable:
333 case Options::kPreload:
334 // by default unused globals in a main executable are stripped
335 return false;
336 case Options::kDynamicLibrary:
337 case Options::kDynamicBundle:
338 case Options::kObjectFile:
339 case Options::kDyld:
340 case Options::kKextBundle:
341 return true;
342 }
343 return false;
344 }
345
346 uint32_t Options::minimumHeaderPad()
347 {
348 return fMinimumHeaderPad;
349 }
350
351 std::vector<Options::ExtraSection>& Options::extraSections()
352 {
353 return fExtraSections;
354 }
355
356 std::vector<Options::SectionAlignment>& Options::sectionAlignments()
357 {
358 return fSectionAlignments;
359 }
360
361 Options::CommonsMode Options::commonsMode()
362 {
363 return fCommonsMode;
364 }
365
366 bool Options::warnCommons()
367 {
368 return fWarnCommons;
369 }
370
371 bool Options::keepRelocations()
372 {
373 return fKeepRelocations;
374 }
375
376 bool Options::warnStabs()
377 {
378 return fWarnStabs;
379 }
380
381 const char* Options::executablePath()
382 {
383 return fExecutablePath;
384 }
385
386 Options::DeadStripMode Options::deadStrip()
387 {
388 return fDeadStrip;
389 }
390
391 bool Options::hasExportedSymbolOrder()
392 {
393 return (fExportSymbolsOrder.size() > 0);
394 }
395
396 bool Options::exportedSymbolOrder(const char* sym, unsigned int* order)
397 {
398 NameToOrder::iterator pos = fExportSymbolsOrder.find(sym);
399 if ( pos != fExportSymbolsOrder.end() ) {
400 *order = pos->second;
401 return true;
402 }
403 else {
404 *order = 0xFFFFFFFF;
405 return false;
406 }
407 }
408
409 void Options::loadSymbolOrderFile(const char* fileOfExports, NameToOrder& orderMapping)
410 {
411 // read in whole file
412 int fd = ::open(fileOfExports, O_RDONLY, 0);
413 if ( fd == -1 )
414 throwf("can't open -exported_symbols_order file: %s", fileOfExports);
415 struct stat stat_buf;
416 ::fstat(fd, &stat_buf);
417 char* p = (char*)malloc(stat_buf.st_size);
418 if ( p == NULL )
419 throwf("can't process -exported_symbols_order file: %s", fileOfExports);
420
421 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
422 throwf("can't read -exported_symbols_order file: %s", fileOfExports);
423
424 ::close(fd);
425
426 // parse into symbols and add to hash_set
427 unsigned int count = 0;
428 char * const end = &p[stat_buf.st_size];
429 enum { lineStart, inSymbol, inComment } state = lineStart;
430 char* symbolStart = NULL;
431 for (char* s = p; s < end; ++s ) {
432 switch ( state ) {
433 case lineStart:
434 if ( *s =='#' ) {
435 state = inComment;
436 }
437 else if ( !isspace(*s) ) {
438 state = inSymbol;
439 symbolStart = s;
440 }
441 break;
442 case inSymbol:
443 if ( (*s == '\n') || (*s == '\r') ) {
444 *s = '\0';
445 // removing any trailing spaces
446 char* last = s-1;
447 while ( isspace(*last) ) {
448 *last = '\0';
449 --last;
450 }
451 orderMapping[symbolStart] = ++count;
452 symbolStart = NULL;
453 state = lineStart;
454 }
455 break;
456 case inComment:
457 if ( (*s == '\n') || (*s == '\r') )
458 state = lineStart;
459 break;
460 }
461 }
462 if ( state == inSymbol ) {
463 warning("missing line-end at end of file \"%s\"", fileOfExports);
464 int len = end-symbolStart+1;
465 char* temp = new char[len];
466 strlcpy(temp, symbolStart, len);
467
468 // remove any trailing spaces
469 char* last = &temp[len-2];
470 while ( isspace(*last) ) {
471 *last = '\0';
472 --last;
473 }
474 orderMapping[temp] = ++count;
475 }
476
477 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
478 }
479
480
481 bool Options::shouldExport(const char* symbolName)
482 {
483 switch (fExportMode) {
484 case kExportSome:
485 return fExportSymbols.contains(symbolName);
486 case kDontExportSome:
487 return ! fDontExportSymbols.contains(symbolName);
488 case kExportDefault:
489 return true;
490 }
491 throw "internal error";
492 }
493
494 bool Options::keepLocalSymbol(const char* symbolName)
495 {
496 switch (fLocalSymbolHandling) {
497 case kLocalSymbolsAll:
498 return true;
499 case kLocalSymbolsNone:
500 return false;
501 case kLocalSymbolsSelectiveInclude:
502 return fLocalSymbolsIncluded.contains(symbolName);
503 case kLocalSymbolsSelectiveExclude:
504 return ! fLocalSymbolsExcluded.contains(symbolName);
505 }
506 throw "internal error";
507 }
508
509 void Options::parseArch(const char* architecture)
510 {
511 if ( architecture == NULL )
512 throw "-arch must be followed by an architecture string";
513 if ( strcmp(architecture, "ppc") == 0 ) {
514 fArchitecture = CPU_TYPE_POWERPC;
515 fSubArchitecture = CPU_SUBTYPE_POWERPC_ALL;
516 }
517 else if ( strcmp(architecture, "ppc64") == 0 ) {
518 fArchitecture = CPU_TYPE_POWERPC64;
519 fSubArchitecture = CPU_SUBTYPE_POWERPC_ALL;
520 }
521 else if ( strcmp(architecture, "i386") == 0 ) {
522 fArchitecture = CPU_TYPE_I386;
523 fSubArchitecture = CPU_SUBTYPE_I386_ALL;
524 }
525 else if ( strcmp(architecture, "x86_64") == 0 ) {
526 fArchitecture = CPU_TYPE_X86_64;
527 fSubArchitecture = CPU_SUBTYPE_X86_64_ALL;
528 }
529 else if ( strcmp(architecture, "arm") == 0 ) {
530 fArchitecture = CPU_TYPE_ARM;
531 fSubArchitecture = CPU_SUBTYPE_ARM_ALL;
532 }
533 // compatibility support for cpu-sub-types
534 else if ( strcmp(architecture, "ppc750") == 0 ) {
535 fArchitecture = CPU_TYPE_POWERPC;
536 fSubArchitecture = CPU_SUBTYPE_POWERPC_750;
537 fHasPreferredSubType = true;
538 }
539 else if ( strcmp(architecture, "ppc7400") == 0 ) {
540 fArchitecture = CPU_TYPE_POWERPC;
541 fSubArchitecture = CPU_SUBTYPE_POWERPC_7400;
542 fHasPreferredSubType = true;
543 }
544 else if ( strcmp(architecture, "ppc7450") == 0 ) {
545 fArchitecture = CPU_TYPE_POWERPC;
546 fSubArchitecture = CPU_SUBTYPE_POWERPC_7450;
547 fHasPreferredSubType = true;
548 }
549 else if ( strcmp(architecture, "ppc970") == 0 ) {
550 fArchitecture = CPU_TYPE_POWERPC;
551 fSubArchitecture = CPU_SUBTYPE_POWERPC_970;
552 fHasPreferredSubType = true;
553 }
554 else if ( strcmp(architecture, "armv6") == 0 ) {
555 fArchitecture = CPU_TYPE_ARM;
556 fSubArchitecture = CPU_SUBTYPE_ARM_V6;
557 fHasPreferredSubType = true;
558 }
559 else if ( strcmp(architecture, "armv5") == 0 ) {
560 fArchitecture = CPU_TYPE_ARM;
561 fSubArchitecture = CPU_SUBTYPE_ARM_V5TEJ;
562 fHasPreferredSubType = true;
563 }
564 else if ( strcmp(architecture, "armv4t") == 0 ) {
565 fArchitecture = CPU_TYPE_ARM;
566 fSubArchitecture = CPU_SUBTYPE_ARM_V4T;
567 fHasPreferredSubType = true;
568 }
569 else if ( strcmp(architecture, "xscale") == 0 ) {
570 fArchitecture = CPU_TYPE_ARM;
571 fSubArchitecture = CPU_SUBTYPE_ARM_XSCALE;
572 fHasPreferredSubType = true;
573 }
574 else if ( strcmp(architecture, "armv7") == 0 ) {
575 fArchitecture = CPU_TYPE_ARM;
576 fSubArchitecture = CPU_SUBTYPE_ARM_V7;
577 fHasPreferredSubType = true;
578 }
579 else
580 throwf("unknown/unsupported architecture name for: -arch %s", architecture);
581 }
582
583 bool Options::checkForFile(const char* format, const char* dir, const char* rootName, FileInfo& result)
584 {
585 struct stat statBuffer;
586 char possiblePath[strlen(dir)+strlen(rootName)+strlen(format)+8];
587 sprintf(possiblePath, format, dir, rootName);
588 bool found = (stat(possiblePath, &statBuffer) == 0);
589 if ( fTraceDylibSearching )
590 printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), possiblePath);
591 if ( found ) {
592 result.path = strdup(possiblePath);
593 result.fileLen = statBuffer.st_size;
594 result.modTime = statBuffer.st_mtime;
595 return true;
596 }
597 return false;
598 }
599
600
601 Options::FileInfo Options::findLibrary(const char* rootName, bool dylibsOnly)
602 {
603 FileInfo result;
604 const int rootNameLen = strlen(rootName);
605 // if rootName ends in .o there is no .a vs .dylib choice
606 if ( (rootNameLen > 3) && (strcmp(&rootName[rootNameLen-2], ".o") == 0) ) {
607 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
608 it != fLibrarySearchPaths.end();
609 it++) {
610 const char* dir = *it;
611 if ( checkForFile("%s/%s", dir, rootName, result) )
612 return result;
613 }
614 }
615 else {
616 bool lookForDylibs = ( fOutputKind != Options::kDyld);
617 switch ( fLibrarySearchMode ) {
618 case kSearchAllDirsForDylibsThenAllDirsForArchives:
619 // first look in all directories for just for dylibs
620 if ( lookForDylibs ) {
621 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
622 it != fLibrarySearchPaths.end();
623 it++) {
624 const char* dir = *it;
625 if ( checkForFile("%s/lib%s.dylib", dir, rootName, result) )
626 return result;
627 }
628 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
629 it != fLibrarySearchPaths.end();
630 it++) {
631 const char* dir = *it;
632 if ( checkForFile("%s/lib%s.so", dir, rootName, result) )
633 return result;
634 }
635 }
636 // next look in all directories for just for archives
637 if ( !dylibsOnly ) {
638 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
639 it != fLibrarySearchPaths.end();
640 it++) {
641 const char* dir = *it;
642 if ( checkForFile("%s/lib%s.a", dir, rootName, result) )
643 return result;
644 }
645 }
646 break;
647
648 case kSearchDylibAndArchiveInEachDir:
649 // look in each directory for just for a dylib then for an archive
650 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
651 it != fLibrarySearchPaths.end();
652 it++) {
653 const char* dir = *it;
654 if ( lookForDylibs && checkForFile("%s/lib%s.dylib", dir, rootName, result) )
655 return result;
656 if ( lookForDylibs && checkForFile("%s/lib%s.so", dir, rootName, result) )
657 return result;
658 if ( !dylibsOnly && checkForFile("%s/lib%s.a", dir, rootName, result) )
659 return result;
660 }
661 break;
662 }
663 }
664 throwf("library not found for -l%s", rootName);
665 }
666
667 Options::FileInfo Options::findFramework(const char* frameworkName)
668 {
669 if ( frameworkName == NULL )
670 throw "-framework missing next argument";
671 char temp[strlen(frameworkName)+1];
672 strcpy(temp, frameworkName);
673 const char* name = temp;
674 const char* suffix = NULL;
675 char* comma = strchr(temp, ',');
676 if ( comma != NULL ) {
677 *comma = '\0';
678 suffix = &comma[1];
679 }
680 return findFramework(name, suffix);
681 }
682
683 Options::FileInfo Options::findFramework(const char* rootName, const char* suffix)
684 {
685 struct stat statBuffer;
686 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
687 it != fFrameworkSearchPaths.end();
688 it++) {
689 // ??? Shouldn't we be using String here and just initializing it?
690 // ??? Use str.c_str () to pull out the string for the stat call.
691 const char* dir = *it;
692 char possiblePath[PATH_MAX];
693 strcpy(possiblePath, dir);
694 strcat(possiblePath, "/");
695 strcat(possiblePath, rootName);
696 strcat(possiblePath, ".framework/");
697 strcat(possiblePath, rootName);
698 if ( suffix != NULL ) {
699 char realPath[PATH_MAX];
700 // no symlink in framework to suffix variants, so follow main symlink
701 if ( realpath(possiblePath, realPath) != NULL ) {
702 strcpy(possiblePath, realPath);
703 strcat(possiblePath, suffix);
704 }
705 }
706 bool found = (stat(possiblePath, &statBuffer) == 0);
707 if ( fTraceDylibSearching )
708 printf("[Logging for XBS]%sfound framework: '%s'\n",
709 (found ? " " : " not "), possiblePath);
710 if ( found ) {
711 FileInfo result;
712 result.path = strdup(possiblePath);
713 result.fileLen = statBuffer.st_size;
714 result.modTime = statBuffer.st_mtime;
715 return result;
716 }
717 }
718 // try without suffix
719 if ( suffix != NULL )
720 return findFramework(rootName, NULL);
721 else
722 throwf("framework not found %s", rootName);
723 }
724
725 Options::FileInfo Options::findFile(const char* path)
726 {
727 FileInfo result;
728 struct stat statBuffer;
729
730 // if absolute path and not a .o file, the use SDK prefix
731 if ( (path[0] == '/') && (strcmp(&path[strlen(path)-2], ".o") != 0) ) {
732 const int pathLen = strlen(path);
733 for (std::vector<const char*>::iterator it = fSDKPaths.begin(); it != fSDKPaths.end(); it++) {
734 // ??? Shouldn't we be using String here?
735 const char* sdkPathDir = *it;
736 const int sdkPathDirLen = strlen(sdkPathDir);
737 char possiblePath[sdkPathDirLen+pathLen+4];
738 strcpy(possiblePath, sdkPathDir);
739 if ( possiblePath[sdkPathDirLen-1] == '/' )
740 possiblePath[sdkPathDirLen-1] = '\0';
741 strcat(possiblePath, path);
742 if ( stat(possiblePath, &statBuffer) == 0 ) {
743 result.path = strdup(possiblePath);
744 result.fileLen = statBuffer.st_size;
745 result.modTime = statBuffer.st_mtime;
746 return result;
747 }
748 }
749 }
750 // try raw path
751 if ( stat(path, &statBuffer) == 0 ) {
752 result.path = strdup(path);
753 result.fileLen = statBuffer.st_size;
754 result.modTime = statBuffer.st_mtime;
755 return result;
756 }
757
758 // try @executable_path substitution
759 if ( (strncmp(path, "@executable_path/", 17) == 0) && (fExecutablePath != NULL) ) {
760 char newPath[strlen(fExecutablePath) + strlen(path)];
761 strcpy(newPath, fExecutablePath);
762 char* addPoint = strrchr(newPath,'/');
763 if ( addPoint != NULL )
764 strcpy(&addPoint[1], &path[17]);
765 else
766 strcpy(newPath, &path[17]);
767 if ( stat(newPath, &statBuffer) == 0 ) {
768 result.path = strdup(newPath);
769 result.fileLen = statBuffer.st_size;
770 result.modTime = statBuffer.st_mtime;
771 return result;
772 }
773 }
774
775 // not found
776 throwf("file not found: %s", path);
777 }
778
779 Options::FileInfo Options::findFileUsingPaths(const char* path)
780 {
781 FileInfo result;
782
783 const char* lastSlash = strrchr(path, '/');
784 const char* leafName = (lastSlash == NULL) ? path : &lastSlash[1];
785
786 // Is this in a framework?
787 // /path/Foo.framework/Foo ==> true (Foo)
788 // /path/Foo.framework/Frameworks/Bar.framework/Bar ==> true (Bar)
789 // /path/Foo.framework/Resources/Bar ==> false
790 bool isFramework = false;
791 if ( lastSlash != NULL ) {
792 char frameworkDir[strlen(leafName) + 20];
793 strcpy(frameworkDir, "/");
794 strcat(frameworkDir, leafName);
795 strcat(frameworkDir, ".framework/");
796 if ( strstr(path, frameworkDir) != NULL )
797 isFramework = true;
798 }
799
800 // These are abbreviated versions of the routines findFramework and findLibrary above
801 // because we already know the final name of the file that we're looking for and so
802 // don't need to try variations, just paths. We do need to add the additional bits
803 // onto the framework path though.
804 if ( isFramework ) {
805 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
806 it != fFrameworkSearchPaths.end();
807 it++) {
808 const char* dir = *it;
809 char possiblePath[PATH_MAX];
810 strcpy(possiblePath, dir);
811 strcat(possiblePath, "/");
812 strcat(possiblePath, leafName);
813 strcat(possiblePath, ".framework");
814
815 //fprintf(stderr,"Finding Framework: %s/%s, leafName=%s\n", possiblePath, leafName, leafName);
816 if ( checkForFile("%s/%s", possiblePath, leafName, result) )
817 return result;
818 }
819 }
820 else {
821 // if this is a .dylib inside a framework, do not search -L paths
822 // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
823 int leafLen = strlen(leafName);
824 bool embeddedDylib = ( (leafLen > 6)
825 && (strcmp(&leafName[leafLen-6], ".dylib") == 0)
826 && (strstr(path, ".framework/") != NULL) );
827 if ( !embeddedDylib ) {
828 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
829 it != fLibrarySearchPaths.end();
830 it++) {
831 const char* dir = *it;
832 //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
833 if ( checkForFile("%s/%s", dir, leafName, result) )
834 return result;
835 }
836 }
837 }
838
839 // If we didn't find it fall back to findFile.
840 return findFile(path);
841 }
842
843
844 void Options::parseSegAddrTable(const char* segAddrPath, const char* installPath)
845 {
846 FILE* file = fopen(segAddrPath, "r");
847 if ( file == NULL ) {
848 warning("-seg_addr_table file cannot be read: %s", segAddrPath);
849 return;
850 }
851
852 char path[PATH_MAX];
853 uint64_t firstColumAddress = 0;
854 uint64_t secondColumAddress = 0;
855 bool hasSecondColumn = false;
856 while ( fgets(path, PATH_MAX, file) != NULL ) {
857 path[PATH_MAX-1] = '\0';
858 char* eol = strchr(path, '\n');
859 if ( eol != NULL )
860 *eol = '\0';
861 // ignore lines not starting with 0x number
862 if ( (path[0] == '0') && (path[1] == 'x') ) {
863 char* p;
864 firstColumAddress = strtoull(path, &p, 16);
865 while ( isspace(*p) )
866 ++p;
867 // see if second column is a number
868 if ( (p[0] == '0') && (p[1] == 'x') ) {
869 secondColumAddress = strtoull(p, &p, 16);
870 hasSecondColumn = true;
871 while ( isspace(*p) )
872 ++p;
873 }
874 while ( isspace(*p) )
875 ++p;
876 if ( p[0] == '/' ) {
877 // remove any trailing whitespace
878 for(char* end = eol-1; (end > p) && isspace(*end); --end)
879 *end = '\0';
880 // see if this line is for the dylib being linked
881 if ( strcmp(p, installPath) == 0 ) {
882 fBaseAddress = firstColumAddress;
883 if ( hasSecondColumn ) {
884 fBaseWritableAddress = secondColumAddress;
885 fSplitSegs = true;
886 }
887 break; // out of while loop
888 }
889 }
890 }
891 }
892
893 fclose(file);
894 }
895
896 void Options::loadFileList(const char* fileOfPaths)
897 {
898 FILE* file;
899 const char* comma = strrchr(fileOfPaths, ',');
900 const char* prefix = NULL;
901 if ( comma != NULL ) {
902 // <rdar://problem/5907981> -filelist fails with comma in path
903 file = fopen(fileOfPaths, "r");
904 if ( file == NULL ) {
905 prefix = comma+1;
906 int realFileOfPathsLen = comma-fileOfPaths;
907 char realFileOfPaths[realFileOfPathsLen+1];
908 strncpy(realFileOfPaths,fileOfPaths, realFileOfPathsLen);
909 realFileOfPaths[realFileOfPathsLen] = '\0';
910 file = fopen(realFileOfPaths, "r");
911 if ( file == NULL )
912 throwf("-filelist file not found: %s\n", realFileOfPaths);
913 }
914 }
915 else {
916 file = fopen(fileOfPaths, "r");
917 if ( file == NULL )
918 throwf("-filelist file not found: %s\n", fileOfPaths);
919 }
920
921 char path[PATH_MAX];
922 while ( fgets(path, PATH_MAX, file) != NULL ) {
923 path[PATH_MAX-1] = '\0';
924 char* eol = strchr(path, '\n');
925 if ( eol != NULL )
926 *eol = '\0';
927 if ( prefix != NULL ) {
928 char builtPath[strlen(prefix)+strlen(path)+2];
929 strcpy(builtPath, prefix);
930 strcat(builtPath, "/");
931 strcat(builtPath, path);
932 fInputFiles.push_back(findFile(builtPath));
933 }
934 else {
935 fInputFiles.push_back(findFile(path));
936 }
937 }
938 fclose(file);
939 }
940
941 bool Options::SetWithWildcards::hasWildCards(const char* symbol)
942 {
943 // an exported symbol name containing *, ?, or [ requires wildcard matching
944 return ( strpbrk(symbol, "*?[") != NULL );
945 }
946
947 void Options::SetWithWildcards::insert(const char* symbol)
948 {
949 if ( hasWildCards(symbol) )
950 fWildCard.push_back(symbol);
951 else
952 fRegular.insert(symbol);
953 }
954
955 bool Options::SetWithWildcards::contains(const char* symbol)
956 {
957 // first look at hash table on non-wildcard symbols
958 if ( fRegular.find(symbol) != fRegular.end() )
959 return true;
960 // next walk list of wild card symbols looking for a match
961 for(std::vector<const char*>::iterator it = fWildCard.begin(); it != fWildCard.end(); ++it) {
962 if ( wildCardMatch(*it, symbol) )
963 return true;
964 }
965 return false;
966 }
967
968
969 bool Options::SetWithWildcards::inCharRange(const char*& p, unsigned char c)
970 {
971 ++p; // find end
972 const char* b = p;
973 while ( *p != '\0' ) {
974 if ( *p == ']') {
975 const char* e = p;
976 // found beginining [ and ending ]
977 unsigned char last = '\0';
978 for ( const char* s = b; s < e; ++s ) {
979 if ( *s == '-' ) {
980 unsigned char next = *(++s);
981 if ( (last <= c) && (c <= next) )
982 return true;
983 ++s;
984 }
985 else {
986 if ( *s == c )
987 return true;
988 last = *s;
989 }
990 }
991 return false;
992 }
993 ++p;
994 }
995 return false;
996 }
997
998 bool Options::SetWithWildcards::wildCardMatch(const char* pattern, const char* symbol)
999 {
1000 const char* s = symbol;
1001 for (const char* p = pattern; *p != '\0'; ++p) {
1002 switch ( *p ) {
1003 case '*':
1004 if ( p[1] == '\0' )
1005 return true;
1006 for (const char* t = s; *t != '\0'; ++t) {
1007 if ( wildCardMatch(&p[1], t) )
1008 return true;
1009 }
1010 return false;
1011 case '?':
1012 if ( *s == '\0' )
1013 return false;
1014 ++s;
1015 break;
1016 case '[':
1017 if ( ! inCharRange(p, *s) )
1018 return false;
1019 ++s;
1020 break;
1021 default:
1022 if ( *s != *p )
1023 return false;
1024 ++s;
1025 }
1026 }
1027 return (*s == '\0');
1028 }
1029
1030
1031 void Options::loadExportFile(const char* fileOfExports, const char* option, SetWithWildcards& set)
1032 {
1033 // read in whole file
1034 int fd = ::open(fileOfExports, O_RDONLY, 0);
1035 if ( fd == -1 )
1036 throwf("can't open %s file: %s", option, fileOfExports);
1037 struct stat stat_buf;
1038 ::fstat(fd, &stat_buf);
1039 char* p = (char*)malloc(stat_buf.st_size);
1040 if ( p == NULL )
1041 throwf("can't process %s file: %s", option, fileOfExports);
1042
1043 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1044 throwf("can't read %s file: %s", option, fileOfExports);
1045
1046 ::close(fd);
1047
1048 // parse into symbols and add to hash_set
1049 char * const end = &p[stat_buf.st_size];
1050 enum { lineStart, inSymbol, inComment } state = lineStart;
1051 char* symbolStart = NULL;
1052 for (char* s = p; s < end; ++s ) {
1053 switch ( state ) {
1054 case lineStart:
1055 if ( *s =='#' ) {
1056 state = inComment;
1057 }
1058 else if ( !isspace(*s) ) {
1059 state = inSymbol;
1060 symbolStart = s;
1061 }
1062 break;
1063 case inSymbol:
1064 if ( (*s == '\n') || (*s == '\r') ) {
1065 *s = '\0';
1066 // removing any trailing spaces
1067 char* last = s-1;
1068 while ( isspace(*last) ) {
1069 *last = '\0';
1070 --last;
1071 }
1072 set.insert(symbolStart);
1073 symbolStart = NULL;
1074 state = lineStart;
1075 }
1076 break;
1077 case inComment:
1078 if ( (*s == '\n') || (*s == '\r') )
1079 state = lineStart;
1080 break;
1081 }
1082 }
1083 if ( state == inSymbol ) {
1084 warning("missing line-end at end of file \"%s\"", fileOfExports);
1085 int len = end-symbolStart+1;
1086 char* temp = new char[len];
1087 strlcpy(temp, symbolStart, len);
1088
1089 // remove any trailing spaces
1090 char* last = &temp[len-2];
1091 while ( isspace(*last) ) {
1092 *last = '\0';
1093 --last;
1094 }
1095 set.insert(temp);
1096 }
1097
1098 // Note: we do not free() the malloc buffer, because the strings are used by the export-set hash table
1099 }
1100
1101 void Options::parseAliasFile(const char* fileOfAliases)
1102 {
1103 // read in whole file
1104 int fd = ::open(fileOfAliases, O_RDONLY, 0);
1105 if ( fd == -1 )
1106 throwf("can't open alias file: %s", fileOfAliases);
1107 struct stat stat_buf;
1108 ::fstat(fd, &stat_buf);
1109 char* p = (char*)malloc(stat_buf.st_size+1);
1110 if ( p == NULL )
1111 throwf("can't process alias file: %s", fileOfAliases);
1112
1113 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1114 throwf("can't read alias file: %s", fileOfAliases);
1115 p[stat_buf.st_size] = '\n';
1116 ::close(fd);
1117
1118 // parse into symbols and add to fAliases
1119 ObjectFile::ReaderOptions::AliasPair pair;
1120 char * const end = &p[stat_buf.st_size+1];
1121 enum { lineStart, inRealName, inBetween, inAliasName, inComment } state = lineStart;
1122 int lineNumber = 1;
1123 for (char* s = p; s < end; ++s ) {
1124 switch ( state ) {
1125 case lineStart:
1126 if ( *s =='#' ) {
1127 state = inComment;
1128 }
1129 else if ( !isspace(*s) ) {
1130 state = inRealName;
1131 pair.realName = s;
1132 }
1133 break;
1134 case inRealName:
1135 if ( *s == '\n' ) {
1136 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
1137 ++lineNumber;
1138 state = lineStart;
1139 }
1140 else if ( isspace(*s) ) {
1141 *s = '\0';
1142 state = inBetween;
1143 }
1144 break;
1145 case inBetween:
1146 if ( *s == '\n' ) {
1147 warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
1148 ++lineNumber;
1149 state = lineStart;
1150 }
1151 else if ( ! isspace(*s) ) {
1152 state = inAliasName;
1153 pair.alias = s;
1154 }
1155 break;
1156 case inAliasName:
1157 if ( *s =='#' ) {
1158 *s = '\0';
1159 // removing any trailing spaces
1160 char* last = s-1;
1161 while ( isspace(*last) ) {
1162 *last = '\0';
1163 --last;
1164 }
1165 fReaderOptions.fAliases.push_back(pair);
1166 state = inComment;
1167 }
1168 else if ( *s == '\n' ) {
1169 *s = '\0';
1170 // removing any trailing spaces
1171 char* last = s-1;
1172 while ( isspace(*last) ) {
1173 *last = '\0';
1174 --last;
1175 }
1176 fReaderOptions.fAliases.push_back(pair);
1177 state = lineStart;
1178 }
1179 break;
1180 case inComment:
1181 if ( *s == '\n' )
1182 state = lineStart;
1183 break;
1184 }
1185 }
1186
1187 // Note: we do not free() the malloc buffer, because the strings therein are used by fAliases
1188 }
1189
1190
1191
1192 void Options::setUndefinedTreatment(const char* treatment)
1193 {
1194 if ( treatment == NULL )
1195 throw "-undefined missing [ warning | error | suppress | dynamic_lookup ]";
1196
1197 if ( strcmp(treatment, "warning") == 0 )
1198 fUndefinedTreatment = kUndefinedWarning;
1199 else if ( strcmp(treatment, "error") == 0 )
1200 fUndefinedTreatment = kUndefinedError;
1201 else if ( strcmp(treatment, "suppress") == 0 )
1202 fUndefinedTreatment = kUndefinedSuppress;
1203 else if ( strcmp(treatment, "dynamic_lookup") == 0 )
1204 fUndefinedTreatment = kUndefinedDynamicLookup;
1205 else
1206 throw "invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]";
1207 }
1208
1209 Options::Treatment Options::parseTreatment(const char* treatment)
1210 {
1211 if ( treatment == NULL )
1212 return kNULL;
1213
1214 if ( strcmp(treatment, "warning") == 0 )
1215 return kWarning;
1216 else if ( strcmp(treatment, "error") == 0 )
1217 return kError;
1218 else if ( strcmp(treatment, "suppress") == 0 )
1219 return kSuppress;
1220 else
1221 return kInvalid;
1222 }
1223
1224 void Options::setMacOSXVersionMin(const char* version)
1225 {
1226 if ( version == NULL )
1227 throw "-macosx_version_min argument missing";
1228
1229 if ( (strncmp(version, "10.", 3) == 0) && isdigit(version[3]) ) {
1230 int num = version[3] - '0';
1231 switch ( num ) {
1232 case 0:
1233 case 1:
1234 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_1;
1235 break;
1236 case 2:
1237 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_2;
1238 break;
1239 case 3:
1240 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_3;
1241 break;
1242 case 4:
1243 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_4;
1244 break;
1245 case 5:
1246 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_5;
1247 break;
1248 case 6:
1249 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_6;
1250 break;
1251 default:
1252 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_6;
1253 break;
1254 }
1255 }
1256 else {
1257 warning("unknown option to -macosx_version_min, not 10.x");
1258 }
1259 }
1260
1261 void Options::setIPhoneVersionMin(const char* version)
1262 {
1263 if ( version == NULL )
1264 throw "-iphoneos_version_min argument missing";
1265 if ( ! isdigit(version[0]) )
1266 throw "-iphoneos_version_min argument is not a number";
1267 if ( version[1] != '.' )
1268 throw "-iphoneos_version_min argument is missing period as second character";
1269 if ( ! isdigit(version[2]) )
1270 throw "-iphoneos_version_min argument is not a number";
1271
1272 if ( version[0] == '2' )
1273 fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
1274 else if ( (version[0] == '3') && (version[2] == '0') )
1275 fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
1276 else if ( (version[0] == '3') && (version[2] >= '1') )
1277 fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k3_1;
1278 else if ( (version[0] >= '4') )
1279 fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k3_1;
1280 else {
1281 fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
1282 warning("unknown option to -iphoneos_version_min, not 2.x, 3.x, or 4.x");
1283 }
1284 }
1285
1286 bool Options::minOS(ObjectFile::ReaderOptions::MacVersionMin requiredMacMin, ObjectFile::ReaderOptions::IPhoneVersionMin requirediPhoneOSMin)
1287 {
1288 if ( fReaderOptions.fMacVersionMin != ObjectFile::ReaderOptions::kMinMacVersionUnset ) {
1289 return ( fReaderOptions.fMacVersionMin >= requiredMacMin );
1290 }
1291 else {
1292 return ( fReaderOptions.fIPhoneVersionMin >= requirediPhoneOSMin);
1293 }
1294 }
1295
1296
1297 void Options::setWeakReferenceMismatchTreatment(const char* treatment)
1298 {
1299 if ( treatment == NULL )
1300 throw "-weak_reference_mismatches missing [ error | weak | non-weak ]";
1301
1302 if ( strcmp(treatment, "error") == 0 )
1303 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchError;
1304 else if ( strcmp(treatment, "weak") == 0 )
1305 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchWeak;
1306 else if ( strcmp(treatment, "non-weak") == 0 )
1307 fWeakReferenceMismatchTreatment = kWeakReferenceMismatchNonWeak;
1308 else
1309 throw "invalid option to -weak_reference_mismatches [ error | weak | non-weak ]";
1310 }
1311
1312 Options::CommonsMode Options::parseCommonsTreatment(const char* mode)
1313 {
1314 if ( mode == NULL )
1315 throw "-commons missing [ ignore_dylibs | use_dylibs | error ]";
1316
1317 if ( strcmp(mode, "ignore_dylibs") == 0 )
1318 return kCommonsIgnoreDylibs;
1319 else if ( strcmp(mode, "use_dylibs") == 0 )
1320 return kCommonsOverriddenByDylibs;
1321 else if ( strcmp(mode, "error") == 0 )
1322 return kCommonsConflictsDylibsError;
1323 else
1324 throw "invalid option to -commons [ ignore_dylibs | use_dylibs | error ]";
1325 }
1326
1327 void Options::addDylibOverride(const char* paths)
1328 {
1329 if ( paths == NULL )
1330 throw "-dylib_file must followed by two colon separated paths";
1331 const char* colon = strchr(paths, ':');
1332 if ( colon == NULL )
1333 throw "-dylib_file must followed by two colon separated paths";
1334 int len = colon-paths;
1335 char* target = new char[len+2];
1336 strncpy(target, paths, len);
1337 target[len] = '\0';
1338 DylibOverride entry;
1339 entry.installName = target;
1340 entry.useInstead = &colon[1];
1341 fDylibOverrides.push_back(entry);
1342 }
1343
1344 uint64_t Options::parseAddress(const char* addr)
1345 {
1346 char* endptr;
1347 uint64_t result = strtoull(addr, &endptr, 16);
1348 return result;
1349 }
1350
1351 uint32_t Options::parseProtection(const char* prot)
1352 {
1353 uint32_t result = 0;
1354 for(const char* p = prot; *p != '\0'; ++p) {
1355 switch(tolower(*p)) {
1356 case 'r':
1357 result |= VM_PROT_READ;
1358 break;
1359 case 'w':
1360 result |= VM_PROT_WRITE;
1361 break;
1362 case 'x':
1363 result |= VM_PROT_EXECUTE;
1364 break;
1365 case '-':
1366 break;
1367 default:
1368 throwf("unknown -segprot lettter in %s", prot);
1369 }
1370 }
1371 return result;
1372 }
1373
1374
1375
1376 //
1377 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
1378 //
1379 //
1380 uint32_t Options::parseVersionNumber(const char* versionString)
1381 {
1382 unsigned long x = 0;
1383 unsigned long y = 0;
1384 unsigned long z = 0;
1385 char* end;
1386 x = strtoul(versionString, &end, 10);
1387 if ( *end == '.' ) {
1388 y = strtoul(&end[1], &end, 10);
1389 if ( *end == '.' ) {
1390 z = strtoul(&end[1], &end, 10);
1391 }
1392 }
1393 if ( (*end != '\0') || (x > 0xffff) || (y > 0xff) || (z > 0xff) )
1394 throwf("malformed version number: %s", versionString);
1395
1396 return (x << 16) | ( y << 8 ) | z;
1397 }
1398
1399 static const char* cstringSymbolName(const char* orderFileString)
1400 {
1401 char* result;
1402 asprintf(&result, "cstring=%s", orderFileString);
1403 // convert escaped characters
1404 char* d = result;
1405 for(const char* s=result; *s != '\0'; ++s, ++d) {
1406 if ( *s == '\\' ) {
1407 ++s;
1408 switch ( *s ) {
1409 case 'n':
1410 *d = '\n';
1411 break;
1412 case 't':
1413 *d = '\t';
1414 break;
1415 case 'v':
1416 *d = '\v';
1417 break;
1418 case 'b':
1419 *d = '\b';
1420 break;
1421 case 'r':
1422 *d = '\r';
1423 break;
1424 case 'f':
1425 *d = '\f';
1426 break;
1427 case 'a':
1428 *d = '\a';
1429 break;
1430 case '\\':
1431 *d = '\\';
1432 break;
1433 case '?':
1434 *d = '\?';
1435 break;
1436 case '\'':
1437 *d = '\r';
1438 break;
1439 case '\"':
1440 *d = '\"';
1441 break;
1442 case 'x':
1443 // hexadecimal value of char
1444 {
1445 ++s;
1446 char value = 0;
1447 while ( isxdigit(*s) ) {
1448 value *= 16;
1449 if ( isdigit(*s) )
1450 value += (*s-'0');
1451 else
1452 value += ((toupper(*s)-'A') + 10);
1453 ++s;
1454 }
1455 *d = value;
1456 }
1457 break;
1458 default:
1459 if ( isdigit(*s) ) {
1460 // octal value of char
1461 char value = 0;
1462 while ( isdigit(*s) ) {
1463 value = (value << 3) + (*s-'0');
1464 ++s;
1465 }
1466 *d = value;
1467 }
1468 }
1469 }
1470 else {
1471 *d = *s;
1472 }
1473 }
1474 *d = '\0';
1475 return result;
1476 }
1477
1478 void Options::parseOrderFile(const char* path, bool cstring)
1479 {
1480 // order files override auto-ordering
1481 fReaderOptions.fAutoOrderInitializers = false;
1482
1483 // read in whole file
1484 int fd = ::open(path, O_RDONLY, 0);
1485 if ( fd == -1 )
1486 throwf("can't open order file: %s", path);
1487 struct stat stat_buf;
1488 ::fstat(fd, &stat_buf);
1489 char* p = (char*)malloc(stat_buf.st_size+1);
1490 if ( p == NULL )
1491 throwf("can't process order file: %s", path);
1492 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1493 throwf("can't read order file: %s", path);
1494 ::close(fd);
1495 p[stat_buf.st_size] = '\n';
1496
1497 // parse into vector of pairs
1498 char * const end = &p[stat_buf.st_size+1];
1499 enum { lineStart, inSymbol, inComment } state = lineStart;
1500 char* symbolStart = NULL;
1501 for (char* s = p; s < end; ++s ) {
1502 switch ( state ) {
1503 case lineStart:
1504 if ( *s =='#' ) {
1505 state = inComment;
1506 }
1507 else if ( !isspace(*s) || cstring ) {
1508 state = inSymbol;
1509 symbolStart = s;
1510 }
1511 break;
1512 case inSymbol:
1513 if ( (*s == '\n') || (!cstring && (*s == '#')) ) {
1514 bool wasComment = (*s == '#');
1515 *s = '\0';
1516 // removing any trailing spaces
1517 char* last = s-1;
1518 while ( isspace(*last) ) {
1519 *last = '\0';
1520 --last;
1521 }
1522 if ( strncmp(symbolStart, "ppc:", 4) == 0 ) {
1523 if ( fArchitecture == CPU_TYPE_POWERPC )
1524 symbolStart = &symbolStart[4];
1525 else
1526 symbolStart = NULL;
1527 }
1528 // if there is an architecture prefix, only use this symbol it if matches current arch
1529 else if ( strncmp(symbolStart, "ppc64:", 6) == 0 ) {
1530 if ( fArchitecture == CPU_TYPE_POWERPC64 )
1531 symbolStart = &symbolStart[6];
1532 else
1533 symbolStart = NULL;
1534 }
1535 else if ( strncmp(symbolStart, "i386:", 5) == 0 ) {
1536 if ( fArchitecture == CPU_TYPE_I386 )
1537 symbolStart = &symbolStart[5];
1538 else
1539 symbolStart = NULL;
1540 }
1541 else if ( strncmp(symbolStart, "x86_64:", 7) == 0 ) {
1542 if ( fArchitecture == CPU_TYPE_X86_64 )
1543 symbolStart = &symbolStart[7];
1544 else
1545 symbolStart = NULL;
1546 }
1547 else if ( strncmp(symbolStart, "arm:", 4) == 0 ) {
1548 if ( fArchitecture == CPU_TYPE_ARM )
1549 symbolStart = &symbolStart[4];
1550 else
1551 symbolStart = NULL;
1552 }
1553 if ( symbolStart != NULL ) {
1554 char* objFileName = NULL;
1555 char* colon = strstr(symbolStart, ".o:");
1556 if ( colon != NULL ) {
1557 colon[2] = '\0';
1558 objFileName = symbolStart;
1559 symbolStart = &colon[3];
1560 }
1561 // trim leading spaces
1562 while ( isspace(*symbolStart) )
1563 ++symbolStart;
1564 Options::OrderedSymbol pair;
1565 if ( cstring )
1566 pair.symbolName = cstringSymbolName(symbolStart);
1567 else
1568 pair.symbolName = symbolStart;
1569 pair.objectFileName = objFileName;
1570 fOrderedSymbols.push_back(pair);
1571 }
1572 symbolStart = NULL;
1573 if ( wasComment )
1574 state = inComment;
1575 else
1576 state = lineStart;
1577 }
1578 break;
1579 case inComment:
1580 if ( *s == '\n' )
1581 state = lineStart;
1582 break;
1583 }
1584 }
1585 // Note: we do not free() the malloc buffer, because the strings are used by the fOrderedSymbols
1586 }
1587
1588 void Options::parseSectionOrderFile(const char* segment, const char* section, const char* path)
1589 {
1590 if ( (strcmp(section, "__cstring") == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1591 parseOrderFile(path, true);
1592 }
1593 else if ( (strncmp(section, "__literal",9) == 0) && (strcmp(segment, "__TEXT") == 0) ) {
1594 warning("sorting of __literal[4,8,16] sections not supported");
1595 }
1596 else {
1597 // ignore section information and append all symbol names to global order file
1598 parseOrderFile(path, false);
1599 }
1600 }
1601
1602 void Options::addSection(const char* segment, const char* section, const char* path)
1603 {
1604 if ( strlen(segment) > 16 )
1605 throw "-seccreate segment name max 16 chars";
1606 if ( strlen(section) > 16 ) {
1607 char* tmp = strdup(section);
1608 tmp[16] = '\0';
1609 warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section, tmp);
1610 section = tmp;
1611 }
1612
1613 // read in whole file
1614 int fd = ::open(path, O_RDONLY, 0);
1615 if ( fd == -1 )
1616 throwf("can't open -sectcreate file: %s", path);
1617 struct stat stat_buf;
1618 ::fstat(fd, &stat_buf);
1619 char* p = (char*)malloc(stat_buf.st_size);
1620 if ( p == NULL )
1621 throwf("can't process -sectcreate file: %s", path);
1622 if ( read(fd, p, stat_buf.st_size) != stat_buf.st_size )
1623 throwf("can't read -sectcreate file: %s", path);
1624 ::close(fd);
1625
1626 // record section to create
1627 ExtraSection info = { segment, section, path, (uint8_t*)p, stat_buf.st_size };
1628 fExtraSections.push_back(info);
1629 }
1630
1631 void Options::addSectionAlignment(const char* segment, const char* section, const char* alignmentStr)
1632 {
1633 if ( strlen(segment) > 16 )
1634 throw "-sectalign segment name max 16 chars";
1635 if ( strlen(section) > 16 )
1636 throw "-sectalign section name max 16 chars";
1637
1638 // argument to -sectalign is a hexadecimal number
1639 char* endptr;
1640 unsigned long value = strtoul(alignmentStr, &endptr, 16);
1641 if ( *endptr != '\0')
1642 throw "argument for -sectalign is not a hexadecimal number";
1643 if ( value > 0x8000 )
1644 throw "argument for -sectalign must be less than or equal to 0x8000";
1645 if ( value == 0 ) {
1646 warning("zero is not a valid -sectalign");
1647 value = 1;
1648 }
1649
1650 // alignment is power of 2 (e.g. page alignment = 12)
1651 uint8_t alignment = (uint8_t)__builtin_ctz(value);
1652 if ( (unsigned long)(1 << alignment) != value ) {
1653 warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
1654 segment, section, 1 << alignment);
1655 }
1656
1657 SectionAlignment info = { segment, section, alignment };
1658 fSectionAlignments.push_back(info);
1659 }
1660
1661 void Options::addLibrary(const FileInfo& info)
1662 {
1663 // if this library has already been added, don't add again (archives are automatically repeatedly searched)
1664 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
1665 if ( strcmp(info.path, fit->path) == 0 ) {
1666 // if dylib is specified again but weak, record that it should be weak
1667 if ( info.options.fWeakImport )
1668 fit->options.fWeakImport = true;
1669 return;
1670 }
1671 }
1672 // add to list
1673 fInputFiles.push_back(info);
1674 }
1675
1676 void Options::warnObsolete(const char* arg)
1677 {
1678 warning("option %s is obsolete and being ignored", arg);
1679 }
1680
1681
1682
1683
1684 //
1685 // Process all command line arguments.
1686 //
1687 // The only error checking done here is that each option is valid and if it has arguments
1688 // that they too are valid.
1689 //
1690 // The general rule is "last option wins", i.e. if both -bundle and -dylib are specified,
1691 // whichever was last on the command line is used.
1692 //
1693 // Error check for invalid combinations of options is done in checkIllegalOptionCombinations()
1694 //
1695 void Options::parse(int argc, const char* argv[])
1696 {
1697 // pass one builds search list from -L and -F options
1698 this->buildSearchPaths(argc, argv);
1699
1700 // reduce re-allocations
1701 fInputFiles.reserve(32);
1702
1703 // pass two parse all other options
1704 for(int i=1; i < argc; ++i) {
1705 const char* arg = argv[i];
1706
1707 if ( arg[0] == '-' ) {
1708
1709 // Since we don't care about the files passed, just the option names, we do this here.
1710 if (fPrintOptions)
1711 fprintf (stderr, "[Logging ld64 options]\t%s\n", arg);
1712
1713 if ( (arg[1] == 'L') || (arg[1] == 'F') ) {
1714 // previously handled by buildSearchPaths()
1715 }
1716 // The one gnu style option we have to keep compatibility
1717 // with gcc. Might as well have the single hyphen one as well.
1718 else if ( (strcmp(arg, "--help") == 0)
1719 || (strcmp(arg, "-help") == 0)) {
1720 fprintf (stdout, "ld64: For information on command line options please use 'man ld'.\n");
1721 exit (0);
1722 }
1723 else if ( strcmp(arg, "-arch") == 0 ) {
1724 parseArch(argv[++i]);
1725 }
1726 else if ( strcmp(arg, "-dynamic") == 0 ) {
1727 // default
1728 }
1729 else if ( strcmp(arg, "-static") == 0 ) {
1730 fReaderOptions.fForStatic = true;
1731 if ( fOutputKind != kObjectFile ) {
1732 fOutputKind = kStaticExecutable;
1733 }
1734 }
1735 else if ( strcmp(arg, "-dylib") == 0 ) {
1736 fOutputKind = kDynamicLibrary;
1737 }
1738 else if ( strcmp(arg, "-bundle") == 0 ) {
1739 fOutputKind = kDynamicBundle;
1740 }
1741 else if ( strcmp(arg, "-dylinker") == 0 ) {
1742 fOutputKind = kDyld;
1743 }
1744 else if ( strcmp(arg, "-execute") == 0 ) {
1745 if ( fOutputKind != kStaticExecutable )
1746 fOutputKind = kDynamicExecutable;
1747 }
1748 else if ( strcmp(arg, "-preload") == 0 ) {
1749 fOutputKind = kPreload;
1750 }
1751 else if ( strcmp(arg, "-r") == 0 ) {
1752 fOutputKind = kObjectFile;
1753 }
1754 else if ( strcmp(arg, "-kext") == 0 ) {
1755 fOutputKind = kKextBundle;
1756 }
1757 else if ( strcmp(arg, "-o") == 0 ) {
1758 fOutputFile = argv[++i];
1759 }
1760 else if ( (arg[1] == 'l') && (strncmp(arg,"-lazy_",6) !=0) ) {
1761 addLibrary(findLibrary(&arg[2]));
1762 }
1763 // This causes a dylib to be weakly bound at
1764 // link time. This corresponds to weak_import.
1765 else if ( strncmp(arg, "-weak-l", 7) == 0 ) {
1766 FileInfo info = findLibrary(&arg[7]);
1767 info.options.fWeakImport = true;
1768 addLibrary(info);
1769 }
1770 else if ( strncmp(arg, "-lazy-l", 7) == 0 ) {
1771 FileInfo info = findLibrary(&arg[7], true);
1772 info.options.fLazyLoad = true;
1773 addLibrary(info);
1774 fUsingLazyDylibLinking = true;
1775 }
1776 // Avoid lazy binding.
1777 // ??? Deprecate.
1778 else if ( strcmp(arg, "-bind_at_load") == 0 ) {
1779 fBindAtLoad = true;
1780 }
1781 else if ( strcmp(arg, "-twolevel_namespace") == 0 ) {
1782 fNameSpace = kTwoLevelNameSpace;
1783 }
1784 else if ( strcmp(arg, "-flat_namespace") == 0 ) {
1785 fNameSpace = kFlatNameSpace;
1786 }
1787 // Also sets a bit to ensure dyld causes everything
1788 // in the namespace to be flat.
1789 // ??? Deprecate
1790 else if ( strcmp(arg, "-force_flat_namespace") == 0 ) {
1791 fNameSpace = kForceFlatNameSpace;
1792 }
1793 // Similar to --whole-archive.
1794 else if ( strcmp(arg, "-all_load") == 0 ) {
1795 fReaderOptions.fFullyLoadArchives = true;
1796 }
1797 else if ( strcmp(arg, "-noall_load") == 0) {
1798 warnObsolete(arg);
1799 }
1800 // Similar to -all_load
1801 else if ( strcmp(arg, "-ObjC") == 0 ) {
1802 fReaderOptions.fLoadAllObjcObjectsFromArchives = true;
1803 }
1804 // Similar to -all_load, but for the following archive only.
1805 else if ( strcmp(arg, "-force_load") == 0 ) {
1806 FileInfo info = findFile(argv[++i]);
1807 info.options.fForceLoad = true;
1808 addLibrary(info);
1809 }
1810 // Library versioning.
1811 else if ( (strcmp(arg, "-dylib_compatibility_version") == 0)
1812 || (strcmp(arg, "-compatibility_version") == 0)) {
1813 const char* vers = argv[++i];
1814 if ( vers == NULL )
1815 throw "-dylib_compatibility_version missing <version>";
1816 fDylibCompatVersion = parseVersionNumber(vers);
1817 }
1818 else if ( (strcmp(arg, "-dylib_current_version") == 0)
1819 || (strcmp(arg, "-current_version") == 0)) {
1820 const char* vers = argv[++i];
1821 if ( vers == NULL )
1822 throw "-dylib_current_version missing <version>";
1823 fDylibCurrentVersion = parseVersionNumber(vers);
1824 }
1825 else if ( strcmp(arg, "-sectorder") == 0 ) {
1826 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
1827 throw "-sectorder missing <segment> <section> <file-path>";
1828 parseSectionOrderFile(argv[i+1], argv[i+2], argv[i+3]);
1829 i += 3;
1830 }
1831 else if ( strcmp(arg, "-order_file") == 0 ) {
1832 parseOrderFile(argv[++i], false);
1833 }
1834 else if ( strcmp(arg, "-order_file_statistics") == 0 ) {
1835 fPrintOrderFileStatistics = true;
1836 }
1837 // ??? Deprecate segcreate.
1838 // -sectcreate puts whole files into a section in the output.
1839 else if ( (strcmp(arg, "-sectcreate") == 0) || (strcmp(arg, "-segcreate") == 0) ) {
1840 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
1841 throw "-sectcreate missing <segment> <section> <file-path>";
1842 addSection(argv[i+1], argv[i+2], argv[i+3]);
1843 i += 3;
1844 }
1845 // Since we have a full path in binary/library names we need to be able to override it.
1846 else if ( (strcmp(arg, "-dylib_install_name") == 0)
1847 || (strcmp(arg, "-dylinker_install_name") == 0)
1848 || (strcmp(arg, "-install_name") == 0)) {
1849 fDylibInstallName = argv[++i];
1850 if ( fDylibInstallName == NULL )
1851 throw "-install_name missing <path>";
1852 }
1853 // Sets the base address of the output.
1854 else if ( (strcmp(arg, "-seg1addr") == 0) || (strcmp(arg, "-image_base") == 0) ) {
1855 const char* address = argv[++i];
1856 if ( address == NULL )
1857 throwf("%s missing <address>", arg);
1858 fBaseAddress = parseAddress(address);
1859 uint64_t temp = ((fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment));
1860 if ( fBaseAddress != temp ) {
1861 warning("-seg1addr not %lld byte aligned, rounding up", fSegmentAlignment);
1862 fBaseAddress = temp;
1863 }
1864 }
1865 else if ( strcmp(arg, "-e") == 0 ) {
1866 fEntryName = argv[++i];
1867 }
1868 // Same as -@ from the FSF linker.
1869 else if ( strcmp(arg, "-filelist") == 0 ) {
1870 const char* path = argv[++i];
1871 if ( (path == NULL) || (path[0] == '-') )
1872 throw "-filelist missing <path>";
1873 loadFileList(path);
1874 }
1875 else if ( strcmp(arg, "-keep_private_externs") == 0 ) {
1876 fKeepPrivateExterns = true;
1877 }
1878 else if ( strcmp(arg, "-final_output") == 0 ) {
1879 fFinalName = argv[++i];
1880 }
1881 // Ensure that all calls to exported symbols go through lazy pointers. Multi-module
1882 // just ensures that this happens for cross object file boundaries.
1883 else if ( (strcmp(arg, "-interposable") == 0) || (strcmp(arg, "-multi_module") == 0)) {
1884 switch ( fInterposeMode ) {
1885 case kInterposeNone:
1886 case kInterposeAllExternal:
1887 fInterposeMode = kInterposeAllExternal;
1888 break;
1889 case kInterposeSome:
1890 // do nothing, -interposable_list overrides -interposable"
1891 break;
1892 }
1893 }
1894 else if ( strcmp(arg, "-interposable_list") == 0 ) {
1895 fInterposeMode = kInterposeSome;
1896 loadExportFile(argv[++i], "-interposable_list", fInterposeList);
1897 }
1898 // Default for -interposable/-multi_module/-single_module.
1899 else if ( strcmp(arg, "-single_module") == 0 ) {
1900 fInterposeMode = kInterposeNone;
1901 }
1902 else if ( strcmp(arg, "-exported_symbols_list") == 0 ) {
1903 if ( fExportMode == kDontExportSome )
1904 throw "can't use -exported_symbols_list and -unexported_symbols_list";
1905 fExportMode = kExportSome;
1906 loadExportFile(argv[++i], "-exported_symbols_list", fExportSymbols);
1907 }
1908 else if ( strcmp(arg, "-unexported_symbols_list") == 0 ) {
1909 if ( fExportMode == kExportSome )
1910 throw "can't use -unexported_symbols_list and -exported_symbols_list";
1911 fExportMode = kDontExportSome;
1912 loadExportFile(argv[++i], "-unexported_symbols_list", fDontExportSymbols);
1913 }
1914 else if ( strcmp(arg, "-exported_symbol") == 0 ) {
1915 if ( fExportMode == kDontExportSome )
1916 throw "can't use -exported_symbol and -unexported_symbols";
1917 fExportMode = kExportSome;
1918 fExportSymbols.insert(argv[++i]);
1919 }
1920 else if ( strcmp(arg, "-unexported_symbol") == 0 ) {
1921 if ( fExportMode == kExportSome )
1922 throw "can't use -unexported_symbol and -exported_symbol";
1923 fExportMode = kDontExportSome;
1924 fDontExportSymbols.insert(argv[++i]);
1925 }
1926 else if ( strcmp(arg, "-non_global_symbols_no_strip_list") == 0 ) {
1927 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveExclude )
1928 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
1929 fLocalSymbolHandling = kLocalSymbolsSelectiveInclude;
1930 loadExportFile(argv[++i], "-non_global_symbols_no_strip_list", fLocalSymbolsIncluded);
1931 }
1932 else if ( strcmp(arg, "-non_global_symbols_strip_list") == 0 ) {
1933 if ( fLocalSymbolHandling == kLocalSymbolsSelectiveInclude )
1934 throw "can't use -non_global_symbols_no_strip_list and -non_global_symbols_strip_list";
1935 fLocalSymbolHandling = kLocalSymbolsSelectiveExclude;
1936 loadExportFile(argv[++i], "-non_global_symbols_strip_list", fLocalSymbolsExcluded);
1937 }
1938 // ??? Deprecate
1939 else if ( strcmp(arg, "-no_arch_warnings") == 0 ) {
1940 fIgnoreOtherArchFiles = true;
1941 }
1942 else if ( strcmp(arg, "-force_cpusubtype_ALL") == 0 ) {
1943 fForceSubtypeAll = true;
1944 }
1945 // Similar to -weak-l but uses the absolute path name to the library.
1946 else if ( strcmp(arg, "-weak_library") == 0 ) {
1947 FileInfo info = findFile(argv[++i]);
1948 info.options.fWeakImport = true;
1949 addLibrary(info);
1950 }
1951 else if ( strcmp(arg, "-lazy_library") == 0 ) {
1952 FileInfo info = findFile(argv[++i]);
1953 info.options.fLazyLoad = true;
1954 addLibrary(info);
1955 fUsingLazyDylibLinking = true;
1956 }
1957 else if ( strcmp(arg, "-framework") == 0 ) {
1958 addLibrary(findFramework(argv[++i]));
1959 }
1960 else if ( strcmp(arg, "-weak_framework") == 0 ) {
1961 FileInfo info = findFramework(argv[++i]);
1962 info.options.fWeakImport = true;
1963 addLibrary(info);
1964 }
1965 else if ( strcmp(arg, "-lazy_framework") == 0 ) {
1966 FileInfo info = findFramework(argv[++i]);
1967 info.options.fLazyLoad = true;
1968 addLibrary(info);
1969 fUsingLazyDylibLinking = true;
1970 }
1971 else if ( strcmp(arg, "-search_paths_first") == 0 ) {
1972 // previously handled by buildSearchPaths()
1973 }
1974 else if ( strcmp(arg, "-undefined") == 0 ) {
1975 setUndefinedTreatment(argv[++i]);
1976 }
1977 // Debugging output flag.
1978 else if ( strcmp(arg, "-arch_multiple") == 0 ) {
1979 fMessagesPrefixedWithArchitecture = true;
1980 }
1981 // Specify what to do with relocations in read only
1982 // sections like .text. Could be errors, warnings,
1983 // or suppressed. Currently we do nothing with the
1984 // flag.
1985 else if ( strcmp(arg, "-read_only_relocs") == 0 ) {
1986 switch ( parseTreatment(argv[++i]) ) {
1987 case kNULL:
1988 case kInvalid:
1989 throw "-read_only_relocs missing [ warning | error | suppress ]";
1990 case kWarning:
1991 fWarnTextRelocs = true;
1992 fAllowTextRelocs = true;
1993 break;
1994 case kSuppress:
1995 fWarnTextRelocs = false;
1996 fAllowTextRelocs = true;
1997 break;
1998 case kError:
1999 fWarnTextRelocs = false;
2000 fAllowTextRelocs = false;
2001 break;
2002 }
2003 }
2004 else if ( strcmp(arg, "-sect_diff_relocs") == 0 ) {
2005 warnObsolete(arg);
2006 ++i;
2007 }
2008 // Warn, error or make strong a mismatch between weak
2009 // and non-weak references.
2010 else if ( strcmp(arg, "-weak_reference_mismatches") == 0 ) {
2011 setWeakReferenceMismatchTreatment(argv[++i]);
2012 }
2013 // For a deployment target of 10.3 and earlier ld64 will
2014 // prebind an executable with 0s in all addresses that
2015 // are prebound. This can then be fixed up by update_prebinding
2016 // later. Prebinding is less useful on 10.4 and greater.
2017 else if ( strcmp(arg, "-prebind") == 0 ) {
2018 fPrebind = true;
2019 }
2020 else if ( strcmp(arg, "-noprebind") == 0 ) {
2021 warnObsolete(arg);
2022 fPrebind = false;
2023 }
2024 else if ( strcmp(arg, "-prebind_allow_overlap") == 0 ) {
2025 warnObsolete(arg);
2026 }
2027 else if ( strcmp(arg, "-prebind_all_twolevel_modules") == 0 ) {
2028 warnObsolete(arg);
2029 }
2030 else if ( strcmp(arg, "-noprebind_all_twolevel_modules") == 0 ) {
2031 warnObsolete(arg);
2032 }
2033 else if ( strcmp(arg, "-nofixprebinding") == 0 ) {
2034 warnObsolete(arg);
2035 }
2036 // This should probably be deprecated when we respect -L and -F
2037 // when searching for libraries.
2038 else if ( strcmp(arg, "-dylib_file") == 0 ) {
2039 addDylibOverride(argv[++i]);
2040 }
2041 // What to expand @executable_path to if found in dependent dylibs
2042 else if ( strcmp(arg, "-executable_path") == 0 ) {
2043 fExecutablePath = argv[++i];
2044 if ( (fExecutablePath == NULL) || (fExecutablePath[0] == '-') )
2045 throw "-executable_path missing <path>";
2046 // if a directory was passed, add / to end
2047 // <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
2048 struct stat statBuffer;
2049 if ( stat(fExecutablePath, &statBuffer) == 0 ) {
2050 if ( (statBuffer.st_mode & S_IFMT) == S_IFDIR ) {
2051 char* pathWithSlash = new char[strlen(fExecutablePath)+2];
2052 strcpy(pathWithSlash, fExecutablePath);
2053 strcat(pathWithSlash, "/");
2054 fExecutablePath = pathWithSlash;
2055 }
2056 }
2057 }
2058 // Aligns all segments to the power of 2 boundary specified.
2059 else if ( strcmp(arg, "-segalign") == 0 ) {
2060 const char* size = argv[++i];
2061 if ( size == NULL )
2062 throw "-segalign missing <size>";
2063 fSegmentAlignment = parseAddress(size);
2064 uint8_t alignment = (uint8_t)__builtin_ctz(fSegmentAlignment);
2065 uint32_t p2aligned = (1 << alignment);
2066 if ( p2aligned != fSegmentAlignment ) {
2067 warning("alignment for -segalign %s is not a power of two, using 0x%X", size, p2aligned);
2068 fSegmentAlignment = p2aligned;
2069 }
2070 }
2071 // Puts a specified segment at a particular address that must
2072 // be a multiple of the segment alignment.
2073 else if ( strcmp(arg, "-segaddr") == 0 ) {
2074 SegmentStart seg;
2075 seg.name = argv[++i];
2076 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
2077 throw "-segaddr missing segName Adddress";
2078 seg.address = parseAddress(argv[++i]);
2079 uint64_t temp = seg.address & (-4096); // page align
2080 if ( (seg.address != temp) )
2081 warning("-segaddr %s not page aligned, rounding down", seg.name);
2082 fCustomSegmentAddresses.push_back(seg);
2083 }
2084 // ??? Deprecate when we deprecate split-seg.
2085 else if ( strcmp(arg, "-segs_read_only_addr") == 0 ) {
2086 fBaseAddress = parseAddress(argv[++i]);
2087 }
2088 // ??? Deprecate when we deprecate split-seg.
2089 else if ( strcmp(arg, "-segs_read_write_addr") == 0 ) {
2090 fBaseWritableAddress = parseAddress(argv[++i]);
2091 fSplitSegs = true;
2092 }
2093 // ??? Deprecate when we get rid of basing at build time.
2094 else if ( strcmp(arg, "-seg_addr_table") == 0 ) {
2095 const char* name = argv[++i];
2096 if ( name == NULL )
2097 throw "-seg_addr_table missing argument";
2098 fSegAddrTablePath = name;
2099 }
2100 else if ( strcmp(arg, "-seg_addr_table_filename") == 0 ) {
2101 warnObsolete(arg);
2102 ++i;
2103 }
2104 else if ( strcmp(arg, "-segprot") == 0 ) {
2105 SegmentProtect seg;
2106 seg.name = argv[++i];
2107 if ( (seg.name == NULL) || (argv[i+1] == NULL) || (argv[i+2] == NULL) )
2108 throw "-segprot missing segName max-prot init-prot";
2109 seg.max = parseProtection(argv[++i]);
2110 seg.init = parseProtection(argv[++i]);
2111 fCustomSegmentProtections.push_back(seg);
2112 }
2113 else if ( strcmp(arg, "-pagezero_size") == 0 ) {
2114 const char* size = argv[++i];
2115 if ( size == NULL )
2116 throw "-pagezero_size missing <size>";
2117 fZeroPageSize = parseAddress(size);
2118 uint64_t temp = fZeroPageSize & (-4096); // page align
2119 if ( (fZeroPageSize != temp) )
2120 warning("-pagezero_size not page aligned, rounding down");
2121 fZeroPageSize = temp;
2122 }
2123 else if ( strcmp(arg, "-stack_addr") == 0 ) {
2124 const char* address = argv[++i];
2125 if ( address == NULL )
2126 throw "-stack_addr missing <address>";
2127 fStackAddr = parseAddress(address);
2128 }
2129 else if ( strcmp(arg, "-stack_size") == 0 ) {
2130 const char* size = argv[++i];
2131 if ( size == NULL )
2132 throw "-stack_size missing <address>";
2133 fStackSize = parseAddress(size);
2134 uint64_t temp = fStackSize & (-4096); // page align
2135 if ( (fStackSize != temp) )
2136 warning("-stack_size not page aligned, rounding down");
2137 }
2138 else if ( strcmp(arg, "-allow_stack_execute") == 0 ) {
2139 fExecutableStack = true;
2140 }
2141 else if ( strcmp(arg, "-sectalign") == 0 ) {
2142 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
2143 throw "-sectalign missing <segment> <section> <file-path>";
2144 addSectionAlignment(argv[i+1], argv[i+2], argv[i+3]);
2145 i += 3;
2146 }
2147 else if ( strcmp(arg, "-sectorder_detail") == 0 ) {
2148 warnObsolete(arg);
2149 }
2150 else if ( strcmp(arg, "-sectobjectsymbols") == 0 ) {
2151 warnObsolete(arg);
2152 i += 2;
2153 }
2154 else if ( strcmp(arg, "-bundle_loader") == 0 ) {
2155 fBundleLoader = argv[++i];
2156 if ( (fBundleLoader == NULL) || (fBundleLoader[0] == '-') )
2157 throw "-bundle_loader missing <path>";
2158 FileInfo info = findFile(fBundleLoader);
2159 info.options.fBundleLoader = true;
2160 fInputFiles.push_back(info);
2161 }
2162 else if ( strcmp(arg, "-private_bundle") == 0 ) {
2163 warnObsolete(arg);
2164 }
2165 else if ( strcmp(arg, "-twolevel_namespace_hints") == 0 ) {
2166 // FIX FIX
2167 }
2168 // Use this flag to set default behavior for deployement targets.
2169 else if ( strcmp(arg, "-macosx_version_min") == 0 ) {
2170 setMacOSXVersionMin(argv[++i]);
2171 }
2172 else if ( strcmp(arg, "-iphoneos_version_min") == 0 ) {
2173 setIPhoneVersionMin(argv[++i]);
2174 }
2175 else if ( strcmp(arg, "-multiply_defined") == 0 ) {
2176 //warnObsolete(arg);
2177 ++i;
2178 }
2179 else if ( strcmp(arg, "-multiply_defined_unused") == 0 ) {
2180 warnObsolete(arg);
2181 ++i;
2182 }
2183 else if ( strcmp(arg, "-nomultidefs") == 0 ) {
2184 warnObsolete(arg);
2185 }
2186 // Display each file in which the argument symbol appears and whether
2187 // the file defines or references it. This option takes an argument
2188 // as -y<symbol> note that there is no space.
2189 else if ( strncmp(arg, "-y", 2) == 0 ) {
2190 warnObsolete("-y");
2191 }
2192 // Same output as -y, but output <arg> number of undefined symbols only.
2193 else if ( strcmp(arg, "-Y") == 0 ) {
2194 //warnObsolete(arg);
2195 ++i;
2196 }
2197 // This option affects all objects linked into the final result.
2198 else if ( strcmp(arg, "-m") == 0 ) {
2199 warnObsolete(arg);
2200 }
2201 else if ( (strcmp(arg, "-why_load") == 0) || (strcmp(arg, "-whyload") == 0) ) {
2202 fReaderOptions.fWhyLoad = true;
2203 }
2204 else if ( strcmp(arg, "-why_live") == 0 ) {
2205 const char* name = argv[++i];
2206 if ( name == NULL )
2207 throw "-why_live missing symbol name argument";
2208 fWhyLive.insert(name);
2209 }
2210 else if ( strcmp(arg, "-u") == 0 ) {
2211 const char* name = argv[++i];
2212 if ( name == NULL )
2213 throw "-u missing argument";
2214 fInitialUndefines.push_back(name);
2215 }
2216 else if ( strcmp(arg, "-U") == 0 ) {
2217 const char* name = argv[++i];
2218 if ( name == NULL )
2219 throw "-U missing argument";
2220 fAllowedUndefined.insert(name);
2221 }
2222 else if ( strcmp(arg, "-s") == 0 ) {
2223 warnObsolete(arg);
2224 fLocalSymbolHandling = kLocalSymbolsNone;
2225 fReaderOptions.fDebugInfoStripping = ObjectFile::ReaderOptions::kDebugInfoNone;
2226 }
2227 else if ( strcmp(arg, "-x") == 0 ) {
2228 fLocalSymbolHandling = kLocalSymbolsNone;
2229 }
2230 else if ( strcmp(arg, "-S") == 0 ) {
2231 fReaderOptions.fDebugInfoStripping = ObjectFile::ReaderOptions::kDebugInfoNone;
2232 }
2233 else if ( strcmp(arg, "-X") == 0 ) {
2234 warnObsolete(arg);
2235 }
2236 else if ( strcmp(arg, "-Si") == 0 ) {
2237 warnObsolete(arg);
2238 fReaderOptions.fDebugInfoStripping = ObjectFile::ReaderOptions::kDebugInfoFull;
2239 }
2240 else if ( strcmp(arg, "-b") == 0 ) {
2241 warnObsolete(arg);
2242 }
2243 else if ( strcmp(arg, "-Sn") == 0 ) {
2244 warnObsolete(arg);
2245 fReaderOptions.fDebugInfoStripping = ObjectFile::ReaderOptions::kDebugInfoFull;
2246 }
2247 else if ( strcmp(arg, "-Sp") == 0 ) {
2248 warnObsolete(arg);
2249 }
2250 else if ( strcmp(arg, "-dead_strip") == 0 ) {
2251 fDeadStrip = kDeadStripOnPlusUnusedInits;
2252 }
2253 else if ( strcmp(arg, "-no_dead_strip_inits_and_terms") == 0 ) {
2254 fDeadStrip = kDeadStripOn;
2255 }
2256 else if ( strcmp(arg, "-w") == 0 ) {
2257 // previously handled by buildSearchPaths()
2258 }
2259 else if ( strcmp(arg, "-arch_errors_fatal") == 0 ) {
2260 fErrorOnOtherArchFiles = true;
2261 }
2262 else if ( strcmp(arg, "-M") == 0 ) {
2263 // FIX FIX
2264 }
2265 else if ( strcmp(arg, "-headerpad") == 0 ) {
2266 const char* size = argv[++i];
2267 if ( size == NULL )
2268 throw "-headerpad missing argument";
2269 fMinimumHeaderPad = parseAddress(size);
2270 }
2271 else if ( strcmp(arg, "-headerpad_max_install_names") == 0 ) {
2272 fMaxMinimumHeaderPad = true;
2273 }
2274 else if ( strcmp(arg, "-t") == 0 ) {
2275 fReaderOptions.fLogAllFiles = true;
2276 }
2277 else if ( strcmp(arg, "-whatsloaded") == 0 ) {
2278 fReaderOptions.fLogObjectFiles = true;
2279 }
2280 else if ( strcmp(arg, "-A") == 0 ) {
2281 warnObsolete(arg);
2282 ++i;
2283 }
2284 else if ( strcmp(arg, "-umbrella") == 0 ) {
2285 const char* name = argv[++i];
2286 if ( name == NULL )
2287 throw "-umbrella missing argument";
2288 fUmbrellaName = name;
2289 }
2290 else if ( strcmp(arg, "-allowable_client") == 0 ) {
2291 const char* name = argv[++i];
2292
2293 if ( name == NULL )
2294 throw "-allowable_client missing argument";
2295
2296 fAllowableClients.push_back(name);
2297 }
2298 else if ( strcmp(arg, "-client_name") == 0 ) {
2299 const char* name = argv[++i];
2300
2301 if ( name == NULL )
2302 throw "-client_name missing argument";
2303
2304 fClientName = name;
2305 }
2306 else if ( strcmp(arg, "-sub_umbrella") == 0 ) {
2307 const char* name = argv[++i];
2308 if ( name == NULL )
2309 throw "-sub_umbrella missing argument";
2310 fSubUmbellas.push_back(name);
2311 }
2312 else if ( strcmp(arg, "-sub_library") == 0 ) {
2313 const char* name = argv[++i];
2314 if ( name == NULL )
2315 throw "-sub_library missing argument";
2316 fSubLibraries.push_back(name);
2317 }
2318 else if ( strcmp(arg, "-init") == 0 ) {
2319 const char* name = argv[++i];
2320 if ( name == NULL )
2321 throw "-init missing argument";
2322 fInitFunctionName = name;
2323 }
2324 else if ( strcmp(arg, "-dot") == 0 ) {
2325 const char* name = argv[++i];
2326 if ( name == NULL )
2327 throw "-dot missing argument";
2328 fDotOutputFile = name;
2329 }
2330 else if ( strcmp(arg, "-warn_commons") == 0 ) {
2331 fWarnCommons = true;
2332 }
2333 else if ( strcmp(arg, "-commons") == 0 ) {
2334 fCommonsMode = parseCommonsTreatment(argv[++i]);
2335 }
2336 else if ( strcmp(arg, "-keep_relocs") == 0 ) {
2337 fKeepRelocations = true;
2338 }
2339 else if ( strcmp(arg, "-warn_stabs") == 0 ) {
2340 fWarnStabs = true;
2341 }
2342 else if ( strcmp(arg, "-pause") == 0 ) {
2343 fPause = true;
2344 }
2345 else if ( strcmp(arg, "-print_statistics") == 0 ) {
2346 fStatistics = true;
2347 }
2348 else if ( strcmp(arg, "-d") == 0 ) {
2349 fReaderOptions.fMakeTentativeDefinitionsReal = true;
2350 }
2351 else if ( strcmp(arg, "-v") == 0 ) {
2352 // previously handled by buildSearchPaths()
2353 }
2354 else if ( strcmp(arg, "-Z") == 0 ) {
2355 // previously handled by buildSearchPaths()
2356 }
2357 else if ( strcmp(arg, "-syslibroot") == 0 ) {
2358 ++i;
2359 // previously handled by buildSearchPaths()
2360 }
2361 else if ( strcmp(arg, "-no_uuid") == 0 ) {
2362 fUUIDMode = kUUIDNone;
2363 }
2364 else if ( strcmp(arg, "-random_uuid") == 0 ) {
2365 fUUIDMode = kUUIDRandom;
2366 }
2367 else if ( strcmp(arg, "-dtrace") == 0 ) {
2368 const char* name = argv[++i];
2369 if ( name == NULL )
2370 throw "-dtrace missing argument";
2371 fDtraceScriptName = name;
2372 }
2373 else if ( strcmp(arg, "-root_safe") == 0 ) {
2374 fReaderOptions.fRootSafe = true;
2375 }
2376 else if ( strcmp(arg, "-setuid_safe") == 0 ) {
2377 fReaderOptions.fSetuidSafe = true;
2378 }
2379 else if ( strcmp(arg, "-alias") == 0 ) {
2380 ObjectFile::ReaderOptions::AliasPair pair;
2381 pair.realName = argv[++i];
2382 if ( pair.realName == NULL )
2383 throw "missing argument to -alias";
2384 pair.alias = argv[++i];
2385 if ( pair.alias == NULL )
2386 throw "missing argument to -alias";
2387 fReaderOptions.fAliases.push_back(pair);
2388 }
2389 else if ( strcmp(arg, "-alias_list") == 0 ) {
2390 parseAliasFile(argv[++i]);
2391 }
2392 // put this last so that it does not interfer with other options starting with 'i'
2393 else if ( strncmp(arg, "-i", 2) == 0 ) {
2394 const char* colon = strchr(arg, ':');
2395 if ( colon == NULL )
2396 throwf("unknown option: %s", arg);
2397 ObjectFile::ReaderOptions::AliasPair pair;
2398 char* temp = new char[colon-arg];
2399 strlcpy(temp, &arg[2], colon-arg-1);
2400 pair.realName = &colon[1];
2401 pair.alias = temp;
2402 fReaderOptions.fAliases.push_back(pair);
2403 }
2404 else if ( strcmp(arg, "-save-temps") == 0 ) {
2405 fSaveTempFiles = true;
2406 }
2407 else if ( strcmp(arg, "-rpath") == 0 ) {
2408 const char* path = argv[++i];
2409 if ( path == NULL )
2410 throw "missing argument to -rpath";
2411 fRPaths.push_back(path);
2412 }
2413 else if ( strcmp(arg, "-read_only_stubs") == 0 ) {
2414 fReadOnlyx86Stubs = true;
2415 }
2416 else if ( strcmp(arg, "-slow_stubs") == 0 ) {
2417 warnObsolete(arg);
2418 }
2419 else if ( strcmp(arg, "-map") == 0 ) {
2420 fMapPath = argv[++i];
2421 if ( fMapPath == NULL )
2422 throw "missing argument to -map";
2423 }
2424 else if ( strcmp(arg, "-pie") == 0 ) {
2425 fPositionIndependentExecutable = true;
2426 }
2427 else if ( strncmp(arg, "-reexport-l", 11) == 0 ) {
2428 FileInfo info = findLibrary(&arg[11], true);
2429 info.options.fReExport = true;
2430 addLibrary(info);
2431 }
2432 else if ( strcmp(arg, "-reexport_library") == 0 ) {
2433 FileInfo info = findFile(argv[++i]);
2434 info.options.fReExport = true;
2435 addLibrary(info);
2436 }
2437 else if ( strcmp(arg, "-reexport_framework") == 0 ) {
2438 FileInfo info = findFramework(argv[++i]);
2439 info.options.fReExport = true;
2440 addLibrary(info);
2441 }
2442 else if ( strcmp(arg, "-dead_strip_dylibs") == 0 ) {
2443 fDeadStripDylibs = true;
2444 }
2445 else if ( strcmp(arg, "-no_implicit_dylibs") == 0 ) {
2446 fReaderOptions.fImplicitlyLinkPublicDylibs = false;
2447 }
2448 else if ( strcmp(arg, "-new_linker") == 0 ) {
2449 // ignore
2450 }
2451 else if ( strcmp(arg, "-no_encryption") == 0 ) {
2452 fEncryptable = false;
2453 }
2454 else if ( strcmp(arg, "-no_compact_unwind") == 0 ) {
2455 fReaderOptions.fAddCompactUnwindEncoding = false;
2456 }
2457 else if ( strcmp(arg, "-mllvm") == 0 ) {
2458 const char* opts = argv[++i];
2459 if ( opts == NULL )
2460 throw "missing argument to -mllvm";
2461 fLLVMOptions.push_back(opts);
2462 }
2463 else if ( strcmp(arg, "-no_order_inits") == 0 ) {
2464 fReaderOptions.fAutoOrderInitializers = false;
2465 }
2466 else if ( strcmp(arg, "-no_order_data") == 0 ) {
2467 fOrderData = false;
2468 }
2469 else if ( strcmp(arg, "-seg_page_size") == 0 ) {
2470 SegmentSize seg;
2471 seg.name = argv[++i];
2472 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
2473 throw "-seg_page_size missing segName Adddress";
2474 seg.size = parseAddress(argv[++i]);
2475 uint64_t temp = seg.size & (-4096); // page align
2476 if ( (seg.size != temp) )
2477 warning("-seg_page_size %s not 4K aligned, rounding down", seg.name);
2478 fCustomSegmentSizes.push_back(seg);
2479 }
2480 else if ( strcmp(arg, "-mark_dead_strippable_dylib") == 0 ) {
2481 fMarkDeadStrippableDylib = true;
2482 }
2483 else if ( strcmp(arg, "-exported_symbols_order") == 0 ) {
2484 loadSymbolOrderFile(argv[++i], fExportSymbolsOrder);
2485 }
2486 else if ( strcmp(arg, "-no_compact_linkedit") == 0 ) {
2487 fMakeCompressedDyldInfo = false;
2488 }
2489 else if ( strcmp(arg, "-no_eh_labels") == 0 ) {
2490 fReaderOptions.fNoEHLabels = true;
2491 }
2492 else if ( strcmp(arg, "-warn_compact_unwind") == 0 ) {
2493 fReaderOptions.fWarnCompactUnwind = true;
2494 }
2495 else if ( strcmp(arg, "-allow_sub_type_mismatches") == 0 ) {
2496 fAllowCpuSubtypeMismatches = true;
2497 }
2498 else if ( strcmp(arg, "-no_zero_fill_sections") == 0 ) {
2499 fReaderOptions.fOptimizeZeroFill = false;
2500 }
2501 else {
2502 throwf("unknown option: %s", arg);
2503 }
2504 }
2505 else {
2506 FileInfo info = findFile(arg);
2507 if ( strcmp(&info.path[strlen(info.path)-2], ".a") == 0 )
2508 addLibrary(info);
2509 else
2510 fInputFiles.push_back(info);
2511 }
2512 }
2513
2514 // if a -lazy option was used, implicitly link in lazydylib1.o
2515 if ( fUsingLazyDylibLinking ) {
2516 addLibrary(findLibrary("lazydylib1.o"));
2517 }
2518 }
2519
2520
2521
2522 //
2523 // -syslibroot <path> is used for SDK support.
2524 // The rule is that all search paths (both explicit and default) are
2525 // checked to see if they exist in the SDK. If so, that path is
2526 // replaced with the sdk prefixed path. If not, that search path
2527 // is used as is. If multiple -syslibroot options are specified
2528 // their directory structures are logically overlayed and files
2529 // from sdks specified earlier on the command line used before later ones.
2530
2531 void Options::buildSearchPaths(int argc, const char* argv[])
2532 {
2533 bool addStandardLibraryDirectories = true;
2534 std::vector<const char*> libraryPaths;
2535 std::vector<const char*> frameworkPaths;
2536 libraryPaths.reserve(10);
2537 frameworkPaths.reserve(10);
2538 // scan through argv looking for -L, -F, -Z, and -syslibroot options
2539 for(int i=0; i < argc; ++i) {
2540 if ( (argv[i][0] == '-') && (argv[i][1] == 'L') )
2541 libraryPaths.push_back(&argv[i][2]);
2542 else if ( (argv[i][0] == '-') && (argv[i][1] == 'F') )
2543 frameworkPaths.push_back(&argv[i][2]);
2544 else if ( strcmp(argv[i], "-Z") == 0 )
2545 addStandardLibraryDirectories = false;
2546 else if ( strcmp(argv[i], "-v") == 0 ) {
2547 fVerbose = true;
2548 extern const char ldVersionString[];
2549 fprintf(stderr, "%s", ldVersionString);
2550 // if only -v specified, exit cleanly
2551 if ( argc == 2 ) {
2552 #if LTO_SUPPORT
2553 printLTOVersion(*this);
2554 #endif
2555 exit(0);
2556 }
2557 }
2558 else if ( strcmp(argv[i], "-syslibroot") == 0 ) {
2559 const char* path = argv[++i];
2560 if ( path == NULL )
2561 throw "-syslibroot missing argument";
2562 fSDKPaths.push_back(path);
2563 }
2564 else if ( strcmp(argv[i], "-search_paths_first") == 0 ) {
2565 // ??? Deprecate when we get -Bstatic/-Bdynamic.
2566 fLibrarySearchMode = kSearchDylibAndArchiveInEachDir;
2567 }
2568 else if ( strcmp(argv[i], "-w") == 0 ) {
2569 sEmitWarnings = false;
2570 }
2571 }
2572 int standardLibraryPathsStartIndex = libraryPaths.size();
2573 int standardFrameworkPathsStartIndex = frameworkPaths.size();
2574 if ( addStandardLibraryDirectories ) {
2575 libraryPaths.push_back("/usr/lib");
2576 libraryPaths.push_back("/usr/local/lib");
2577
2578 frameworkPaths.push_back("/Library/Frameworks/");
2579 frameworkPaths.push_back("/System/Library/Frameworks/");
2580 // <rdar://problem/5433882> remove /Network/Library/Frameworks from default search path
2581 }
2582
2583 // <rdar://problem/5829579> Support for configure based hacks
2584 // if last -syslibroot is /, then ignore all syslibroots
2585 if ( fSDKPaths.size() > 0 ) {
2586 if ( strcmp(fSDKPaths.back(), "/") == 0 ) {
2587 fSDKPaths.clear();
2588 }
2589 }
2590
2591 // now merge sdk and library paths to make real search paths
2592 fLibrarySearchPaths.reserve(libraryPaths.size()*(fSDKPaths.size()+1));
2593 int libIndex = 0;
2594 for (std::vector<const char*>::iterator it = libraryPaths.begin(); it != libraryPaths.end(); ++it, ++libIndex) {
2595 const char* libDir = *it;
2596 bool sdkOverride = false;
2597 if ( libDir[0] == '/' ) {
2598 char betterLibDir[PATH_MAX];
2599 if ( strstr(libDir, "/..") != NULL ) {
2600 if ( realpath(libDir, betterLibDir) != NULL )
2601 libDir = strdup(betterLibDir);
2602 }
2603 const int libDirLen = strlen(libDir);
2604 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
2605 const char* sdkDir = *sdkit;
2606 const int sdkDirLen = strlen(sdkDir);
2607 char newPath[libDirLen + sdkDirLen+4];
2608 strcpy(newPath, sdkDir);
2609 if ( newPath[sdkDirLen-1] == '/' )
2610 newPath[sdkDirLen-1] = '\0';
2611 strcat(newPath, libDir);
2612 struct stat statBuffer;
2613 if ( stat(newPath, &statBuffer) == 0 ) {
2614 fLibrarySearchPaths.push_back(strdup(newPath));
2615 sdkOverride = true;
2616 }
2617 }
2618 }
2619 if ( !sdkOverride ) {
2620 if ( (libIndex >= standardLibraryPathsStartIndex) && (fSDKPaths.size() == 1) ) {
2621 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
2622 // if one SDK is specified and a standard library path is not in the SDK, don't use it
2623 }
2624 else {
2625 fLibrarySearchPaths.push_back(libDir);
2626 }
2627 }
2628 }
2629
2630 // now merge sdk and framework paths to make real search paths
2631 fFrameworkSearchPaths.reserve(frameworkPaths.size()*(fSDKPaths.size()+1));
2632 int frameIndex = 0;
2633 for (std::vector<const char*>::iterator it = frameworkPaths.begin(); it != frameworkPaths.end(); ++it, ++frameIndex) {
2634 const char* frameworkDir = *it;
2635 bool sdkOverride = false;
2636 if ( frameworkDir[0] == '/' ) {
2637 char betterFrameworkDir[PATH_MAX];
2638 if ( strstr(frameworkDir, "/..") != NULL ) {
2639 if ( realpath(frameworkDir, betterFrameworkDir) != NULL )
2640 frameworkDir = strdup(betterFrameworkDir);
2641 }
2642 const int frameworkDirLen = strlen(frameworkDir);
2643 for (std::vector<const char*>::iterator sdkit = fSDKPaths.begin(); sdkit != fSDKPaths.end(); sdkit++) {
2644 const char* sdkDir = *sdkit;
2645 const int sdkDirLen = strlen(sdkDir);
2646 char newPath[frameworkDirLen + sdkDirLen+4];
2647 strcpy(newPath, sdkDir);
2648 if ( newPath[sdkDirLen-1] == '/' )
2649 newPath[sdkDirLen-1] = '\0';
2650 strcat(newPath, frameworkDir);
2651 struct stat statBuffer;
2652 if ( stat(newPath, &statBuffer) == 0 ) {
2653 fFrameworkSearchPaths.push_back(strdup(newPath));
2654 sdkOverride = true;
2655 }
2656 }
2657 }
2658 if ( !sdkOverride ) {
2659 if ( (frameIndex >= standardFrameworkPathsStartIndex) && (fSDKPaths.size() == 1) ) {
2660 // <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
2661 // if one SDK is specified and a standard library path is not in the SDK, don't use it
2662 }
2663 else {
2664 fFrameworkSearchPaths.push_back(frameworkDir);
2665 }
2666 }
2667 }
2668
2669 if ( fVerbose ) {
2670 fprintf(stderr,"Library search paths:\n");
2671 for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
2672 it != fLibrarySearchPaths.end();
2673 it++)
2674 fprintf(stderr,"\t%s\n", *it);
2675 fprintf(stderr,"Framework search paths:\n");
2676 for (std::vector<const char*>::iterator it = fFrameworkSearchPaths.begin();
2677 it != fFrameworkSearchPaths.end();
2678 it++)
2679 fprintf(stderr,"\t%s\n", *it);
2680 }
2681 }
2682
2683 // this is run before the command line is parsed
2684 void Options::parsePreCommandLineEnvironmentSettings()
2685 {
2686 if ((getenv("LD_TRACE_ARCHIVES") != NULL)
2687 || (getenv("RC_TRACE_ARCHIVES") != NULL))
2688 fReaderOptions.fTraceArchives = true;
2689
2690 if ((getenv("LD_TRACE_DYLIBS") != NULL)
2691 || (getenv("RC_TRACE_DYLIBS") != NULL)) {
2692 fReaderOptions.fTraceDylibs = true;
2693 fReaderOptions.fTraceIndirectDylibs = true;
2694 }
2695
2696 if (getenv("RC_TRACE_DYLIB_SEARCHING") != NULL) {
2697 fTraceDylibSearching = true;
2698 }
2699
2700 if (getenv("LD_PRINT_OPTIONS") != NULL)
2701 fPrintOptions = true;
2702
2703 if (fReaderOptions.fTraceDylibs || fReaderOptions.fTraceArchives)
2704 fReaderOptions.fTraceOutputFile = getenv("LD_TRACE_FILE");
2705
2706 if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL)
2707 fPrintOrderFileStatistics = true;
2708
2709 if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL)
2710 fSplitSegs = true;
2711
2712 if (getenv("LD_NO_ENCRYPT") != NULL)
2713 fEncryptable = false;
2714
2715 if (getenv("LD_ALLOW_CPU_SUBTYPE_MISMATCHES") != NULL)
2716 fAllowCpuSubtypeMismatches = true;
2717
2718 // for now disable compressed linkedit functionality
2719 if ( getenv("LD_NO_COMPACT_LINKEDIT") != NULL ) {
2720 fMakeCompressedDyldInfo = false;
2721 fMakeClassicDyldInfo = true;
2722 }
2723
2724 sWarningsSideFilePath = getenv("LD_WARN_FILE");
2725 }
2726
2727
2728 // this is run after the command line is parsed
2729 void Options::parsePostCommandLineEnvironmentSettings()
2730 {
2731 // when building a dynamic main executable, default any use of @executable_path to output path
2732 if ( fExecutablePath == NULL && (fOutputKind == kDynamicExecutable) ) {
2733 fExecutablePath = fOutputFile;
2734 }
2735
2736 // allow build system to set default seg_addr_table
2737 if ( fSegAddrTablePath == NULL )
2738 fSegAddrTablePath = getenv("LD_SEG_ADDR_TABLE");
2739
2740 // allow build system to turn on prebinding
2741 if ( !fPrebind ) {
2742 fPrebind = ( getenv("LD_PREBIND") != NULL );
2743 }
2744
2745 // allow build system to force on dead-code-stripping
2746 if ( fDeadStrip == kDeadStripOff ) {
2747 if ( getenv("LD_DEAD_STRIP") != NULL ) {
2748 switch (fOutputKind) {
2749 case Options::kDynamicLibrary:
2750 case Options::kDynamicExecutable:
2751 case Options::kDynamicBundle:
2752 fDeadStrip = kDeadStripOn;
2753 break;
2754 case Options::kPreload:
2755 case Options::kObjectFile:
2756 case Options::kDyld:
2757 case Options::kStaticExecutable:
2758 case Options::kKextBundle:
2759 break;
2760 }
2761 }
2762 }
2763
2764 // allow build system to force on -warn_commons
2765 if ( getenv("LD_WARN_COMMONS") != NULL )
2766 fWarnCommons = true;
2767
2768 }
2769
2770 void Options::reconfigureDefaults()
2771 {
2772 // sync reader options
2773 switch ( fOutputKind ) {
2774 case Options::kObjectFile:
2775 fReaderOptions.fForFinalLinkedImage = false;
2776 break;
2777 case Options::kDyld:
2778 fReaderOptions.fForDyld = true;
2779 fReaderOptions.fForFinalLinkedImage = true;
2780 fReaderOptions.fNoEHLabels = true;
2781 break;
2782 case Options::kDynamicLibrary:
2783 case Options::kDynamicBundle:
2784 case Options::kKextBundle:
2785 fReaderOptions.fForFinalLinkedImage = true;
2786 fReaderOptions.fNoEHLabels = true;
2787 break;
2788 case Options::kDynamicExecutable:
2789 case Options::kStaticExecutable:
2790 case Options::kPreload:
2791 fReaderOptions.fLinkingMainExecutable = true;
2792 fReaderOptions.fForFinalLinkedImage = true;
2793 fReaderOptions.fNoEHLabels = true;
2794 break;
2795 }
2796
2797 // set default min OS version
2798 if ( (fReaderOptions.fMacVersionMin == ObjectFile::ReaderOptions::kMinMacVersionUnset)
2799 && (fReaderOptions.fIPhoneVersionMin == ObjectFile::ReaderOptions::kMinIPhoneVersionUnset) ) {
2800 // if neither -macosx_version_min nor -iphoneos_version_min used, try environment variables
2801 const char* macVers = getenv("MACOSX_DEPLOYMENT_TARGET");
2802 const char* iPhoneVers = getenv("IPHONEOS_DEPLOYMENT_TARGET");
2803 if ( macVers != NULL )
2804 setMacOSXVersionMin(macVers);
2805 else if ( iPhoneVers != NULL )
2806 setIPhoneVersionMin(iPhoneVers);
2807 else {
2808 // if still nothing, set default based on architecture
2809 switch ( fArchitecture ) {
2810 case CPU_TYPE_I386:
2811 case CPU_TYPE_X86_64:
2812 case CPU_TYPE_POWERPC:
2813 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_6; // FIX FIX, this really should be a check of the OS version the linker is running o
2814 break;
2815 case CPU_TYPE_ARM:
2816 fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
2817 break;
2818 }
2819 }
2820 }
2821
2822
2823 // adjust min based on architecture
2824 switch ( fArchitecture ) {
2825 case CPU_TYPE_I386:
2826 if ( fReaderOptions.fMacVersionMin < ObjectFile::ReaderOptions::k10_4 ) {
2827 //warning("-macosx_version_min should be 10.4 or later for i386");
2828 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_4;
2829 }
2830 break;
2831 case CPU_TYPE_POWERPC64:
2832 if ( fReaderOptions.fMacVersionMin < ObjectFile::ReaderOptions::k10_4 ) {
2833 //warning("-macosx_version_min should be 10.4 or later for ppc64");
2834 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_4;
2835 }
2836 break;
2837 case CPU_TYPE_X86_64:
2838 if ( fReaderOptions.fMacVersionMin < ObjectFile::ReaderOptions::k10_4 ) {
2839 //warning("-macosx_version_min should be 10.4 or later for x86_64");
2840 fReaderOptions.fMacVersionMin = ObjectFile::ReaderOptions::k10_4;
2841 }
2842 break;
2843 }
2844
2845 // adjust kext type based on architecture
2846 if ( fOutputKind == kKextBundle ) {
2847 switch ( fArchitecture ) {
2848 case CPU_TYPE_X86_64:
2849 // x86_64 uses new MH_KEXT_BUNDLE type
2850 fMakeClassicDyldInfo = true;
2851 fMakeCompressedDyldInfo = false;
2852 fAllowTextRelocs = true;
2853 fUndefinedTreatment = kUndefinedDynamicLookup;
2854 break;
2855 case CPU_TYPE_POWERPC:
2856 case CPU_TYPE_I386:
2857 case CPU_TYPE_ARM:
2858 // use .o files
2859 fOutputKind = kObjectFile;
2860 break;
2861 }
2862 }
2863
2864 // disable implicit dylibs when targeting 10.3
2865 // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
2866 if ( !minOS(ObjectFile::ReaderOptions::k10_4, ObjectFile::ReaderOptions::k2_0) )
2867 fReaderOptions.fImplicitlyLinkPublicDylibs = false;
2868
2869
2870 // allow build system to force linker to ignore -prebind
2871 if ( getenv("LD_FORCE_NO_PREBIND") != NULL )
2872 fPrebind = false;
2873
2874 // allow build system to force linker to ignore -seg_addr_table
2875 if ( getenv("LD_FORCE_NO_SEG_ADDR_TABLE") != NULL )
2876 fSegAddrTablePath = NULL;
2877
2878 // check for base address specified externally
2879 if ( (fSegAddrTablePath != NULL) && (fOutputKind == Options::kDynamicLibrary) ) {
2880 parseSegAddrTable(fSegAddrTablePath, this->installPath());
2881 // HACK to support seg_addr_table entries that are physical paths instead of install paths
2882 if ( fBaseAddress == 0 ) {
2883 if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) {
2884 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.4.dylib");
2885 if ( fBaseAddress == 0 )
2886 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.9.dylib");
2887 }
2888
2889 else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 )
2890 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libz.1.2.3.dylib");
2891
2892 else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 )
2893 parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libutil1.0.dylib");
2894 }
2895 }
2896
2897 // split segs only allowed for dylibs
2898 if ( fSplitSegs ) {
2899 // split seg only supported for ppc, i386, and arm.
2900 switch ( fArchitecture ) {
2901 case CPU_TYPE_POWERPC:
2902 case CPU_TYPE_I386:
2903 if ( fOutputKind != Options::kDynamicLibrary )
2904 fSplitSegs = false;
2905 // make sure read and write segments are proper distance apart
2906 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x10000000) )
2907 fBaseWritableAddress = fBaseAddress + 0x10000000;
2908 break;
2909 case CPU_TYPE_ARM:
2910 if ( fOutputKind != Options::kDynamicLibrary ) {
2911 fSplitSegs = false;
2912 }
2913 else {
2914 // make sure read and write segments are proper distance apart
2915 if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x08000000) )
2916 fBaseWritableAddress = fBaseAddress + 0x08000000;
2917 }
2918 break;
2919 default:
2920 fSplitSegs = false;
2921 fBaseAddress = 0;
2922 fBaseWritableAddress = 0;
2923 }
2924 }
2925
2926 // <rdar://problem/6138961> -r implies no prebinding for all architectures
2927 if ( fOutputKind == Options::kObjectFile )
2928 fPrebind = false;
2929
2930 // disable prebinding depending on arch and min OS version
2931 if ( fPrebind ) {
2932 switch ( fArchitecture ) {
2933 case CPU_TYPE_POWERPC:
2934 case CPU_TYPE_I386:
2935 if ( fReaderOptions.fMacVersionMin == ObjectFile::ReaderOptions::k10_4 ) {
2936 // in 10.4 only split seg dylibs are prebound
2937 if ( (fOutputKind != Options::kDynamicLibrary) || ! fSplitSegs )
2938 fPrebind = false;
2939 }
2940 else if ( fReaderOptions.fMacVersionMin >= ObjectFile::ReaderOptions::k10_5 ) {
2941 // in 10.5 nothing is prebound
2942 fPrebind = false;
2943 }
2944 else {
2945 // in 10.3 and earlier only dylibs and main executables could be prebound
2946 switch ( fOutputKind ) {
2947 case Options::kDynamicExecutable:
2948 case Options::kDynamicLibrary:
2949 // only main executables and dylibs can be prebound
2950 break;
2951 case Options::kStaticExecutable:
2952 case Options::kDynamicBundle:
2953 case Options::kObjectFile:
2954 case Options::kDyld:
2955 case Options::kPreload:
2956 case Options::kKextBundle:
2957 // disable prebinding for everything else
2958 fPrebind = false;
2959 break;
2960 }
2961 }
2962 break;
2963 case CPU_TYPE_POWERPC64:
2964 case CPU_TYPE_X86_64:
2965 fPrebind = false;
2966 break;
2967 case CPU_TYPE_ARM:
2968 switch ( fOutputKind ) {
2969 case Options::kDynamicExecutable:
2970 case Options::kDynamicLibrary:
2971 // only main executables and dylibs can be prebound
2972 break;
2973 case Options::kStaticExecutable:
2974 case Options::kDynamicBundle:
2975 case Options::kObjectFile:
2976 case Options::kDyld:
2977 case Options::kPreload:
2978 case Options::kKextBundle:
2979 // disable prebinding for everything else
2980 fPrebind = false;
2981 break;
2982 }
2983 break;
2984 }
2985 }
2986
2987 // only prebound images can be split-seg
2988 if ( fSplitSegs && !fPrebind )
2989 fSplitSegs = false;
2990
2991 // determine if info for shared region should be added
2992 if ( fOutputKind == Options::kDynamicLibrary ) {
2993 if ( minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k3_1) )
2994 if ( !fPrebind )
2995 if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
2996 || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
2997 fSharedRegionEligible = true;
2998 }
2999
3000 // figure out if module table is needed for compatibility with old ld/dyld
3001 if ( fOutputKind == Options::kDynamicLibrary ) {
3002 switch ( fArchitecture ) {
3003 case CPU_TYPE_POWERPC: // 10.3 and earlier dyld requires a module table
3004 case CPU_TYPE_I386: // ld_classic for 10.4.x requires a module table
3005 if ( fReaderOptions.fMacVersionMin <= ObjectFile::ReaderOptions::k10_5 )
3006 fNeedsModuleTable = true;
3007 break;
3008 case CPU_TYPE_ARM:
3009 if ( fPrebind )
3010 fNeedsModuleTable = true; // redo_prebinding requires a module table
3011 break;
3012 }
3013 }
3014
3015 // <rdar://problem/5366363> -r -x implies -S
3016 if ( (fOutputKind == Options::kObjectFile) && (fLocalSymbolHandling == kLocalSymbolsNone) )
3017 fReaderOptions.fDebugInfoStripping = ObjectFile::ReaderOptions::kDebugInfoNone;
3018
3019 // choose how to process unwind info
3020 switch ( fArchitecture ) {
3021 case CPU_TYPE_I386:
3022 case CPU_TYPE_X86_64:
3023 switch ( fOutputKind ) {
3024 case Options::kObjectFile:
3025 case Options::kStaticExecutable:
3026 case Options::kPreload:
3027 case Options::kKextBundle:
3028 fReaderOptions.fAddCompactUnwindEncoding = false;
3029 break;
3030 case Options::kDyld:
3031 case Options::kDynamicLibrary:
3032 case Options::kDynamicBundle:
3033 case Options::kDynamicExecutable:
3034 //if ( fReaderOptions.fAddCompactUnwindEncoding && (fReaderOptions.fVersionMin >= ObjectFile::ReaderOptions::k10_6) )
3035 // fReaderOptions.fRemoveDwarfUnwindIfCompactExists = true;
3036 break;
3037 }
3038 break;
3039 case CPU_TYPE_POWERPC:
3040 case CPU_TYPE_POWERPC64:
3041 case CPU_TYPE_ARM:
3042 fReaderOptions.fAddCompactUnwindEncoding = false;
3043 fReaderOptions.fRemoveDwarfUnwindIfCompactExists = false;
3044 break;
3045 case 0:
3046 // if -arch is missing, assume we don't want compact unwind info
3047 fReaderOptions.fAddCompactUnwindEncoding = false;
3048 break;
3049 }
3050
3051 // only ARM main executables can be encrypted
3052 if ( fOutputKind != Options::kDynamicExecutable )
3053 fEncryptable = false;
3054 if ( fArchitecture != CPU_TYPE_ARM )
3055 fEncryptable = false;
3056
3057 // don't move inits in dyld because dyld wants certain
3058 // entries point at stable locations at the start of __text
3059 if ( fOutputKind == Options::kDyld )
3060 fReaderOptions.fAutoOrderInitializers = false;
3061
3062
3063 // disable __data ordering for some output kinds
3064 switch ( fOutputKind ) {
3065 case Options::kObjectFile:
3066 case Options::kDyld:
3067 case Options::kStaticExecutable:
3068 case Options::kPreload:
3069 case Options::kKextBundle:
3070 fOrderData = false;
3071 break;
3072 case Options::kDynamicExecutable:
3073 case Options::kDynamicLibrary:
3074 case Options::kDynamicBundle:
3075 break;
3076 }
3077
3078 // only use compressed LINKEDIT for:
3079 // x86_64 and i386 on Mac OS X 10.6 or later
3080 // arm on iPhoneOS 3.1 or later
3081 if ( fMakeCompressedDyldInfo ) {
3082 switch (fArchitecture) {
3083 case CPU_TYPE_I386:
3084 case CPU_TYPE_X86_64:
3085 if ( fReaderOptions.fMacVersionMin >= ObjectFile::ReaderOptions::k10_6 )
3086 fMakeClassicDyldInfo = false;
3087 else if ( fReaderOptions.fMacVersionMin < ObjectFile::ReaderOptions::k10_5 )
3088 fMakeCompressedDyldInfo = false;
3089 break;
3090 case CPU_TYPE_ARM:
3091 if ( fReaderOptions.fIPhoneVersionMin >= ObjectFile::ReaderOptions::k3_1 )
3092 fMakeClassicDyldInfo = false;
3093 else if ( fReaderOptions.fIPhoneVersionMin < ObjectFile::ReaderOptions::k3_1 )
3094 fMakeCompressedDyldInfo = false;
3095 break;
3096 case CPU_TYPE_POWERPC:
3097 case CPU_TYPE_POWERPC64:
3098 default:
3099 fMakeCompressedDyldInfo = false;
3100 }
3101 }
3102
3103
3104 // only use compressed LINKEDIT for final linked images
3105 if ( fMakeCompressedDyldInfo ) {
3106 switch ( fOutputKind ) {
3107 case Options::kDynamicExecutable:
3108 case Options::kDynamicLibrary:
3109 case Options::kDynamicBundle:
3110 break;
3111 case Options::kPreload:
3112 case Options::kStaticExecutable:
3113 case Options::kObjectFile:
3114 case Options::kDyld:
3115 case Options::kKextBundle:
3116 fMakeCompressedDyldInfo = false;
3117 break;
3118 }
3119 }
3120 fReaderOptions.fMakeCompressedDyldInfo = fMakeCompressedDyldInfo;
3121
3122 // only ARM enforces that cpu-sub-types must match
3123 if ( fArchitecture != CPU_TYPE_ARM )
3124 fAllowCpuSubtypeMismatches = true;
3125
3126 // only final linked images can not optimize zero fill sections
3127 if ( fOutputKind == Options::kObjectFile )
3128 fReaderOptions.fOptimizeZeroFill = true;
3129
3130 // only dynamic final linked images should warn about use of commmons
3131 if ( fWarnCommons ) {
3132 switch ( fOutputKind ) {
3133 case Options::kDynamicExecutable:
3134 case Options::kDynamicLibrary:
3135 case Options::kDynamicBundle:
3136 break;
3137 case Options::kPreload:
3138 case Options::kStaticExecutable:
3139 case Options::kObjectFile:
3140 case Options::kDyld:
3141 case Options::kKextBundle:
3142 fWarnCommons = false;
3143 break;
3144 }
3145 }
3146
3147 // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
3148 if ( minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k2_0) )
3149 fUseSimplifiedDylibReExports = true;
3150 }
3151
3152 void Options::checkIllegalOptionCombinations()
3153 {
3154 // check -undefined setting
3155 switch ( fUndefinedTreatment ) {
3156 case kUndefinedError:
3157 case kUndefinedDynamicLookup:
3158 // always legal
3159 break;
3160 case kUndefinedWarning:
3161 case kUndefinedSuppress:
3162 // requires flat namespace
3163 if ( fNameSpace == kTwoLevelNameSpace )
3164 throw "can't use -undefined warning or suppress with -twolevel_namespace";
3165 break;
3166 }
3167
3168 // unify -sub_umbrella with dylibs
3169 for (std::vector<const char*>::iterator it = fSubUmbellas.begin(); it != fSubUmbellas.end(); it++) {
3170 const char* subUmbrella = *it;
3171 bool found = false;
3172 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
3173 Options::FileInfo& info = *fit;
3174 const char* lastSlash = strrchr(info.path, '/');
3175 if ( lastSlash == NULL )
3176 lastSlash = info.path - 1;
3177 if ( strcmp(&lastSlash[1], subUmbrella) == 0 ) {
3178 info.options.fReExport = true;
3179 found = true;
3180 break;
3181 }
3182 }
3183 if ( ! found )
3184 warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella);
3185 }
3186
3187 // unify -sub_library with dylibs
3188 for (std::vector<const char*>::iterator it = fSubLibraries.begin(); it != fSubLibraries.end(); it++) {
3189 const char* subLibrary = *it;
3190 bool found = false;
3191 for (std::vector<Options::FileInfo>::iterator fit = fInputFiles.begin(); fit != fInputFiles.end(); fit++) {
3192 Options::FileInfo& info = *fit;
3193 const char* lastSlash = strrchr(info.path, '/');
3194 if ( lastSlash == NULL )
3195 lastSlash = info.path - 1;
3196 const char* dot = strchr(&lastSlash[1], '.');
3197 if ( dot == NULL )
3198 dot = &lastSlash[strlen(lastSlash)];
3199 if ( strncmp(&lastSlash[1], subLibrary, dot-lastSlash-1) == 0 ) {
3200 info.options.fReExport = true;
3201 found = true;
3202 break;
3203 }
3204 }
3205 if ( ! found )
3206 warning("-sub_library %s does not match a supplied dylib", subLibrary);
3207 }
3208
3209 // sync reader options
3210 if ( fNameSpace != kTwoLevelNameSpace )
3211 fReaderOptions.fFlatNamespace = true;
3212
3213 // check -stack_addr
3214 if ( fStackAddr != 0 ) {
3215 switch (fArchitecture) {
3216 case CPU_TYPE_I386:
3217 case CPU_TYPE_POWERPC:
3218 case CPU_TYPE_ARM:
3219 if ( fStackAddr > 0xFFFFFFFF )
3220 throw "-stack_addr must be < 4G for 32-bit processes";
3221 break;
3222 case CPU_TYPE_POWERPC64:
3223 case CPU_TYPE_X86_64:
3224 break;
3225 }
3226 if ( (fStackAddr & -4096) != fStackAddr )
3227 throw "-stack_addr must be multiples of 4K";
3228 if ( fStackSize == 0 )
3229 throw "-stack_addr must be used with -stack_size";
3230 }
3231
3232 // check -stack_size
3233 if ( fStackSize != 0 ) {
3234 switch (fArchitecture) {
3235 case CPU_TYPE_I386:
3236 case CPU_TYPE_POWERPC:
3237 if ( fStackSize > 0xFFFFFFFF )
3238 throw "-stack_size must be < 4G for 32-bit processes";
3239 if ( fStackAddr == 0 ) {
3240 fStackAddr = 0xC0000000;
3241 }
3242 if ( (fStackAddr > 0xB0000000) && ((fStackAddr-fStackSize) < 0xB0000000) )
3243 warning("custom stack placement overlaps and will disable shared region");
3244 break;
3245 case CPU_TYPE_ARM:
3246 if ( fStackSize > 0x2F000000 )
3247 throw "-stack_size must be < 752MB";
3248 if ( fStackAddr == 0 )
3249 fStackAddr = 0x2F000000;
3250 if ( fStackAddr > 0x30000000)
3251 throw "-stack_addr must be < 0x30000000 for arm";
3252 case CPU_TYPE_POWERPC64:
3253 case CPU_TYPE_X86_64:
3254 if ( fStackAddr == 0 ) {
3255 fStackAddr = 0x00007FFF5C000000LL;
3256 }
3257 break;
3258 }
3259 if ( (fStackSize & -4096) != fStackSize )
3260 throw "-stack_size must be multiples of 4K";
3261 switch ( fOutputKind ) {
3262 case Options::kDynamicExecutable:
3263 case Options::kStaticExecutable:
3264 // custom stack size only legal when building main executable
3265 break;
3266 case Options::kDynamicLibrary:
3267 case Options::kDynamicBundle:
3268 case Options::kObjectFile:
3269 case Options::kDyld:
3270 case Options::kPreload:
3271 case Options::kKextBundle:
3272 throw "-stack_size option can only be used when linking a main executable";
3273 }
3274 }
3275
3276 // check that -allow_stack_execute is only used with main executables
3277 if ( fExecutableStack ) {
3278 switch ( fOutputKind ) {
3279 case Options::kDynamicExecutable:
3280 case Options::kStaticExecutable:
3281 // -allow_stack_execute size only legal when building main executable
3282 break;
3283 case Options::kDynamicLibrary:
3284 case Options::kDynamicBundle:
3285 case Options::kObjectFile:
3286 case Options::kDyld:
3287 case Options::kPreload:
3288 case Options::kKextBundle:
3289 throw "-allow_stack_execute option can only be used when linking a main executable";
3290 }
3291 }
3292
3293 // check -client_name is only used when making a bundle or main executable
3294 if ( fClientName != NULL ) {
3295 switch ( fOutputKind ) {
3296 case Options::kDynamicExecutable:
3297 case Options::kDynamicBundle:
3298 break;
3299 case Options::kStaticExecutable:
3300 case Options::kDynamicLibrary:
3301 case Options::kObjectFile:
3302 case Options::kDyld:
3303 case Options::kPreload:
3304 case Options::kKextBundle:
3305 throw "-client_name can only be used with -bundle";
3306 }
3307 }
3308
3309 // check -init is only used when building a dylib
3310 if ( (fInitFunctionName != NULL) && (fOutputKind != Options::kDynamicLibrary) )
3311 throw "-init can only be used with -dynamiclib";
3312
3313 // check -bundle_loader only used with -bundle
3314 if ( (fBundleLoader != NULL) && (fOutputKind != Options::kDynamicBundle) )
3315 throw "-bundle_loader can only be used with -bundle";
3316
3317 // check -dtrace not used with -r
3318 if ( (fDtraceScriptName != NULL) && (fOutputKind == Options::kObjectFile) )
3319 throw "-dtrace can only be used when creating final linked images";
3320
3321 // check -d can only be used with -r
3322 if ( fReaderOptions.fMakeTentativeDefinitionsReal && (fOutputKind != Options::kObjectFile) )
3323 throw "-d can only be used with -r";
3324
3325 // check that -root_safe is not used with -r
3326 if ( fReaderOptions.fRootSafe && (fOutputKind == Options::kObjectFile) )
3327 throw "-root_safe cannot be used with -r";
3328
3329 // check that -setuid_safe is not used with -r
3330 if ( fReaderOptions.fSetuidSafe && (fOutputKind == Options::kObjectFile) )
3331 throw "-setuid_safe cannot be used with -r";
3332
3333 // make sure all required exported symbols exist
3334 std::vector<const char*> impliedExports;
3335 for (NameSet::iterator it=fExportSymbols.regularBegin(); it != fExportSymbols.regularEnd(); it++) {
3336 const char* name = *it;
3337 // never export .eh symbols
3338 const int len = strlen(name);
3339 if ( (strcmp(&name[len-3], ".eh") == 0) || (strncmp(name, ".objc_category_name_", 20) == 0) )
3340 warning("ignoring %s in export list", name);
3341 else
3342 fInitialUndefines.push_back(name);
3343 if ( strncmp(name, ".objc_class_name_", 17) == 0 ) {
3344 // rdar://problem/4718189 map ObjC class names to new runtime names
3345 switch (fArchitecture) {
3346 case CPU_TYPE_POWERPC64:
3347 case CPU_TYPE_X86_64:
3348 case CPU_TYPE_ARM:
3349 char* temp;
3350 asprintf(&temp, "_OBJC_CLASS_$_%s", &name[17]);
3351 impliedExports.push_back(temp);
3352 asprintf(&temp, "_OBJC_METACLASS_$_%s", &name[17]);
3353 impliedExports.push_back(temp);
3354 break;
3355 }
3356 }
3357 }
3358 for (std::vector<const char*>::iterator it=impliedExports.begin(); it != impliedExports.end(); it++) {
3359 const char* name = *it;
3360 fExportSymbols.insert(name);
3361 fInitialUndefines.push_back(name);
3362 }
3363
3364 // make sure that -init symbol exist
3365 if ( fInitFunctionName != NULL )
3366 fInitialUndefines.push_back(fInitFunctionName);
3367
3368 // check custom segments
3369 if ( fCustomSegmentAddresses.size() != 0 ) {
3370 // verify no segment is in zero page
3371 if ( fZeroPageSize != ULLONG_MAX ) {
3372 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
3373 if ( (it->address >= 0) && (it->address < fZeroPageSize) )
3374 throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it->name, it->address);
3375 }
3376 }
3377 // verify no duplicates
3378 for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
3379 for (std::vector<SegmentStart>::iterator it2 = fCustomSegmentAddresses.begin(); it2 != fCustomSegmentAddresses.end(); ++it2) {
3380 if ( (it->address == it2->address) && (it != it2) )
3381 throwf("duplicate -segaddr addresses for %s and %s", it->name, it2->name);
3382 }
3383 // a custom segment address of zero will disable the use of a zero page
3384 if ( it->address == 0 )
3385 fZeroPageSize = 0;
3386 }
3387 }
3388
3389 if ( fZeroPageSize == ULLONG_MAX ) {
3390 // zero page size not specified on command line, set default
3391 switch (fArchitecture) {
3392 case CPU_TYPE_I386:
3393 case CPU_TYPE_POWERPC:
3394 case CPU_TYPE_ARM:
3395 // first 4KB for 32-bit architectures
3396 fZeroPageSize = 0x1000;
3397 break;
3398 case CPU_TYPE_POWERPC64:
3399 // first 4GB for ppc64 on 10.5
3400 if ( fReaderOptions.fMacVersionMin >= ObjectFile::ReaderOptions::k10_5 )
3401 fZeroPageSize = 0x100000000ULL;
3402 else
3403 fZeroPageSize = 0x1000; // 10.4 dyld may not be able to handle >4GB zero page
3404 break;
3405 case CPU_TYPE_X86_64:
3406 // first 4GB for x86_64 on all OS's
3407 fZeroPageSize = 0x100000000ULL;
3408 break;
3409 default:
3410 // if -arch not used, default to 4K zero-page
3411 fZeroPageSize = 0x1000;
3412 }
3413 }
3414 else {
3415 switch ( fOutputKind ) {
3416 case Options::kDynamicExecutable:
3417 case Options::kStaticExecutable:
3418 // -pagezero_size size only legal when building main executable
3419 break;
3420 case Options::kDynamicLibrary:
3421 case Options::kDynamicBundle:
3422 case Options::kObjectFile:
3423 case Options::kDyld:
3424 case Options::kPreload:
3425 case Options::kKextBundle:
3426 if ( fZeroPageSize != 0 )
3427 throw "-pagezero_size option can only be used when linking a main executable";
3428 }
3429 }
3430
3431 // -dead_strip and -r are incompatible
3432 if ( (fDeadStrip != kDeadStripOff) && (fOutputKind == Options::kObjectFile) )
3433 throw "-r and -dead_strip cannot be used together";
3434
3435 // can't use -rpath unless targeting 10.5 or later
3436 if ( fRPaths.size() > 0 ) {
3437 if ( !minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k2_0) )
3438 throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
3439 switch ( fOutputKind ) {
3440 case Options::kDynamicExecutable:
3441 case Options::kDynamicLibrary:
3442 case Options::kDynamicBundle:
3443 break;
3444 case Options::kStaticExecutable:
3445 case Options::kObjectFile:
3446 case Options::kDyld:
3447 case Options::kPreload:
3448 case Options::kKextBundle:
3449 throw "-rpath can only be used when creating a dynamic final linked image";
3450 }
3451 }
3452
3453 // check -pie is only used when building a dynamic main executable for 10.5
3454 if ( fPositionIndependentExecutable ) {
3455 switch ( fOutputKind ) {
3456 case Options::kDynamicExecutable:
3457 case Options::kPreload:
3458 break;
3459 case Options::kDynamicLibrary:
3460 case Options::kDynamicBundle:
3461 warning("-pie being ignored. It is only used when linking a main executable");
3462 break;
3463 case Options::kStaticExecutable:
3464 case Options::kObjectFile:
3465 case Options::kDyld:
3466 case Options::kKextBundle:
3467 throw "-pie can only be used when linking a main executable";
3468 }
3469 if ( !minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k2_0) )
3470 throw "-pie can only be used when targeting Mac OS X 10.5 or later";
3471 }
3472
3473 // check -read_only_relocs is not used with x86_64
3474 if ( fAllowTextRelocs ) {
3475 if ( (fArchitecture == CPU_TYPE_X86_64) && (fOutputKind != kKextBundle) ) {
3476 warning("-read_only_relocs cannot be used with x86_64");
3477 fAllowTextRelocs = false;
3478 }
3479 }
3480
3481 // check -mark_auto_dead_strip is only used with dylibs
3482 if ( fMarkDeadStrippableDylib ) {
3483 if ( fOutputKind != Options::kDynamicLibrary ) {
3484 warning("-mark_auto_dead_strip can only be used when creating a dylib");
3485 fMarkDeadStrippableDylib = false;
3486 }
3487 }
3488
3489 // -force_cpusubtype_ALL is not supported for ARM
3490 if ( fForceSubtypeAll ) {
3491 if ( fArchitecture == CPU_TYPE_ARM ) {
3492 warning("-force_cpusubtype_ALL will become unsupported for ARM architectures");
3493 }
3494 }
3495 }
3496
3497
3498 void Options::checkForClassic(int argc, const char* argv[])
3499 {
3500 // scan options
3501 bool archFound = false;
3502 bool staticFound = false;
3503 bool dtraceFound = false;
3504 bool kextFound = false;
3505 bool rFound = false;
3506 bool creatingMachKernel = false;
3507 bool newLinker = false;
3508
3509 // build command line buffer in case ld crashes
3510 for(int i=1; i < argc; ++i) {
3511 strlcat(crashreporterBuffer, argv[i], 1000);
3512 strlcat(crashreporterBuffer, " ", 1000);
3513 }
3514
3515 for(int i=0; i < argc; ++i) {
3516 const char* arg = argv[i];
3517 if ( arg[0] == '-' ) {
3518 if ( strcmp(arg, "-arch") == 0 ) {
3519 parseArch(argv[++i]);
3520 archFound = true;
3521 }
3522 else if ( strcmp(arg, "-static") == 0 ) {
3523 staticFound = true;
3524 }
3525 else if ( strcmp(arg, "-kext") == 0 ) {
3526 kextFound = true;
3527 }
3528 else if ( strcmp(arg, "-dtrace") == 0 ) {
3529 dtraceFound = true;
3530 }
3531 else if ( strcmp(arg, "-r") == 0 ) {
3532 rFound = true;
3533 }
3534 else if ( strcmp(arg, "-new_linker") == 0 ) {
3535 newLinker = true;
3536 }
3537 else if ( strcmp(arg, "-classic_linker") == 0 ) {
3538 // ld_classic does not understand this option, so remove it
3539 for(int j=i; j < argc; ++j)
3540 argv[j] = argv[j+1];
3541 this->gotoClassicLinker(argc-1, argv);
3542 }
3543 else if ( strcmp(arg, "-o") == 0 ) {
3544 const char* outfile = argv[++i];
3545 if ( (outfile != NULL) && (strstr(outfile, "/mach_kernel") != NULL) )
3546 creatingMachKernel = true;
3547 }
3548 }
3549 }
3550
3551 // -dtrace only supported by new linker
3552 if( dtraceFound )
3553 return;
3554
3555 if( archFound ) {
3556 switch ( fArchitecture ) {
3557 case CPU_TYPE_POWERPC:
3558 case CPU_TYPE_I386:
3559 case CPU_TYPE_ARM:
3560 // if ( staticFound && (rFound || !creatingMachKernel) ) {
3561 if ( (staticFound || kextFound) && !newLinker ) {
3562 // this environment variable will disable use of ld_classic for -static links
3563 if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL ) {
3564 // ld_classic does not support -iphoneos_version_min, so change
3565 for(int j=0; j < argc; ++j) {
3566 if ( strcmp(argv[j], "-iphoneos_version_min") == 0) {
3567 argv[j] = "-macosx_version_min";
3568 if ( j < argc-1 )
3569 argv[j+1] = "10.5";
3570 break;
3571 }
3572 }
3573 // ld classic does not understand -kext (change to -static -r)
3574 if ( kextFound ) {
3575 for(int j=0; j < argc; ++j) {
3576 if ( strcmp(argv[j], "-kext") == 0)
3577 argv[j] = "-r";
3578 else if ( strcmp(argv[j], "-dynamic") == 0)
3579 argv[j] = "-static";
3580 }
3581 }
3582 this->gotoClassicLinker(argc, argv);
3583 }
3584 }
3585 break;
3586 }
3587 }
3588 else {
3589 // work around for VSPTool
3590 if ( staticFound )
3591 this->gotoClassicLinker(argc, argv);
3592 }
3593
3594 }
3595
3596 void Options::gotoClassicLinker(int argc, const char* argv[])
3597 {
3598 argv[0] = "ld_classic";
3599 char rawPath[PATH_MAX];
3600 char path[PATH_MAX];
3601 uint32_t bufSize = PATH_MAX;
3602 if ( _NSGetExecutablePath(rawPath, &bufSize) != -1 ) {
3603 if ( realpath(rawPath, path) != NULL ) {
3604 char* lastSlash = strrchr(path, '/');
3605 if ( lastSlash != NULL ) {
3606 strcpy(lastSlash+1, "ld_classic");
3607 argv[0] = path;
3608 execvp(path, (char**)argv);
3609 }
3610 }
3611 }
3612 // in case of error in above, try searching for ld_classic via PATH
3613 execvp(argv[0], (char**)argv);
3614 fprintf(stderr, "can't exec ld_classic\n");
3615 exit(1);
3616 }