diff options
| author | Stephen Hines <srhines@google.com> | 2013-06-12 13:32:42 -0700 |
|---|---|---|
| committer | Stephen Hines <srhines@google.com> | 2013-06-12 13:32:42 -0700 |
| commit | 1878f9a7874b1ff569d745c0269f49d3daf7203d (patch) | |
| tree | 19a8dbaaedf6a056c617e87596b32d3f452af137 /include/llvm/Object/RelocVisitor.h | |
| parent | 7a57f27b857ec4b243d83d392a399f02fc196c0a (diff) | |
| parent | 100fbdd06be7590b23c4707a98cd605bdb519498 (diff) | |
| download | external_llvm-1878f9a7874b1ff569d745c0269f49d3daf7203d.zip external_llvm-1878f9a7874b1ff569d745c0269f49d3daf7203d.tar.gz external_llvm-1878f9a7874b1ff569d745c0269f49d3daf7203d.tar.bz2 | |
Merge commit '100fbdd06be7590b23c4707a98cd605bdb519498' into merge_20130612
Diffstat (limited to 'include/llvm/Object/RelocVisitor.h')
| -rw-r--r-- | include/llvm/Object/RelocVisitor.h | 102 |
1 files changed, 83 insertions, 19 deletions
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 59d8107..52e4d6f 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/ELF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" @@ -84,6 +85,14 @@ public: HasError = true; return RelocToApply(); } + } else if (FileFormat == "ELF32-ppc") { + switch (RelocType) { + case llvm::ELF::R_PPC_ADDR32: + return visitELF_PPC_ADDR32(R, Value); + default: + HasError = true; + return RelocToApply(); + } } else if (FileFormat == "ELF32-mips") { switch (RelocType) { case llvm::ELF::R_MIPS_32: @@ -102,6 +111,16 @@ public: HasError = true; return RelocToApply(); } + } else if (FileFormat == "ELF64-s390") { + switch (RelocType) { + case llvm::ELF::R_390_32: + return visitELF_390_32(R, Value); + case llvm::ELF::R_390_64: + return visitELF_390_64(R, Value); + default: + HasError = true; + return RelocToApply(); + } } HasError = true; return RelocToApply(); @@ -113,6 +132,37 @@ private: StringRef FileFormat; bool HasError; + int64_t getAddend32LE(RelocationRef R) { + const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile()); + DataRefImpl DRI = R.getRawDataRefImpl(); + int64_t 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 @@ -123,15 +173,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; - R.getAdditionalInfo(Addend); + 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; - R.getAdditionalInfo(Addend); + int64_t Addend = getAddend32LE(R); uint64_t Address; R.getOffset(Address); return RelocToApply(Value + Addend - Address, 4); @@ -142,35 +190,37 @@ private: return RelocToApply(0, 0); } RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { - int64_t Addend; - R.getAdditionalInfo(Addend); + 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; - R.getAdditionalInfo(Addend); + 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; - R.getAdditionalInfo(Addend); + 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; - R.getAdditionalInfo(Addend); + 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; - R.getAdditionalInfo(Addend); + int64_t Addend = getAddend64BE(R); + uint32_t Res = (Value + Addend) & 0xFFFFFFFF; + return RelocToApply(Res, 4); + } + + /// PPC32 ELF + RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { + int64_t Addend = getAddend32BE(R); uint32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } @@ -178,15 +228,14 @@ private: /// MIPS ELF RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { int64_t Addend; - R.getAdditionalInfo(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; - R.getAdditionalInfo(Addend); + int64_t Addend = getAddend64LE(R); int64_t Res = Value + Addend; // Overflow check allows for both signed and unsigned interpretation. @@ -197,11 +246,26 @@ private: } RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { - int64_t Addend; - R.getAdditionalInfo(Addend); + int64_t Addend = getAddend64LE(R); return RelocToApply(Value + Addend, 8); } + // SystemZ ELF + RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) { + int64_t Addend = getAddend64BE(R); + int64_t Res = Value + Addend; + + // Overflow check allows for both signed and unsigned interpretation. + if (Res < INT32_MIN || Res > UINT32_MAX) + HasError = true; + + return RelocToApply(static_cast<uint32_t>(Res), 4); + } + + RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) { + int64_t Addend = getAddend64BE(R); + return RelocToApply(Value + Addend, 8); + } }; } |
