From f2548caaa8b290aa598bf49c27dff72f7751ba5c Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 16 Apr 2010 23:33:45 +0000 Subject: [PATCH] Add support to emit dwarf ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101575 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 6 ++++++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 30 +++++++++++++++++++++++++++ lib/CodeGen/AsmPrinter/DIE.h | 3 ++- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 26 ++++++++++++++++++++--- lib/CodeGen/AsmPrinter/DwarfDebug.h | 5 ++++- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 2eff50123a2..85c267eea91 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -333,6 +333,12 @@ namespace llvm { void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const; + /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" + /// where the size in bytes of the directive is specified by Size and Hi/Lo + /// specify the labels. This implicitly uses .set if it is available. + void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, + const MCSymbol *Lo, unsigned Size) const; + //===------------------------------------------------------------------===// // Dwarf Emission Helper Routines //===------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 63f865d40d3..cb2187d530b 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1094,6 +1094,36 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); } +/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" +/// where the size in bytes of the directive is specified by Size and Hi/Lo +/// specify the labels. This implicitly uses .set if it is available. +void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, + const MCSymbol *Lo, unsigned Size) + const { + + // Emit Hi+Offset - Lo + // Get the Hi+Offset expression. + const MCExpr *Plus = + MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), + MCConstantExpr::Create(Offset, OutContext), + OutContext); + + // Get the Hi+Offset-Lo expression. + const MCExpr *Diff = + MCBinaryExpr::CreateSub(Plus, + MCSymbolRefExpr::Create(Lo, OutContext), + OutContext); + + if (!MAI->hasSetDirective()) + OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/); + else { + // Otherwise, emit with .set (aka assignment). + MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); + OutStreamer.EmitAssignment(SetLabel, Diff); + OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/); + } +} + //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h index 454326db0ea..9cb8314bd95 100644 --- a/lib/CodeGen/AsmPrinter/DIE.h +++ b/lib/CodeGen/AsmPrinter/DIE.h @@ -261,11 +261,12 @@ namespace llvm { /// virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; + uint64_t getValue() const { return Integer; } + /// SizeOf - Determine size of integer value in bytes. /// virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; - // Implement isa/cast/dyncast. static bool classof(const DIEInteger *) { return true; } static bool classof(const DIEValue *I) { return I->getType() == isInteger; } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index ff69f549425..07d60732d9e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -302,7 +302,7 @@ DbgScope::~DbgScope() { DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), ModuleCU(0), AbbreviationsSet(InitAbbreviationsSetSize), - CurrentFnDbgScope(0) { + CurrentFnDbgScope(0), PrevLabel(NULL) { NextStringPoolNumber = 0; DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; @@ -2354,6 +2354,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { InsnBeforeLabelMap.clear(); InsnAfterLabelMap.clear(); Lines.clear(); + PrevLabel = NULL; } /// recordSourceLine - Register a source line with debug info. Returns the @@ -2490,7 +2491,8 @@ void DwarfDebug::EmitSectionLabels() { EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection()); DwarfStrSectionSym = EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str"); - EmitSectionSym(Asm, TLOF.getDwarfRangesSection()); + DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(), + "debug_range"); TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin"); EmitSectionSym(Asm, TLOF.getDataSection()); @@ -2534,6 +2536,15 @@ void DwarfDebug::emitDIE(DIE *Die) { Asm->EmitInt32(Addr); break; } + case dwarf::DW_AT_ranges: { + // DW_AT_range Value encodes offset in debug_range section. + DIEInteger *V = cast(Values[i]); + Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym, + V->getValue(), + DwarfDebugRangeSectionSym, + 4); + break; + } default: // Emit an attribute using the defined form. Values[i]->EmitValue(Asm, Form); @@ -3055,7 +3066,16 @@ void DwarfDebug::EmitDebugARanges() { void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfRangesSection()); + Asm->getObjFileLowering().getDwarfRangesSection()); + for (SmallVector::const_iterator I = DebugRangeSymbols.begin(), + E = DebugRangeSymbols.end(); I != E; ++I) { + if (*I) + Asm->EmitLabelDifference(*I, TextSectionSym, + Asm->getTargetData().getPointerSize()); + else + Asm->OutStreamer.EmitIntValue(0, Asm->getTargetData().getPointerSize(), + /*addrspace*/0); + } } /// emitDebugMacInfo - Emit visible names into a debug macinfo section. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index b42232b5d13..bfd6f48d2e3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -196,9 +196,12 @@ class DwarfDebug { /// instruction. DenseMap InsnAfterLabelMap; + SmallVector DebugRangeSymbols; + /// Previous instruction's location information. This is used to determine /// label location to indicate scope boundries in dwarf debug info. DebugLoc PrevInstLoc; + MCSymbol *PrevLabel; struct FunctionDebugFrameInfo { unsigned Number; @@ -214,7 +217,7 @@ class DwarfDebug { // the beginning of each supported dwarf section. These are used to form // section offsets and are created by EmitSectionLabels. MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym; - MCSymbol *DwarfStrSectionSym, *TextSectionSym; + MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym; private: -- 2.34.1