summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/ReferenceKinds.h')
-rw-r--r--lld/lib/ReaderWriter/MachO/ReferenceKinds.h133
1 files changed, 126 insertions, 7 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
index adc196137e6..994c384f099 100644
--- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
+++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
+#include "MachONormalizedFile.h"
+
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
@@ -20,15 +22,9 @@
namespace lld {
namespace mach_o {
+
// Additional Reference Kind values used internally.
enum {
- LLD_X86_64_RELOC_GOT_LOAD_NOW_LEA = 100,
- LLD_X86_64_RELOC_TLV_NOW_LEA = 101,
- LLD_X86_64_RELOC_LAZY_TARGET = 102,
- LLD_X86_64_RELOC_LAZY_IMMEDIATE = 103,
- LLD_X86_64_RELOC_SIGNED_32 = 104,
-};
-enum {
LLD_X86_RELOC_BRANCH32 = 100, // CALL or JMP 32-bit pc-rel
LLD_X86_RELOC_ABS32 = 101, // 32-bit absolute addr in instruction
LLD_X86_RELOC_FUNC_REL32 = 102, // 32-bit target from start of func
@@ -62,6 +58,53 @@ public:
virtual bool isPointer(const Reference &) = 0;
virtual bool isLazyImmediate(const Reference &) = 0;
virtual bool isLazyTarget(const Reference &) = 0;
+
+ /// Returns true if the specified relocation is paired to the next relocation.
+ virtual bool isPairedReloc(const normalized::Relocation &);
+
+ /// Prototype for a helper function. Given a sectionIndex and address,
+ /// finds the atom and offset with that atom of that address.
+ typedef std::function<std::error_code (uint32_t sectionIndex, uint64_t addr,
+ const lld::Atom **, Reference::Addend *)>
+ FindAtomBySectionAndAddress;
+
+ /// Prototype for a helper function. Given a symbolIndex, finds the atom
+ /// representing that symbol.
+ typedef std::function<std::error_code (uint32_t symbolIndex,
+ const lld::Atom**)> FindAtomBySymbolIndex;
+
+ /// Analyzes a relocation from a .o file and returns the info
+ /// (kind, target, addend) needed to instantiate a Reference.
+ /// Two helper functions are passed as parameters to find the target atom
+ /// given a symbol index or address.
+ virtual std::error_code
+ getReferenceInfo(const normalized::Relocation &reloc,
+ const DefinedAtom *inAtom,
+ uint32_t offsetInAtom,
+ uint64_t fixupAddress, bool swap,
+ FindAtomBySectionAndAddress atomFromAddress,
+ FindAtomBySymbolIndex atomFromSymbolIndex,
+ Reference::KindValue *kind,
+ const lld::Atom **target,
+ Reference::Addend *addend);
+
+ /// Analyzes a pair of relocations from a .o file and returns the info
+ /// (kind, target, addend) needed to instantiate a Reference.
+ /// Two helper functions are passed as parameters to find the target atom
+ /// given a symbol index or address.
+ virtual std::error_code
+ getPairReferenceInfo(const normalized::Relocation &reloc1,
+ const normalized::Relocation &reloc2,
+ const DefinedAtom *inAtom,
+ uint32_t offsetInAtom,
+ uint64_t fixupAddress, bool swap,
+ FindAtomBySectionAndAddress atomFromAddress,
+ FindAtomBySymbolIndex atomFromSymbolIndex,
+ Reference::KindValue *kind,
+ const lld::Atom **target,
+ Reference::Addend *addend);
+
+ /// Fixup an atom when generating a final linked binary.
virtual void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue kindValue, uint64_t addend,
uint8_t *location, uint64_t fixupAddress,
@@ -69,6 +112,20 @@ public:
protected:
KindHandler();
+
+ // Handy way to pack mach-o r_type and other bit fields into one 16-bit value.
+ typedef uint16_t RelocPattern;
+ enum {
+ rScattered = 0x8000,
+ rPcRel = 0x4000,
+ rExtern = 0x2000,
+ rLength1 = 0x0000,
+ rLength2 = 0x0100,
+ rLength4 = 0x0200,
+ rLength8 = 0x0300
+ };
+ static RelocPattern relocPattern(const normalized::Relocation &reloc);
+
};
@@ -82,10 +139,72 @@ public:
bool isPointer(const Reference &) override;
bool isLazyImmediate(const Reference &) override;
bool isLazyTarget(const Reference &) override;
+ bool isPairedReloc(const normalized::Relocation &) override;
+ std::error_code getReferenceInfo(const normalized::Relocation &reloc,
+ const DefinedAtom *inAtom,
+ uint32_t offsetInAtom,
+ uint64_t fixupAddress, bool swap,
+ FindAtomBySectionAndAddress atomFromAddress,
+ FindAtomBySymbolIndex atomFromSymbolIndex,
+ Reference::KindValue *kind,
+ const lld::Atom **target,
+ Reference::Addend *addend) override;
+ std::error_code
+ getPairReferenceInfo(const normalized::Relocation &reloc1,
+ const normalized::Relocation &reloc2,
+ const DefinedAtom *inAtom,
+ uint32_t offsetInAtom,
+ uint64_t fixupAddress, bool swap,
+ FindAtomBySectionAndAddress atomFromAddress,
+ FindAtomBySymbolIndex atomFromSymbolIndex,
+ Reference::KindValue *kind,
+ const lld::Atom **target,
+ Reference::Addend *addend) override;
+
virtual void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue kindValue, uint64_t addend,
uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress) override;
+
+private:
+ friend class X86_64LazyPointerAtom;
+ friend class X86_64StubHelperAtom;
+ friend class X86_64StubAtom;
+ friend class X86_64StubHelperCommonAtom;
+ friend class X86_64NonLazyPointerAtom;
+
+ enum : Reference::KindValue {
+ invalid, /// for error condition
+
+ // Kinds found in mach-o .o files:
+ branch32, /// ex: call _foo
+ ripRel32, /// ex: movq _foo(%rip), %rax
+ ripRel32Minus1, /// ex: movb $0x12, _foo(%rip)
+ ripRel32Minus2, /// ex: movw $0x1234, _foo(%rip)
+ ripRel32Minus4, /// ex: movl $0x12345678, _foo(%rip)
+ ripRel32Anon, /// ex: movq L1(%rip), %rax
+ ripRel32GotLoad, /// ex: movq _foo@GOTPCREL(%rip), %rax
+ ripRel32Got, /// ex: pushq _foo@GOTPCREL(%rip)
+ pointer64, /// ex: .quad _foo
+ pointer64Anon, /// ex: .quad L1
+ delta64, /// ex: .quad _foo - .
+ delta32, /// ex: .long _foo - .
+ delta64Anon, /// ex: .quad L1 - .
+ delta32Anon, /// ex: .long L1 - .
+
+ // Kinds introduced by Passes:
+ ripRel32GotLoadNowLea, /// Target of GOT load is in linkage unit so
+ /// "movq _foo@GOTPCREL(%rip), %rax" can be changed
+ /// to "leaq _foo(%rip), %rax
+ lazyPointer, /// Location contains a lazy pointer.
+ lazyImmediateLocation, /// Location contains immediate value used in stub.
+ };
+
+ Reference::KindValue kindFromReloc(const normalized::Relocation &reloc);
+ Reference::KindValue kindFromRelocPair(const normalized::Relocation &reloc1,
+ const normalized::Relocation &reloc2);
+
+
};
class KindHandler_x86 : public KindHandler {
OpenPOWER on IntegriCloud