[PATCH] D143513: [DebugInfo] Allow parsing line tables aligned to 4 or 8-byte boundaries

Benjamin Maxwell via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 7 09:24:30 PST 2023


benmxwl-arm created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
benmxwl-arm requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This allows the DWARFDebugLine::SectionParser to try parsing line tables
at 4 or 8-byte boundaries if the unaligned offset appears invalid. If
aligning the offset does not reduce errors the offset is used unchanged.

This is needed for llvm-dwarfdump to be able to extract the line tables
(with --debug-lines) from binaries produced by certain compilers that
like to align each line table in the .debug_line section. Note that this
alignment does not seem to be invalid since the units do point to the
correct line table offsets via the DW_AT_stmt_list attribute.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143513

Files:
  llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
  llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp


Index: llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1505,6 +1505,15 @@
   return U;
 }
 
+bool DWARFDebugLine::SectionParser::lineTableHeaderHasValidVersion(
+    uint64_t Offset) {
+  DataExtractor::Cursor Cursor(Offset);
+  auto [TotalLength, _] = DebugLineData.getInitialLength(Cursor);
+  DWARFDataExtractor HeaderData(DebugLineData, Cursor.tell() + TotalLength);
+  uint16_t Version = DebugLineData.getU16(Cursor);
+  return versionIsSupported(Version);
+}
+
 void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
                                                     const Prologue &P) {
   // If the length field is not valid, we don't know where the next table is, so
@@ -1518,5 +1527,30 @@
   Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
   if (!DebugLineData.isValidOffset(Offset)) {
     Done = true;
+    return;
+  }
+
+  // Heuristic: If the version is valid, then this is probably a line table,
+  // otherwise the offset might need alignment.
+  if (lineTableHeaderHasValidVersion(Offset))
+    return;
+
+  // Certain compilers align each line table to word boundaries and pad out the
+  // .debug_line section to a word multiple. Note that in the specification this
+  // does not seem forbidden since each unit as a DW_AT_stmt_list.
+  std::array PossibleAlignments{4, 8};
+  for (unsigned Align : PossibleAlignments) {
+    uint64_t AlignedOffset =
+        (Offset + (Align - 1)) & ~static_cast<uint64_t>(Align - 1);
+    if (!DebugLineData.isValidOffset(AlignedOffset)) {
+      // This is almost certainly not another line table but some alignment
+      // padding.
+      Done = true;
+      return;
+    }
+    if (lineTableHeaderHasValidVersion(AlignedOffset)) {
+      Offset = AlignedOffset;
+      break;
+    }
   }
 }
Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
===================================================================
--- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -355,6 +355,7 @@
   private:
     DWARFUnit *prepareToParse(uint64_t Offset);
     void moveToNextTable(uint64_t OldOffset, const Prologue &P);
+    bool lineTableHeaderHasValidVersion(uint64_t Offset);
 
     LineToUnitMap LineToUnit;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143513.495575.patch
Type: text/x-patch
Size: 2426 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230207/b19969a5/attachment.bin>


More information about the llvm-commits mailing list