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