diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-01-23 21:51:52 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-01-23 21:51:52 +0000 |
commit | 16d7d437e03ce87fdaef7971919302920d54a966 (patch) | |
tree | 917db501075fe629e6a63083ed422f9ec9aae063 /lib/MC | |
parent | e55bbfe145cf8dcb9594865f0242321d2be681d6 (diff) |
Add support for .cfi_signal_frame. Fixes pr11762.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 11 | ||||
-rw-r--r-- | lib/MC/MCDwarf.cpp | 22 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 16 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 6 |
4 files changed, 48 insertions, 7 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 87516e04cf..a2fb7a40d4 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -222,6 +222,7 @@ public: virtual void EmitCFISameValue(int64_t Register); virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); + virtual void EmitCFISignalFrame(); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); @@ -993,6 +994,16 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { EmitEOL(); } +void MCAsmStreamer::EmitCFISignalFrame() { + MCStreamer::EmitCFISignalFrame(); + + if (!UseCFI) + return; + + OS << "\t.cif_signal_frame"; + EmitEOL(); +} + void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { MCStreamer::EmitWin64EHStartProc(Symbol); diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 15476872c8..65f1ad1e17 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -840,6 +840,7 @@ namespace { const MCSymbol *personality, unsigned personalityEncoding, const MCSymbol *lsda, + bool IsSignalFrame, unsigned lsdaEncoding); MCSymbol *EmitFDE(MCStreamer &streamer, const MCSymbol &cieStart, @@ -1111,6 +1112,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, const MCSymbol *lsda, + bool IsSignalFrame, unsigned lsdaEncoding) { MCContext &context = streamer.getContext(); const MCRegisterInfo &MRI = context.getRegisterInfo(); @@ -1153,6 +1155,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, if (lsda) Augmentation += "L"; Augmentation += "R"; + if (IsSignalFrame) + Augmentation += "S"; streamer.EmitBytes(Augmentation.str(), 0); } streamer.EmitIntValue(0, 1); @@ -1312,17 +1316,18 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, namespace { struct CIEKey { - static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1); } - static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0); } + static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); } + static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); } CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_, - unsigned LsdaEncoding_) : Personality(Personality_), - PersonalityEncoding(PersonalityEncoding_), - LsdaEncoding(LsdaEncoding_) { + unsigned LsdaEncoding_, bool IsSignalFrame_) : + Personality(Personality_), PersonalityEncoding(PersonalityEncoding_), + LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) { } const MCSymbol* Personality; unsigned PersonalityEncoding; unsigned LsdaEncoding; + bool IsSignalFrame; }; } @@ -1340,13 +1345,15 @@ namespace llvm { ID.AddPointer(Key.Personality); ID.AddInteger(Key.PersonalityEncoding); ID.AddInteger(Key.LsdaEncoding); + ID.AddBoolean(Key.IsSignalFrame); return ID.ComputeHash(); } static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) { return LHS.Personality == RHS.Personality && LHS.PersonalityEncoding == RHS.PersonalityEncoding && - LHS.LsdaEncoding == RHS.LsdaEncoding; + LHS.LsdaEncoding == RHS.LsdaEncoding && + LHS.IsSignalFrame == RHS.IsSignalFrame; } }; } @@ -1382,11 +1389,12 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) { const MCDwarfFrameInfo &Frame = FrameArray[i]; CIEKey Key(Frame.Personality, Frame.PersonalityEncoding, - Frame.LsdaEncoding); + Frame.LsdaEncoding, Frame.IsSignalFrame); const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey; if (!CIEStart) CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality, Frame.PersonalityEncoding, Frame.Lsda, + Frame.IsSignalFrame, Frame.LsdaEncoding); FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index baf8b30a9b..64d0dd8563 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -306,6 +306,8 @@ public: &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore"); AddDirectiveHandler< &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape"); + AddDirectiveHandler< + &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame"); // Macro directives. AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( @@ -341,6 +343,7 @@ public: bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); @@ -2855,6 +2858,19 @@ bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal, return false; } +/// ParseDirectiveCFISignalFrame +/// ::= .cfi_signal_frame +bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive, + SMLoc DirectiveLoc) { + if (getLexer().isNot(AsmToken::EndOfStatement)) + return Error(getLexer().getLoc(), + "unexpected token in '" + Directive + "' directive"); + + getStreamer().EmitCFISignalFrame(); + + return false; +} + /// ParseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 7bbb379a2c..1690eea73c 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -439,6 +439,12 @@ void MCStreamer::EmitCFIEscape(StringRef Values) { CurFrame->Instructions.push_back(Instruction); } +void MCStreamer::EmitCFISignalFrame() { + EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + CurFrame->IsSignalFrame = true; +} + void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { W64UnwindInfos.push_back(Frame); CurrentW64UnwindInfo = W64UnwindInfos.back(); |