From 374d7f2b160143e4fe413783d230b028127217c9 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 26 Sep 2008 00:28:12 +0000 Subject: [PATCH] If we have a function with an unreachable statement such that the ending debug information is in an unreachable block, then it's possible that the high/low pc values won't be set for the dwarf information. E.g., this function: void abort(void) __attribute__((__noreturn__)); void dead_beef(void) __attribute__ ((noreturn)); int *b; void dead_beef(void) { *b=0xdeadbeef; abort(); } has a call to "@llvm.dbg.region.end" only in the unreachable block: define void @dead_beef() noreturn nounwind { entry: call void @llvm.dbg.func.start(...) call void @llvm.dbg.stoppoint(...) ... call void @abort( ) noreturn nounwind unreachable return: ; No predecessors! call void @llvm.dbg.stoppoint(...) call void @llvm.dbg.region.end(...) ret void } The dwarf information emitted is something like: 0x00000084: TAG_subprogram [5] AT_name( "dead_beef" ) AT_external( 0x01 ) AT_prototyped( 0x01 ) AT_decl_file( 0x01 ) AT_decl_line( 0x08 ) Note that this is *not* the best fix for this problem, but a band-aid for an gaping wound. This code needs to be changed when we revamp our debugging information. llvm-svn: 56628 --- llvm/include/llvm/CodeGen/DwarfWriter.h | 2 +- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 56 +++++++++++++++++-- llvm/lib/Target/CellSPU/SPUAsmPrinter.cpp | 2 +- .../PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 4 +- .../X86/AsmPrinter/X86ATTAsmPrinter.cpp | 2 +- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DwarfWriter.h b/llvm/include/llvm/CodeGen/DwarfWriter.h index 981513baee03..f5f5cd30d350 100644 --- a/llvm/include/llvm/CodeGen/DwarfWriter.h +++ b/llvm/include/llvm/CodeGen/DwarfWriter.h @@ -74,7 +74,7 @@ public: /// EndFunction - Gather and emit post-function debug information. /// - void EndFunction(); + void EndFunction(MachineFunction *MF); }; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index d45ab13e8639..06282211d17c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -2031,6 +2031,39 @@ private: ConstructScope(RootScope, 0, 0, SPDie, Unit); } + /// ConstructDefaultScope - Construct a default scope for the subprogram. + /// + void ConstructDefaultScope(MachineFunction *MF) { + // Find the correct subprogram descriptor. + std::vector Subprograms; + MMI->getAnchoredDescriptors(*M, Subprograms); + + for (unsigned i = 0, N = Subprograms.size(); i < N; ++i) { + SubprogramDesc *SPD = Subprograms[i]; + + if (SPD->getName() == MF->getFunction()->getName()) { + // Get the compile unit context. + CompileUnit *Unit = GetBaseCompileUnit(); + + // Get the subprogram die. + DIE *SPDie = Unit->getDieMapSlotFor(SPD); + assert(SPDie && "Missing subprogram descriptor"); + + // Add the function bounds. + AddLabel(SPDie, DW_AT_low_pc, DW_FORM_addr, + DWLabel("func_begin", SubprogramCount)); + AddLabel(SPDie, DW_AT_high_pc, DW_FORM_addr, + DWLabel("func_end", SubprogramCount)); + + MachineLocation Location(RI->getFrameRegister(*MF)); + AddAddress(SPDie, DW_AT_frame_base, Location); + return; + } + } + + assert(0 && "Couldn't find DIE for machine function!"); + } + /// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc /// tools to recognize the object file contains Dwarf information. void EmitInitial() { @@ -2588,7 +2621,7 @@ private: Asm->SwitchToDataSection(TAI->getDwarfARangesSection()); // FIXME - Mock up - #if 0 +#if 0 CompileUnit *Unit = GetBaseCompileUnit(); // Don't include size of length @@ -2612,7 +2645,7 @@ private: Asm->EmitInt32(0); Asm->EOL("EOM (1)"); Asm->EmitInt32(0); Asm->EOL("EOM (2)"); - #endif +#endif Asm->EOL(); } @@ -2822,7 +2855,7 @@ public: /// EndFunction - Gather and emit post-function debug information. /// - void EndFunction() { + void EndFunction(MachineFunction *MF) { if (!ShouldEmitDwarf()) return; // Define end label for subprogram. @@ -2842,7 +2875,18 @@ public: } // Construct scopes for subprogram. - ConstructRootScope(MMI->getRootScope()); + if (MMI->getRootScope()) + ConstructRootScope(MMI->getRootScope()); + else + // FIXME: This is wrong. We are essentially getting past a problem with + // debug information not being able to handle unreachable blocks that have + // debug information in them. In particular, those unreachable blocks that + // have "region end" info in them. That situation results in the "root + // scope" not being created. If that's the case, then emit a "default" + // scope, i.e., one that encompasses the whole function. This isn't + // desirable. And a better way of handling this (and all of the debugging + // information) needs to be explored. + ConstructDefaultScope(MF); DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, MMI->getFrameMoves())); @@ -3922,8 +3966,8 @@ void DwarfWriter::BeginFunction(MachineFunction *MF) { /// EndFunction - Gather and emit post-function debug information. /// -void DwarfWriter::EndFunction() { - DD->EndFunction(); +void DwarfWriter::EndFunction(MachineFunction *MF) { + DD->EndFunction(MF); DE->EndFunction(); if (MachineModuleInfo *MMI = DD->getMMI() ? DD->getMMI() : DE->getMMI()) diff --git a/llvm/lib/Target/CellSPU/SPUAsmPrinter.cpp b/llvm/lib/Target/CellSPU/SPUAsmPrinter.cpp index 5b0bacfc89f4..8d9e89111628 100644 --- a/llvm/lib/Target/CellSPU/SPUAsmPrinter.cpp +++ b/llvm/lib/Target/CellSPU/SPUAsmPrinter.cpp @@ -461,7 +461,7 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) EmitJumpTableInfo(MF.getJumpTableInfo(), MF); // Emit post-function debug information. - DW.EndFunction(); + DW.EndFunction(&MF); // We didn't modify anything. return false; diff --git a/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index f21cb4e710fa..557c3af86f05 100644 --- a/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -617,7 +617,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { EmitJumpTableInfo(MF.getJumpTableInfo(), MF); // Emit post-function debug information. - DW.EndFunction(); + DW.EndFunction(&MF); // We didn't modify anything. return false; @@ -809,7 +809,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { EmitJumpTableInfo(MF.getJumpTableInfo(), MF); // Emit post-function debug information. - DW.EndFunction(); + DW.EndFunction(&MF); // We didn't modify anything. return false; diff --git a/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index 57db93387f0e..eb66a4fc611d 100644 --- a/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -260,7 +260,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Emit post-function debug information. if (TAI->doesSupportDebugInformation()) - DW.EndFunction(); + DW.EndFunction(&MF); // Print out jump tables referenced by the function. EmitJumpTableInfo(MF.getJumpTableInfo(), MF);