]> git.saurik.com Git - apple/ld64.git/blame - src/ld/ld.hpp
ld64-351.8.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;
f410558f 217 struct AstTimeAndPath { uint64_t time; std::string path; };
a645023d 218
ebf6f434
A
219 File(const char* pth, time_t modTime, Ordinal ord)
220 : ld::File(pth, modTime, ord, Reloc) { }
a645023d 221 virtual ~File() {}
a645023d
A
222 virtual DebugInfoKind debugInfo() const = 0;
223 virtual const char* debugInfoPath() const { return path(); }
224 virtual time_t debugInfoModificationTime() const { return modificationTime(); }
225 virtual const std::vector<Stab>* stabs() const = 0;
226 virtual bool canScatterAtoms() const = 0;
227 virtual bool hasLongBranchStubs() { return false; }
f410558f 228 virtual bool hasllvmProfiling() const { return false; }
f80fe69f 229 virtual LinkerOptionsList* linkerOptions() const = 0;
bee7e226 230 virtual const ToolVersionList& toolVersions() const = 0;
eaf282aa 231 virtual SourceKind sourceKind() const { return kSourceUnknown; }
82b4b32b 232 virtual const uint8_t* fileContent() const { return nullptr; }
f410558f 233 virtual const std::vector<AstTimeAndPath>* astFiles() const { return nullptr; }
a645023d
A
234 };
235} // namespace relocatable
236
237
238namespace dylib {
239
240 //
241 // ld::dylib::File
242 //
243 // Abstract base class for dynamic shared libraries read by the linker processes.
244 //
245 class File : public ld::File
246 {
247 public:
248 class DylibHandler
249 {
250 public:
251 virtual ~DylibHandler() {}
0a8dc3df 252 virtual File* findDylib(const char* installPath, const ld::dylib::File* fromDylib, bool speculative) = 0;
a645023d
A
253 };
254
ebf6f434 255 File(const char* pth, time_t modTime, Ordinal ord)
ec29ba20 256 : ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL), _frameworkName(NULL),
a645023d 257 _dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
0a8dc3df 258 _explicitlyLinked(false), _implicitlyLinked(false), _speculativelyLoaded(false),
afe874b1
A
259 _lazyLoadedDylib(false), _forcedWeakLinked(false), _reExported(false),
260 _upward(false), _dead(false) { }
a645023d 261 const char* installPath() const { return _dylibInstallPath; }
ec29ba20 262 const char* frameworkName() const { return _frameworkName; }
a645023d
A
263 uint32_t timestamp() const { return _dylibTimeStamp; }
264 uint32_t currentVersion() const { return _dylibCurrentVersion; }
265 uint32_t compatibilityVersion() const{ return _dylibCompatibilityVersion; }
266 void setExplicitlyLinked() { _explicitlyLinked = true; }
267 bool explicitlyLinked() const { return _explicitlyLinked; }
268 void setImplicitlyLinked() { _implicitlyLinked = true; }
269 bool implicitlyLinked() const { return _implicitlyLinked; }
0a8dc3df
A
270 void setSpeculativelyLoaded() { _speculativelyLoaded = true; }
271 bool speculativelyLoaded() const { return _speculativelyLoaded; }
272
a645023d
A
273 // attributes of how dylib will be used when linked
274 void setWillBeLazyLoadedDylb() { _lazyLoadedDylib = true; }
275 bool willBeLazyLoadedDylib() const { return _lazyLoadedDylib; }
afe874b1
A
276 void setForcedWeakLinked() { _forcedWeakLinked = true; }
277 bool forcedWeakLinked() const { return _forcedWeakLinked; }
278
a645023d
A
279 void setWillBeReExported() { _reExported = true; }
280 bool willBeReExported() const { return _reExported; }
281 void setWillBeUpwardDylib() { _upward = true; }
282 bool willBeUpwardDylib() const { return _upward; }
a645023d
A
283 void setWillBeRemoved(bool value) { _dead = value; }
284 bool willRemoved() const { return _dead; }
285
286 virtual void processIndirectLibraries(DylibHandler* handler, bool addImplicitDylibs) = 0;
287 virtual bool providedExportAtom() const = 0;
288 virtual const char* parentUmbrella() const = 0;
289 virtual const std::vector<const char*>* allowableClients() const = 0;
0a8dc3df 290 virtual const std::vector<const char*>& rpaths() const = 0;
a645023d
A
291 virtual bool hasWeakExternals() const = 0;
292 virtual bool deadStrippable() const = 0;
293 virtual bool hasWeakDefinition(const char* name) const = 0;
294 virtual bool hasPublicInstallName() const = 0;
afe874b1 295 virtual bool allSymbolsAreWeakImported() const = 0;
f80fe69f 296 virtual bool installPathVersionSpecific() const { return false; }
599556ff 297 virtual bool appExtensionSafe() const = 0;
599556ff 298
ec29ba20 299 public:
a645023d 300 const char* _dylibInstallPath;
ec29ba20 301 const char* _frameworkName;
a645023d
A
302 uint32_t _dylibTimeStamp;
303 uint32_t _dylibCurrentVersion;
304 uint32_t _dylibCompatibilityVersion;
305 bool _explicitlyLinked;
306 bool _implicitlyLinked;
0a8dc3df 307 bool _speculativelyLoaded;
a645023d 308 bool _lazyLoadedDylib;
afe874b1 309 bool _forcedWeakLinked;
a645023d
A
310 bool _reExported;
311 bool _upward;
a645023d
A
312 bool _dead;
313 };
314} // namespace dylib
315
316
afe874b1
A
317namespace archive {
318 //
319 // ld::archive::File
320 //
321 // Abstract base class for static libraries read by the linker processes.
322 //
323 class File : public ld::File
324 {
325 public:
ebf6f434
A
326 File(const char* pth, time_t modTime, Ordinal ord)
327 : ld::File(pth, modTime, ord, Archive) { }
afe874b1
A
328 virtual ~File() {}
329 virtual bool justInTimeDataOnlyforEachAtom(const char* name, AtomHandler&) const = 0;
330 };
331} // namespace archive
332
a645023d
A
333
334//
335// ld::Section
336//
337class Section
338{
339public:
340 enum Type { typeUnclassified, typeCode, typePageZero, typeImportProxies, typeLinkEdit, typeMachHeader, typeStack,
599556ff 341 typeLiteral4, typeLiteral8, typeLiteral16, typeConstants, typeTempLTO, typeTempAlias,
a645023d
A
342 typeCString, typeNonStdCString, typeCStringPointer, typeUTF16Strings, typeCFString, typeObjC1Classes,
343 typeCFI, typeLSDA, typeDtraceDOF, typeUnwindInfo, typeObjCClassRefs, typeObjC2CategoryList,
344 typeZeroFill, typeTentativeDefs, typeLazyPointer, typeStub, typeNonLazyPointer, typeDyldInfo,
345 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
346 typeStubClose, typeLazyPointerClose, typeAbsoluteSymbols,
347 typeTLVDefs, typeTLVZeroFill, typeTLVInitialValues, typeTLVInitializerPointers, typeTLVPointers,
eaf282aa 348 typeFirstSection, typeLastSection, typeDebug, typeSectCreate };
a645023d
A
349
350
351 Section(const char* sgName, const char* sctName,
352 Type t, bool hidden=false)
353 : _segmentName(sgName), _sectionName(sctName),
354 _type(t), _hidden(hidden) {}
355 Section(const Section& sect)
356 : _segmentName(sect.segmentName()), _sectionName(sect.sectionName()),
357 _type(sect.type()), _hidden(sect.isSectionHidden()) {}
358
359 bool operator==(const Section& rhs) const { return ( (_hidden==rhs._hidden) &&
360 (strcmp(_segmentName, rhs._segmentName)==0) &&
361 (strcmp(_sectionName, rhs._sectionName)==0) ); }
362 bool operator!=(const Section& rhs) const { return ! (*this == rhs); }
363 const char* segmentName() const { return _segmentName; }
364 const char* sectionName() const { return _sectionName; }
365 Type type() const { return _type; }
366 bool isSectionHidden() const { return _hidden; }
367
368private:
369 const char* _segmentName;
370 const char* _sectionName;
371 Type _type;
372 bool _hidden;
373};
374
375
376
377//
378// ld::Fixup
379//
380// A Fixup describes how part of an Atom's content must be fixed up. For instance,
381// an instruction may contain a displacement to another Atom that must be
382// fixed up by the linker.
383//
384// A Fixup my reference another Atom. There are two kinds of references: direct and by-name.
385// With a direct reference, the target is bound by the File that created it.
386// For instance a reference to a static would produce a direct reference.
387// A by-name reference requires the linker to find the target Atom with the
388// required name in order to be bound.
389//
390// For a link to succeed all Fixup must be bound.
391//
392// A Reference also has a fix-up-offset. This is the offset into the content of the
393// Atom holding the reference where the fix-up (relocation) will be applied.
394//
395//
396struct Fixup
397{
398 enum TargetBinding { bindingNone, bindingByNameUnbound, bindingDirectlyBound, bindingByContentBound, bindingsIndirectlyBound };
399 enum Cluster { k1of1, k1of2, k2of2, k1of3, k2of3, k3of3, k1of4, k2of4, k3of4, k4of4, k1of5, k2of5, k3of5, k4of5, k5of5 };
400 enum Kind { kindNone, kindNoneFollowOn,
401 // grouping
402 kindNoneGroupSubordinate,
403 kindNoneGroupSubordinateFDE, kindNoneGroupSubordinateLSDA, kindNoneGroupSubordinatePersonality,
404 // value calculations
405 kindSetTargetAddress,
406 kindSubtractTargetAddress,
407 kindAddAddend,
408 kindSubtractAddend,
409 kindSetTargetImageOffset,
410 kindSetTargetSectionOffset,
411 kindSetTargetTLVTemplateOffset,
412 // pointer store kinds (of current calculated value)
413 kindStore8,
414 kindStoreLittleEndian16,
415 kindStoreLittleEndianLow24of32,
416 kindStoreLittleEndian32,
417 kindStoreLittleEndian64,
418 kindStoreBigEndian16,
419 kindStoreBigEndianLow24of32,
420 kindStoreBigEndian32,
421 kindStoreBigEndian64,
422 // Intel specific store kinds
423 kindStoreX86BranchPCRel8, kindStoreX86BranchPCRel32,
424 kindStoreX86PCRel8, kindStoreX86PCRel16,
425 kindStoreX86PCRel32, kindStoreX86PCRel32_1, kindStoreX86PCRel32_2, kindStoreX86PCRel32_4,
426 kindStoreX86PCRel32GOTLoad, kindStoreX86PCRel32GOTLoadNowLEA, kindStoreX86PCRel32GOT,
427 kindStoreX86PCRel32TLVLoad, kindStoreX86PCRel32TLVLoadNowLEA,
428 kindStoreX86Abs32TLVLoad, kindStoreX86Abs32TLVLoadNowLEA,
429 // ARM specific store kinds
430 kindStoreARMBranch24, kindStoreThumbBranch22,
431 kindStoreARMLoad12,
432 kindStoreARMLow16, kindStoreARMHigh16,
433 kindStoreThumbLow16, kindStoreThumbHigh16,
f80fe69f
A
434#if SUPPORT_ARCH_arm64
435 // ARM64 specific store kinds
436 kindStoreARM64Branch26,
437 kindStoreARM64Page21, kindStoreARM64PageOff12,
438 kindStoreARM64GOTLoadPage21, kindStoreARM64GOTLoadPageOff12,
439 kindStoreARM64GOTLeaPage21, kindStoreARM64GOTLeaPageOff12,
440 kindStoreARM64TLVPLoadPage21, kindStoreARM64TLVPLoadPageOff12,
9543cb2f 441 kindStoreARM64TLVPLoadNowLeaPage21, kindStoreARM64TLVPLoadNowLeaPageOff12,
f80fe69f
A
442 kindStoreARM64PointerToGOT, kindStoreARM64PCRelToGOT,
443#endif
a645023d
A
444 // dtrace probes
445 kindDtraceExtra,
446 kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
447 kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
f80fe69f 448 kindStoreARM64DtraceCallSiteNop, kindStoreARM64DtraceIsEnableSiteClear,
a645023d 449 kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
a645023d
A
450 // lazy binding
451 kindLazyTarget, kindSetLazyOffset,
9543cb2f
A
452 // islands
453 kindIslandTarget,
ebf6f434
A
454 // data-in-code markers
455 kindDataInCodeStartData, kindDataInCodeStartJT8, kindDataInCodeStartJT16,
456 kindDataInCodeStartJT32, kindDataInCodeStartJTA32, kindDataInCodeEnd,
ec29ba20 457 // linker optimization hints
9543cb2f 458 kindLinkerOptimizationHint,
a645023d
A
459 // pointer store combinations
460 kindStoreTargetAddressLittleEndian32, // kindSetTargetAddress + kindStoreLittleEndian32
461 kindStoreTargetAddressLittleEndian64, // kindSetTargetAddress + kindStoreLittleEndian64
462 kindStoreTargetAddressBigEndian32, // kindSetTargetAddress + kindStoreBigEndian32
463 kindStoreTargetAddressBigEndian64, // kindSetTargetAddress + kindStoreBigEndian364
464 kindSetTargetTLVTemplateOffsetLittleEndian32, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian32
465 kindSetTargetTLVTemplateOffsetLittleEndian64, // kindSetTargetTLVTemplateOffset + kindStoreLittleEndian64
466 // Intel value calculation and store combinations
467 kindStoreTargetAddressX86PCRel32, // kindSetTargetAddress + kindStoreX86PCRel32
468 kindStoreTargetAddressX86BranchPCRel32, // kindSetTargetAddress + kindStoreX86BranchPCRel32
469 kindStoreTargetAddressX86PCRel32GOTLoad,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoad
470 kindStoreTargetAddressX86PCRel32GOTLoadNowLEA,// kindSetTargetAddress + kindStoreX86PCRel32GOTLoadNowLEA
471 kindStoreTargetAddressX86PCRel32TLVLoad, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoad
472 kindStoreTargetAddressX86PCRel32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86PCRel32TLVLoadNowLEA
473 kindStoreTargetAddressX86Abs32TLVLoad, // kindSetTargetAddress + kindStoreX86Abs32TLVLoad
474 kindStoreTargetAddressX86Abs32TLVLoadNowLEA, // kindSetTargetAddress + kindStoreX86Abs32TLVLoadNowLEA
475 // ARM value calculation and store combinations
476 kindStoreTargetAddressARMBranch24, // kindSetTargetAddress + kindStoreARMBranch24
477 kindStoreTargetAddressThumbBranch22, // kindSetTargetAddress + kindStoreThumbBranch22
478 kindStoreTargetAddressARMLoad12, // kindSetTargetAddress + kindStoreARMLoad12
f80fe69f
A
479#if SUPPORT_ARCH_arm64
480 // ARM64 value calculation and store combinations
481 kindStoreTargetAddressARM64Branch26, // kindSetTargetAddress + kindStoreARM64Branch26
482 kindStoreTargetAddressARM64Page21, // kindSetTargetAddress + kindStoreARM64Page21
483 kindStoreTargetAddressARM64PageOff12, // kindSetTargetAddress + kindStoreARM64PageOff12
484 kindStoreTargetAddressARM64GOTLoadPage21, // kindSetTargetAddress + kindStoreARM64GOTLoadPage21
485 kindStoreTargetAddressARM64GOTLoadPageOff12,// kindSetTargetAddress + kindStoreARM64GOTLoadPageOff12
486 kindStoreTargetAddressARM64GOTLeaPage21, // kindSetTargetAddress + kindStoreARM64GOTLeaPage21
487 kindStoreTargetAddressARM64GOTLeaPageOff12, // kindSetTargetAddress + kindStoreARM64GOTLeaPageOff12
9543cb2f
A
488 kindStoreTargetAddressARM64TLVPLoadPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadPage21
489 kindStoreTargetAddressARM64TLVPLoadPageOff12,// kindSetTargetAddress + kindStoreARM64TLVPLoadPageOff12
490 kindStoreTargetAddressARM64TLVPLoadNowLeaPage21, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPage21
491 kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12, // kindSetTargetAddress + kindStoreARM64TLVPLoadNowLeaPageOff12
f80fe69f 492#endif
a645023d
A
493 };
494
495 union {
496 const Atom* target;
497 const char* name;
498 uint64_t addend;
499 uint32_t bindingIndex;
500 } u;
501 uint32_t offsetInAtom;
502 Kind kind : 8;
503 Cluster clusterSize : 4;
504 bool weakImport : 1;
505 TargetBinding binding : 3;
506 bool contentAddendOnly : 1;
507 bool contentDetlaToAddendOnly : 1;
f80fe69f 508 bool contentIgnoresAddend : 1;
a645023d
A
509
510 typedef Fixup* iterator;
511
512 Fixup() :
513 offsetInAtom(0), kind(kindNone), clusterSize(k1of1), weakImport(false),
514 binding(bindingNone),
f80fe69f 515 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false) { u.target = NULL; }
a645023d
A
516
517 Fixup(Kind k, Atom* targetAtom) :
518 offsetInAtom(0), kind(k), clusterSize(k1of1), weakImport(false),
519 binding(Fixup::bindingDirectlyBound),
f80fe69f 520 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
521 { assert(targetAtom != NULL); u.target = targetAtom; }
522
523 Fixup(uint32_t off, Cluster c, Kind k) :
524 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
525 binding(Fixup::bindingNone),
f80fe69f 526 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
527 { u.addend = 0; }
528
529 Fixup(uint32_t off, Cluster c, Kind k, bool weakIm, const char* name) :
530 offsetInAtom(off), kind(k), clusterSize(c), weakImport(weakIm),
531 binding(Fixup::bindingByNameUnbound),
f80fe69f 532 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
533 { assert(name != NULL); u.name = name; }
534
535 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const char* name) :
536 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
f80fe69f 537 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
538 { assert(name != NULL); u.name = name; }
539
540 Fixup(uint32_t off, Cluster c, Kind k, const Atom* targetAtom) :
541 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
542 binding(Fixup::bindingDirectlyBound),
f80fe69f 543 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
544 { assert(targetAtom != NULL); u.target = targetAtom; }
545
546 Fixup(uint32_t off, Cluster c, Kind k, TargetBinding b, const Atom* targetAtom) :
547 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false), binding(b),
f80fe69f 548 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
549 { assert(targetAtom != NULL); u.target = targetAtom; }
550
551 Fixup(uint32_t off, Cluster c, Kind k, uint64_t addend) :
552 offsetInAtom(off), kind(k), clusterSize(c), weakImport(false),
553 binding(Fixup::bindingNone),
f80fe69f 554 contentAddendOnly(false), contentDetlaToAddendOnly(false), contentIgnoresAddend(false)
a645023d
A
555 { u.addend = addend; }
556
9543cb2f
A
557 Fixup(Kind k, uint32_t lohKind, uint32_t off1, uint32_t off2) :
558 offsetInAtom(off1), kind(k), clusterSize(k1of1),
559 weakImport(false), binding(Fixup::bindingNone), contentAddendOnly(false),
560 contentDetlaToAddendOnly(false), contentIgnoresAddend(false) {
561 assert(k == kindLinkerOptimizationHint);
562 LOH_arm64 extra;
563 extra.addend = 0;
564 extra.info.kind = lohKind;
565 extra.info.count = 1;
566 extra.info.delta1 = 0;
567 extra.info.delta2 = (off2 - off1) >> 2;
568 u.addend = extra.addend;
569 }
9543cb2f
A
570
571
a645023d
A
572 bool firstInCluster() const {
573 switch (clusterSize) {
574 case k1of1:
575 case k1of2:
576 case k1of3:
577 case k1of4:
578 case k1of5:
579 return true;
580 default:
581 break;
582 }
583 return false;
584 }
585
586 bool lastInCluster() const {
587 switch (clusterSize) {
588 case k1of1:
589 case k2of2:
590 case k3of3:
591 case k4of4:
592 case k5of5:
593 return true;
594 default:
595 break;
596 }
597 return false;
598 }
599
9543cb2f
A
600 union LOH_arm64 {
601 uint64_t addend;
602 struct {
603 unsigned kind : 6,
604 count : 2, // 00 => 1 addr, 11 => 4 addrs
605 delta1 : 14, // 16-bit delta, low 2 bits assumed zero
606 delta2 : 14,
607 delta3 : 14,
608 delta4 : 14;
609 } info;
610 };
9543cb2f 611
a645023d
A
612};
613
614//
615// ld::Atom
616//
617// An atom is the fundamental unit of linking. A C function or global variable is an atom.
618// An atom has content and attributes. The content of a function atom is the instructions
619// that implement the function. The content of a global variable atom is its initial bits.
620//
621// Name:
622// The name of an atom is the label name generated by the compiler. A C compiler names foo()
623// as _foo. A C++ compiler names foo() as __Z3foov.
624// The name refers to the first byte of the content. An atom cannot have multiple entry points.
625// Such code is modeled as multiple atoms, each having a "follow on" reference to the next.
626// A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously.
627//
628// Scope:
629// An atom is in one of three scopes: translation-unit, linkage-unit, or global. These correspond
630// to the C visibility of static, hidden, default.
631//
632// DefinitionKind:
633// An atom is one of five defintion kinds:
634// regular Most atoms.
635// weak C++ compiler makes some functions weak if there might be multiple copies
636// that the linker needs to coalesce.
637// tentative A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous.
638// It could be a prototype or it could be a definition.
639// external This is a "proxy" atom produced by a dylib reader. It has no content. It exists
640// so that the graph of Atoms can be complete.
641// external-weak Same as external, but the definition in the dylib is weak.
642//
643// SymbolTableInclusion:
644// An atom may or may not be in the symbol table in an object file.
645// in Most atoms for functions or global data
646// not-in Anonymous atoms such literal c-strings, or other compiler generated data
647// not-in-final Atom whose name should not be in the symbol table of final linkd image (e.g. 'l' labels .eh labels)
648// in-never-strip Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o)
649//
650// ContentType:
651// Some atoms require specially processing by the linker based on their content. For instance, zero-fill data
652// atom are group together at the end of the DATA segment to reduce disk size.
653//
654// ObjectAddress:
655// For reproducability, the linker lays out atoms in the order they occurred in the source (object) files.
656// The objectAddress() method returns the address of an atom in the object file so that the linker
657// can arrange the atoms.
658//
659//
660class Atom
661{
662public:
663 enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
664 enum Definition { definitionRegular, definitionTentative, definitionAbsolute, definitionProxy };
665 enum Combine { combineNever, combineByName, combineByNameAndContent, combineByNameAndReferences };
666 enum ContentType { typeUnclassified, typeZeroFill, typeCString, typeCFI, typeLSDA, typeSectionStart,
667 typeSectionEnd, typeBranchIsland, typeLazyPointer, typeStub, typeNonLazyPointer,
668 typeLazyDylibPointer, typeStubHelper, typeInitializerPointers, typeTerminatorPointers,
669 typeLTOtemporary, typeResolver,
eaf282aa 670 typeTLV, typeTLVZeroFill, typeTLVInitialValue, typeTLVInitializerPointers, typeTLVPointer };
a645023d
A
671
672 enum SymbolTableInclusion { symbolTableNotIn, symbolTableNotInFinalLinkedImages, symbolTableIn,
673 symbolTableInAndNeverStrip, symbolTableInAsAbsolute,
674 symbolTableInWithRandomAutoStripLabel };
afe874b1
A
675 enum WeakImportState { weakImportUnset, weakImportTrue, weakImportFalse };
676
a645023d
A
677 struct Alignment {
678 Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
679 uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
680 uint16_t powerOf2;
681 uint16_t modulus;
682 };
683 struct LineInfo {
684 const char* fileName;
685 uint32_t atomOffset;
686 uint32_t lineNumber;
687
688 typedef LineInfo* iterator;
689 };
690 struct UnwindInfo {
691 uint32_t startOffset;
692 uint32_t unwindInfo;
693
694 typedef UnwindInfo* iterator;
695 };
696
697 Atom(const Section& sect, Definition d, Combine c, Scope s, ContentType ct,
698 SymbolTableInclusion i, bool dds, bool thumb, bool al, Alignment a) :
699 _section(&sect), _address(0), _alignmentModulus(a.modulus),
700 _alignmentPowerOf2(a.powerOf2), _definition(d), _combine(c),
701 _dontDeadStrip(dds), _thumb(thumb), _alias(al), _autoHide(false),
702 _contentType(ct), _symbolTableInclusion(i),
703 _scope(s), _mode(modeSectionOffset),
704 _overridesADylibsWeakDef(false), _coalescedAway(false),
eaf282aa
A
705 _live(false), _dontDeadStripIfRefLive(false),
706 _machoSection(0), _weakImportState(weakImportUnset)
a645023d
A
707 {
708 #ifndef NDEBUG
709 switch ( _combine ) {
710 case combineByNameAndContent:
711 case combineByNameAndReferences:
f80fe69f 712 assert(_symbolTableInclusion != symbolTableIn);
a645023d
A
713 assert(_scope != scopeGlobal);
714 break;
715 case combineByName:
716 case combineNever:
717 break;
718 };
719 #endif
720 }
721 virtual ~Atom() {}
722
723 const Section& section() const { return *_section; }
724 Definition definition() const { return _definition; }
725 Combine combine() const { return _combine; }
726 Scope scope() const { return _scope; }
727 ContentType contentType() const { return _contentType; }
728 SymbolTableInclusion symbolTableInclusion() const{ return _symbolTableInclusion; }
729 bool dontDeadStrip() const { return _dontDeadStrip; }
eaf282aa 730 bool dontDeadStripIfReferencesLive() const { return _dontDeadStripIfRefLive; }
a645023d
A
731 bool isThumb() const { return _thumb; }
732 bool isAlias() const { return _alias; }
733 Alignment alignment() const { return Alignment(_alignmentPowerOf2, _alignmentModulus); }
734 bool overridesDylibsWeakDef() const { return _overridesADylibsWeakDef; }
735 bool coalescedAway() const { return _coalescedAway; }
afe874b1
A
736 bool weakImported() const { return _weakImportState == weakImportTrue; }
737 WeakImportState weakImportState() const { return _weakImportState; }
a645023d
A
738 bool autoHide() const { return _autoHide; }
739 bool live() const { return _live; }
740 uint8_t machoSection() const { assert(_machoSection != 0); return _machoSection; }
741
742 void setScope(Scope s) { _scope = s; }
743 void setSymbolTableInclusion(SymbolTableInclusion i)
744 { _symbolTableInclusion = i; }
745 void setCombine(Combine c) { _combine = c; }
746 void setOverridesDylibsWeakDef() { _overridesADylibsWeakDef = true; }
747 void setCoalescedAway() { _coalescedAway = true; }
afe874b1 748 void setWeakImportState(bool w) { assert(_definition == definitionProxy); _weakImportState = ( w ? weakImportTrue : weakImportFalse); }
a645023d 749 void setAutoHide() { _autoHide = true; }
eaf282aa 750 void setDontDeadStripIfReferencesLive() { _dontDeadStripIfRefLive = true; }
a645023d
A
751 void setLive() { _live = true; }
752 void setLive(bool value) { _live = value; }
753 void setMachoSection(unsigned x) { assert(x != 0); assert(x < 256); _machoSection = x; }
754 void setSectionOffset(uint64_t o){ assert(_mode == modeSectionOffset); _address = o; _mode = modeSectionOffset; }
755 void setSectionStartAddress(uint64_t a) { assert(_mode == modeSectionOffset); _address += a; _mode = modeFinalAddress; }
756 uint64_t sectionOffset() const { assert(_mode == modeSectionOffset); return _address; }
757 uint64_t finalAddress() const { assert(_mode == modeFinalAddress); return _address; }
ebf6f434
A
758#ifndef NDEBUG
759 bool finalAddressMode() const { return (_mode == modeFinalAddress); }
760#endif
a645023d 761 virtual const File* file() const = 0;
0a8dc3df
A
762 // Return the original file this atom belongs to, for instance for an LTO atom,
763 // file() would return the LTO MachO file instead of the original bitcode file.
764 virtual const ld::File* originalFile() const { return file(); }
b1f7435d 765 virtual const char* translationUnitSource() const { return NULL; }
a645023d
A
766 virtual const char* name() const = 0;
767 virtual uint64_t objectAddress() const = 0;
768 virtual uint64_t size() const = 0;
769 virtual void copyRawContent(uint8_t buffer[]) const = 0;
770 virtual const uint8_t* rawContentPointer() const { return NULL; }
771 virtual unsigned long contentHash(const class IndirectBindingTable&) const { return 0; }
772 virtual bool canCoalesceWith(const Atom& rhs, const class IndirectBindingTable&) const { return false; }
773 virtual Fixup::iterator fixupsBegin() const { return NULL; }
774 virtual Fixup::iterator fixupsEnd() const { return NULL; }
ebf6f434
A
775 bool hasFixupsOfKind(Fixup::Kind kind) const {
776 for (ld::Fixup::iterator fit = fixupsBegin(), end=fixupsEnd(); fit != end; ++fit) {
777 if ( fit->kind == kind ) return true;
778 }
779 return false;
780 }
9543cb2f 781 virtual void setFile(const File* f) { }
ebf6f434 782
a645023d
A
783 virtual UnwindInfo::iterator beginUnwind() const { return NULL; }
784 virtual UnwindInfo::iterator endUnwind() const { return NULL; }
785 virtual LineInfo::iterator beginLineInfo() const { return NULL; }
786 virtual LineInfo::iterator endLineInfo() const { return NULL; }
787
a645023d
A
788 void setAttributesFromAtom(const Atom& a) {
789 _section = a._section;
790 _alignmentModulus = a._alignmentModulus;
791 _alignmentPowerOf2 = a._alignmentPowerOf2;
792 _definition = a._definition;
793 _combine = a._combine;
794 _dontDeadStrip = a._dontDeadStrip;
82b4b32b 795 _dontDeadStripIfRefLive = a._dontDeadStripIfRefLive;
a645023d 796 _thumb = a._thumb;
a645023d
A
797 _autoHide = a._autoHide;
798 _contentType = a._contentType;
799 _symbolTableInclusion = a._symbolTableInclusion;
800 _scope = a._scope;
801 _mode = a._mode;
802 _overridesADylibsWeakDef = a._overridesADylibsWeakDef;
803 _coalescedAway = a._coalescedAway;
afe874b1 804 _weakImportState = a._weakImportState;
a645023d
A
805 }
806
82b4b32b
A
807 const char* safeFilePath() const {
808 const File* f = this->file();
809 if ( f != NULL )
810 return f->path();
811 else
812 return "<internal>";
813 }
814
599556ff
A
815protected:
816 enum AddressMode { modeSectionOffset, modeFinalAddress };
817
a645023d
A
818 const Section * _section;
819 uint64_t _address;
820 uint16_t _alignmentModulus;
821 uint8_t _alignmentPowerOf2;
822 Definition _definition : 2;
823 Combine _combine : 2;
824 bool _dontDeadStrip : 1;
825 bool _thumb : 1;
826 bool _alias : 1;
827 int _autoHide : 1;
828 ContentType _contentType : 5;
829 SymbolTableInclusion _symbolTableInclusion : 3;
830 Scope _scope : 2;
831 AddressMode _mode: 2;
832 bool _overridesADylibsWeakDef : 1;
833 bool _coalescedAway : 1;
a645023d 834 bool _live : 1;
eaf282aa 835 bool _dontDeadStripIfRefLive : 1;
a645023d 836 unsigned _machoSection : 8;
afe874b1 837 WeakImportState _weakImportState : 2;
a645023d
A
838};
839
840
841class IndirectBindingTable
842{
843public:
844 virtual const char* indirectName(uint32_t bindingIndex) const = 0;
845 virtual const ld::Atom* indirectAtom(uint32_t bindingIndex) const = 0;
846};
847
848
82b4b32b 849
f80fe69f
A
850// utility classes for using std::unordered_map with c-strings
851struct CStringHash {
852 size_t operator()(const char* __s) const {
853 size_t __h = 0;
854 for ( ; *__s; ++__s)
855 __h = 5 * __h + *__s;
856 return __h;
857 };
858};
859struct CStringEquals
860{
861 bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
862};
863
864typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals> CStringSet;
865
eaf282aa 866
a645023d
A
867class Internal
868{
869public:
870 class FinalSection : public ld::Section {
871 public:
872 FinalSection(const Section& sect) : Section(sect), address(0),
873 fileOffset(0), size(0), alignment(0),
874 indirectSymTabStartIndex(0), indirectSymTabElementSize(0),
875 relocStart(0), relocCount(0),
876 hasLocalRelocs(false), hasExternalRelocs(false) {}
877 std::vector<const Atom*> atoms;
878 uint64_t address;
879 uint64_t fileOffset;
880 uint64_t size;
881 uint32_t alignmentPaddingBytes;
882 uint8_t alignment;
883 uint32_t indirectSymTabStartIndex;
884 uint32_t indirectSymTabElementSize;
885 uint32_t relocStart;
886 uint32_t relocCount;
887 bool hasLocalRelocs;
888 bool hasExternalRelocs;
889 };
890
eaf282aa
A
891 typedef std::map<const ld::Atom*, FinalSection*> AtomToSection;
892
9543cb2f
A
893 virtual uint64_t assignFileOffsets() = 0;
894 virtual void setSectionSizesAndAlignments() = 0;
a645023d
A
895 virtual ld::Internal::FinalSection* addAtom(const Atom&) = 0;
896 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section& inputSection) = 0;
897 virtual ~Internal() {}
898 Internal() : bundleLoader(NULL),
899 entryPoint(NULL), classicBindingHelper(NULL),
900 lazyBindingHelper(NULL), compressedFastBinderProxy(NULL),
901 objcObjectConstraint(ld::File::objcConstraintNone),
902 objcDylibConstraint(ld::File::objcConstraintNone),
eaf282aa
A
903 swiftVersion(0), cpuSubType(0), minOSVersion(0),
904 objectFileFoundWithNoVersion(false),
ebf6f434 905 allObjectFilesScatterable(true),
9543cb2f
A
906 someObjectFileHasDwarf(false), usingHugeSections(false),
907 hasThreadLocalVariableDefinitions(false),
908 hasWeakExternalSymbols(false),
eaf282aa 909 someObjectHasOptimizationHints(false),
82b4b32b
A
910 dropAllBitcode(false), embedMarkerOnly(false),
911 forceLoadCompilerRT(false) { }
eaf282aa 912
a645023d
A
913 std::vector<FinalSection*> sections;
914 std::vector<ld::dylib::File*> dylibs;
0a8dc3df 915 std::vector<std::string> archivePaths;
a645023d 916 std::vector<ld::relocatable::File::Stab> stabs;
eaf282aa 917 AtomToSection atomToSection;
0a8dc3df
A
918 CStringSet unprocessedLinkerOptionLibraries;
919 CStringSet unprocessedLinkerOptionFrameworks;
f80fe69f
A
920 CStringSet linkerOptionLibraries;
921 CStringSet linkerOptionFrameworks;
a645023d 922 std::vector<const ld::Atom*> indirectBindingTable;
eaf282aa 923 std::vector<const ld::relocatable::File*> filesWithBitcode;
82b4b32b 924 std::vector<const ld::relocatable::File*> filesFromCompilerRT;
0a8dc3df 925 std::vector<const ld::Atom*> deadAtoms;
ec29ba20 926 std::unordered_set<const char*> allUndefProxies;
bee7e226 927 std::unordered_set<uint64_t> toolsVersions;
a645023d
A
928 const ld::dylib::File* bundleLoader;
929 const Atom* entryPoint;
930 const Atom* classicBindingHelper;
931 const Atom* lazyBindingHelper;
932 const Atom* compressedFastBinderProxy;
933 ld::File::ObjcConstraint objcObjectConstraint;
934 ld::File::ObjcConstraint objcDylibConstraint;
599556ff 935 uint8_t swiftVersion;
a645023d 936 uint32_t cpuSubType;
eaf282aa 937 uint32_t minOSVersion;
bee7e226 938 uint32_t derivedPlatform;
eaf282aa 939 bool objectFileFoundWithNoVersion;
a645023d 940 bool allObjectFilesScatterable;
a645023d
A
941 bool someObjectFileHasDwarf;
942 bool usingHugeSections;
9543cb2f
A
943 bool hasThreadLocalVariableDefinitions;
944 bool hasWeakExternalSymbols;
945 bool someObjectHasOptimizationHints;
eaf282aa
A
946 bool dropAllBitcode;
947 bool embedMarkerOnly;
82b4b32b 948 bool forceLoadCompilerRT;
0a8dc3df 949 std::vector<std::string> ltoBitcodePath;
a645023d
A
950};
951
952
953
a645023d
A
954
955
956
957
a645023d
A
958} // namespace ld
959
960#endif // __LD_HPP__