Fix .debug_range for linux. Patch by Krister Wombell.
authorDevang Patel <dpatel@apple.com>
Thu, 2 Sep 2010 16:43:44 +0000 (16:43 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 2 Sep 2010 16:43:44 +0000 (16:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112830 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
include/llvm/MC/MCAsmInfo.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/MC/MCAsmInfo.cpp
lib/MC/MCAsmInfoDarwin.cpp

index 62a18fe2511b4caf064becc793683d54b7e81da3..b018603b314ea2fd40b934d2e818b096c052e079 100644 (file)
@@ -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
     //===------------------------------------------------------------------===//
index 176221eccfce20f4057ea9446eafaf17a323770c..43952e0845da1cb7e8599d0b6ab531c5ebebf0fd 100644 (file)
@@ -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;
     }
index 257134192908fdb4aae63359451eff14d4f953cb..9078f282025f1bc85b688b83aef7e10402f78ad3 100644 (file)
@@ -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*/);
+  }
+}
     
 
 //===----------------------------------------------------------------------===//
index 6edce5a2cd94531c99aa8d5ad97e957e52625ec7..c886a5ecc6153e74504d40e311d6e18ac482a5f2 100644 (file)
@@ -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<DIEInteger>(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: {
index b859825d668753d54ec6c8c4420ba6be13e6b574..670b2e9b292a53e63ae11a816efcbf5353a8852c 100644 (file)
@@ -70,6 +70,7 @@ MCAsmInfo::MCAsmInfo() {
   DwarfUsesInlineInfoSection = false;
   DwarfUsesAbsoluteLabelForStmtList = true;
   DwarfSectionOffsetDirective = 0;
+  DwarfUsesLabelOffsetForRanges = true;
   HasMicrosoftFastStdCallMangling = false;
 
   AsmTransCBE = 0;
index 4856def2605d564bf5907e8a09babf154093f1a9..e0e261a63c707d87ed7a5aa8bf662daad69e00ce 100644 (file)
@@ -46,5 +46,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
   HasNoDeadStrip = true;
 
   DwarfUsesAbsoluteLabelForStmtList = false;
+  DwarfUsesLabelOffsetForRanges = false;
 }