]> git.saurik.com Git - apple/ld64.git/blame - src/ld/ld.hpp
ld64-305.tar.gz
[apple/ld64.git] / src / ld / ld.hpp
CommitLineData
a645023d
A
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2005-2010 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#ifndef __LD_HPP__
27#define __LD_HPP__
28
29#include <stdint.h>
30#include <math.h>
31#include <unistd.h>
32#include <assert.h>
33
eaf282aa
A
34#include <set>
35#include <map>
a645023d 36#include <vector>
eaf282aa 37#include <string>
f80fe69f 38#include <unordered_set>
a645023d 39
f80fe69f 40#include "configure.h"
a645023d
A
41
42namespace ld {
43
eaf282aa
A
44// Forward declaration for bitcode support
45class Bitcode;
46
a645023d
A
47//
48// ld::File
49//
50// Abstract base class for all object or library files the linker processes.
51//
52// forEachAtom() iterates over the Atoms in the order they occur in the file.
53//
54// justInTimeforEachAtom(name) iterates over lazily created Atoms. For instance if
55// File is a static library, justInTimeforEachAtom() will iterate over the base set
56// of Atoms from the archive member implementing 'name'.
57//
58class File
59{
60public:
f80fe69f
A
61 enum ObjcConstraint { objcConstraintNone, objcConstraintRetainRelease,
62 objcConstraintRetainReleaseOrGC, objcConstraintGC,
63 objcConstraintRetainReleaseForSimulator };
a645023d
A
64
65 class AtomHandler {
66 public:
67 virtual ~AtomHandler() {}
68 virtual void doAtom(const class Atom&) = 0;
69 virtual void doFile(const class File&) = 0;
70 };
71
ebf6f434
A
72 //
73 // ld::File::Ordinal
74 //
75 // Codifies the rules of ordering input files for symbol precedence. These are:
76 // - Input files listed on the command line are ordered according to their index in the argument list.
77 // - Input files listed in a file list are ordered first at the index of the file list argument, then
78 // by index in the file list
79 // - Input files extracted from archives are ordered using the ordinal of the archive itself plus the
80 // index of the object file within the archive
81 // - Indirect dylibs are ordered after all input files derived from the command line, in the order that
82 // they are discovered.
83 // - The LTO object file is last.
84 //
85 class Ordinal
86 {
87 private:
88 // The actual numeric ordinal. Lower values have higher precedence and a zero value is invalid.
89 // The 64 bit ordinal is broken into 4 16 bit chunks. The high 16 bits are a "partition" that
90 // is used to distinguish major ordinal groups: command line, indirect dylib, LTO.
91 // The remaining chunks are used according to the partition (see below).
92 uint64_t _ordinal;
93
94 Ordinal (uint64_t ordinal) : _ordinal(ordinal) {}
95
0a8dc3df 96 enum { kArgListPartition=0, kIndirectDylibPartition=1, kLTOPartition = 2, kLinkerOptionPartition = 3, InvalidParition=0xffff };
ebf6f434
A
97 Ordinal(uint16_t partition, uint16_t majorIndex, uint16_t minorIndex, uint16_t counter) {
98 _ordinal = ((uint64_t)partition<<48) | ((uint64_t)majorIndex<<32) | ((uint64_t)minorIndex<<16) | ((uint64_t)counter<<0);
99 }
100
101 const uint16_t partition() const { return (_ordinal>>48)&0xffff; }
102 const uint16_t majorIndex() const { return (_ordinal>>32)&0xffff; }
103 const uint16_t minorIndex() const { return (_ordinal>>16)&0xffff; }
104 const uint16_t counter() const { return (_ordinal>>00)&0xffff; }
0a8dc3df 105
ebf6f434
A
106 const Ordinal nextMajorIndex() const { assert(majorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<32)); }
107 const Ordinal nextMinorIndex() const { assert(minorIndex() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<16)); }
108 const Ordinal nextCounter() const { assert(counter() < 0xffff); return Ordinal(_ordinal+((uint64_t)1<<0)); }
109
110 public:
111 Ordinal() : _ordinal(0) {};
0a8dc3df 112
ebf6f434
A
113 static const Ordinal NullOrdinal() { return Ordinal((uint64_t)0); }
114
115 const bool validOrdinal() const { return _ordinal != 0; }
116
117 bool operator ==(const Ordinal& rhs) const { return _ordinal == rhs._ordinal; }
118 bool operator !=(const Ordinal& rhs) const { return _ordinal != rhs._ordinal; }
119 bool operator < (const Ordinal& rhs) const { return _ordinal < rhs._ordinal; }
120 bool operator > (const Ordinal& rhs) const { return _ordinal > rhs._ordinal; }
121
122 // For ordinals derived from the command line args the partition is ArgListPartition
123 // The majorIndex is the arg index that pulls in the file, file list, or archive.
124 // The minorIndex is used for files pulled in by a file list and the value is the index of the file in the file list.
125 // The counter is used for .a files and the value is the index of the object in the archive.
126 // Thus, an object pulled in from a .a that was listed in a file list could use all three fields.
f80fe69f 127 static const Ordinal makeArgOrdinal(uint16_t argIndex) { return Ordinal(kArgListPartition, argIndex, 0, 0); };
ebf6f434 128 const Ordinal nextFileListOrdinal() const { return nextMinorIndex(); }
0a8dc3df 129 const Ordinal archiveOrdinalWithMemberIndex(uint16_t memberIndex) const { return Ordinal(partition(), majorIndex(), minorIndex(), memberIndex); }
ebf6f434
A
130
131 // For indirect libraries the partition is IndirectDylibPartition and the counter is used or order the libraries.
f80fe69f 132 static const ld::File::Ordinal indirectDylibBase() { return Ordinal(kIndirectDylibPartition, 0, 0, 0); }
ebf6f434
A
133 const Ordinal nextIndirectDylibOrdinal() const { return nextCounter(); }
134
135 // For the LTO mach-o the partition is LTOPartition. As there is only one LTO file no other fields are needed.
f80fe69f
A
136 static const ld::File::Ordinal LTOOrdinal() { return Ordinal(kLTOPartition, 0, 0, 0); }
137
138 // For linker options embedded in object files
139 static const ld::File::Ordinal linkeOptionBase() { return Ordinal(kIndirectDylibPartition, 1, 0, 0); }
0a8dc3df
A
140 const Ordinal nextLinkerOptionOrdinal() { return nextCounter(); };
141
ebf6f434
A
142 };
143
144 typedef enum { Reloc, Dylib, Archive, Other } Type;
145
146 File(const char* pth, time_t modTime, Ordinal ord, Type type)
147 : _path(pth), _modTime(modTime), _ordinal(ord), _type(type) { }
a645023d
A
148 virtual ~File() {}
149 const char* path() const { return _path; }
150 time_t modificationTime() const{ return _modTime; }
ebf6f434 151 Ordinal ordinal() const { return _ordinal; }
a645023d
A
152 virtual bool forEachAtom(AtomHandler&) const = 0;
153 virtual bool justInTimeforEachAtom(const char* name, AtomHandler&) const = 0;
154 virtual ObjcConstraint objCConstraint() const { return objcConstraintNone; }
0a8dc3df 155 virtual bool objcHasCategoryClassPropertiesField() const { return false; }
599556ff 156 virtual uint8_t swiftVersion() const { return 0; }
a645023d
A
157 virtual uint32_t cpuSubType() const { return 0; }
158 virtual uint32_t subFileCount() const { return 1; }
eaf282aa 159 virtual uint32_t minOSVersion() const { return 0; }
bee7e226 160 virtual uint32_t platform() const { return 0; }
ebf6f434
A
161 bool fileExists() const { return _modTime != 0; }
162 Type type() const { return _type; }
eaf282aa 163 virtual Bitcode* getBitcode() const { return NULL; }
a645023d
A
164private:
165 const char* _path;
166 time_t _modTime;
ebf6f434
A
167 const Ordinal _ordinal;
168 const Type _type;
a645023d
A
169};
170
171
172//
173// minumum OS versions
174//
175enum MacVersionMin { macVersionUnset=0, mac10_4=0x000A0400, mac10_5=0x000A0500,
ebf6f434 176 mac10_6=0x000A0600, mac10_7=0x000A0700, mac10_8=0x000A0800,
0a8dc3df 177 mac10_9=0x000A0900, mac10_12=0x000A0C00, mac10_Future=0x10000000 };
afe874b1 178enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100,
ebf6f434 179 iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
599556ff 180 iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_8_0=0x00080000,
0a8dc3df 181 iOS_9_0=0x00090000, iOS_10_0=0x000A0000, iOS_Future=0x10000000};
eaf282aa
A
182enum WatchOSVersionMin { wOSVersionUnset=0, wOS_1_0=0x00010000, wOS_2_0=0x00020000 };
183
184
a645023d
A
185namespace relocatable {
186 //
187 // ld::relocatable::File
188 //
189 // Abstract base class for object files the linker processes.
190 //
a645023d
A
191 // debugInfo() returns if the object file contains debugger information (stabs or dwarf).
192 //
193 // stabs() lazily creates a vector of Stab objects for each atom
194 //
195 // canScatterAtoms() true for all compiler generated code. Hand written assembly can opt-in
196 // via .subsections_via_symbols directive. When true it means the linker can break up section
197 // content at symbol boundaries and do optimizations like coalescing, dead code stripping, or
198 // apply order files.
199 //
200 // optimize() used by libLTO to lazily generate code from llvm bit-code files
201 //
202 class File : public ld::File
203 {
204 public:
205 enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
dd9e569f 206 enum SourceKind { kSourceUnknown=0, kSourceObj, kSourceLTO, kSourceArchive, kSourceCompilerArchive };
a645023d
A
207 struct Stab {
208 const class Atom* atom;
209 uint8_t type;
210 uint8_t other;
211 uint16_t desc;
212 uint32_t value;
213 const char* string;
214 };
f80fe69f 215 typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
bee7e226 216 typedef std::vector<std::pair<uint32_t,uint32_t>> ToolVersionList;
a645023d 217
ebf6f434
A
218 File(const char* pth, time_t modTime, Ordinal ord)
219 : ld::File(pth, modTime, ord, Reloc) { }
a645023d 220 virtual ~File() {}
a645023d
A
221 virtual DebugInfoKind debugInfo() const = 0;
222 virtual const char* debugInfoPath() const { return path(); }
223 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
224 virtual const std::vector<Stab>* stabs() const = 0;
225 virtual bool canScatterAtoms() const = 0;
226 virtual bool hasLongBranchStubs() { return false; }
f80fe69f 227 virtual LinkerOptionsList* linkerOptions() const = 0;
bee7e226 228 virtual const ToolVersionList& toolVersions() const = 0;
eaf282aa 229 virtual SourceKind sourceKind() const { return kSourceUnknown; }
82b4b32b 230 virtual const uint8_t* fileContent() const { return nullptr; }
a645023d
A
231 };
232} // namespace relocatable
233
234
235namespace dylib {
236
237 //
238 // ld::dylib::File
239 //
240 // Abstract base class for dynamic shared libraries read by the linker processes.
241 //
242 class File : public ld::File
243 {
244 public:
245 class DylibHandler
246 {
247 public:
248 virtual ~DylibHandler() {}
0a8dc3df 249 virtual File* findDylib(const char* installPath, const ld::dylib::File* fromDylib, bool speculative) = 0;
a645023d
A
250 };
251
ebf6f434 252 File(const char* pth, time_t modTime, Ordinal ord)
ec29ba20 253 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL), _frameworkName(NULL),
a645023d 254 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
0a8dc3df 255 _explicitlyLinked(false), _implicitlyLinked(false), _speculativelyLoaded(false),
afe874b1
A
256 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
257 _upward(false), _dead(false) { }
a645023d 258 const char* installPath() const { return _dylibInstallPath; }
ec29ba20 259 const char* frameworkName() const { return _frameworkName; }
a645023d
A
260 uint32_t timestamp() const { return _dylibTimeStamp; }
261 uint32_t currentVersion() const { return _dylibCurrentVersion; }
262 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
263 void setExplicitlyLinked() { _explicitlyLinked = true; }
264 bool explicitlyLinked() const { return _explicitlyLinked; }
265 void setImplicitlyLinked() { _implicitlyLinked = true; }
266 bool implicitlyLinked() const { return _implicitlyLinked; }
0a8dc3df
A
267 void setSpeculativelyLoaded() { _speculativelyLoaded = true; }
268 bool speculativelyLoaded() const { return _speculativelyLoaded; }
269
a645023d
A
270 // attributes of how dylib will be used when linked
271 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
272 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
afe874b1
A
273 void setForcedWeakLinked() { _forcedWeakLinked = true; }
274 bool forcedWeakLinked() const { return _forcedWeakLinked; }
275
a645023d
A
276 void setWillBeReExported() { _reExported = true; }
277 bool willBeReExported() const { return _reExported; }
278 void setWillBeUpwardDylib() { _upward = true; }
279 bool willBeUpwardDylib() const { return _upward; }
a645023d
A
280 void setWillBeRemoved(bool value) { _dead = value; }
281 bool willRemoved() const { return _dead; }
282
283 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
284 virtual bool providedExportAtom() const = 0;
285 virtual const char* parentUmbrella() const = 0;
286 virtual const std::vector<const char*>* allowableClients() const = 0;
0a8dc3df 287 virtual const std::vector<const char*>& rpaths() const = 0;
a645023d
A
288 virtual bool hasWeakExternals() const = 0;
289 virtual bool deadStrippable() const = 0;
290 virtual bool hasWeakDefinition(const char* name) const = 0;
291 virtual bool hasPublicInstallName() const = 0;
afe874b1 292 virtual bool allSymbolsAreWeakImported() const = 0;
f80fe69f 293 virtual bool installPathVersionSpecific() const { return false; }
599556ff 294 virtual bool appExtensionSafe() const = 0;
599556ff 295
ec29ba20 296 public:
a645023d 297 const char* _dylibInstallPath;
ec29ba20 298 const char* _frameworkName;
a645023d
A
299 uint32_t _dylibTimeStamp;
300 uint32_t _dylibCurrentVersion;
301 uint32_t _dylibCompatibilityVersion;
302 bool _explicitlyLinked;
303 bool _implicitlyLinked;
0a8dc3df 304 bool _speculativelyLoaded;
a645023d 305 bool _lazyLoadedDylib;
afe874b1 306 bool _forcedWeakLinked;
a645023d
A
307 bool _reExported;
308 bool _upward;
a645023d
A
309 bool _dead;
310 };
311} // namespace dylib
312
313
afe874b1
A
314namespace archive {
315 //
316 // ld::archive::File
317 //
318 // Abstract base class for static libraries read by the linker processes.
319 //
320 class File : public ld::File
321 {
322 public:
ebf6f434
A
323 File(const char* pth, time_t modTime, Ordinal ord)
324 : ld::File(pth, modTime, ord, Archive) { }
afe874b1
A
325 virtual ~File() {}
326 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
327 };
328} // namespace archive
329
a645023d
A
330
331//
332// ld::Section
333//
334class Section
335{
336public:
337 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
599556ff 338 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO, typeTempAlias,
a645023d
A
339 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
340 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
341 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
342 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
343 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
344 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
eaf282aa 345 typeFirstSection, typeLastSection, typeDebug, typeSectCreate };
a645023d
A
346
347
348 Section(const char* sgName, const char* sctName,
349 Type t, bool hidden=false)
350 : _segmentName(sgName), _sectionName(sctName),
351 _type(t), _hidden(hidden) {}
352 Section(const Section& sect)
353 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
354 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
355
356 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
357 (strcmp(_segmentName, rhs._segmentName)==0) &&
358 (strcmp(_sectionName, rhs._sectionName)==0) ); }
359 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
360 const char* segmentName() const { return _segmentName; }
361 const char* sectionName() const { return _sectionName; }
362 Type type() const { return _type; }
363 bool isSectionHidden() const { return _hidden; }
364
365private:
366 const char* _segmentName;
367 const char* _sectionName;
368 Type _type;
369 bool _hidden;
370};
371
372
373
374//
375// ld::Fixup
376//
377// A Fixup describes how part of an Atom's content must be fixed up. For instance,
378// an instruction may contain a displacement to another Atom that must be
379// fixed up by the linker.
380//
381// A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
382// With a direct reference, the target is bound by the File that created it.
383// For instance a reference to a static would produce a direct reference.
384// A by-name reference requires the linker to find the target Atom with the
385// required name in order to be bound.
386//
387// For a link to succeed all Fixup must be bound.
388//
389// A Reference also has a fix-up-offset. This is the offset into the content of the
390// Atom holding the reference where the fix-up (relocation) will be applied.
391//
392//
393struct Fixup
394{
395 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
396 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
397 enum Kind { kindNone, kindNoneFollowOn,
398 // grouping
399 kindNoneGroupSubordinate,
400 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
401 // value calculations
402 kindSetTargetAddress,
403 kindSubtractTargetAddress,
404 kindAddAddend,
405 kindSubtractAddend,
406 kindSetTargetImageOffset,
407 kindSetTargetSectionOffset,
408 kindSetTargetTLVTemplateOffset,
409 // pointer store kinds (of current calculated value)
410 kindStore8,
411 kindStoreLittleEndian16,
412 kindStoreLittleEndianLow24of32,
413 kindStoreLittleEndian32,
414 kindStoreLittleEndian64,
415 kindStoreBigEndian16,
416 kindStoreBigEndianLow24of32,
417 kindStoreBigEndian32,
418 kindStoreBigEndian64,
419 // Intel specific store kinds
420 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
421 kindStoreX86PCRel8, kindStoreX86PCRel16,
422 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
423 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
424 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
425 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
426 // ARM specific store kinds
427 kindStoreARMBranch24, kindStoreThumbBranch22,
428 kindStoreARMLoad12,
429 kindStoreARMLow16, kindStoreARMHigh16,
430 kindStoreThumbLow16, kindStoreThumbHigh16,
f80fe69f
A
431#if SUPPORT_ARCH_arm64
432 // ARM64 specific store kinds
433 kindStoreARM64Branch26,
434 kindStoreARM64Page21, kindStoreARM64PageOff12,
435 kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
436 kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
437 kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
9543cb2f 438 kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
f80fe69f
A
439 kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
440#endif
a645023d
A
441 // dtrace probes
442 kindDtraceExtra,
443 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
444 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
f80fe69f 445 kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
a645023d 446 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
a645023d
A
447 // lazy binding
448 kindLazyTarget, kindSetLazyOffset,
9543cb2f
A
449 // islands
450 kindIslandTarget,
ebf6f434
A
451 // data-in-code markers
452 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
453 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
ec29ba20 454 // linker optimization hints
9543cb2f 455 kindLinkerOptimizationHint,
a645023d
A
456 // pointer store combinations
457 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
458 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
459 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
460 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
461 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
462 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
463 // Intel value calculation and store combinations
464 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
465 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
466 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
467 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
468 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
469 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
470 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
471 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
472 // ARM value calculation and store combinations
473 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
474 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
475 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
f80fe69f
A
476#if SUPPORT_ARCH_arm64
477 // ARM64 value calculation and store combinations
478 kindStoreTargetAddressARM64Branch26, // kindSetTargetAddress + kindStoreARM64Branch26
479 kindStoreTargetAddressARM64Page21, // kindSetTargetAddress + kindStoreARM64Page21
480 kindStoreTargetAddressARM64PageOff12, // kindSetTargetAddress + kindStoreARM64PageOff12
481 kindStoreTargetAddressARM64GOTLoadPage21, // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
482 kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
483 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
484 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
9543cb2f
A
485 kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
486 kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
487 kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
488 kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
f80fe69f 489#endif
a645023d
A
490 };
491
492 union {
493 const Atom* target;
494 const char* name;
495 uint64_t addend;
496 uint32_t bindingIndex;
497 } u;
498 uint32_t offsetInAtom;
499 Kind kind : 8;
500 Cluster clusterSize : 4;
501 bool weakImport : 1;
502 TargetBinding binding : 3;
503 bool contentAddendOnly : 1;
504 bool contentDetlaToAddendOnly : 1;
f80fe69f 505 bool contentIgnoresAddend : 1;
a645023d
A
506
507 typedef Fixup* iterator;
508
509 Fixup() :
510 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
511 binding(bindingNone),
f80fe69f 512 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
a645023d
A
513
514 Fixup(Kind k, Atom* targetAtom) :
515 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
516 binding(Fixup::bindingDirectlyBound),
f80fe69f 517 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
518 { assert(targetAtom != NULL); u.target = targetAtom; }
519
520 Fixup(uint32_t off, Cluster c, Kind k) :
521 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
522 binding(Fixup::bindingNone),
f80fe69f 523 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
524 { u.addend = 0; }
525
526 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
527 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
528 binding(Fixup::bindingByNameUnbound),
f80fe69f 529 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
530 { assert(name != NULL); u.name = name; }
531
532 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
533 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
f80fe69f 534 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
535 { assert(name != NULL); u.name = name; }
536
537 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
538 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
539 binding(Fixup::bindingDirectlyBound),
f80fe69f 540 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
541 { assert(targetAtom != NULL); u.target = targetAtom; }
542
543 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
544 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
f80fe69f 545 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
546 { assert(targetAtom != NULL); u.target = targetAtom; }
547
548 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
549 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
550 binding(Fixup::bindingNone),
f80fe69f 551 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
552 { u.addend = addend; }
553
9543cb2f
A
554 Fixup(Kind k, uint32_t lohKind, uint32_t off1, uint32_t off2) :
555 offsetInAtom(off1), kind(k), clusterSize(k1of1),
556 weakImport(false), binding(Fixup::bindingNone), contentAddendOnly(false),
557 contentDetlaToAddendOnly(false), contentIgnoresAddend(false) {
558 assert(k == kindLinkerOptimizationHint);
559 LOH_arm64 extra;
560 extra.addend = 0;
561 extra.info.kind = lohKind;
562 extra.info.count = 1;
563 extra.info.delta1 = 0;
564 extra.info.delta2 = (off2 - off1) >> 2;
565 u.addend = extra.addend;
566 }
9543cb2f
A
567
568
a645023d
A
569 bool firstInCluster() const {
570 switch (clusterSize) {
571 case k1of1:
572 case k1of2:
573 case k1of3:
574 case k1of4:
575 case k1of5:
576 return true;
577 default:
578 break;
579 }
580 return false;
581 }
582
583 bool lastInCluster() const {
584 switch (clusterSize) {
585 case k1of1:
586 case k2of2:
587 case k3of3:
588 case k4of4:
589 case k5of5:
590 return true;
591 default:
592 break;
593 }
594 return false;
595 }
596
9543cb2f
A
597 union LOH_arm64 {
598 uint64_t addend;
599 struct {
600 unsigned kind : 6,
601 count : 2, // 00 => 1 addr, 11 => 4 addrs
602 delta1 : 14, // 16-bit delta, low 2 bits assumed zero
603 delta2 : 14,
604 delta3 : 14,
605 delta4 : 14;
606 } info;
607 };
9543cb2f 608
a645023d
A
609};
610
611//
612// ld::Atom
613//
614// An atom is the fundamental unit of linking. A C function or global variable is an atom.
615// An atom has content and attributes. The content of a function atom is the instructions
616// that implement the function. The content of a global variable atom is its initial bits.
617//
618// Name:
619// The name of an atom is the label name generated by the compiler. A C compiler names foo()
620// as _foo. A C++ compiler names foo() as __Z3foov.
621// The name refers to the first byte of the content. An atom cannot have multiple entry points.
622// Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
623// A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
624//
625// Scope:
626// An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
627// to the C visibility of static, hidden, default.
628//
629// DefinitionKind:
630// An atom is one of five defintion kinds:
631// regular Most atoms.
632// weak C++ compiler makes some functions weak if there might be multiple copies
633// that the linker needs to coalesce.
634// tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
635// It could be a prototype or it could be a definition.
636// external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
637// so that the graph of Atoms can be complete.
638// external-weak Same as external, but the definition in the dylib is weak.
639//
640// SymbolTableInclusion:
641// An atom may or may not be in the symbol table in an object file.
642// in Most atoms for functions or global data
643// not-in Anonymous atoms such literal c-strings, or other compiler generated data
644// not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
645// in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
646//
647// ContentType:
648// Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
649// atom are group together at the end of the DATA segment to reduce disk size.
650//
651// ObjectAddress:
652// For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
653// The objectAddress() method returns the address of an atom in the object file so that the linker
654// can arrange the atoms.
655//
656//
657class Atom
658{
659public:
660 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
661 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
662 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
663 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
664 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
665 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
666 typeLTOtemporary, typeResolver,
eaf282aa 667 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers, typeTLVPointer };
a645023d
A
668
669 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
670 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
671 symbolTableInWithRandomAutoStripLabel };
afe874b1
A
672 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
673
a645023d
A
674 struct Alignment {
675 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
676 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
677 uint16_t powerOf2;
678 uint16_t modulus;
679 };
680 struct LineInfo {
681 const char* fileName;
682 uint32_t atomOffset;
683 uint32_t lineNumber;
684
685 typedef LineInfo* iterator;
686 };
687 struct UnwindInfo {
688 uint32_t startOffset;
689 uint32_t unwindInfo;
690
691 typedef UnwindInfo* iterator;
692 };
693
694 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
695 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
696 _section(&sect), _address(0), _alignmentModulus(a.modulus),
697 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
698 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
699 _contentType(ct), _symbolTableInclusion(i),
700 _scope(s), _mode(modeSectionOffset),
701 _overridesADylibsWeakDef(false), _coalescedAway(false),
eaf282aa
A
702 _live(false), _dontDeadStripIfRefLive(false),
703 _machoSection(0), _weakImportState(weakImportUnset)
a645023d
A
704 {
705 #ifndef NDEBUG
706 switch ( _combine ) {
707 case combineByNameAndContent:
708 case combineByNameAndReferences:
f80fe69f 709 assert(_symbolTableInclusion != symbolTableIn);
a645023d
A
710 assert(_scope != scopeGlobal);
711 break;
712 case combineByName:
713 case combineNever:
714 break;
715 };
716 #endif
717 }
718 virtual ~Atom() {}
719
720 const Section& section() const { return *_section; }
721 Definition definition() const { return _definition; }
722 Combine combine() const { return _combine; }
723 Scope scope() const { return _scope; }
724 ContentType contentType() const { return _contentType; }
725 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
726 bool dontDeadStrip() const { return _dontDeadStrip; }
eaf282aa 727 bool dontDeadStripIfReferencesLive() const { return _dontDeadStripIfRefLive; }
a645023d
A
728 bool isThumb() const { return _thumb; }
729 bool isAlias() const { return _alias; }
730 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
731 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
732 bool coalescedAway() const { return _coalescedAway; }
afe874b1
A
733 bool weakImported() const { return _weakImportState == weakImportTrue; }
734 WeakImportState weakImportState() const { return _weakImportState; }
a645023d
A
735 bool autoHide() const { return _autoHide; }
736 bool live() const { return _live; }
737 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
738
739 void setScope(Scope s) { _scope = s; }
740 void setSymbolTableInclusion(SymbolTableInclusion i)
741 { _symbolTableInclusion = i; }
742 void setCombine(Combine c) { _combine = c; }
743 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
744 void setCoalescedAway() { _coalescedAway = true; }
afe874b1 745 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
a645023d 746 void setAutoHide() { _autoHide = true; }
eaf282aa 747 void setDontDeadStripIfReferencesLive() { _dontDeadStripIfRefLive = true; }
a645023d
A
748 void setLive() { _live = true; }
749 void setLive(bool value) { _live = value; }
750 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
751 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
752 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
753 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
754 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
ebf6f434
A
755#ifndef NDEBUG
756 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
757#endif
a645023d 758 virtual const File* file() const = 0;
0a8dc3df
A
759 // Return the original file this atom belongs to, for instance for an LTO atom,
760 // file() would return the LTO MachO file instead of the original bitcode file.
761 virtual const ld::File* originalFile() const { return file(); }
b1f7435d 762 virtual const char* translationUnitSource() const { return NULL; }
a645023d
A
763 virtual const char* name() const = 0;
764 virtual uint64_t objectAddress() const = 0;
765 virtual uint64_t size() const = 0;
766 virtual void copyRawContent(uint8_t buffer[]) const = 0;
767 virtual const uint8_t* rawContentPointer() const { return NULL; }
768 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
769 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
770 virtual Fixup::iterator fixupsBegin() const { return NULL; }
771 virtual Fixup::iterator fixupsEnd() const { return NULL; }
ebf6f434
A
772 bool hasFixupsOfKind(Fixup::Kind kind) const {
773 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
774 if ( fit->kind == kind ) return true;
775 }
776 return false;
777 }
9543cb2f 778 virtual void setFile(const File* f) { }
ebf6f434 779
a645023d
A
780 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
781 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
782 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
783 virtual LineInfo::iterator endLineInfo() const { return NULL; }
784
a645023d
A
785 void setAttributesFromAtom(const Atom& a) {
786 _section = a._section;
787 _alignmentModulus = a._alignmentModulus;
788 _alignmentPowerOf2 = a._alignmentPowerOf2;
789 _definition = a._definition;
790 _combine = a._combine;
791 _dontDeadStrip = a._dontDeadStrip;
82b4b32b 792 _dontDeadStripIfRefLive = a._dontDeadStripIfRefLive;
a645023d 793 _thumb = a._thumb;
a645023d
A
794 _autoHide = a._autoHide;
795 _contentType = a._contentType;
796 _symbolTableInclusion = a._symbolTableInclusion;
797 _scope = a._scope;
798 _mode = a._mode;
799 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
800 _coalescedAway = a._coalescedAway;
afe874b1 801 _weakImportState = a._weakImportState;
a645023d
A
802 }
803
82b4b32b
A
804 const char* safeFilePath() const {
805 const File* f = this->file();
806 if ( f != NULL )
807 return f->path();
808 else
809 return "<internal>";
810 }
811
599556ff
A
812protected:
813 enum AddressMode { modeSectionOffset, modeFinalAddress };
814
a645023d
A
815 const Section * _section;
816 uint64_t _address;
817 uint16_t _alignmentModulus;
818 uint8_t _alignmentPowerOf2;
819 Definition _definition : 2;
820 Combine _combine : 2;
821 bool _dontDeadStrip : 1;
822 bool _thumb : 1;
823 bool _alias : 1;
824 int _autoHide : 1;
825 ContentType _contentType : 5;
826 SymbolTableInclusion _symbolTableInclusion : 3;
827 Scope _scope : 2;
828 AddressMode _mode: 2;
829 bool _overridesADylibsWeakDef : 1;
830 bool _coalescedAway : 1;
a645023d 831 bool _live : 1;
eaf282aa 832 bool _dontDeadStripIfRefLive : 1;
a645023d 833 unsigned _machoSection : 8;
afe874b1 834 WeakImportState _weakImportState : 2;
a645023d
A
835};
836
837
838class IndirectBindingTable
839{
840public:
841 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
842 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
843};
844
845
82b4b32b 846
f80fe69f
A
847// utility classes for using std::unordered_map with c-strings
848struct CStringHash {
849 size_t operator()(const char* __s) const {
850 size_t __h = 0;
851 for ( ; *__s; ++__s)
852 __h = 5 * __h + *__s;
853 return __h;
854 };
855};
856struct CStringEquals
857{
858 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
859};
860
861typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
862
eaf282aa 863
a645023d
A
864class Internal
865{
866public:
867 class FinalSection : public ld::Section {
868 public:
869 FinalSection(const Section& sect) : Section(sect), address(0),
870 fileOffset(0), size(0), alignment(0),
871 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
872 relocStart(0), relocCount(0),
873 hasLocalRelocs(false), hasExternalRelocs(false) {}
874 std::vector<const Atom*> atoms;
875 uint64_t address;
876 uint64_t fileOffset;
877 uint64_t size;
878 uint32_t alignmentPaddingBytes;
879 uint8_t alignment;
880 uint32_t indirectSymTabStartIndex;
881 uint32_t indirectSymTabElementSize;
882 uint32_t relocStart;
883 uint32_t relocCount;
884 bool hasLocalRelocs;
885 bool hasExternalRelocs;
886 };
887
eaf282aa
A
888 typedef std::map<const ld::Atom*, FinalSection*> AtomToSection;
889
9543cb2f
A
890 virtual uint64_t assignFileOffsets() = 0;
891 virtual void setSectionSizesAndAlignments() = 0;
a645023d
A
892 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
893 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
894 virtual ~Internal() {}
895 Internal() : bundleLoader(NULL),
896 entryPoint(NULL), classicBindingHelper(NULL),
897 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
898 objcObjectConstraint(ld::File::objcConstraintNone),
899 objcDylibConstraint(ld::File::objcConstraintNone),
eaf282aa
A
900 swiftVersion(0), cpuSubType(0), minOSVersion(0),
901 objectFileFoundWithNoVersion(false),
ebf6f434 902 allObjectFilesScatterable(true),
9543cb2f
A
903 someObjectFileHasDwarf(false), usingHugeSections(false),
904 hasThreadLocalVariableDefinitions(false),
905 hasWeakExternalSymbols(false),
eaf282aa 906 someObjectHasOptimizationHints(false),
82b4b32b
A
907 dropAllBitcode(false), embedMarkerOnly(false),
908 forceLoadCompilerRT(false) { }
eaf282aa 909
a645023d
A
910 std::vector<FinalSection*> sections;
911 std::vector<ld::dylib::File*> dylibs;
0a8dc3df 912 std::vector<std::string> archivePaths;
a645023d 913 std::vector<ld::relocatable::File::Stab> stabs;
eaf282aa 914 AtomToSection atomToSection;
0a8dc3df
A
915 CStringSet unprocessedLinkerOptionLibraries;
916 CStringSet unprocessedLinkerOptionFrameworks;
f80fe69f
A
917 CStringSet linkerOptionLibraries;
918 CStringSet linkerOptionFrameworks;
a645023d 919 std::vector<const ld::Atom*> indirectBindingTable;
eaf282aa 920 std::vector<const ld::relocatable::File*> filesWithBitcode;
82b4b32b 921 std::vector<const ld::relocatable::File*> filesFromCompilerRT;
0a8dc3df 922 std::vector<const ld::Atom*> deadAtoms;
ec29ba20 923 std::unordered_set<const char*> allUndefProxies;
bee7e226 924 std::unordered_set<uint64_t> toolsVersions;
a645023d
A
925 const ld::dylib::File* bundleLoader;
926 const Atom* entryPoint;
927 const Atom* classicBindingHelper;
928 const Atom* lazyBindingHelper;
929 const Atom* compressedFastBinderProxy;
930 ld::File::ObjcConstraint objcObjectConstraint;
931 ld::File::ObjcConstraint objcDylibConstraint;
599556ff 932 uint8_t swiftVersion;
a645023d 933 uint32_t cpuSubType;
eaf282aa 934 uint32_t minOSVersion;
bee7e226 935 uint32_t derivedPlatform;
eaf282aa 936 bool objectFileFoundWithNoVersion;
a645023d 937 bool allObjectFilesScatterable;
a645023d
A
938 bool someObjectFileHasDwarf;
939 bool usingHugeSections;
9543cb2f
A
940 bool hasThreadLocalVariableDefinitions;
941 bool hasWeakExternalSymbols;
942 bool someObjectHasOptimizationHints;
eaf282aa
A
943 bool dropAllBitcode;
944 bool embedMarkerOnly;
82b4b32b 945 bool forceLoadCompilerRT;
0a8dc3df 946 std::vector<std::string> ltoBitcodePath;
a645023d
A
947};
948
949
950
a645023d
A
951
952
953
954
a645023d
A
955} // namespace ld
956
957#endif // __LD_HPP__