From 5426a9ee37667660935d80841c5392d78e254318 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 1 May 2011 04:49:54 +0000 Subject: [PATCH] GCC uses a different encoding of pointers in the FDE when using -fno-dwarf2-cfi-asm. Implement the same behavior. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130637 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../CodeGen/TargetLoweringObjectFileImpl.h | 2 +- include/llvm/MC/MCDwarf.h | 4 +- include/llvm/Target/TargetAsmInfo.h | 4 +- .../llvm/Target/TargetLoweringObjectFile.h | 2 +- .../AsmPrinter/DwarfTableException.cpp | 4 +- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 2 +- lib/MC/MCAsmStreamer.cpp | 3 ++ lib/MC/MCDwarf.cpp | 20 ++++++---- lib/MC/MCELFStreamer.cpp | 2 +- lib/Target/TargetLoweringObjectFile.cpp | 2 +- lib/Target/X86/X86TargetObjectFile.cpp | 13 +++++-- lib/Target/X86/X86TargetObjectFile.h | 4 +- test/CodeGen/X86/no-cfi.ll | 38 +++++++++++++++++++ 13 files changed, 76 insertions(+), 24 deletions(-) create mode 100644 test/CodeGen/X86/no-cfi.ll diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 493526aa7f3..829f580df33 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -188,7 +188,7 @@ public: virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; }; diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index ea2af78eb4e..3bbcf3eb6ed 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -281,8 +281,8 @@ namespace llvm { // // This emits the frame info section. // - static void Emit(MCStreamer &streamer); - static void EmitDarwin(MCStreamer &streamer); + static void Emit(MCStreamer &streamer, bool usingCFI); + static void EmitDarwin(MCStreamer &streamer, bool usingCFI); static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS, const TargetAsmInfo &AsmInfo); diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index f469cbb02c5..0271b670464 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -58,8 +58,8 @@ public: return TLOF->getEHFrameSection(); } - unsigned getFDEEncoding() const { - return TLOF->getFDEEncoding(); + unsigned getFDEEncoding(bool CFI) const { + return TLOF->getFDEEncoding(CFI); } bool isFunctionEHFrameSymbolPrivate() const { diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 360f3ceb2ab..7402ed69723 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -233,7 +233,7 @@ public: virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; protected: diff --git a/lib/CodeGen/AsmPrinter/DwarfTableException.cpp b/lib/CodeGen/AsmPrinter/DwarfTableException.cpp index 751901183cd..b50d8bd3cec 100644 --- a/lib/CodeGen/AsmPrinter/DwarfTableException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfTableException.cpp @@ -92,7 +92,7 @@ void DwarfTableException::EmitCIE(const Function *PersonalityFn, unsigned Index) // personality function reference: unsigned LSDAEncoding = TLOF.getLSDAEncoding(); - unsigned FDEEncoding = TLOF.getFDEEncoding(); + unsigned FDEEncoding = TLOF.getFDEEncoding(false); unsigned PerEncoding = TLOF.getPersonalityEncoding(); char Augmentation[6] = { 0 }; @@ -168,7 +168,7 @@ void DwarfTableException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); unsigned LSDAEncoding = TLOF.getLSDAEncoding(); - unsigned FDEEncoding = TLOF.getFDEEncoding(); + unsigned FDEEncoding = TLOF.getFDEEncoding(false); Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index aff33aa9d51..6ed91b09966 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -879,7 +879,7 @@ unsigned TargetLoweringObjectFileMachO::getLSDAEncoding() const { return DW_EH_PE_pcrel; } -unsigned TargetLoweringObjectFileMachO::getFDEEncoding() const { +unsigned TargetLoweringObjectFileMachO::getFDEEncoding(bool CFI) const { return DW_EH_PE_pcrel; } diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 8f9209d67f0..9717c016a92 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -1069,6 +1069,9 @@ void MCAsmStreamer::Finish() { // Dump out the dwarf file & directory tables and line tables. if (getContext().hasDwarfFiles() && !UseLoc) MCDwarfFileTable::Emit(this); + + if (getNumFrameInfos() && !UseCFI) + MCDwarfFrameEmitter::Emit(*this, false); } MCStreamer *llvm::createAsmStreamer(MCContext &Context, diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 09a87fb0bfd..f61f0c24cf6 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -500,9 +500,11 @@ namespace { class FrameEmitterImpl { int CFAOffset; int CIENum; + bool UsingCFI; public: - FrameEmitterImpl() : CFAOffset(0), CIENum(0) { + FrameEmitterImpl(bool usingCFI) : CFAOffset(0), CIENum(0), + UsingCFI(usingCFI) { } const MCSymbol &EmitCIE(MCStreamer &streamer, @@ -702,7 +704,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, streamer.EmitIntValue(lsdaEncoding, 1); } // Encoding of the FDE pointers - streamer.EmitIntValue(asmInfo.getFDEEncoding(), 1); + streamer.EmitIntValue(asmInfo.getFDEEncoding(UsingCFI), 1); // Initial Instructions @@ -753,7 +755,7 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart, 0); streamer.EmitAbsValue(offset, 4); - unsigned fdeEncoding = asmInfo.getFDEEncoding(); + unsigned fdeEncoding = asmInfo.getFDEEncoding(UsingCFI); unsigned size = getSizeForEncoding(streamer, fdeEncoding); // PC Begin @@ -837,8 +839,9 @@ namespace llvm { // compatible with the one in CodeGen. It is useful during the transition // to make it easy to compare the outputs, but should probably be removed // afterwards. -void MCDwarfFrameEmitter::EmitDarwin(MCStreamer &streamer) { - FrameEmitterImpl Emitter; +void MCDwarfFrameEmitter::EmitDarwin(MCStreamer &streamer, + bool usingCFI) { + FrameEmitterImpl Emitter(usingCFI); DenseMap Personalities; const MCSymbol *aCIE = NULL; const MCDwarfFrameInfo *aFrame = NULL; @@ -892,17 +895,18 @@ void MCDwarfFrameEmitter::EmitDarwin(MCStreamer &streamer) { streamer.EmitLabel(fdeEnd); } -void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { +void MCDwarfFrameEmitter::Emit(MCStreamer &streamer, + bool usingCFI) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); if (!asmInfo.isFunctionEHFrameSymbolPrivate()) { - EmitDarwin(streamer); + EmitDarwin(streamer, usingCFI); return; } MCSymbol *fdeEnd = NULL; DenseMap CIEStarts; - FrameEmitterImpl Emitter; + FrameEmitterImpl Emitter(usingCFI); for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 9fc9173914d..be8e2e3891f 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -346,7 +346,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) { void MCELFStreamer::Finish() { if (getNumFrameInfos()) - MCDwarfFrameEmitter::Emit(*this); + MCDwarfFrameEmitter::Emit(*this, true); for (std::vector::const_iterator i = LocalCommons.begin(), e = LocalCommons.end(); diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 325493db25d..717ad412201 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -350,7 +350,7 @@ unsigned TargetLoweringObjectFile::getLSDAEncoding() const { return dwarf::DW_EH_PE_absptr; } -unsigned TargetLoweringObjectFile::getFDEEncoding() const { +unsigned TargetLoweringObjectFile::getFDEEncoding(bool CFI) const { return dwarf::DW_EH_PE_absptr; } diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp index b32fe798392..f4adeb5ab69 100644 --- a/lib/Target/X86/X86TargetObjectFile.cpp +++ b/lib/Target/X86/X86TargetObjectFile.cpp @@ -58,7 +58,7 @@ unsigned X8632_ELFTargetObjectFile::getLSDAEncoding() const { return DW_EH_PE_absptr; } -unsigned X8632_ELFTargetObjectFile::getFDEEncoding() const { +unsigned X8632_ELFTargetObjectFile::getFDEEncoding(bool FDE) const { if (TM.getRelocationModel() == Reloc::PIC_) return DW_EH_PE_pcrel | DW_EH_PE_sdata4; else @@ -97,8 +97,15 @@ unsigned X8664_ELFTargetObjectFile::getLSDAEncoding() const { return DW_EH_PE_absptr; } -unsigned X8664_ELFTargetObjectFile::getFDEEncoding() const { - return DW_EH_PE_pcrel | DW_EH_PE_sdata4; +unsigned X8664_ELFTargetObjectFile::getFDEEncoding(bool CFI) const { + if (CFI) + return DW_EH_PE_pcrel | DW_EH_PE_sdata4; + + CodeModel::Model Model = TM.getCodeModel(); + if (TM.getRelocationModel() == Reloc::PIC_) + return DW_EH_PE_pcrel | DW_EH_PE_sdata4; + + return DW_EH_PE_udata4; } unsigned X8664_ELFTargetObjectFile::getTTypeEncoding() const { diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h index e7ed014f12e..e21b5bffd05 100644 --- a/lib/Target/X86/X86TargetObjectFile.h +++ b/lib/Target/X86/X86TargetObjectFile.h @@ -40,7 +40,7 @@ namespace llvm { :TM(tm) { } virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; }; @@ -51,7 +51,7 @@ namespace llvm { :TM(tm) { } virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; }; diff --git a/test/CodeGen/X86/no-cfi.ll b/test/CodeGen/X86/no-cfi.ll new file mode 100644 index 00000000000..f9985d45851 --- /dev/null +++ b/test/CodeGen/X86/no-cfi.ll @@ -0,0 +1,38 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -disable-cfi | FileCheck --check-prefix=STATIC %s +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -disable-cfi -relocation-model=pic | FileCheck --check-prefix=PIC %s + +; STATIC: .ascii "zPLR" +; STATIC: .byte 3 +; STATIC-NEXT: .long __gxx_personality_v0 +; STATIC-NEXT: .byte 3 +; STATIC-NEXT: .byte 3 + +; PIC: .ascii "zPLR" +; PIC: .byte 155 +; PIC-NEXT: .L +; PIC-NEXT: .long DW.ref.__gxx_personality_v0-.L +; PIC-NEXT: .byte 27 +; PIC-NEXT: .byte 27 + + +define void @bar() { +entry: + %call = invoke i32 @foo() + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret void + +lpad: + %exn = call i8* @llvm.eh.exception() nounwind + %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) nounwind + ret void +} + +declare i32 @foo() + +declare i8* @llvm.eh.exception() nounwind readonly + +declare i32 @__gxx_personality_v0(...) + +declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind