From: Rafael Espindola Date: Fri, 23 Nov 2012 16:59:41 +0000 (+0000) Subject: Implement .cfi_undefined. Based on a patch from PaX team, updated by X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9bb247813aae7cda7b883f1bd0bff2697877dbb1;p=platform%2Fupstream%2Fllvm.git Implement .cfi_undefined. Based on a patch from PaX team, updated by Roman Divacky. I just added the testcase. llvm-svn: 168520 --- diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h index 8fc437f3..6fa41ae 100644 --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -267,7 +267,7 @@ namespace llvm { class MCCFIInstruction { public: enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape, - Restore}; + Restore, Undefined }; private: OpType Operation; MCSymbol *Label; @@ -282,7 +282,7 @@ namespace llvm { } MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) : Operation(Op), Label(L), Destination(Register) { - assert(Op == SameValue || Op == Restore); + assert(Op == SameValue || Op == Restore || Op == Undefined); } MCCFIInstruction(MCSymbol *L, const MachineLocation &D, const MachineLocation &S) diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 230d27e..b5c8008 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -515,6 +515,7 @@ namespace llvm { virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFIEscape(StringRef Values); virtual void EmitCFISignalFrame(); + virtual void EmitCFIUndefined(int64_t Register); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 17a6323..e53bc7b 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -226,6 +226,7 @@ public: virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFISignalFrame(); + virtual void EmitCFIUndefined(int64_t Register); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); @@ -1036,6 +1037,16 @@ void MCAsmStreamer::EmitCFISignalFrame() { EmitEOL(); } +void MCAsmStreamer::EmitCFIUndefined(int64_t Register) { + MCStreamer::EmitCFIUndefined(Register); + + if (!UseCFI) + return; + + OS << "\t.cfi_undefined " << Register; + EmitEOL(); +} + void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { MCStreamer::EmitWin64EHStartProc(Symbol); diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index bb9ed49..85b47fe 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -938,6 +938,16 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer, bool VerboseAsm = Streamer.isVerboseAsm(); switch (Instr.getOperation()) { + case MCCFIInstruction::Undefined: { + unsigned Reg = Instr.getDestination().getReg(); + if (VerboseAsm) { + Streamer.AddComment("DW_CFA_undefined"); + Streamer.AddComment(Twine("Reg ") + Twine(Reg)); + } + Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1); + Streamer.EmitULEB128IntValue(Reg); + return; + } case MCCFIInstruction::Move: case MCCFIInstruction::RelMove: { const MachineLocation &Dst = Instr.getDestination(); diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 6f2e85e..34ebe3b 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -396,6 +396,8 @@ public: &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape"); AddDirectiveHandler< &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame"); + AddDirectiveHandler< + &GenericAsmParser::ParseDirectiveCFIUndefined>(".cfi_undefined"); // Macro directives. AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( @@ -433,6 +435,7 @@ public: bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFIUndefined(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); @@ -3246,6 +3249,20 @@ bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive, return false; } +/// ParseDirectiveCFIUndefined +/// ::= .cfi_undefined register +bool GenericAsmParser::ParseDirectiveCFIUndefined(StringRef Directive, + SMLoc DirectiveLoc) { + int64_t Register = 0; + + if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + return true; + + getStreamer().EmitCFIUndefined(Register); + + return false; +} + /// ParseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index afece0b..02e1028 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -367,6 +367,15 @@ void MCStreamer::EmitCFISignalFrame() { CurFrame->IsSignalFrame = true; } +void MCStreamer::EmitCFIUndefined(int64_t Register) { + EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + MCSymbol *Label = getContext().CreateTempSymbol(); + EmitLabel(Label); + MCCFIInstruction Instruction(MCCFIInstruction::Undefined, Label, Register); + CurFrame->Instructions.push_back(Instruction); +} + void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { W64UnwindInfos.push_back(Frame); CurrentW64UnwindInfo = W64UnwindInfos.back(); diff --git a/llvm/test/MC/ELF/cfi-undefined.s b/llvm/test/MC/ELF/cfi-undefined.s new file mode 100644 index 0000000..28049fa --- /dev/null +++ b/llvm/test/MC/ELF/cfi-undefined.s @@ -0,0 +1,41 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +f: + .cfi_startproc + nop + .cfi_undefined %rbp + nop + .cfi_endproc +// CHECK: # Section 4 +// CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000001) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) +// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410706 00000000') +// CHECK-NEXT: ), +// CHECK-NEXT: # Section 5 +// CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' +// CHECK-NEXT: ('sh_type', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) +// CHECK-NEXT: ('sh_link', 0x00000007) +// CHECK-NEXT: ('sh_info', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) +// CHECK-NEXT: ),