diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index 3734d7e006b4..c9cecc17387b 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -271,6 +271,10 @@ namespace llvm { /// .file directive, this is true for ELF targets. bool HasSingleParameterDotFile; // Defaults to true. + /// hasIdentDirective - True if the target has a .ident directive, this is + /// true for ELF targets. + bool HasIdentDirective; // Defaults to false. + /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip /// directive. bool HasNoDeadStrip; // Defaults to false. @@ -523,6 +527,7 @@ namespace llvm { } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } + bool hasIdentDirective() const { return HasIdentDirective; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } bool hasSymbolResolver() const { return HasSymbolResolver; } const char *getWeakRefDirective() const { return WeakRefDirective; } diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 8dbe337b0f29..4e24dcfacd50 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -31,13 +31,14 @@ class MCELFStreamer : public MCObjectStreamer { public: MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter) {} + : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter), + SeenIdent(false) {} MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, MCAssembler *Assembler) - : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler) { - } + : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler), + SeenIdent(false) {} virtual ~MCELFStreamer(); @@ -77,6 +78,8 @@ public: virtual void EmitFileDirective(StringRef Filename); + virtual void EmitIdent(StringRef IdentString); + virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned); virtual void Flush(); @@ -93,6 +96,8 @@ private: void fixSymbolsInTLSFixups(const MCExpr *expr); + bool SeenIdent; + struct LocalCommon { MCSymbolData *SD; uint64_t Size; diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index d24f3fd4be27..974feea08e08 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -571,6 +571,10 @@ public: /// implement the '.file "foo.c"' assembler directive. virtual void EmitFileDirective(StringRef Filename) = 0; + /// Emit the "identifiers" directive. This implements the + /// '.ident "version foo"' assembler directive. + virtual void EmitIdent(StringRef IdentString) {} + /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp index 152aae15af17..6112ad1fcaca 100644 --- a/llvm/lib/MC/MCAsmInfo.cpp +++ b/llvm/lib/MC/MCAsmInfo.cpp @@ -76,6 +76,7 @@ MCAsmInfo::MCAsmInfo() { LCOMMDirectiveAlignmentType = LCOMM::NoAlignment; HasDotTypeDotSizeDirective = true; HasSingleParameterDotFile = true; + HasIdentDirective = false; HasNoDeadStrip = false; HasSymbolResolver = false; WeakRefDirective = 0; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index e735344a69b9..e751a6d9fc3b 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -213,6 +213,7 @@ public: unsigned Isa, unsigned Discriminator, StringRef FileName); + virtual void EmitIdent(StringRef IdentString); virtual void EmitCFISections(bool EH, bool Debug); virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); virtual void EmitCFIDefCfaOffset(int64_t Offset); @@ -880,6 +881,13 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, EmitEOL(); } +void MCAsmStreamer::EmitIdent(StringRef IdentString) { + assert(MAI->hasIdentDirective() && ".ident directive not supported"); + OS << "\t.ident\t"; + PrintQuotedString(IdentString, OS); + EmitEOL(); +} + void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) { MCStreamer::EmitCFISections(EH, Debug); diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index c16a61d2b695..3f6c62c0625c 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -329,7 +329,22 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) { SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); } -void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { +void MCELFStreamer::EmitIdent(StringRef IdentString) { + const MCSection *Comment = getAssembler().getContext().getELFSection( + ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, + SectionKind::getReadOnly(), 1, ""); + PushSection(); + SwitchSection(Comment); + if (!SeenIdent) { + EmitIntValue(0, 1); + SeenIdent = true; + } + EmitBytes(IdentString); + EmitIntValue(0, 1); + PopSection(); +} + +void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { switch (expr->getKind()) { case MCExpr::Target: cast(expr)->fixELFSymbolsInTLSFixups(getAssembler()); diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 78c009423c81..2924dcd87630 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -82,7 +82,11 @@ public: // FIXME: Just ignore the .file; it isn't important enough to fail the // entire assembly. - //report_fatal_error("unsupported directive: '.file'"); + // report_fatal_error("unsupported directive: '.file'"); + } + + virtual void EmitIdent(StringRef IdentString) { + llvm_unreachable("macho doesn't support this directive"); } virtual void FinishImpl(); diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index ca7117362812..8807975e8545 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -31,14 +31,11 @@ class ELFAsmParser : public MCAsmParserExtension { getParser().addDirectiveHandler(Directive, Handler); } - bool ParseSectionSwitch(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind); - bool SeenIdent; + bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind); public: - ELFAsmParser() : SeenIdent(false) { - BracketExpressionsSupported = true; - } + ELFAsmParser() { BracketExpressionsSupported = true; } virtual void Initialize(MCAsmParser &Parser) { // Call the base implementation. @@ -579,22 +576,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { Lex(); - const MCSection *Comment = - getContext().getELFSection(".comment", ELF::SHT_PROGBITS, - ELF::SHF_MERGE | - ELF::SHF_STRINGS, - SectionKind::getReadOnly(), - 1, ""); - - getStreamer().PushSection(); - getStreamer().SwitchSection(Comment); - if (!SeenIdent) { - getStreamer().EmitIntValue(0, 1); - SeenIdent = true; - } - getStreamer().EmitBytes(Data); - getStreamer().EmitIntValue(0, 1); - getStreamer().PopSection(); + getStreamer().EmitIdent(Data); return false; } diff --git a/llvm/lib/MC/MCPureStreamer.cpp b/llvm/lib/MC/MCPureStreamer.cpp index e5843b3da5f7..f7bf002fbc67 100644 --- a/llvm/lib/MC/MCPureStreamer.cpp +++ b/llvm/lib/MC/MCPureStreamer.cpp @@ -94,6 +94,9 @@ public: virtual void EmitFileDirective(StringRef Filename) { report_fatal_error("unsupported directive in pure streamer"); } + virtual void EmitIdent(StringRef IdentString) { + report_fatal_error("unsupported directive in pure streamer"); + } virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, unsigned CUID = 0) { report_fatal_error("unsupported directive in pure streamer"); diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 8d42d5a57917..6744df5c91fb 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -72,6 +72,7 @@ public: virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); virtual void EmitFileDirective(StringRef Filename); + virtual void EmitIdent(StringRef IdentString); virtual void EmitWin64EHHandlerData(); virtual void FinishImpl(); @@ -306,6 +307,11 @@ void WinCOFFStreamer::EmitFileDirective(StringRef Filename) { // info will be a much large effort. } +// TODO: Implement this if you want to emit .comment section in COFF obj files. +void WinCOFFStreamer::EmitIdent(StringRef IdentString) { + llvm_unreachable("unsupported directive"); +} + void WinCOFFStreamer::EmitWin64EHHandlerData() { MCStreamer::EmitWin64EHHandlerData(); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp index 826caf4b4c56..032e910bbcea 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp @@ -91,6 +91,7 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) { PrivateGlobalPrefix = ".L"; WeakRefDirective = "\t.weak\t"; + HasIdentDirective = true; // Set up DWARF directives HasLEB128 = true; // Target asm supports leb128 directives (little-endian)