diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-11-25 15:14:49 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-11-25 15:14:49 +0000 |
commit | f4f14f68f6078ea6681ee27b5bf42719d7db3441 (patch) | |
tree | 008861973146b0c72963fbaec75f7e9cb8c64798 /lib/MC | |
parent | a91eead943d9016fd25f92ab723d8e44ead34109 (diff) | |
download | external_llvm-f4f14f68f6078ea6681ee27b5bf42719d7db3441.zip external_llvm-f4f14f68f6078ea6681ee27b5bf42719d7db3441.tar.gz external_llvm-f4f14f68f6078ea6681ee27b5bf42719d7db3441.tar.bz2 |
Add support for .cfi_register now that it is easy to extent the representation
to support it. Original patch with the parsing and plumbing by the PaX team and
Roman Divacky. I added the bits in MCDwarf.cpp and the test.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168565 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 | 13 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 26 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 8 |
4 files changed, 58 insertions, 0 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index e53bc7b..32dee5e 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -227,6 +227,7 @@ public: virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFISignalFrame(); virtual void EmitCFIUndefined(int64_t Register); + virtual void EmitCFIRegister(int64_t Register1, int64_t Register2); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); @@ -1047,6 +1048,16 @@ void MCAsmStreamer::EmitCFIUndefined(int64_t Register) { EmitEOL(); } +void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { + MCStreamer::EmitCFIRegister(Register1, Register2); + + if (!UseCFI) + return; + + OS << "\t.cfi_register " << Register1 << ", " << Register2; + EmitEOL(); +} + void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { MCStreamer::EmitWin64EHStartProc(Symbol); diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 4a07537..92ed6cc 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -938,6 +938,19 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer, bool VerboseAsm = Streamer.isVerboseAsm(); switch (Instr.getOperation()) { + case MCCFIInstruction::OpRegister: { + unsigned Reg1 = Instr.getRegister(); + unsigned Reg2 = Instr.getRegister2(); + if (VerboseAsm) { + Streamer.AddComment("DW_CFA_register"); + Streamer.AddComment(Twine("Reg1 ") + Twine(Reg1)); + Streamer.AddComment(Twine("Reg2 ") + Twine(Reg2)); + } + Streamer.EmitIntValue(dwarf::DW_CFA_register, 1); + Streamer.EmitULEB128IntValue(Reg1); + Streamer.EmitULEB128IntValue(Reg2); + return; + } case MCCFIInstruction::OpUndefined: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) { diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 34ebe3b..106dd53 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -398,6 +398,8 @@ public: &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame"); AddDirectiveHandler< &GenericAsmParser::ParseDirectiveCFIUndefined>(".cfi_undefined"); + AddDirectiveHandler< + &GenericAsmParser::ParseDirectiveCFIRegister>(".cfi_register"); // Macro directives. AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( @@ -436,6 +438,7 @@ public: bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIUndefined(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFIRegister(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); @@ -3263,6 +3266,29 @@ bool GenericAsmParser::ParseDirectiveCFIUndefined(StringRef Directive, return false; } +/// ParseDirectiveCFIRegister +/// ::= .cfi_register register, register +bool GenericAsmParser::ParseDirectiveCFIRegister(StringRef Directive, + SMLoc DirectiveLoc) { + int64_t Register1 = 0; + + if (ParseRegisterOrRegisterNumber(Register1, DirectiveLoc)) + return true; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + + int64_t Register2 = 0; + + if (ParseRegisterOrRegisterNumber(Register2, DirectiveLoc)) + return true; + + getStreamer().EmitCFIRegister(Register1, Register2); + + return false; +} + /// ParseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 4f6b623..cdfd524 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -356,6 +356,14 @@ void MCStreamer::EmitCFIUndefined(int64_t Register) { CurFrame->Instructions.push_back(Instruction); } +void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { + MCSymbol *Label = EmitCFICommon(); + MCCFIInstruction Instruction = + MCCFIInstruction::createRegister(Label, Register1, Register2); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + CurFrame->Instructions.push_back(Instruction); +} + void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { W64UnwindInfos.push_back(Frame); CurrentW64UnwindInfo = W64UnwindInfos.back(); |