From cdfecc8759941c2996214070478d30084b79d463 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 22 Nov 2010 14:27:24 +0000 Subject: [PATCH] Add basic CFI methods to the streamer interface. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119972 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCStreamer.h | 8 ++++ lib/MC/MCAsmStreamer.cpp | 78 +++++++++++++++++++++++++++++++++++ lib/MC/MCParser/AsmParser.cpp | 26 ++++++++---- lib/MC/MCStreamer.cpp | 28 +++++++++++++ 4 files changed, 133 insertions(+), 7 deletions(-) diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 55dc6f102b6..e6dd6386ec6 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -352,6 +352,14 @@ namespace llvm { unsigned Isa, unsigned Discriminator); + virtual bool EmitCFIStartProc(); + virtual bool EmitCFIEndProc(); + virtual bool EmitCFIDefCfaOffset(int64_t Offset); + virtual bool EmitCFIDefCfaRegister(int64_t Register); + virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); + virtual bool EmitCFIPersonality(const MCSymbol *Sym); + virtual bool EmitCFILsda(const MCSymbol *Sym); + /// EmitInstruction - Emit the given @p Instruction into the current /// section. virtual void EmitInstruction(const MCInst &Inst) = 0; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 012c79c8829..8ee5542d369 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -177,6 +177,14 @@ public: unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator); + virtual bool EmitCFIStartProc(); + virtual bool EmitCFIEndProc(); + virtual bool EmitCFIDefCfaOffset(int64_t Offset); + virtual bool EmitCFIDefCfaRegister(int64_t Register); + virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); + virtual bool EmitCFIPersonality(const MCSymbol *Sym); + virtual bool EmitCFILsda(const MCSymbol *Sym); + virtual void EmitInstruction(const MCInst &Inst); /// EmitRawText - If this file is backed by an assembly streamer, this dumps @@ -702,6 +710,76 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, EmitEOL(); } +bool MCAsmStreamer::EmitCFIStartProc() { + if (this->MCStreamer::EmitCFIStartProc()) + return true; + + OS << ".cfi_startproc"; + EmitEOL(); + + return false; +} + +bool MCAsmStreamer::EmitCFIEndProc() { + if (this->MCStreamer::EmitCFIEndProc()) + return true; + + OS << ".cfi_endproc"; + EmitEOL(); + + return false; +} + +bool MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { + if (this->MCStreamer::EmitCFIDefCfaOffset(Offset)) + return true; + + OS << ".cfi_def_cfa_offset " << Offset; + EmitEOL(); + + return false; +} + +bool MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { + if (this->MCStreamer::EmitCFIDefCfaRegister(Register)) + return true; + + OS << ".cfi_def_cfa_register " << Register; + EmitEOL(); + + return false; +} + +bool MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { + if (this->MCStreamer::EmitCFIOffset(Register, Offset)) + return true; + + OS << ".cfi_offset " << Register << ", " << Offset; + EmitEOL(); + + return false; +} + +bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym) { + if (this->MCStreamer::EmitCFIPersonality(Sym)) + return true; + + OS << ".cfi_personality 0, " << *Sym; + EmitEOL(); + + return false; +} + +bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym) { + if (this->MCStreamer::EmitCFILsda(Sym)) + return true; + + OS << ".cfi_lsda 0, " << *Sym; + EmitEOL(); + + return false; +} + void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { raw_ostream &OS = GetCommentOS(); SmallString<256> Code; diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 63ddfb9f825..a03e496763d 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -2151,13 +2151,13 @@ bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive, /// ::= .cfi_startproc bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc) { - return false; + return getStreamer().EmitCFIStartProc(); } /// ParseDirectiveCFIEndProc /// ::= .cfi_endproc bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) { - return false; + return getStreamer().EmitCFIEndProc(); } /// ParseDirectiveCFIDefCfaOffset @@ -2168,7 +2168,7 @@ bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef, if (getParser().ParseAbsoluteExpression(Offset)) return true; - return false; + return getStreamer().EmitCFIDefCfaOffset(Offset); } /// ParseDirectiveCFIDefCfaRegister @@ -2178,7 +2178,8 @@ bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef, int64_t Register = 0; if (getParser().ParseAbsoluteExpression(Register)) return true; - return false; + + return getStreamer().EmitCFIDefCfaRegister(Register); } /// ParseDirectiveCFIOffset @@ -2196,13 +2197,13 @@ bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) { if (getParser().ParseAbsoluteExpression(Offset)) return true; - return false; + return getStreamer().EmitCFIOffset(Register, Offset); } /// ParseDirectiveCFIPersonalityOrLsda /// ::= .cfi_personality encoding, [symbol_name] /// ::= .cfi_lsda encoding, [symbol_name] -bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef, +bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal, SMLoc DirectiveLoc) { int64_t Encoding = 0; if (getParser().ParseAbsoluteExpression(Encoding)) @@ -2210,6 +2211,9 @@ bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef, if (Encoding == 255) return false; + if (Encoding != 0) + return TokError("unsupported encoding."); + if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); Lex(); @@ -2217,7 +2221,15 @@ bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef, StringRef Name; if (getParser().ParseIdentifier(Name)) return TokError("expected identifier in directive"); - return false; + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + + if (IDVal == ".cfi_personality") + return getStreamer().EmitCFIPersonality(Sym); + else { + assert(IDVal == ".cfi_lsda"); + return getStreamer().EmitCFILsda(Sym); + } } /// ParseDirectiveMacrosOnOff diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index fc2f65eb085..69318ea3543 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -77,6 +77,34 @@ void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, Discriminator); } +bool MCStreamer::EmitCFIStartProc() { + return false; +} + +bool MCStreamer::EmitCFIEndProc() { + return false; +} + +bool MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { + return false; +} + +bool MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { + return false; +} + +bool MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { + return false; +} + +bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym) { + return false; +} + +bool MCStreamer::EmitCFILsda(const MCSymbol *Sym) { + return false; +} + /// EmitRawText - If this file is backed by an assembly streamer, this dumps /// the specified string in the output .s file. This capability is /// indicated by the hasRawTextSupport() predicate. -- 2.34.1