diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-09 15:10:36 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-09 15:10:36 +0000 |
commit | 4fcf82f3163f34ddc5c659ceb20e87057a287e10 (patch) | |
tree | e43228968b1cb82dd83fc6a8b5acd7d08d949c95 /include/llvm/Object | |
parent | 6ce62dc1d05cb97c048d0e248781c959cbffdd8b (diff) | |
download | external_llvm-4fcf82f3163f34ddc5c659ceb20e87057a287e10.zip external_llvm-4fcf82f3163f34ddc5c659ceb20e87057a287e10.tar.gz external_llvm-4fcf82f3163f34ddc5c659ceb20e87057a287e10.tar.bz2 |
Avoid runtime type checks.
In most cases the relocation type implies the object word size and
endianness.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Object')
-rw-r--r-- | include/llvm/Object/RelocVisitor.h | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index df21e86..69ce5cf 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -124,12 +124,37 @@ private: StringRef FileFormat; bool HasError; - int64_t getAddend(RelocationRef R) { + int64_t getAddend32LE(RelocationRef R) { + const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile()); + DataRefImpl DRI = R.getRawDataRefImpl(); int64_t Addend; - getELFRelocationAddend(R, Addend); + Obj->getRelocationAddend(DRI, Addend); + return Addend; + } + + int64_t getAddend64LE(RelocationRef R) { + const ELF64LEObjectFile *Obj = cast<ELF64LEObjectFile>(R.getObjectFile()); + DataRefImpl DRI = R.getRawDataRefImpl(); + int64_t Addend; + Obj->getRelocationAddend(DRI, Addend); + return Addend; + } + + int64_t getAddend32BE(RelocationRef R) { + const ELF32BEObjectFile *Obj = cast<ELF32BEObjectFile>(R.getObjectFile()); + DataRefImpl DRI = R.getRawDataRefImpl(); + int64_t Addend; + Obj->getRelocationAddend(DRI, Addend); return Addend; } + int64_t getAddend64BE(RelocationRef R) { + const ELF64BEObjectFile *Obj = cast<ELF64BEObjectFile>(R.getObjectFile()); + DataRefImpl DRI = R.getRawDataRefImpl(); + int64_t Addend; + Obj->getRelocationAddend(DRI, Addend); + return Addend; + } /// Operations /// 386-ELF @@ -140,13 +165,13 @@ private: // Ideally the Addend here will be the addend in the data for // the relocation. It's not actually the case for Rel relocations. RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend32LE(R); return RelocToApply(Value + Addend, 4); } RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value, uint64_t SecAddr) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend32LE(R); uint64_t Address; R.getOffset(Address); return RelocToApply(Value + Addend - Address, 4); @@ -157,44 +182,45 @@ private: return RelocToApply(0, 0); } RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64LE(R); return RelocToApply(Value + Addend, 8); } RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value, uint64_t SecAddr) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64LE(R); uint64_t Address; R.getOffset(Address); return RelocToApply(Value + Addend - Address, 4); } RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64LE(R); uint32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64LE(R); int32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } /// PPC64 ELF RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64BE(R); uint32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } /// MIPS ELF RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend; + getELFRelocationAddend(R, Addend); uint32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } // AArch64 ELF RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64LE(R); int64_t Res = Value + Addend; // Overflow check allows for both signed and unsigned interpretation. @@ -205,13 +231,13 @@ private: } RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64LE(R); return RelocToApply(Value + Addend, 8); } // SystemZ ELF RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64BE(R); int64_t Res = Value + Addend; // Overflow check allows for both signed and unsigned interpretation. @@ -222,7 +248,7 @@ private: } RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getAddend(R); + int64_t Addend = getAddend64BE(R); return RelocToApply(Value + Addend, 8); } }; |