From b1fcfbe89bd155fb88485b2a3a995adba3994003 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Thu, 2 Sep 2010 16:43:44 +0000 Subject: [PATCH] Fix .debug_range for linux. Patch by Krister Wombell. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112830 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 6 ++++++ include/llvm/MC/MCAsmInfo.h | 7 +++++++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 23 +++++++++++++++++++++++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 15 +++++++++++---- lib/MC/MCAsmInfo.cpp | 1 + lib/MC/MCAsmInfoDarwin.cpp | 1 + 6 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 62a18fe2511..b018603b314 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -328,6 +328,12 @@ namespace llvm { void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, const MCSymbol *Lo, unsigned Size) const; + /// EmitLabelPlusOffset - Emit something like ".long Label+Offset" + /// where the size in bytes of the directive is specified by Size and Label + /// specifies the label. This implicitly uses .set if it is available. + void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, + unsigned Size) const; + //===------------------------------------------------------------------===// // Dwarf Emission Helper Routines //===------------------------------------------------------------------===// diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 176221eccfc..43952e0845d 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -259,6 +259,10 @@ namespace llvm { /// absolute label instead of offset. bool DwarfUsesAbsoluteLabelForStmtList; // Defaults to true; + // DwarfUsesLabelOffsetDifference - True if Dwarf2 output can + // use EmitLabelOffsetDifference. + bool DwarfUsesLabelOffsetForRanges; + //===--- CBE Asm Translation Table -----------------------------------===// const char *const *AsmTransCBE; // Defaults to empty @@ -424,6 +428,9 @@ namespace llvm { bool doesDwarfUsesAbsoluteLabelForStmtList() const { return DwarfUsesAbsoluteLabelForStmtList; } + bool doesDwarfUsesLabelOffsetForRanges() const { + return DwarfUsesLabelOffsetForRanges; + } const char *const *getAsmCBE() const { return AsmTransCBE; } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 25713419290..9078f282025 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1218,6 +1218,29 @@ void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/); } } + +/// EmitLabelPlusOffset - Emit something like ".long Label+Offset" +/// where the size in bytes of the directive is specified by Size and Label +/// specifies the label. This implicitly uses .set if it is available. +void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, + unsigned Size) + const { + + // Emit Label+Offset + const MCExpr *Plus = + MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext), + MCConstantExpr::Create(Offset, OutContext), + OutContext); + + if (!MAI->hasSetDirective()) + OutStreamer.EmitValue(Plus, 4, 0/*AddrSpace*/); + else { + // Otherwise, emit with .set (aka assignment). + MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); + OutStreamer.EmitAssignment(SetLabel, Plus); + OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/); + } +} //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6edce5a2cd9..c886a5ecc61 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3130,10 +3130,17 @@ void DwarfDebug::emitDIE(DIE *Die) { 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); + + if (Asm->MAI->doesDwarfUsesLabelOffsetForRanges()) { + Asm->EmitLabelPlusOffset(DwarfDebugRangeSectionSym, + V->getValue(), + 4); + } else { + Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym, + V->getValue(), + DwarfDebugRangeSectionSym, + 4); + } break; } case dwarf::DW_AT_location: { diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index b859825d668..670b2e9b292 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -70,6 +70,7 @@ MCAsmInfo::MCAsmInfo() { DwarfUsesInlineInfoSection = false; DwarfUsesAbsoluteLabelForStmtList = true; DwarfSectionOffsetDirective = 0; + DwarfUsesLabelOffsetForRanges = true; HasMicrosoftFastStdCallMangling = false; AsmTransCBE = 0; diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index 4856def2605..e0e261a63c7 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -46,5 +46,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { HasNoDeadStrip = true; DwarfUsesAbsoluteLabelForStmtList = false; + DwarfUsesLabelOffsetForRanges = false; } -- 2.34.1