[DEBUGINFO] Add flag for DWARF2 or less to use sections as references.

Summary:
Some targets does not support labels inside debug sections, but support
references in form `section +|- offset`. Patch adds initial support
for this. Also, this patch disables emission of all additional debug
  sections that may have labels inside of it (like pub sections and
  string tables).

Reviewers: probinson, echristo

Subscribers: JDevlieghere, llvm-commits

Differential Revision: https://reviews.llvm.org/D43627

llvm-svn: 326328
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 7985908..a9aa00c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -123,6 +123,13 @@
                             clEnumVal(Disable, "Disabled")),
                  cl::init(Default));
 
+static cl::opt<DefaultOnOff> DwarfSectionsAsReferences(
+    "dwarf-sections-as-references", cl::Hidden,
+    cl::desc("Use sections+offset as references rather than labels."),
+    cl::values(clEnumVal(Default, "Default for platform"),
+               clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
+    cl::init(Default));
+
 enum LinkageNameOption {
   DefaultLinkageNames,
   AllLinkageNames,
@@ -310,6 +317,10 @@
   // Use dwarf 4 by default if nothing is requested.
   DwarfVersion = DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION;
 
+  // Use sections as references in DWARF v2.
+  UseSectionsAsReferences =
+      DwarfVersion == 2 && DwarfSectionsAsReferences == Enable;
+
   // Work around a GDB bug. GDB doesn't support the standard opcode;
   // SCE doesn't support GNU's; LLDB prefers the standard opcode, which
   // is defined as of DWARF 3.
@@ -737,7 +748,7 @@
     // ranges for all subprogram DIEs for mach-o.
     DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
     if (unsigned NumRanges = TheCU.getRanges().size()) {
-      if (NumRanges > 1)
+      if (NumRanges > 1 && !useSectionsAsReferences())
         // A DW_AT_low_pc attribute may also be specified in combination with
         // DW_AT_ranges to specify the default base address for use in
         // location lists (see Section 2.6.2) and range lists (see Section
@@ -1565,7 +1576,13 @@
   Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION);
 
   Asm->OutStreamer->AddComment("Offset of Compilation Unit Info");
-  Asm->emitDwarfSymbolReference(TheU->getLabelBegin());
+  if (useSectionsAsReferences()) {
+    Asm->EmitLabelPlusOffset(TheU->getSection()->getBeginSymbol(),
+                             TheU->getDebugSectionOffset(),
+                             Asm->MAI->getCodePointerSize());
+  } else {
+    Asm->emitDwarfSymbolReference(TheU->getLabelBegin());
+  }
 
   Asm->OutStreamer->AddComment("Compilation Unit Length");
   Asm->EmitInt32(TheU->getLength());
@@ -1864,7 +1881,13 @@
     Asm->OutStreamer->AddComment("DWARF Arange version number");
     Asm->EmitInt16(dwarf::DW_ARANGES_VERSION);
     Asm->OutStreamer->AddComment("Offset Into Debug Info Section");
-    Asm->emitDwarfSymbolReference(CU->getLabelBegin());
+    if (useSectionsAsReferences()) {
+      Asm->EmitLabelPlusOffset(CU->getSection()->getBeginSymbol(),
+                               CU->getDebugSectionOffset(),
+                               Asm->MAI->getCodePointerSize());
+    } else {
+      Asm->emitDwarfSymbolReference(CU->getLabelBegin());
+    }
     Asm->OutStreamer->AddComment("Address Size (in bytes)");
     Asm->EmitInt8(PtrSize);
     Asm->OutStreamer->AddComment("Segment Size (in bytes)");