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