1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

Add support to emit dwarf ranges.

llvm-svn: 101575
This commit is contained in:
Devang Patel 2010-04-16 23:33:45 +00:00
parent 51248b6cb4
commit 1929d78e71
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,
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
//===------------------------------------------------------------------===//

View File

@ -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*/);
}
}
//===----------------------------------------------------------------------===//

View File

@ -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; }

View File

@ -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<DIEInteger>(Values[i]);
Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym,
V->getValue(),
DwarfDebugRangeSectionSym,
4);
break;
}
default:
// Emit an attribute using the defined form.
Values[i]->EmitValue(Asm, Form);
@ -3056,6 +3067,15 @@ void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section.
Asm->OutStreamer.SwitchSection(
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.

View File

@ -196,9 +196,12 @@ class DwarfDebug {
/// instruction.
DenseMap<const MachineInstr *, MCSymbol *> InsnAfterLabelMap;
SmallVector<const MCSymbol *, 8> 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: