From 02b8511364a61b559369d8dc36e82a486f42fec3 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Mon, 30 Oct 2006 22:32:30 +0000 Subject: [PATCH] Add debug support for X86/ELF targets (Linux). This allows llvm-gcc4 generated object modules to be debugged with gdb. Hopefully this helps pre-release debugging. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31299 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetAsmInfo.h | 7 +++++++ lib/CodeGen/DwarfWriter.cpp | 20 ++++++++++++-------- lib/Target/TargetAsmInfo.cpp | 1 + lib/Target/X86/X86ATTAsmPrinter.cpp | 6 +++--- lib/Target/X86/X86AsmPrinter.cpp | 8 +++++++- lib/Target/X86/X86AsmPrinter.h | 2 +- lib/Target/X86/X86ISelLowering.cpp | 2 +- lib/Target/X86/X86InstrInfo.td | 6 +++--- lib/Target/X86/X86TargetAsmInfo.cpp | 24 ++++++++++++++++++++++++ 9 files changed, 59 insertions(+), 17 deletions(-) diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index a1f4553e455..cf8f7a55be1 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -227,6 +227,10 @@ namespace llvm { /// bool HasDotFile; // Defaults to false. + /// RequiresFrameSection - true if the Dwarf2 output needs a frame section + /// + bool DwarfRequiresFrameSection; // Defaults to false. + /// DwarfAbbrevSection - Section directive for Dwarf abbrev. /// const char *DwarfAbbrevSection; // Defaults to ".debug_abbrev". @@ -417,6 +421,9 @@ namespace llvm { bool hasDotFile() const { return HasDotFile; } + bool getDwarfRequiresFrameSection() const { + return DwarfRequiresFrameSection; + } const char *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp index fbcf6413be1..40de586a3e5 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -1921,8 +1921,8 @@ CompileUnit *Dwarf::NewCompileUnit(CompileUnitDesc *UnitDesc, unsigned ID) { // Construct debug information entry. DIE *Die = new DIE(DW_TAG_compile_unit); - Die->AddDelta (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0), - DWLabel("section_line", 0)); + Die->AddDelta (DW_AT_stmt_list, DW_FORM_data4, DWLabel("section_line", 0), + DWLabel("section_line", 0)); // Die->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0)); // Die->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0)); Die->AddString(DW_AT_producer, DW_FORM_string, UnitDesc->getProducer()); @@ -2175,21 +2175,20 @@ void Dwarf::EmitInitial() { didInitial = true; // Dwarf sections base addresses. - Asm->SwitchToDataSection(TAI->getDwarfFrameSection(), 0); - EmitLabel("section_frame", 0); + if (TAI->getDwarfRequiresFrameSection()) { + Asm->SwitchToDataSection(TAI->getDwarfFrameSection(), 0); + EmitLabel("section_frame", 0); + } Asm->SwitchToDataSection(TAI->getDwarfInfoSection(), 0); EmitLabel("section_info", 0); - EmitLabel("info", 0); Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection(), 0); EmitLabel("section_abbrev", 0); - EmitLabel("abbrev", 0); Asm->SwitchToDataSection(TAI->getDwarfARangesSection(), 0); EmitLabel("section_aranges", 0); Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection(), 0); EmitLabel("section_macinfo", 0); Asm->SwitchToDataSection(TAI->getDwarfLineSection(), 0); EmitLabel("section_line", 0); - EmitLabel("line", 0); Asm->SwitchToDataSection(TAI->getDwarfLocSection(), 0); EmitLabel("section_loc", 0); Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection(), 0); @@ -2198,7 +2197,6 @@ void Dwarf::EmitInitial() { EmitLabel("section_str", 0); Asm->SwitchToDataSection(TAI->getDwarfRangesSection(), 0); EmitLabel("section_ranges", 0); - Asm->SwitchToTextSection(TAI->getTextSection(), 0); EmitLabel("text_begin", 0); Asm->SwitchToDataSection(TAI->getDataSection(), 0); @@ -2629,6 +2627,9 @@ void Dwarf::EmitDebugLines() const { /// EmitInitialDebugFrame - Emit common frame info into a debug frame section. /// void Dwarf::EmitInitialDebugFrame() { + if (TAI->getDwarfRequiresFrameSection()) + return; + int stackGrowth = Asm->TM.getFrameInfo()->getStackGrowthDirection() == TargetFrameInfo::StackGrowsUp ? @@ -2664,6 +2665,9 @@ void Dwarf::EmitInitialDebugFrame() { /// EmitFunctionDebugFrame - Emit per function frame info into a debug frame /// section. void Dwarf::EmitFunctionDebugFrame() { + if (TAI->getDwarfRequiresFrameSection()) + return; + // Start the dwarf frame section. Asm->SwitchToDataSection(TAI->getDwarfFrameSection(), 0); diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index b4014dd6b29..d68affd96b1 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -64,6 +64,7 @@ TargetAsmInfo::TargetAsmInfo() : HasLEB128(false), HasDotLoc(false), HasDotFile(false), + DwarfRequiresFrameSection(true), DwarfAbbrevSection(".debug_abbrev"), DwarfInfoSection(".debug_info"), DwarfLineSection(".debug_line"), diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index dc2ecca7cb4..42af5b69ac1 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -52,7 +52,7 @@ std::string X86ATTAsmPrinter::getSectionForFunction(const Function &F) const { /// method to print assembly for each instruction. /// bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - if (Subtarget->isTargetDarwin()) { + if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF()) { // Let PassManager know we need debug information and relay // the MachineDebugInfo address on to DwarfWriter. DW.SetDebugInfo(&getAnalysis()); @@ -111,7 +111,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { F->getLinkage() == Function::WeakLinkage)) O << "_llvm$workaround$fake$stub_" << CurrentFnName << ":\n"; - if (Subtarget->isTargetDarwin()) { + if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF()) { // Emit pre-function debug information. DW.BeginFunction(&MF); } @@ -141,7 +141,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { if (TAI->hasDotTypeDotSizeDirective()) O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; - if (Subtarget->isTargetDarwin()) { + if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF()) { // Emit post-function debug information. DW.EndFunction(); } diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 38dbe57aed0..60316517a82 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -114,6 +114,9 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) { if (!Subtarget->is64Bit()) X86PICStyle = PICStyle::Stub; + // Emit initial debug information. + DW.BeginModule(&M); + } else if (Subtarget->isTargetELF()) { // Emit initial debug information. DW.BeginModule(&M); } @@ -278,7 +281,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { O << "\t.long\t0\n"; } - // Emit initial debug information. + // Emit final debug information. DW.EndModule(); // Funny Darwin hack: This flag tells the linker that no global symbols @@ -287,6 +290,9 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { // linker can safely perform dead code stripping. Since LLVM never // generates code that does this, it is always safe to set. O << "\t.subsections_via_symbols\n"; + } else if (Subtarget->isTargetELF()) { + // Emit final debug information. + DW.EndModule(); } AsmPrinter::doFinalization(M); diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h index 1bbfa559e6e..b2fbe0529cb 100755 --- a/lib/Target/X86/X86AsmPrinter.h +++ b/lib/Target/X86/X86AsmPrinter.h @@ -67,7 +67,7 @@ struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter { void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - if (Subtarget->isTargetDarwin()) { + if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF()) { AU.addRequired(); } MachineFunctionPass::getAnalysisUsage(AU); diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 0b8550686c3..6de5032ff30 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -219,7 +219,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::LOCATION, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); // FIXME - use subtarget debug flags - if (!Subtarget->isTargetDarwin()) + if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetELF()) setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); // VASTART needs to be custom lowered to use the VarArgsFrameIndex diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 509fb053895..359513c9487 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -2451,9 +2451,9 @@ def DWARF_LOC : I<0, Pseudo, (ops i32imm:$line, i32imm:$col, i32imm:$file), [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>; -def DWARF_LABEL : I<0, Pseudo, (ops i32imm:$id), - "\nLdebug_loc${id:debug}:", - [(dwarf_label (i32 imm:$id))]>; +def DWARF_LABEL : I<0, Pseudo, (ops i32imm:$id), + "\n${:private}debug_loc${id:debug}:", + [(dwarf_label (i32 imm:$id))]>; //===----------------------------------------------------------------------===// // Non-Instruction Patterns diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index e67773711cb..93596c04b46 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -60,6 +60,30 @@ X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) { DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; break; + + case X86Subtarget::isELF: + // Set up DWARF directives + HasLEB128 = true; // Target asm supports leb128 directives (little-endian) + // bool HasLEB128; // Defaults to false. + // hasDotLoc - True if target asm supports .loc directives. + // bool HasDotLoc; // Defaults to false. + // HasDotFile - True if target asm supports .file directives. + // bool HasDotFile; // Defaults to false. + PrivateGlobalPrefix = "."; // Prefix for private global symbols + DwarfRequiresFrameSection = false; + DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits"; + DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits"; + DwarfLineSection = "\t.section\t.debug_line,\"\",@progbits"; + DwarfFrameSection = "\t.section\t.debug_frame,\"\",@progbits"; + DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits"; + DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits"; + DwarfStrSection = "\t.section\t.debug_str,\"\",@progbits"; + DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; + DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; + DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; + DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; + break; + case X86Subtarget::isCygwin: GlobalPrefix = "_"; COMMDirectiveTakesAlignment = false; -- 2.34.1