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