[DWARF] - Introduce DWARFDebugPubTable class for dumping pub* sections.
authorGeorge Rimar <grimar@accesssoftek.com>
Sat, 17 Dec 2016 09:10:32 +0000 (09:10 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Sat, 17 Dec 2016 09:10:32 +0000 (09:10 +0000)
Patch implements parser of pubnames/pubtypes tables instead of static
function used before. It is now should be possible to reuse it
in LLD or other projects and clean up the duplication code.

Differential revision: https://reviews.llvm.org/D27851

llvm-svn: 290040

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h [new file with mode: 0644]
llvm/lib/DebugInfo/DWARF/CMakeLists.txt
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp [new file with mode: 0644]

diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
new file mode 100644 (file)
index 0000000..2b23837
--- /dev/null
@@ -0,0 +1,77 @@
+//===-- DWARFDebugPubTable.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Dwarf.h"
+#include <vector>
+
+namespace llvm {
+
+class raw_ostream;
+
+/// Represents structure for holding and parsing .debug_pub* tables.
+class DWARFDebugPubTable {
+public:
+  struct Entry {
+    /// Section offset from the beginning of the compilation unit.
+    uint32_t SecOffset;
+
+    /// An entry of the various gnu_pub* debug sections.
+    llvm::dwarf::PubIndexEntryDescriptor Descriptor;
+
+    /// The name of the object as given by the DW_AT_name attribute of the
+    /// referenced DIE.
+    const char *Name;
+  };
+
+  /// Each table consists of sets of variable length entries. Each set describes
+  /// the names of global objects and functions, or global types, respectively,
+  /// whose definitions are represented by debugging information entries owned
+  /// by a single compilation unit.
+  struct Set {
+    /// The total length of the entries for that set, not including the length
+    /// field itself.
+    uint32_t Length;
+
+    /// This number is specific to the name lookup table and is independent of
+    /// the DWARF version number.
+    uint16_t Version;
+
+    /// The offset from the beginning of the .debug_info section of the
+    /// compilation unit header referenced by the set.
+    uint32_t Offset;
+
+    /// The size in bytes of the contents of the .debug_info section generated
+    /// to represent that compilation unit.
+    uint32_t Size;
+
+    std::vector<Entry> Entries;
+  };
+
+private:
+  std::vector<Set> Sets;
+
+  /// gnu styled tables contains additional information.
+  /// This flag determines whether or not section we parse is debug_gnu* table.
+  bool GnuStyle;
+
+public:
+  DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle);
+  void dump(StringRef Name, raw_ostream &OS) const;
+
+  ArrayRef<Set> getData() { return Sets; }
+};
+}
+
+#endif
index 329ccfb..495edb7 100644 (file)
@@ -11,6 +11,7 @@ add_llvm_library(LLVMDebugInfoDWARF
   DWARFDebugLine.cpp
   DWARFDebugLoc.cpp
   DWARFDebugMacro.cpp
+  DWARFDebugPubTable.cpp
   DWARFDebugRangeList.cpp
   DWARFDie.cpp
   DWARFFormValue.cpp
index 0f2a48b..7df66c7 100644 (file)
@@ -12,6 +12,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Object/RelocVisitor.h"
@@ -32,39 +33,6 @@ typedef DWARFDebugLine::LineTable DWARFLineTable;
 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
 
-static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
-                           bool LittleEndian, bool GnuStyle) {
-  OS << "\n." << Name << " contents:\n";
-  DataExtractor pubNames(Data, LittleEndian, 0);
-  uint32_t offset = 0;
-  while (pubNames.isValidOffset(offset)) {
-    OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
-    OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
-    OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
-    OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
-    if (GnuStyle)
-      OS << "Offset     Linkage  Kind     Name\n";
-    else
-      OS << "Offset     Name\n";
-
-    while (offset < Data.size()) {
-      uint32_t dieRef = pubNames.getU32(&offset);
-      if (dieRef == 0)
-        break;
-      OS << format("0x%8.8x ", dieRef);
-      if (GnuStyle) {
-        PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
-        OS << format("%-8s",
-                     dwarf::GDBIndexEntryLinkageString(desc.Linkage).data())
-           << ' '
-           << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind).data())
-           << ' ';
-      }
-      OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
-    }
-  }
-}
-
 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
                              const DWARFSection& Section, StringRef StringSection,
                              bool LittleEndian) {
@@ -231,20 +199,22 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
   }
 
   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
-    dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
-                   isLittleEndian(), false);
+    DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
+        .dump("debug_pubnames", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
-    dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
-                   isLittleEndian(), false);
+    DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
+        .dump("debug_pubtypes", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
-    dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
-                   isLittleEndian(), true /* GnuStyle */);
+    DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
+                       true /* GnuStyle */)
+        .dump("debug_gnu_pubnames", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
-    dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
-                   isLittleEndian(), true /* GnuStyle */);
+    DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
+                       true /* GnuStyle */)
+        .dump("debug_gnu_pubtypes", OS);
 
   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
       !getStringOffsetDWOSection().empty()) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
new file mode 100644 (file)
index 0000000..3c1fe93
--- /dev/null
@@ -0,0 +1,65 @@
+//===-- DWARFDebugPubTable.cpp ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::dwarf;
+
+DWARFDebugPubTable::DWARFDebugPubTable(StringRef Data, bool LittleEndian,
+                                       bool GnuStyle)
+    : GnuStyle(GnuStyle) {
+  DataExtractor PubNames(Data, LittleEndian, 0);
+  uint32_t Offset = 0;
+  while (PubNames.isValidOffset(Offset)) {
+    Sets.push_back({});
+    Set &SetData = Sets.back();
+
+    SetData.Length = PubNames.getU32(&Offset);
+    SetData.Version = PubNames.getU16(&Offset);
+    SetData.Offset = PubNames.getU32(&Offset);
+    SetData.Size = PubNames.getU32(&Offset);
+
+    while (Offset < Data.size()) {
+      uint32_t DieRef = PubNames.getU32(&Offset);
+      if (DieRef == 0)
+        break;
+      uint8_t IndexEntryValue = GnuStyle ? PubNames.getU8(&Offset) : 0;
+      const char *Name = PubNames.getCStr(&Offset);
+      SetData.Entries.push_back(
+          {DieRef, PubIndexEntryDescriptor(IndexEntryValue), Name});
+    }
+  }
+}
+
+void DWARFDebugPubTable::dump(StringRef Name, raw_ostream &OS) const {
+  OS << "\n." << Name << " contents: a\n";
+  for (const Set &S : Sets) {
+    OS << "length = " << format("0x%08x", S.Length);
+    OS << " version = " << format("0x%04x", S.Version);
+    OS << " unit_offset = " << format("0x%08x", S.Offset);
+    OS << " unit_size = " << format("0x%08x", S.Size) << '\n';
+    OS << (GnuStyle ? "Offset     Linkage  Kind     Name\n"
+                    : "Offset     Name\n");
+
+    for (const Entry &E : S.Entries) {
+      OS << format("0x%8.8x ", E.SecOffset);
+      if (GnuStyle) {
+        StringRef EntryLinkage =
+            dwarf::GDBIndexEntryLinkageString(E.Descriptor.Linkage);
+        StringRef EntryKind = dwarf::GDBIndexEntryKindString(E.Descriptor.Kind);
+        OS << format("%-8s", EntryLinkage.data()) << ' '
+           << format("%-8s", EntryKind.data()) << ' ';
+      }
+      OS << '\"' << E.Name << "\"\n";
+    }
+  }
+}