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 | 56e06e86406421bd0d4ea86e07cca3621dbf2382 (patch) | |
| tree | 35365d85b9dc017cd9d3a26007607fa7567daa07 /llvm/lib | |
| parent | a3f12bdeecaae4a8c17483f096d4c30a02036dd8 (diff) | |
| download | bcm5719-llvm-56e06e86406421bd0d4ea86e07cca3621dbf2382.tar.gz bcm5719-llvm-56e06e86406421bd0d4ea86e07cca3621dbf2382.zip | |
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.
llvm-svn: 200448
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/MC/MCExpr.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 19 |
4 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index d402e6d896b..75bde8ed36b 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/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/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 2f9a12f2c77..2b4eaf0f15c 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/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/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 5f719d5bb7c..d9a1453cc35 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/llvm/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/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index efee318a047..c2e3503278b 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/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; |

