]> git.saurik.com Git - apple/ld64.git/blob - src/ld/Options.h
9b8890e647d308d8a35b45b68128760426106410
[apple/ld64.git] / src / ld / Options.h
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2005-2007 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 #ifndef __OPTIONS__
26 #define __OPTIONS__
27
28
29 #include <stdint.h>
30 #include <mach/machine.h>
31
32 #include <vector>
33 #include <ext/hash_set>
34 #include <ext/hash_map>
35
36 #include "ObjectFile.h"
37
38 extern void throwf (const char* format, ...) __attribute__ ((noreturn));
39 extern void warning(const char* format, ...);
40
41 class LibraryOptions
42 {
43 public:
44 LibraryOptions() : fWeakImport(false), fReExport(false), fBundleLoader(false), fLazyLoad(false), fForceLoad(false) {}
45 // for dynamic libraries
46 bool fWeakImport;
47 bool fReExport;
48 bool fBundleLoader;
49 bool fLazyLoad;
50 // for static libraries
51 bool fForceLoad;
52 };
53
54
55
56 //
57 // The public interface to the Options class is the abstract representation of what work the linker
58 // should do.
59 //
60 // This abstraction layer will make it easier to support a future where the linker is a shared library
61 // invoked directly from Xcode. The target settings in Xcode would be used to directly construct an Options
62 // object (without building a command line which is then parsed).
63 //
64 //
65 class Options
66 {
67 public:
68 Options(int argc, const char* argv[]);
69 ~Options();
70
71 enum OutputKind { kDynamicExecutable, kStaticExecutable, kDynamicLibrary, kDynamicBundle, kObjectFile, kDyld, kPreload, kKextBundle };
72 enum NameSpace { kTwoLevelNameSpace, kFlatNameSpace, kForceFlatNameSpace };
73 // Standard treatment for many options.
74 enum Treatment { kError, kWarning, kSuppress, kNULL, kInvalid };
75 enum UndefinedTreatment { kUndefinedError, kUndefinedWarning, kUndefinedSuppress, kUndefinedDynamicLookup };
76 enum WeakReferenceMismatchTreatment { kWeakReferenceMismatchError, kWeakReferenceMismatchWeak,
77 kWeakReferenceMismatchNonWeak };
78 enum CommonsMode { kCommonsIgnoreDylibs, kCommonsOverriddenByDylibs, kCommonsConflictsDylibsError };
79 enum DeadStripMode { kDeadStripOff, kDeadStripOn, kDeadStripOnPlusUnusedInits };
80 enum UUIDMode { kUUIDNone, kUUIDRandom, kUUIDContent };
81 enum LocalSymbolHandling { kLocalSymbolsAll, kLocalSymbolsNone, kLocalSymbolsSelectiveInclude, kLocalSymbolsSelectiveExclude };
82
83 struct FileInfo {
84 const char* path;
85 uint64_t fileLen;
86 time_t modTime;
87 LibraryOptions options;
88 };
89
90 struct ExtraSection {
91 const char* segmentName;
92 const char* sectionName;
93 const char* path;
94 const uint8_t* data;
95 uint64_t dataLen;
96 };
97
98 struct SectionAlignment {
99 const char* segmentName;
100 const char* sectionName;
101 uint8_t alignment;
102 };
103
104 struct OrderedSymbol {
105 const char* symbolName;
106 const char* objectFileName;
107 };
108
109 struct SegmentStart {
110 const char* name;
111 uint64_t address;
112 };
113
114 struct SegmentSize {
115 const char* name;
116 uint64_t size;
117 };
118
119 struct SegmentProtect {
120 const char* name;
121 uint32_t max;
122 uint32_t init;
123 };
124
125 struct DylibOverride {
126 const char* installName;
127 const char* useInstead;
128 };
129
130
131 const ObjectFile::ReaderOptions& readerOptions();
132 const char* getOutputFilePath();
133 std::vector<FileInfo>& getInputFiles();
134
135 cpu_type_t architecture() { return fArchitecture; }
136 bool preferSubArchitecture() { return fHasPreferredSubType; }
137 cpu_subtype_t subArchitecture() { return fSubArchitecture; }
138 bool allowSubArchitectureMismatches() { return fAllowCpuSubtypeMismatches; }
139 OutputKind outputKind();
140 bool prebind();
141 bool bindAtLoad();
142 bool fullyLoadArchives();
143 NameSpace nameSpace();
144 const char* installPath(); // only for kDynamicLibrary
145 uint32_t currentVersion(); // only for kDynamicLibrary
146 uint32_t compatibilityVersion(); // only for kDynamicLibrary
147 const char* entryName(); // only for kDynamicExecutable or kStaticExecutable
148 const char* executablePath();
149 uint64_t baseAddress();
150 bool keepPrivateExterns(); // only for kObjectFile
151 bool needsModuleTable(); // only for kDynamicLibrary
152 bool interposable(const char* name);
153 bool hasExportRestrictList(); // -exported_symbol or -unexported_symbol
154 bool hasExportMaskList(); // just -exported_symbol
155 bool hasWildCardExportRestrictList();
156 bool allGlobalsAreDeadStripRoots();
157 bool shouldExport(const char*);
158 bool ignoreOtherArchInputFiles();
159 bool forceCpuSubtypeAll();
160 bool traceDylibs();
161 bool traceArchives();
162 DeadStripMode deadStrip();
163 UndefinedTreatment undefinedTreatment();
164 ObjectFile::ReaderOptions::MacVersionMin macosxVersionMin() { return fReaderOptions.fMacVersionMin; }
165 ObjectFile::ReaderOptions::IPhoneVersionMin iphoneOSVersionMin() { return fReaderOptions.fIPhoneVersionMin; }
166 bool minOS(ObjectFile::ReaderOptions::MacVersionMin mac, ObjectFile::ReaderOptions::IPhoneVersionMin iPhoneOS);
167 bool messagesPrefixedWithArchitecture();
168 Treatment picTreatment();
169 WeakReferenceMismatchTreatment weakReferenceMismatchTreatment();
170 const char* umbrellaName();
171 std::vector<const char*>& allowableClients();
172 const char* clientName();
173 const char* initFunctionName(); // only for kDynamicLibrary
174 const char* dotOutputFile();
175 uint64_t zeroPageSize();
176 bool hasCustomStack();
177 uint64_t customStackSize();
178 uint64_t customStackAddr();
179 bool hasExecutableStack();
180 std::vector<const char*>& initialUndefines();
181 bool printWhyLive(const char* name);
182 uint32_t minimumHeaderPad();
183 uint64_t segmentAlignment() { return fSegmentAlignment; }
184 bool maxMminimumHeaderPad() { return fMaxMinimumHeaderPad; }
185 std::vector<ExtraSection>& extraSections();
186 std::vector<SectionAlignment>& sectionAlignments();
187 CommonsMode commonsMode();
188 bool warnCommons();
189 bool keepRelocations();
190 FileInfo findFile(const char* path);
191 UUIDMode getUUIDMode() { return fUUIDMode; }
192 bool warnStabs();
193 bool pauseAtEnd() { return fPause; }
194 bool printStatistics() { return fStatistics; }
195 bool printArchPrefix() { return fMessagesPrefixedWithArchitecture; }
196 void gotoClassicLinker(int argc, const char* argv[]);
197 bool sharedRegionEligible() { return fSharedRegionEligible; }
198 bool printOrderFileStatistics() { return fPrintOrderFileStatistics; }
199 const char* dTraceScriptName() { return fDtraceScriptName; }
200 bool dTrace() { return (fDtraceScriptName != NULL); }
201 std::vector<OrderedSymbol>& orderedSymbols() { return fOrderedSymbols; }
202 bool splitSeg() { return fSplitSegs; }
203 uint64_t baseWritableAddress() { return fBaseWritableAddress; }
204 std::vector<SegmentStart>& customSegmentAddresses() { return fCustomSegmentAddresses; }
205 std::vector<SegmentSize>& customSegmentSizes() { return fCustomSegmentSizes; }
206 std::vector<SegmentProtect>& customSegmentProtections() { return fCustomSegmentProtections; }
207 bool saveTempFiles() { return fSaveTempFiles; }
208 const std::vector<const char*>& rpaths() { return fRPaths; }
209 bool readOnlyx86Stubs() { return fReadOnlyx86Stubs; }
210 std::vector<DylibOverride>& dylibOverrides() { return fDylibOverrides; }
211 const char* generatedMapPath() { return fMapPath; }
212 bool positionIndependentExecutable() { return fPositionIndependentExecutable; }
213 Options::FileInfo findFileUsingPaths(const char* path);
214 bool deadStripDylibs() { return fDeadStripDylibs; }
215 bool allowedUndefined(const char* name) { return ( fAllowedUndefined.find(name) != fAllowedUndefined.end() ); }
216 bool someAllowedUndefines() { return (fAllowedUndefined.size() != 0); }
217 LocalSymbolHandling localSymbolHandling() { return fLocalSymbolHandling; }
218 bool keepLocalSymbol(const char* symbolName);
219 bool allowTextRelocs() { return fAllowTextRelocs; }
220 bool warnAboutTextRelocs() { return fWarnTextRelocs; }
221 bool usingLazyDylibLinking() { return fUsingLazyDylibLinking; }
222 bool verbose() { return fVerbose; }
223 bool makeEncryptable() { return fEncryptable; }
224 bool needsUnwindInfoSection() { return fReaderOptions.fAddCompactUnwindEncoding; }
225 std::vector<const char*>& llvmOptions() { return fLLVMOptions; }
226 bool makeClassicDyldInfo() { return fMakeClassicDyldInfo; }
227 bool makeCompressedDyldInfo() { return fMakeCompressedDyldInfo; }
228 bool hasExportedSymbolOrder();
229 bool exportedSymbolOrder(const char* sym, unsigned int* order);
230 bool orderData() { return fOrderData; }
231 bool errorOnOtherArchFiles() { return fErrorOnOtherArchFiles; }
232 bool markAutoDeadStripDylib() { return fMarkDeadStrippableDylib; }
233 bool removeEHLabels() { return fReaderOptions.fNoEHLabels; }
234
235 private:
236 class CStringEquals
237 {
238 public:
239 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
240 };
241 typedef __gnu_cxx::hash_map<const char*, unsigned int, __gnu_cxx::hash<const char*>, CStringEquals> NameToOrder;
242 typedef __gnu_cxx::hash_set<const char*, __gnu_cxx::hash<const char*>, CStringEquals> NameSet;
243 enum ExportMode { kExportDefault, kExportSome, kDontExportSome };
244 enum LibrarySearchMode { kSearchDylibAndArchiveInEachDir, kSearchAllDirsForDylibsThenAllDirsForArchives };
245 enum InterposeMode { kInterposeNone, kInterposeAllExternal, kInterposeSome };
246
247 class SetWithWildcards {
248 public:
249 void insert(const char*);
250 bool contains(const char*);
251 bool hasWildCards() { return !fWildCard.empty(); }
252 NameSet::iterator regularBegin() { return fRegular.begin(); }
253 NameSet::iterator regularEnd() { return fRegular.end(); }
254 private:
255 static bool hasWildCards(const char*);
256 bool wildCardMatch(const char* pattern, const char* candidate);
257 bool inCharRange(const char*& range, unsigned char c);
258
259 NameSet fRegular;
260 std::vector<const char*> fWildCard;
261 };
262
263
264 void parse(int argc, const char* argv[]);
265 void checkIllegalOptionCombinations();
266 void buildSearchPaths(int argc, const char* argv[]);
267 void parseArch(const char* architecture);
268 FileInfo findLibrary(const char* rootName, bool dylibsOnly=false);
269 FileInfo findFramework(const char* frameworkName);
270 FileInfo findFramework(const char* rootName, const char* suffix);
271 bool checkForFile(const char* format, const char* dir, const char* rootName,
272 FileInfo& result);
273 uint32_t parseVersionNumber(const char*);
274 void parseSectionOrderFile(const char* segment, const char* section, const char* path);
275 void parseOrderFile(const char* path, bool cstring);
276 void addSection(const char* segment, const char* section, const char* path);
277 void addSubLibrary(const char* name);
278 void loadFileList(const char* fileOfPaths);
279 uint64_t parseAddress(const char* addr);
280 void loadExportFile(const char* fileOfExports, const char* option, SetWithWildcards& set);
281 void parseAliasFile(const char* fileOfAliases);
282 void parsePreCommandLineEnvironmentSettings();
283 void parsePostCommandLineEnvironmentSettings();
284 void setUndefinedTreatment(const char* treatment);
285 void setMacOSXVersionMin(const char* version);
286 void setIPhoneVersionMin(const char* version);
287 void setWeakReferenceMismatchTreatment(const char* treatment);
288 void addDylibOverride(const char* paths);
289 void addSectionAlignment(const char* segment, const char* section, const char* alignment);
290 CommonsMode parseCommonsTreatment(const char* mode);
291 Treatment parseTreatment(const char* treatment);
292 void reconfigureDefaults();
293 void checkForClassic(int argc, const char* argv[]);
294 void parseSegAddrTable(const char* segAddrPath, const char* installPath);
295 void addLibrary(const FileInfo& info);
296 void warnObsolete(const char* arg);
297 uint32_t parseProtection(const char* prot);
298 void loadSymbolOrderFile(const char* fileOfExports, NameToOrder& orderMapping);
299
300
301 ObjectFile::ReaderOptions fReaderOptions;
302 const char* fOutputFile;
303 std::vector<Options::FileInfo> fInputFiles;
304 cpu_type_t fArchitecture;
305 cpu_subtype_t fSubArchitecture;
306 OutputKind fOutputKind;
307 bool fHasPreferredSubType;
308 bool fPrebind;
309 bool fBindAtLoad;
310 bool fKeepPrivateExterns;
311 bool fNeedsModuleTable;
312 bool fIgnoreOtherArchFiles;
313 bool fErrorOnOtherArchFiles;
314 bool fForceSubtypeAll;
315 InterposeMode fInterposeMode;
316 DeadStripMode fDeadStrip;
317 NameSpace fNameSpace;
318 uint32_t fDylibCompatVersion;
319 uint32_t fDylibCurrentVersion;
320 const char* fDylibInstallName;
321 const char* fFinalName;
322 const char* fEntryName;
323 uint64_t fBaseAddress;
324 uint64_t fBaseWritableAddress;
325 bool fSplitSegs;
326 SetWithWildcards fExportSymbols;
327 SetWithWildcards fDontExportSymbols;
328 SetWithWildcards fInterposeList;
329 NameToOrder fExportSymbolsOrder;
330 ExportMode fExportMode;
331 LibrarySearchMode fLibrarySearchMode;
332 UndefinedTreatment fUndefinedTreatment;
333 bool fMessagesPrefixedWithArchitecture;
334 WeakReferenceMismatchTreatment fWeakReferenceMismatchTreatment;
335 std::vector<const char*> fSubUmbellas;
336 std::vector<const char*> fSubLibraries;
337 std::vector<const char*> fAllowableClients;
338 std::vector<const char*> fRPaths;
339 const char* fClientName;
340 const char* fUmbrellaName;
341 const char* fInitFunctionName;
342 const char* fDotOutputFile;
343 const char* fExecutablePath;
344 const char* fBundleLoader;
345 const char* fDtraceScriptName;
346 const char* fSegAddrTablePath;
347 const char* fMapPath;
348 uint64_t fZeroPageSize;
349 uint64_t fStackSize;
350 uint64_t fStackAddr;
351 bool fExecutableStack;
352 uint32_t fMinimumHeaderPad;
353 uint64_t fSegmentAlignment;
354 CommonsMode fCommonsMode;
355 UUIDMode fUUIDMode;
356 SetWithWildcards fLocalSymbolsIncluded;
357 SetWithWildcards fLocalSymbolsExcluded;
358 LocalSymbolHandling fLocalSymbolHandling;
359 bool fWarnCommons;
360 bool fVerbose;
361 bool fKeepRelocations;
362 bool fWarnStabs;
363 bool fTraceDylibSearching;
364 bool fPause;
365 bool fStatistics;
366 bool fPrintOptions;
367 bool fSharedRegionEligible;
368 bool fPrintOrderFileStatistics;
369 bool fReadOnlyx86Stubs;
370 bool fPositionIndependentExecutable;
371 bool fMaxMinimumHeaderPad;
372 bool fDeadStripDylibs;
373 bool fAllowTextRelocs;
374 bool fWarnTextRelocs;
375 bool fUsingLazyDylibLinking;
376 bool fEncryptable;
377 bool fOrderData;
378 bool fMarkDeadStrippableDylib;
379 bool fMakeClassicDyldInfo;
380 bool fMakeCompressedDyldInfo;
381 bool fNoEHLabels;
382 bool fAllowCpuSubtypeMismatches;
383 std::vector<const char*> fInitialUndefines;
384 NameSet fAllowedUndefined;
385 NameSet fWhyLive;
386 std::vector<ExtraSection> fExtraSections;
387 std::vector<SectionAlignment> fSectionAlignments;
388 std::vector<OrderedSymbol> fOrderedSymbols;
389 std::vector<SegmentStart> fCustomSegmentAddresses;
390 std::vector<SegmentSize> fCustomSegmentSizes;
391 std::vector<SegmentProtect> fCustomSegmentProtections;
392 std::vector<DylibOverride> fDylibOverrides;
393 std::vector<const char*> fLLVMOptions;
394 std::vector<const char*> fLibrarySearchPaths;
395 std::vector<const char*> fFrameworkSearchPaths;
396 std::vector<const char*> fSDKPaths;
397 bool fSaveTempFiles;
398 };
399
400
401
402 #endif // __OPTIONS__