[SystemZ] Add ELF relocation support

Another step towards reinstating the SystemZ backend.  Tests will be
included in the main backend patch.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181008 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Sandiford 2013-05-03 11:11:15 +00:00
parent 0512910867
commit 820b3fd771
3 changed files with 165 additions and 0 deletions

View File

@ -2102,6 +2102,73 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
default: break;
}
break;
case ELF::EM_S390:
switch (Type) {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_NONE);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_8);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_12);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT12);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_COPY);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GLOB_DAT);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_JMP_SLOT);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_RELATIVE);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPC);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16DBL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT16DBL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32DBL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32DBL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPCDBL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTENT);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT12);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLTENT);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LOAD);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GDCALL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDCALL);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE12);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IEENT);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPMOD);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPOFF);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_TPOFF);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_20);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT20);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT20);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE20);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_IRELATIVE);
default: break;
}
break;
default: break;
}
return Res;
@ -2629,6 +2696,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF64-aarch64";
case ELF::EM_PPC64:
return "ELF64-ppc64";
case ELF::EM_S390:
return "ELF64-s390";
default:
return "ELF64-unknown";
}
@ -2656,6 +2725,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
Triple::mipsel : Triple::mips;
case ELF::EM_PPC64:
return Triple::ppc64;
case ELF::EM_S390:
return Triple::systemz;
default:
return Triple::UnknownArch;
}

View File

@ -102,6 +102,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();
@ -202,6 +212,24 @@ private:
return RelocToApply(Value + Addend, 8);
}
// SystemZ ELF
RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
int64_t Addend;
R.getAdditionalInfo(Addend);
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;
R.getAdditionalInfo(Addend);
return RelocToApply(Value + Addend, 8);
}
};
}

View File

@ -946,6 +946,72 @@ enum {
R_HEX_TPREL_11_X = 85
};
// ELF Relocation types for S390/zSeries
enum {
R_390_NONE = 0,
R_390_8 = 1,
R_390_12 = 2,
R_390_16 = 3,
R_390_32 = 4,
R_390_PC32 = 5,
R_390_GOT12 = 6,
R_390_GOT32 = 7,
R_390_PLT32 = 8,
R_390_COPY = 9,
R_390_GLOB_DAT = 10,
R_390_JMP_SLOT = 11,
R_390_RELATIVE = 12,
R_390_GOTOFF = 13,
R_390_GOTPC = 14,
R_390_GOT16 = 15,
R_390_PC16 = 16,
R_390_PC16DBL = 17,
R_390_PLT16DBL = 18,
R_390_PC32DBL = 19,
R_390_PLT32DBL = 20,
R_390_GOTPCDBL = 21,
R_390_64 = 22,
R_390_PC64 = 23,
R_390_GOT64 = 24,
R_390_PLT64 = 25,
R_390_GOTENT = 26,
R_390_GOTOFF16 = 27,
R_390_GOTOFF64 = 28,
R_390_GOTPLT12 = 29,
R_390_GOTPLT16 = 30,
R_390_GOTPLT32 = 31,
R_390_GOTPLT64 = 32,
R_390_GOTPLTENT = 33,
R_390_PLTOFF16 = 34,
R_390_PLTOFF32 = 35,
R_390_PLTOFF64 = 36,
R_390_TLS_LOAD = 37,
R_390_TLS_GDCALL = 38,
R_390_TLS_LDCALL = 39,
R_390_TLS_GD32 = 40,
R_390_TLS_GD64 = 41,
R_390_TLS_GOTIE12 = 42,
R_390_TLS_GOTIE32 = 43,
R_390_TLS_GOTIE64 = 44,
R_390_TLS_LDM32 = 45,
R_390_TLS_LDM64 = 46,
R_390_TLS_IE32 = 47,
R_390_TLS_IE64 = 48,
R_390_TLS_IEENT = 49,
R_390_TLS_LE32 = 50,
R_390_TLS_LE64 = 51,
R_390_TLS_LDO32 = 52,
R_390_TLS_LDO64 = 53,
R_390_TLS_DTPMOD = 54,
R_390_TLS_DTPOFF = 55,
R_390_TLS_TPOFF = 56,
R_390_20 = 57,
R_390_GOT20 = 58,
R_390_GOTPLT20 = 59,
R_390_TLS_GOTIE20 = 60,
R_390_IRELATIVE = 61
};
// Section header.
struct Elf32_Shdr {
Elf32_Word sh_name; // Section name (index into string table)