[llvm] r318839 - [DWARFv5] Support DW_FORM_strp in the .debug_line.dwo header.

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 22 07:33:17 PST 2017


Author: probinson
Date: Wed Nov 22 07:33:17 2017
New Revision: 318839

URL: http://llvm.org/viewvc/llvm-project?rev=318839&view=rev
Log:
[DWARFv5] Support DW_FORM_strp in the .debug_line.dwo header.

As a side effect, the .debug_line section will be dumped in physical
order, rather than in the order that compile units refer to their
associated portions of the .debug_line section.  These are probably
always the same order anyway, and no tests noticed the difference.

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

Modified:
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
    llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=318839&r1=318838&r2=318839&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Wed Nov 22 07:33:17 2017
@@ -204,6 +204,28 @@ static void dumpStringOffsetsSection(raw
   }
 }
 
+// We want to supply the Unit associated with a .debug_line[.dwo] table when
+// we dump it, if possible, but still dump the table even if there isn't a Unit.
+// Therefore, collect up handles on all the Units that point into the
+// line-table section.
+typedef std::map<uint64_t, DWARFUnit *> LineToUnitMap;
+
+static LineToUnitMap
+buildLineToUnitMap(DWARFContext::cu_iterator_range CUs,
+                   DWARFContext::tu_section_iterator_range TUSections) {
+  LineToUnitMap LineToUnit;
+  for (const auto &CU : CUs)
+    if (auto CUDIE = CU->getUnitDIE())
+      if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
+        LineToUnit.insert(std::make_pair(*StmtOffset, &*CU));
+  for (const auto &TUS : TUSections)
+    for (const auto &TU : TUS)
+      if (auto TUDIE = TU->getUnitDIE())
+        if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
+          LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
+  return LineToUnit;
+}
+
 void DWARFContext::dump(
     raw_ostream &OS, DIDumpOptions DumpOpts,
     std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
@@ -310,48 +332,57 @@ void DWARFContext::dump(
       set.dump(OS);
   }
 
-  uint8_t savedAddressByteSize = 0;
   if (shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
                  DObj->getLineSection().Data)) {
-    for (const auto &CU : compile_units()) {
-      savedAddressByteSize = CU->getAddressByteSize();
-      auto CUDIE = CU->getUnitDIE();
-      if (!CUDIE)
+    LineToUnitMap LineToUnit =
+        buildLineToUnitMap(compile_units(), type_unit_sections());
+    unsigned Offset = 0;
+    DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
+                                0);
+    while (Offset < LineData.getData().size()) {
+      DWARFUnit *U = nullptr;
+      auto It = LineToUnit.find(Offset);
+      if (It != LineToUnit.end()) {
+        U = It->second;
+        LineData.setAddressSize(U->getAddressByteSize());
+      }
+      DWARFDebugLine::LineTable LineTable;
+      if (DumpOffset && Offset != *DumpOffset) {
+        // Find the size of this part of the line table section and skip it.
+        unsigned OldOffset = Offset;
+        LineTable.Prologue.parse(LineData, &Offset, U);
+        Offset = OldOffset + LineTable.Prologue.TotalLength +
+                 LineTable.Prologue.sizeofTotalLength();
         continue;
-      if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
-        if (DumpOffset && *StmtOffset != *DumpOffset)
-          continue;
-        DWARFDataExtractor lineData(*DObj, DObj->getLineSection(),
-                                    isLittleEndian(), savedAddressByteSize);
-        DWARFDebugLine::LineTable LineTable;
-        uint32_t Offset = *StmtOffset;
-        // Verbose dumping is done during parsing and not on the intermediate
-        // representation.
-        OS << "debug_line[" << format("0x%8.8x", Offset) << "]\n";
-        if (DumpOpts.Verbose) {
-          LineTable.parse(lineData, &Offset, &*CU, &OS);
-        } else {
-          LineTable.parse(lineData, &Offset, &*CU);
-          LineTable.dump(OS);
-        }
+      }
+      // Verbose dumping is done during parsing and not on the intermediate
+      // representation.
+      OS << "debug_line[" << format("0x%8.8x", Offset) << "]\n";
+      if (DumpOpts.Verbose) {
+        LineTable.parse(LineData, &Offset, U, &OS);
+      } else {
+        LineTable.parse(LineData, &Offset, U);
+        LineTable.dump(OS);
       }
     }
   }
 
-  // FIXME: This seems sketchy.
-  for (const auto &CU : compile_units()) {
-    savedAddressByteSize = CU->getAddressByteSize();
-    break;
-  }
   if (shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
                  DObj->getLineDWOSection().Data)) {
-    unsigned stmtOffset = 0;
-    DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
-                                isLittleEndian(), savedAddressByteSize);
-    DWARFDebugLine::LineTable LineTable;
-    while (LineTable.Prologue.parse(lineData, &stmtOffset, nullptr)) {
+    LineToUnitMap LineToUnit =
+        buildLineToUnitMap(dwo_compile_units(), dwo_type_unit_sections());
+    unsigned Offset = 0;
+    DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
+                                isLittleEndian(), 0);
+    while (Offset < LineData.getData().size()) {
+      DWARFUnit *U = nullptr;
+      auto It = LineToUnit.find(Offset);
+      if (It != LineToUnit.end())
+        U = It->second;
+      DWARFDebugLine::LineTable LineTable;
+      if (!LineTable.Prologue.parse(LineData, &Offset, U))
+        break;
       LineTable.dump(OS);
-      LineTable.clear();
     }
   }
 
@@ -393,6 +424,11 @@ void DWARFContext::dump(
     // last compile unit (there is no easy and fast way to associate address
     // range list and the compile unit it describes).
     // FIXME: savedAddressByteSize seems sketchy.
+    uint8_t savedAddressByteSize = 0;
+    for (const auto &CU : compile_units()) {
+      savedAddressByteSize = CU->getAddressByteSize();
+      break;
+    }
     DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
                                   isLittleEndian(), savedAddressByteSize);
     uint32_t offset = 0;

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp?rev=318839&r1=318838&r2=318839&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp Wed Nov 22 07:33:17 2017
@@ -230,7 +230,8 @@ bool DWARFDebugLine::Prologue::parse(con
 
   if (getVersion() >= 5) {
     FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
-    assert(getAddressSize() == DebugLineData.getAddressSize() &&
+    assert((DebugLineData.getAddressSize() == 0 ||
+            DebugLineData.getAddressSize() == getAddressSize()) &&
            "Line table header and data extractor disagree");
     SegSelectorSize = DebugLineData.getU8(OffsetPtr);
   }

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s?rev=318839&r1=318838&r2=318839&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s Wed Nov 22 07:33:17 2017
@@ -22,6 +22,14 @@ str_LT_5b:
         .section .debug_str.dwo,"MS", at progbits,1
 dwo_TU_5:
         .asciz "V5_split_type_unit"
+dwo_producer:
+        .asciz "Handmade DWO producer"
+dwo_CU_5:
+        .asciz "V5_dwo_compile_unit"
+dwo_LT_5a:
+        .asciz "DWODirectory5a"
+dwo_LT_5b:
+        .asciz "DWODirectory5b"
 
 # All CUs/TUs use the same abbrev section for simplicity.
         .section .debug_abbrev,"", at progbits
@@ -61,6 +69,8 @@ dwo_TU_5:
         .byte 0x0e  # DW_FORM_strp
         .byte 0x03  # DW_AT_name
         .byte 0x0e  # DW_FORM_strp
+        .byte 0x10  # DW_AT_stmt_list
+        .byte 0x17  # DW_FORM_sec_offset
         .byte 0x00  # EOM(1)
         .byte 0x00  # EOM(2)
         .byte 0x02  # Abbrev code
@@ -117,6 +127,29 @@ CU_5_end:
 # CHECK: 0x00000019: Compile Unit: length = 0x00000016 version = 0x0005 unit_type = DW_UT_compile abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000033)
 # CHECK: 0x00000025: DW_TAG_compile_unit
 
+        .section .debug_info.dwo,"", at progbits
+# CHECK-LABEL: .debug_info.dwo
+
+# DWARF v5 split CU header.
+        .long  CU_split_5_end-CU_split_5_version # Length of Unit
+CU_split_5_version:
+        .short 5                # DWARF version number
+        .byte 5                 # DWARF Unit Type
+        .byte 8                 # Address Size (in bytes)
+        .long .debug_abbrev.dwo # Offset Into Abbrev. Section
+# The split compile-unit DIE, with DW_AT_producer, DW_AT_name, DW_AT_stmt_list.
+        .byte 1
+        .long dwo_producer
+        .long dwo_CU_5
+        .long dwo_LH_5_start
+        .byte 0 # NULL
+CU_split_5_end:
+
+# CHECK: 0x00000000: Compile Unit: length = 0x00000016 version = 0x0005 unit_type = DW_UT_split_compile abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000001a)
+# CHECK: 0x0000000c: DW_TAG_compile_unit
+# CHECK-NEXT: DW_AT_producer {{.*}} "Handmade DWO producer"
+# CHECK-NEXT: DW_AT_name {{.*}} "V5_dwo_compile_unit"
+
         .section .debug_types,"", at progbits
 # CHECK-LABEL: .debug_types contents:
 
@@ -299,3 +332,77 @@ LH_5_end:
 # CHECK: file_names[  1]    1 0x00000051 0x00000052 File5a{{$}}
 # CHECK: file_names[  2]    2 0x00000053 0x00000054 File5b{{$}}
 # CHECK-NOT: file_names
+
+	.section .debug_line.dwo,"", at progbits
+# CHECK-LABEL: .debug_line.dwo
+
+# DWARF v5 DWO line-table header.
+dwo_LH_5_start:
+        .long   dwo_LH_5_end-dwo_LH_5_version   # Length of Unit
+dwo_LH_5_version:
+        .short  5               # DWARF version number
+        .byte   8               # Address Size
+        .byte   0               # Segment Selector Size
+        .long   dwo_LH_5_header_end-dwo_LH_5_params # Length of Prologue
+dwo_LH_5_params:
+        .byte   1               # Minimum Instruction Length
+        .byte   1               # Maximum Operations per Instruction
+        .byte   1               # Default is_stmt
+        .byte   -5              # Line Base
+        .byte   14              # Line Range
+        .byte   13              # Opcode Base
+        .byte   0               # Standard Opcode Lengths
+        .byte   1
+        .byte   1
+        .byte   1
+        .byte   1
+        .byte   0
+        .byte   0
+        .byte   0
+        .byte   1
+        .byte   0
+        .byte   0
+        .byte   1
+        # Directory table format
+        .byte   1               # One element per directory entry
+        .byte   1               # DW_LNCT_path
+        .byte   0x0e            # DW_FORM_strp (-> .debug_str.dwo)
+        # Directory table entries
+        .byte   2               # Two directories
+        .long   dwo_LT_5a
+        .long   dwo_LT_5b
+        # File table format
+        .byte   4               # Four elements per file entry
+        .byte   1               # DW_LNCT_path
+        .byte   0x08            # DW_FORM_string
+        .byte   2               # DW_LNCT_directory_index
+        .byte   0x0b            # DW_FORM_data1
+        .byte   3               # DW_LNCT_timestamp
+        .byte   0x0f            # DW_FORM_udata
+        .byte   4               # DW_LNCT_size
+        .byte   0x0f            # DW_FORM_udata
+        # File table entries
+        .byte   2               # Two files
+        .asciz "DWOFile5a"
+        .byte   1
+        .byte   0x15
+        .byte   0x25
+        .asciz "DWOFile5b"
+        .byte   2
+        .byte   0x35
+        .byte   0x45
+dwo_LH_5_header_end:
+        # Line number program, which is empty.
+dwo_LH_5_end:
+
+# CHECK: Line table prologue:
+# CHECK: version: 5
+# CHECK: address_size: 8
+# CHECK: seg_select_size: 0
+# CHECK: max_ops_per_inst: 1
+# CHECK: include_directories[  1] = 'DWODirectory5a'
+# CHECK: include_directories[  2] = 'DWODirectory5b'
+# CHECK-NOT: include_directories
+# CHECK: file_names[  1]    1 0x00000015 0x00000025 DWOFile5a{{$}}
+# CHECK: file_names[  2]    2 0x00000035 0x00000045 DWOFile5b{{$}}
+# CHECK-NOT: file_names




More information about the llvm-commits mailing list