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