summaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:57:38 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:57:38 +0000
commit5a5c549fe9a3fef595297bd21d36bed8409dc37d (patch)
treea964c8f5ac85b7b641cac022c5f9bf4eed3d2b9b /lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
parentfb911942f1434f3d1750f83f25f5e42c80e60638 (diff)
Notes
Diffstat (limited to 'lib/ReaderWriter/MachO/ArchHandler_arm64.cpp')
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_arm64.cpp23
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
index fd9984b89ce6..5e5a426b310b 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
@@ -31,8 +31,8 @@ using llvm::support::little64_t;
class ArchHandler_arm64 : public ArchHandler {
public:
- ArchHandler_arm64();
- virtual ~ArchHandler_arm64();
+ ArchHandler_arm64() = default;
+ ~ArchHandler_arm64() override = default;
const Registry::KindStrings *kindStrings() override { return _sKindStrings; }
@@ -50,6 +50,9 @@ public:
case gotOffset12:
canBypassGOT = true;
return true;
+ case delta32ToGOT:
+ canBypassGOT = false;
+ return true;
case imageOffsetGot:
canBypassGOT = false;
return true;
@@ -74,6 +77,9 @@ public:
const_cast<Reference *>(ref)->setKindValue(targetNowGOT ?
offset12scale8 : addOffset12);
break;
+ case delta32ToGOT:
+ const_cast<Reference *>(ref)->setKindValue(delta32);
+ break;
case imageOffsetGot:
const_cast<Reference *>(ref)->setKindValue(imageOffset);
break;
@@ -213,10 +219,6 @@ private:
static uint32_t setImm12(uint32_t instr, uint32_t offset);
};
-ArchHandler_arm64::ArchHandler_arm64() {}
-
-ArchHandler_arm64::~ArchHandler_arm64() {}
-
const Registry::KindStrings ArchHandler_arm64::_sKindStrings[] = {
LLD_KIND_STRING_ENTRY(invalid),
LLD_KIND_STRING_ENTRY(branch26),
@@ -437,7 +439,7 @@ std::error_code ArchHandler_arm64::getReferenceInfo(
*addend = 0;
return std::error_code();
default:
- return make_dynamic_error_code(Twine("unsupported arm64 relocation type"));
+ return make_dynamic_error_code("unsupported arm64 relocation type");
}
}
@@ -480,6 +482,9 @@ std::error_code ArchHandler_arm64::getPairReferenceInfo(
*kind = delta64;
if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
return ec;
+ // The offsets of the 2 relocations must match
+ if (reloc1.offset != reloc2.offset)
+ return make_dynamic_error_code("paired relocs must have the same offset");
*addend = (int64_t)*(const little64_t *)fixupContent + offsetInAtom;
return std::error_code();
case ((ARM64_RELOC_SUBTRACTOR | rExtern | rLength4) << 16 |
@@ -491,7 +496,7 @@ std::error_code ArchHandler_arm64::getPairReferenceInfo(
*addend = (int32_t)*(const little32_t *)fixupContent + offsetInAtom;
return std::error_code();
default:
- return make_dynamic_error_code(Twine("unsupported arm64 relocation pair"));
+ return make_dynamic_error_code("unsupported arm64 relocation pair");
}
}
@@ -669,7 +674,7 @@ void ArchHandler_arm64::applyFixupRelocatable(const Reference &ref,
*loc32 = ref.addend() + inAtomAddress - fixupAddress;
return;
case negDelta32:
- *loc32 = fixupAddress - inAtomAddress + ref.addend();
+ *loc32 = fixupAddress - targetAddress + ref.addend();
return;
case pointer64ToGOT:
*loc64 = 0;