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