diff options
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp | 248 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ReferenceKinds.h | 60 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp | 2 |
4 files changed, 218 insertions, 96 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp index bde60db2850..ff19e2db07d 100644 --- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp +++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp @@ -53,25 +53,39 @@ KindHandler_x86_64::~KindHandler_x86_64() { Reference::Kind KindHandler_x86_64::stringToKind(StringRef str) { if ( str.equals("none") ) - return KindHandler_x86_64::none; - else if ( str.equals("call32") ) - return KindHandler_x86_64::call32; + return none; + else if ( str.equals("branch32") ) + return branch32; else if ( str.equals("ripRel32") ) - return KindHandler_x86_64::ripRel32; - else if ( str.equals("gotLoad32") ) - return KindHandler_x86_64::gotLoad32; - else if ( str.equals("gotUse32") ) - return KindHandler_x86_64::gotUse32; + return ripRel32; + else if ( str.equals("ripRel32_1") ) + return ripRel32_1; + else if ( str.equals("ripRel32_2") ) + return ripRel32_2; + else if ( str.equals("ripRel32_4") ) + return ripRel32_4; + else if ( str.equals("gotLoadRipRel32") ) + return gotLoadRipRel32; + else if ( str.equals("gotLoadRipRel32NowLea") ) + return gotLoadRipRel32NowLea; + else if ( str.equals("gotUseRipRel32") ) + return gotUseRipRel32; + else if ( str.equals("tlvLoadRipRel32") ) + return tlvLoadRipRel32; + else if ( str.equals("tlvLoadRipRel32NowLea") ) + return tlvLoadRipRel32NowLea; else if ( str.equals("pointer64") ) - return KindHandler_x86_64::pointer64; - else if ( str.equals("lea32WasGot") ) - return KindHandler_x86_64::lea32WasGot; + return pointer64; + else if ( str.equals("pointerRel32") ) + return pointerRel32; else if ( str.equals("lazyTarget") ) - return KindHandler_x86_64::lazyTarget; - else if ( str.equals("lazyImm") ) - return KindHandler_x86_64::lazyImm; - else if ( str.equals("gotTarget") ) - return KindHandler_x86_64::gotTarget; + return lazyTarget; + else if ( str.equals("lazyImmediate") ) + return lazyImmediate; + else if ( str.equals("subordinateFDE") ) + return subordinateFDE; + else if ( str.equals("subordinateLSDA") ) + return subordinateLSDA; assert(0 && "invalid x86_64 Reference kind"); return 0; @@ -81,68 +95,100 @@ StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) { switch ( (Kinds)kind ) { case none: return StringRef("none"); - case call32: - return StringRef("call32"); + case branch32: + return StringRef("branch32"); case ripRel32: return StringRef("ripRel32"); - case gotLoad32: - return StringRef("gotLoad32"); - case gotUse32: - return StringRef("gotUse32"); + case ripRel32_1: + return StringRef("ripRel32_1"); + case ripRel32_2: + return StringRef("ripRel32_2"); + case ripRel32_4: + return StringRef("ripRel32_4"); + case gotLoadRipRel32: + return StringRef("gotLoadRipRel32"); + case gotLoadRipRel32NowLea: + return StringRef("gotLoadRipRel32NowLea"); + case gotUseRipRel32: + return StringRef("gotUseRipRel32"); + case tlvLoadRipRel32: + return StringRef("tlvLoadRipRel32"); + case tlvLoadRipRel32NowLea: + return StringRef("tlvLoadRipRel32NowLea"); case pointer64: return StringRef("pointer64"); - case lea32WasGot: - return StringRef("lea32WasGot"); + case pointerRel32: + return StringRef("pointerRel32"); case lazyTarget: return StringRef("lazyTarget"); - case lazyImm: - return StringRef("lazyImm"); - case gotTarget: - return StringRef("gotTarget"); + case lazyImmediate: + return StringRef("lazyImmediate"); + case subordinateFDE: + return StringRef("subordinateFDE"); + case subordinateLSDA: + return StringRef("subordinateLSDA"); } assert(0 && "invalid x86_64 Reference kind"); return StringRef(); } bool KindHandler_x86_64::isCallSite(Kind kind) { - return (kind == call32); + return (kind == branch32); } bool KindHandler_x86_64::isPointer(Kind kind) { return (kind == pointer64); } - bool KindHandler_x86_64::isLazyImmediate(Kind kind) { - return (kind == lazyImm); + return (kind == lazyImmediate); } - bool KindHandler_x86_64::isLazyTarget(Kind kind) { return (kind == lazyTarget); } -void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend, uint8_t *location, - uint64_t fixupAddress, uint64_t targetAddress) { +void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend, + uint8_t *location, uint64_t fixupAddress, + uint64_t targetAddress) { int32_t *loc32 = reinterpret_cast<int32_t*>(location); uint64_t* loc64 = reinterpret_cast<uint64_t*>(location); switch ( (Kinds)kind ) { - case call32: + case branch32: case ripRel32: - case gotLoad32: - case gotUse32: + case gotLoadRipRel32: + case gotUseRipRel32: + case tlvLoadRipRel32: *loc32 = (targetAddress - (fixupAddress+4)) + addend; break; case pointer64: *loc64 = targetAddress + addend; break; - case lea32WasGot: + case ripRel32_1: + *loc32 = (targetAddress - (fixupAddress+5)) + addend; + break; + case ripRel32_2: + *loc32 = (targetAddress - (fixupAddress+6)) + addend; + break; + case ripRel32_4: + *loc32 = (targetAddress - (fixupAddress+8)) + addend; + break; + case pointerRel32: + *loc32 = (targetAddress - fixupAddress) + addend; + break; + case gotLoadRipRel32NowLea: + case tlvLoadRipRel32NowLea: + // Change MOVQ to LEA + assert(location[-2] == 0x8B); + location[-2] = 0x8D; + *loc32 = (targetAddress - (fixupAddress+4)) + addend; break; case none: case lazyTarget: - case lazyImm: - case gotTarget: + case lazyImmediate: + case subordinateFDE: + case subordinateLSDA: // do nothing break; } @@ -158,17 +204,19 @@ KindHandler_x86::~KindHandler_x86() { Reference::Kind KindHandler_x86::stringToKind(StringRef str) { if ( str.equals("none") ) - return KindHandler_x86::none; - else if ( str.equals("call32") ) - return KindHandler_x86::call32; + return none; + else if ( str.equals("branch32") ) + return branch32; else if ( str.equals("abs32") ) - return KindHandler_x86::abs32; + return abs32; + else if ( str.equals("funcRel32") ) + return funcRel32; else if ( str.equals("pointer32") ) - return KindHandler_x86::pointer32; + return pointer32; else if ( str.equals("lazyTarget") ) - return KindHandler_x86::lazyTarget; - else if ( str.equals("lazyImm") ) - return KindHandler_x86::lazyImm; + return lazyTarget; + else if ( str.equals("lazyImmediate") ) + return lazyImmediate; assert(0 && "invalid x86 Reference kind"); return 0; @@ -178,23 +226,29 @@ StringRef KindHandler_x86::kindToString(Reference::Kind kind) { switch ( (Kinds)kind ) { case none: return StringRef("none"); - case call32: - return StringRef("call32"); + case branch32: + return StringRef("branch32"); case abs32: return StringRef("abs32"); + case funcRel32: + return StringRef("funcRel32"); case pointer32: return StringRef("pointer32"); case lazyTarget: return StringRef("lazyTarget"); - case lazyImm: - return StringRef("lazyImm"); + case lazyImmediate: + return StringRef("lazyImmediate"); + case subordinateFDE: + return StringRef("subordinateFDE"); + case subordinateLSDA: + return StringRef("subordinateLSDA"); } assert(0 && "invalid x86 Reference kind"); return StringRef(); } bool KindHandler_x86::isCallSite(Kind kind) { - return (kind == call32); + return (kind == branch32); } bool KindHandler_x86::isPointer(Kind kind) { @@ -203,7 +257,7 @@ bool KindHandler_x86::isPointer(Kind kind) { bool KindHandler_x86::isLazyImmediate(Kind kind) { - return (kind == lazyImm); + return (kind == lazyImmediate); } @@ -216,16 +270,21 @@ void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress) { int32_t *loc32 = reinterpret_cast<int32_t*>(location); switch ( (Kinds)kind ) { - case call32: + case branch32: *loc32 = (targetAddress - (fixupAddress+4)) + addend; break; case pointer32: case abs32: *loc32 = targetAddress + addend; break; + case funcRel32: + *loc32 = targetAddress + addend; + break; case none: case lazyTarget: - case lazyImm: + case lazyImmediate: + case subordinateFDE: + case subordinateLSDA: // do nothing break; } @@ -241,15 +300,29 @@ KindHandler_arm::~KindHandler_arm() { Reference::Kind KindHandler_arm::stringToKind(StringRef str) { if ( str.equals("none") ) - return KindHandler_arm::none; - else if ( str.equals("br22") ) - return KindHandler_arm::br22; + return none; + else if ( str.equals("thumbBranch22") ) + return thumbBranch22; + else if ( str.equals("armBranch24") ) + return armBranch24; + else if ( str.equals("thumbAbsLow16") ) + return thumbAbsLow16; + else if ( str.equals("thumbAbsHigh16") ) + return thumbAbsHigh16; + else if ( str.equals("thumbPcRelLow16") ) + return thumbPcRelLow16; + else if ( str.equals("thumbPcRelHigh16") ) + return thumbPcRelHigh16; + else if ( str.equals("abs32") ) + return abs32; else if ( str.equals("pointer32") ) - return KindHandler_arm::pointer32; + return pointer32; else if ( str.equals("lazyTarget") ) - return KindHandler_arm::lazyTarget; - else if ( str.equals("lazyImm") ) - return KindHandler_arm::lazyImm; + return lazyTarget; + else if ( str.equals("lazyImmediate") ) + return lazyImmediate; + else if ( str.equals("subordinateLSDA") ) + return subordinateLSDA; assert(0 && "invalid ARM Reference kind"); return 0; @@ -259,21 +332,35 @@ StringRef KindHandler_arm::kindToString(Reference::Kind kind) { switch ( (Kinds)kind ) { case none: return StringRef("none"); - case br22: - return StringRef("br22"); + case thumbBranch22: + return StringRef("thumbBranch22"); + case armBranch24: + return StringRef("armBranch24"); + case thumbAbsLow16: + return StringRef("thumbAbsLow16"); + case thumbAbsHigh16: + return StringRef("thumbAbsHigh16"); + case thumbPcRelLow16: + return StringRef("thumbPcRelLow16"); + case thumbPcRelHigh16: + return StringRef("thumbPcRelHigh16"); + case abs32: + return StringRef("abs32"); case pointer32: return StringRef("pointer32"); case lazyTarget: return StringRef("lazyTarget"); - case lazyImm: - return StringRef("lazyImm"); + case lazyImmediate: + return StringRef("lazyImmediate"); + case subordinateLSDA: + return StringRef("subordinateLSDA"); } assert(0 && "invalid ARM Reference kind"); return StringRef(); } bool KindHandler_arm::isCallSite(Kind kind) { - return (kind == br22); + return (kind == thumbBranch22) || (kind == armBranch24); } bool KindHandler_arm::isPointer(Kind kind) { @@ -282,7 +369,7 @@ bool KindHandler_arm::isPointer(Kind kind) { bool KindHandler_arm::isLazyImmediate(Kind kind) { - return (kind == lazyImm); + return (kind == lazyImmediate); } @@ -295,7 +382,25 @@ void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress) { //int32_t *loc32 = reinterpret_cast<int32_t*>(location); switch ( (Kinds)kind ) { - case br22: + case thumbBranch22: + // FIXME + break; + case armBranch24: + // FIXME + break; + case thumbAbsLow16: + // FIXME + break; + case thumbAbsHigh16: + // FIXME + break; + case thumbPcRelLow16: + // FIXME + break; + case thumbPcRelHigh16: + // FIXME + break; + case abs32: // FIXME break; case pointer32: @@ -303,7 +408,8 @@ void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location, break; case none: case lazyTarget: - case lazyImm: + case lazyImmediate: + case subordinateLSDA: // do nothing break; } diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h index ea889747f10..063b273c91f 100644 --- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h +++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h @@ -48,16 +48,23 @@ protected: class KindHandler_x86_64 : public KindHandler { public: enum Kinds { - none = 0, - call32 = 1, - ripRel32 = 2, - gotLoad32 = 3, - gotUse32 = 4, - lea32WasGot = 5, - lazyTarget = 6, - lazyImm = 7, - gotTarget = 8, - pointer64 = 9 + none, + branch32, // CALL or JMP 32-bit pc-rel + ripRel32, // RIP-rel access pc-rel to fix up location + ripRel32_1, // RIP-rel access pc-rel to fix up location + 1 + ripRel32_2, // RIP-rel access pc-rel to fix up location + 2 + ripRel32_4, // RIP-rel access pc-rel to fix up location + 4 + gotLoadRipRel32, // RIP-rel load of GOT slot (can be optimized) + gotLoadRipRel32NowLea, // RIP-rel movq load of GOT slot optimized to LEA + gotUseRipRel32, // RIP-rel non-load of GOT slot (not a movq load of GOT) + tlvLoadRipRel32, // RIP-rel load of thread local pointer (can be optimized) + tlvLoadRipRel32NowLea, // RIP-rel movq load of TLV pointer optimized to LEA + pointer64, // 64-bit data pointer + pointerRel32, // 32-bit pc-rel offset + lazyTarget, // Used in lazy pointers to reference ultimate target + lazyImmediate, // Location in stub where lazy info offset to be stored + subordinateFDE, // Reference to unwind info for this function + subordinateLSDA // Reference to excecption info for this function }; virtual ~KindHandler_x86_64(); @@ -76,12 +83,15 @@ public: class KindHandler_x86 : public KindHandler { public: enum Kinds { - none = 0, - call32 = 1, - abs32 = 2, - pointer32 = 3, - lazyTarget = 4, - lazyImm = 5 + none, + branch32, // CALL or JMP 32-bit pc-rel + abs32, // 32-bit absolute address embedded in instruction + funcRel32, // 32-bit offset to target from start of function + pointer32, // 32-bit data pointer + lazyTarget, // Used in lazy pointers to reference ultimate target + lazyImmediate, // Location in stub where lazy info offset to be stored + subordinateFDE, // Reference to unwind info for this function + subordinateLSDA // Reference to excecption info for this function }; virtual ~KindHandler_x86(); @@ -99,12 +109,18 @@ public: class KindHandler_arm : public KindHandler { public: enum Kinds { - none = 0, - br22 = 1, - pointer32 = 2, - lazyTarget = 3, - lazyImm = 4 - // FIXME + none, + thumbBranch22, // thumb b or bl with 22/24-bits of displacement + armBranch24, // arm b or bl with 24-bits of displacement + thumbAbsLow16, // thumb movw of absolute address + thumbAbsHigh16, // thumb movt of absolute address + thumbPcRelLow16, // thumb movw of (target - pc) + thumbPcRelHigh16,// thumb movt of (target - pc) + abs32, // 32-bit absolute address embedded in instructions + pointer32, // 32-bit data pointer + lazyTarget, // Used in lazy pointers to reference ultimate target + lazyImmediate, // Location in stub where lazy info offset to be stored + subordinateLSDA // Reference to excecption info for this function }; virtual ~KindHandler_arm(); diff --git a/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp b/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp index 8697db583ab..4e50592b724 100644 --- a/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp +++ b/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp @@ -100,8 +100,8 @@ class X86StubHelperAtom : public SimpleDefinedAtom { public: X86StubHelperAtom(const File &file, const Atom &helperCommon) : SimpleDefinedAtom(file) { - this->addReference(KindHandler_x86::lazyImm, 1, nullptr, 0); - this->addReference(KindHandler_x86::call32, 6, &helperCommon, 0); + this->addReference(KindHandler_x86::lazyImmediate, 1, nullptr, 0); + this->addReference(KindHandler_x86::branch32, 6, &helperCommon, 0); } virtual ContentType contentType() const { diff --git a/lld/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp b/lld/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp index 0524e55837e..d3caff0e0bf 100644 --- a/lld/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp +++ b/lld/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp @@ -101,7 +101,7 @@ class X86_64StubHelperAtom : public SimpleDefinedAtom { public: X86_64StubHelperAtom(const File &file, const Atom &helperCommon) : SimpleDefinedAtom(file) { - this->addReference(KindHandler_x86_64::lazyImm, 1, nullptr, 0); + this->addReference(KindHandler_x86_64::lazyImmediate, 1, nullptr, 0); this->addReference(KindHandler_x86_64::ripRel32, 6, &helperCommon, 0); } |