diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-01-30 04:02:47 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-01-30 04:02:47 +0000 |
commit | 2c9ed5d050b5c57bfed35bd82c23f46c714d10c0 (patch) | |
tree | f6f3cffacae3d7b2a3597f3756f89ce97481c48b /lib | |
parent | 4747d6b0a50fe9fd22c03d10d72a748bef3edb58 (diff) | |
download | llvm-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.cpp | 1 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 27 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 3 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 19 |
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; |