summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-01-30 04:02:31 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-01-30 04:02:31 +0000
commit9629ad300552f1a34f806eae90afb85bc6c55e9b (patch)
tree901a202de9c80f36d61e0730b4e6357b4a442d5a /lib
parentd26c0e731ced4dfcb1dfe9c67b0822fe96d0ad6a (diff)
downloadllvm-9629ad300552f1a34f806eae90afb85bc6c55e9b.tar.gz
llvm-9629ad300552f1a34f806eae90afb85bc6c55e9b.tar.bz2
llvm-9629ad300552f1a34f806eae90afb85bc6c55e9b.tar.xz
ARM: support tlscall relocations
This adds support for TLS CALL relocations. TLS CALL relocations are used to indicate to the linker to generate appropriate entries to resolve TLS references via an appropriate function invocation (e.g. __tls_get_addr(PLT)). In order to accomodate the linker relaxation of the TLS access model for the references (GD/LD -> IE, IE -> LE), the relocation addend must be incomplete. This requires that the partial inplace value is also incomplete (i.e. 0). We simply avoid the offset value calculation at the time of the fixup adjustment in the ARM assembler backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200446 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/MC/MCExpr.cpp3
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp6
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp15
3 files changed, 23 insertions, 1 deletions
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index 2052d55dc7..3772bceea5 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -185,6 +185,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_ARM_TARGET2: return "target2";
case VK_ARM_PREL31: return "prel31";
case VK_ARM_TLSLDO: return "tlsldo";
+ case VK_ARM_TLSCALL: return "tlscall";
case VK_PPC_LO: return "l";
case VK_PPC_HI: return "h";
case VK_PPC_HA: return "ha";
@@ -408,6 +409,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("prel31", VK_ARM_PREL31)
.Case("TLSLDO", VK_ARM_TLSLDO)
.Case("tlsldo", VK_ARM_TLSLDO)
+ .Case("TLSCALL", VK_ARM_TLSCALL)
+ .Case("tlscall", VK_ARM_TLSCALL)
.Default(VK_Invalid);
}
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 305c7587cb..7db700472c 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -380,6 +380,9 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case ARM::fixup_arm_blx:
// These values don't encode the low two bits since they're always zero.
// Offset by 8 just as above.
+ if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
+ if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL)
+ return 0;
return 0xffffff & ((Value - 8) >> 2);
case ARM::fixup_t2_uncondbranch: {
Value = Value - 4;
@@ -461,6 +464,9 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
// Note that the halfwords are stored high first, low second; so we need
// to transpose the fixup value here to map properly.
uint32_t offset = (Value - 2) >> 2;
+ if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
+ if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL)
+ offset = 0;
uint32_t signBit = (offset & 0x400000) >> 22;
uint32_t I1Bit = (offset & 0x200000) >> 21;
uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
index 6fcc021a6c..08c040235f 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -179,6 +179,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
case MCSymbolRefExpr::VK_PLT:
Type = ELF::R_ARM_PLT32;
break;
+ case MCSymbolRefExpr::VK_ARM_TLSCALL:
+ Type = ELF::R_ARM_TLS_CALL;
+ break;
default:
Type = ELF::R_ARM_CALL;
break;
@@ -211,7 +214,14 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
break;
case ARM::fixup_arm_thumb_bl:
case ARM::fixup_arm_thumb_blx:
- Type = ELF::R_ARM_THM_CALL;
+ switch (Modifier) {
+ case MCSymbolRefExpr::VK_ARM_TLSCALL:
+ Type = ELF::R_ARM_THM_TLS_CALL;
+ break;
+ default:
+ Type = ELF::R_ARM_THM_CALL;
+ break;
+ }
break;
}
} else {
@@ -253,6 +263,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
case MCSymbolRefExpr::VK_ARM_TLSLDO:
Type = ELF::R_ARM_TLS_LDO32;
break;
+ case MCSymbolRefExpr::VK_ARM_TLSCALL:
+ Type = ELF::R_ARM_TLS_CALL;
+ break;
}
break;
case ARM::fixup_arm_ldst_pcrel_12: