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