diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2015-02-18 09:11:36 +0000 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2015-02-18 09:11:36 +0000 |
commit | 7bdd7c2346ff53c68a8748893170134826f23012 (patch) | |
tree | dfa9bc931679bcc8721b2f80a754dc4a6a22428a /llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp | |
parent | a250484c4c7a7b1c88b5383fc922f64a7f70e40e (diff) | |
download | bcm5719-llvm-7bdd7c2346ff53c68a8748893170134826f23012.tar.gz bcm5719-llvm-7bdd7c2346ff53c68a8748893170134826f23012.zip |
[SystemZ] Support all TLS access models - MC part
The current SystemZ back-end only supports the local-exec TLS access model.
This patch adds all required MC support for the other TLS models, which
means in particular:
- Support additional relocation types for
Initial-exec model: R_390_TLS_IEENT
Local-dynamic-model: R_390_TLS_LDO32, R_390_TLS_LDO64,
R_390_TLS_LDM32, R_390_TLS_LDM64, R_390_TLS_LDCALL
General-dynamic model: R_390_TLS_GD32, R_390_TLS_GD64, R_390_TLS_GDCALL
- Support assembler syntax to generate additional relocations
for use with __tls_get_offset calls:
:tls_gdcall:
:tls_ldcall:
The patch also adds a new test to verify fixups and relocations,
and removes the (already unused) FK_390_PLT16DBL/FK_390_PLT32DBL
fixup kinds.
llvm-svn: 229652
Diffstat (limited to 'llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp')
-rw-r--r-- | llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp index c6a18165889..263251800d7 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp @@ -55,8 +55,6 @@ static unsigned getPCRelReloc(unsigned Kind) { case FK_Data_8: return ELF::R_390_PC64; case SystemZ::FK_390_PC16DBL: return ELF::R_390_PC16DBL; case SystemZ::FK_390_PC32DBL: return ELF::R_390_PC32DBL; - case SystemZ::FK_390_PLT16DBL: return ELF::R_390_PLT16DBL; - case SystemZ::FK_390_PLT32DBL: return ELF::R_390_PLT32DBL; } llvm_unreachable("Unsupported PC-relative address"); } @@ -70,6 +68,35 @@ static unsigned getTLSLEReloc(unsigned Kind) { llvm_unreachable("Unsupported absolute address"); } +// Return the R_390_TLS_LDO* relocation type for MCFixupKind Kind. +static unsigned getTLSLDOReloc(unsigned Kind) { + switch (Kind) { + case FK_Data_4: return ELF::R_390_TLS_LDO32; + case FK_Data_8: return ELF::R_390_TLS_LDO64; + } + llvm_unreachable("Unsupported absolute address"); +} + +// Return the R_390_TLS_LDM* relocation type for MCFixupKind Kind. +static unsigned getTLSLDMReloc(unsigned Kind) { + switch (Kind) { + case FK_Data_4: return ELF::R_390_TLS_LDM32; + case FK_Data_8: return ELF::R_390_TLS_LDM64; + case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_LDCALL; + } + llvm_unreachable("Unsupported absolute address"); +} + +// Return the R_390_TLS_GD* relocation type for MCFixupKind Kind. +static unsigned getTLSGDReloc(unsigned Kind) { + switch (Kind) { + case FK_Data_4: return ELF::R_390_TLS_GD32; + case FK_Data_8: return ELF::R_390_TLS_GD64; + case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_GDCALL; + } + llvm_unreachable("Unsupported absolute address"); +} + // Return the PLT relocation counterpart of MCFixupKind Kind. static unsigned getPLTReloc(unsigned Kind) { switch (Kind) { @@ -94,6 +121,23 @@ unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target, assert(!IsPCRel && "NTPOFF shouldn't be PC-relative"); return getTLSLEReloc(Kind); + case MCSymbolRefExpr::VK_INDNTPOFF: + if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL) + return ELF::R_390_TLS_IEENT; + llvm_unreachable("Only PC-relative INDNTPOFF accesses are supported for now"); + + case MCSymbolRefExpr::VK_DTPOFF: + assert(!IsPCRel && "DTPOFF shouldn't be PC-relative"); + return getTLSLDOReloc(Kind); + + case MCSymbolRefExpr::VK_TLSLDM: + assert(!IsPCRel && "TLSLDM shouldn't be PC-relative"); + return getTLSLDMReloc(Kind); + + case MCSymbolRefExpr::VK_TLSGD: + assert(!IsPCRel && "TLSGD shouldn't be PC-relative"); + return getTLSGDReloc(Kind); + case MCSymbolRefExpr::VK_GOT: if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL) return ELF::R_390_GOTENT; |