diff options
| author | Nick Kledzik <kledzik@apple.com> | 2014-06-27 18:25:01 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2014-06-27 18:25:01 +0000 |
| commit | 3f69076278421d731a80804a743f89c72384b379 (patch) | |
| tree | c169e62efc983af55f662101612ae1241d2ff07f /lld/lib/ReaderWriter/MachO/ReferenceKinds.h | |
| parent | dad0a645a7b392900c9fb34f11815060d03a2233 (diff) | |
| download | bcm5719-llvm-3f69076278421d731a80804a743f89c72384b379.tar.gz bcm5719-llvm-3f69076278421d731a80804a743f89c72384b379.zip | |
[mach-o] refactor x86_64 relocation handling.
This is first step in reworking how mach-o relocations are processed.
The existing KindHandler is going to become a delgate/helper object for
processing architecture specific references. The KindHandler knows how
to convert mach-o relocations into References and back, as well, as fixing
up the content the relocation is on.
One of the messy things about mach-o relocations is that they sometime
come in pairs, but the pairs still convert to one lld::Reference. So, the
conversion has to detect pairs (arch specific) and change the stride.
llvm-svn: 211921
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/ReferenceKinds.h')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/ReferenceKinds.h | 133 |
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 { |

