Add support to emit dwarf ranges.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101575 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel
2010-04-16 23:33:45 +00:00
parent cf7fbd41be
commit f2548caaa8
5 changed files with 65 additions and 5 deletions

View File

@ -333,6 +333,12 @@ namespace llvm {
void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const; 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 // Dwarf Emission Helper Routines
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//

View File

@ -1094,6 +1094,36 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); 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*/);
}
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -261,11 +261,12 @@ namespace llvm {
/// ///
virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
uint64_t getValue() const { return Integer; }
/// SizeOf - Determine size of integer value in bytes. /// SizeOf - Determine size of integer value in bytes.
/// ///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast. // Implement isa/cast/dyncast.
static bool classof(const DIEInteger *) { return true; } static bool classof(const DIEInteger *) { return true; }
static bool classof(const DIEValue *I) { return I->getType() == isInteger; } static bool classof(const DIEValue *I) { return I->getType() == isInteger; }

View File

@ -302,7 +302,7 @@ DbgScope::~DbgScope() {
DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
: Asm(A), MMI(Asm->MMI), ModuleCU(0), : Asm(A), MMI(Asm->MMI), ModuleCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), AbbreviationsSet(InitAbbreviationsSetSize),
CurrentFnDbgScope(0) { CurrentFnDbgScope(0), PrevLabel(NULL) {
NextStringPoolNumber = 0; NextStringPoolNumber = 0;
DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
@ -2354,6 +2354,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
InsnBeforeLabelMap.clear(); InsnBeforeLabelMap.clear();
InsnAfterLabelMap.clear(); InsnAfterLabelMap.clear();
Lines.clear(); Lines.clear();
PrevLabel = NULL;
} }
/// recordSourceLine - Register a source line with debug info. Returns the /// recordSourceLine - Register a source line with debug info. Returns the
@ -2490,7 +2491,8 @@ void DwarfDebug::EmitSectionLabels() {
EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection()); EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
DwarfStrSectionSym = DwarfStrSectionSym =
EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str"); EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
EmitSectionSym(Asm, TLOF.getDwarfRangesSection()); DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(),
"debug_range");
TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin"); TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
EmitSectionSym(Asm, TLOF.getDataSection()); EmitSectionSym(Asm, TLOF.getDataSection());
@ -2534,6 +2536,15 @@ void DwarfDebug::emitDIE(DIE *Die) {
Asm->EmitInt32(Addr); Asm->EmitInt32(Addr);
break; break;
} }
case dwarf::DW_AT_ranges: {
// DW_AT_range Value encodes offset in debug_range section.
DIEInteger *V = cast<DIEInteger>(Values[i]);
Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym,
V->getValue(),
DwarfDebugRangeSectionSym,
4);
break;
}
default: default:
// Emit an attribute using the defined form. // Emit an attribute using the defined form.
Values[i]->EmitValue(Asm, Form); Values[i]->EmitValue(Asm, Form);
@ -3055,7 +3066,16 @@ void DwarfDebug::EmitDebugARanges() {
void DwarfDebug::emitDebugRanges() { void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section. // Start the dwarf ranges section.
Asm->OutStreamer.SwitchSection( Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfRangesSection()); Asm->getObjFileLowering().getDwarfRangesSection());
for (SmallVector<const MCSymbol *, 8>::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. /// emitDebugMacInfo - Emit visible names into a debug macinfo section.

View File

@ -196,9 +196,12 @@ class DwarfDebug {
/// instruction. /// instruction.
DenseMap<const MachineInstr *, MCSymbol *> InsnAfterLabelMap; DenseMap<const MachineInstr *, MCSymbol *> InsnAfterLabelMap;
SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
/// Previous instruction's location information. This is used to determine /// Previous instruction's location information. This is used to determine
/// label location to indicate scope boundries in dwarf debug info. /// label location to indicate scope boundries in dwarf debug info.
DebugLoc PrevInstLoc; DebugLoc PrevInstLoc;
MCSymbol *PrevLabel;
struct FunctionDebugFrameInfo { struct FunctionDebugFrameInfo {
unsigned Number; unsigned Number;
@ -214,7 +217,7 @@ class DwarfDebug {
// the beginning of each supported dwarf section. These are used to form // the beginning of each supported dwarf section. These are used to form
// section offsets and are created by EmitSectionLabels. // section offsets and are created by EmitSectionLabels.
MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym; MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym;
MCSymbol *DwarfStrSectionSym, *TextSectionSym; MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym;
private: private: