aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Object/RelocVisitor.h
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-06-12 13:32:42 -0700
committerStephen Hines <srhines@google.com>2013-06-12 13:32:42 -0700
commit1878f9a7874b1ff569d745c0269f49d3daf7203d (patch)
tree19a8dbaaedf6a056c617e87596b32d3f452af137 /include/llvm/Object/RelocVisitor.h
parent7a57f27b857ec4b243d83d392a399f02fc196c0a (diff)
parent100fbdd06be7590b23c4707a98cd605bdb519498 (diff)
downloadexternal_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.h102
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);
+ }
};
}