summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2010-04-16 23:33:45 +0000
committerDevang Patel <dpatel@apple.com>2010-04-16 23:33:45 +0000
commitf2548caaa8b290aa598bf49c27dff72f7751ba5c (patch)
tree7c78f9dc2f734a62f7264ce6b77901ad09742630
parentcf7fbd41be73c2738ee07fded656d23f798976df (diff)
downloadllvm-f2548caaa8b290aa598bf49c27dff72f7751ba5c.tar.gz
llvm-f2548caaa8b290aa598bf49c27dff72f7751ba5c.tar.bz2
llvm-f2548caaa8b290aa598bf49c27dff72f7751ba5c.tar.xz
Add support to emit dwarf ranges.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101575 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h6
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp30
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h3
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp26
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h5
5 files changed, 65 insertions, 5 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 2eff50123a..85c267eea9 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 63f865d40d..cb2187d530 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 454326db0e..9cb8314bd9 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 ff69f54942..07d60732d9 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<DIEInteger>(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 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.
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index b42232b5d1..bfd6f48d2e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -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: