diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:57:38 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:57:38 +0000 |
| commit | 5a5c549fe9a3fef595297bd21d36bed8409dc37d (patch) | |
| tree | a964c8f5ac85b7b641cac022c5f9bf4eed3d2b9b /lib/ReaderWriter/MachO/ArchHandler_arm64.cpp | |
| parent | fb911942f1434f3d1750f83f25f5e42c80e60638 (diff) | |
Notes
Diffstat (limited to 'lib/ReaderWriter/MachO/ArchHandler_arm64.cpp')
| -rw-r--r-- | lib/ReaderWriter/MachO/ArchHandler_arm64.cpp | 23 |
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; |
