summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-01-30 04:02:47 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-01-30 04:02:47 +0000
commit2c9ed5d050b5c57bfed35bd82c23f46c714d10c0 (patch)
treef6f3cffacae3d7b2a3597f3756f89ce97481c48b /lib
parent4747d6b0a50fe9fd22c03d10d72a748bef3edb58 (diff)
downloadllvm-2c9ed5d050b5c57bfed35bd82c23f46c714d10c0.tar.gz
llvm-2c9ed5d050b5c57bfed35bd82c23f46c714d10c0.tar.bz2
llvm-2c9ed5d050b5c57bfed35bd82c23f46c714d10c0.tar.xz
ARM: suuport .tlsdescseq directive
This enhances the ARMAsmParser to handle .tlsdescseq directives. This is a slightly special relocation. We must be able to generate them, but not consume them in assembly. The relocation is meant to assist the linker in generating a TLS descriptor sequence. The ELF target streamer is enhanced to append additional fixups into the current segment and that is used to emit the new R_ARM_TLS_DESCSEQ relocations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200448 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/MC/MCExpr.cpp1
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp27
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp3
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp19
4 files changed, 50 insertions, 0 deletions
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index d402e6d896..75bde8ed36 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -187,6 +187,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_ARM_TLSLDO: return "tlsldo";
case VK_ARM_TLSCALL: return "tlscall";
case VK_ARM_TLSDESC: return "tlsdesc";
+ case VK_ARM_TLSDESCSEQ: return "tlsdescseq";
case VK_PPC_LO: return "l";
case VK_PPC_HI: return "h";
case VK_PPC_HA: return "ha";
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 2f9a12f2c7..2b4eaf0f15 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -296,6 +296,7 @@ class ARMAsmParser : public MCTargetAsmParser {
bool parseDirectiveEven(SMLoc L);
bool parseDirectivePersonalityIndex(SMLoc L);
bool parseDirectiveUnwindRaw(SMLoc L);
+ bool parseDirectiveTLSDescSeq(SMLoc L);
StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
bool &CarrySetting, unsigned &ProcessorIMod,
@@ -8084,6 +8085,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
return parseDirectivePersonalityIndex(DirectiveID.getLoc());
else if (IDVal == ".unwind_raw")
return parseDirectiveUnwindRaw(DirectiveID.getLoc());
+ else if (IDVal == ".tlsdescseq")
+ return parseDirectiveTLSDescSeq(DirectiveID.getLoc());
return true;
}
@@ -9001,6 +9004,30 @@ bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
return false;
}
+/// parseDirectiveTLSDescSeq
+/// ::= .tlsdescseq tls-variable
+bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
+ if (getLexer().isNot(AsmToken::Identifier)) {
+ TokError("expected variable after '.tlsdescseq' directive");
+ Parser.eatToEndOfStatement();
+ return false;
+ }
+
+ const MCSymbolRefExpr *SRE =
+ MCSymbolRefExpr::Create(Parser.getTok().getIdentifier(),
+ MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext());
+ Lex();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ Error(Parser.getTok().getLoc(), "unexpected token");
+ Parser.eatToEndOfStatement();
+ return false;
+ }
+
+ getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
+ return false;
+}
+
/// Force static initialization.
extern "C" void LLVMInitializeARMAsmParser() {
RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
index 5f719d5bb7..d9a1453cc3 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -269,6 +269,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
case MCSymbolRefExpr::VK_ARM_TLSDESC:
Type = ELF::R_ARM_TLS_GOTDESC;
break;
+ case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
+ Type = ELF::R_ARM_TLS_DESCSEQ;
+ break;
}
break;
case ARM::fixup_arm_ldst_pcrel_12:
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index efee318a04..c2e3503278 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -139,6 +139,8 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
virtual void finishAttributeSection();
+ virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE);
+
public:
ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
MCInstPrinter &InstPrinter, bool VerboseAsm);
@@ -241,6 +243,10 @@ void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
}
void ARMTargetAsmStreamer::finishAttributeSection() {
}
+void
+ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
+ OS << "\t.tlsdescseq\t" << S->getSymbol().getName();
+}
void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
OS << "\t.inst";
@@ -397,6 +403,8 @@ private:
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
virtual void finishAttributeSection();
+ virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE);
+
size_t calculateContentSize() const;
public:
@@ -605,6 +613,8 @@ private:
void SwitchToExTabSection(const MCSymbol &FnStart);
void SwitchToExIdxSection(const MCSymbol &FnStart);
+ void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
+
bool IsThumb;
int64_t MappingSymbolCounter;
@@ -953,6 +963,10 @@ void ARMTargetELFStreamer::finishAttributeSection() {
Contents.clear();
FPU = ARM::INVALID_FPU;
}
+void
+ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
+ getStreamer().EmitFixup(S, FK_Data_4);
+}
void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
getStreamer().emitInst(Inst, Suffix);
}
@@ -1011,6 +1025,11 @@ inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
SectionKind::getDataRel(),
FnStart);
}
+void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
+ MCDataFragment *Frag = getOrCreateDataFragment();
+ Frag->getFixups().push_back(MCFixup::Create(Frag->getContents().size(), Expr,
+ Kind));
+}
void ARMELFStreamer::Reset() {
ExTab = NULL;