[dwarfdump] Add support for dumping accelerator tables.
authorFrederic Riss <friss@apple.com>
Wed, 12 Nov 2014 23:48:10 +0000 (23:48 +0000)
committerFrederic Riss <friss@apple.com>
Wed, 12 Nov 2014 23:48:10 +0000 (23:48 +0000)
The class used for the dump only allows to dump for the moment, but
it can (and will) be easily extended to support search also.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221836 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DIContext.h
lib/DebugInfo/CMakeLists.txt
lib/DebugInfo/DWARFAcceleratorTable.cpp [new file with mode: 0644]
lib/DebugInfo/DWARFAcceleratorTable.h [new file with mode: 0644]
lib/DebugInfo/DWARFContext.cpp
lib/DebugInfo/DWARFContext.h
test/DebugInfo/Inputs/gmlt.ll
test/DebugInfo/dwarfdump-accel.test [new file with mode: 0644]
tools/llvm-dwarfdump/llvm-dwarfdump.cpp

index 3ef541aa3035a2f2e8fe0b9e72034f2e80e4eb94..3aa098d7c30b2c895c1c67eb17a0ca525c1f31ba 100644 (file)
@@ -107,7 +107,11 @@ enum DIDumpType {
   DIDT_GnuPubtypes,
   DIDT_Str,
   DIDT_StrDwo,
-  DIDT_StrOffsetsDwo
+  DIDT_StrOffsetsDwo,
+  DIDT_AppleNames,
+  DIDT_AppleTypes,
+  DIDT_AppleNamespaces,
+  DIDT_AppleObjC
 };
 
 // In place of applying the relocations to the data we've read from disk we use
index 61a3fb066d115a0c05f9fcc48c7ecfaaed146b16..81fc84d4a80522ba25c3c420c968ef8e6bc2fc2e 100644 (file)
@@ -1,6 +1,7 @@
 add_llvm_library(LLVMDebugInfo
   DIContext.cpp
   DWARFAbbreviationDeclaration.cpp
+  DWARFAcceleratorTable.cpp
   DWARFCompileUnit.cpp
   DWARFContext.cpp
   DWARFDebugAbbrev.cpp
diff --git a/lib/DebugInfo/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARFAcceleratorTable.cpp
new file mode 100644 (file)
index 0000000..c984769
--- /dev/null
@@ -0,0 +1,110 @@
+#include "DWARFAcceleratorTable.h"
+
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+bool DWARFAcceleratorTable::extract() {
+  uint32_t Offset = 0;
+
+  // Check that we can at least read the header.
+  if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
+    return false;
+
+  Hdr.Magic = AccelSection.getU32(&Offset);
+  Hdr.Version = AccelSection.getU16(&Offset);
+  Hdr.HashFunction = AccelSection.getU16(&Offset);
+  Hdr.NumBuckets = AccelSection.getU32(&Offset);
+  Hdr.NumHashes = AccelSection.getU32(&Offset);
+  Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
+
+  // Check that we can read all the hashes and offsets from the
+  // section (see SourceLevelDebugging.rst for the structure of the index).
+  if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
+                                  Hdr.NumBuckets*4 + Hdr.NumHashes*8))
+    return false;
+
+  HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
+  uint32_t NumAtoms = AccelSection.getU32(&Offset);
+
+  for (unsigned i = 0; i < NumAtoms; ++i) {
+    auto Atom = std::make_pair(AccelSection.getU16(&Offset),
+                               DWARFFormValue(AccelSection.getU16(&Offset)));
+    HdrData.Atoms.push_back(Atom);
+  }
+
+  return true;
+}
+
+void DWARFAcceleratorTable::dump(raw_ostream &OS) {
+  // Dump the header.
+  OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n';
+  OS << "Version = " << format("0x%04x", Hdr.Version) << '\n';
+  OS << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n';
+  OS << "Bucket count = " << Hdr.NumBuckets << '\n';
+  OS << "Hashes count = " << Hdr.NumHashes << '\n';
+  OS << "HeaderData length = " << Hdr.HeaderDataLength << '\n';
+  OS << "DIE offset base = " << HdrData.DIEOffsetBase << '\n';
+  OS << "Number of atoms = " << HdrData.Atoms.size() << '\n';
+
+  unsigned i = 0;
+  for (const auto &Atom: HdrData.Atoms) {
+    OS << format("Atom[%d] ", i++);
+    OS << " Type: " << dwarf::AtomTypeString(Atom.first);
+    OS << " Form: " << dwarf::FormEncodingString(Atom.second.getForm());
+    OS << "\n";
+  }
+
+  // Now go through the actual tables and dump them.
+  uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
+  unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
+  unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
+
+  for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
+    unsigned Index;
+    Index = AccelSection.getU32(&Offset);
+
+    OS << format("Bucket[%d]\n", Bucket);
+    if (Index == UINT32_MAX) {
+      OS << "  EMPTY\n";
+      continue;
+    }
+
+    for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
+      unsigned HashOffset = HashesBase + HashIdx*4;
+      unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
+      uint32_t Hash = AccelSection.getU32(&HashOffset);
+
+      if (Hash % Hdr.NumBuckets != Bucket)
+        break;
+
+      unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
+      OS << format("  Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
+      if (!AccelSection.isValidOffset(DataOffset)) {
+        OS << "    Invalid section offset\n";
+        continue;
+      }
+      while (unsigned StringOffset = AccelSection.getU32(&DataOffset)) {
+        OS << format("    Name: %08x \"%s\"\n", StringOffset,
+                     StringSection.getCStr(&StringOffset));
+        unsigned NumData = AccelSection.getU32(&DataOffset);
+        for (unsigned Data = 0; Data < NumData; ++Data) {
+          OS << format("    Data[%d] => ", Data);
+          unsigned i = 0;
+          for (auto &Atom : HdrData.Atoms) {
+            OS << format("{Atom[%d]: ", i++);
+            if (Atom.second.extractValue(AccelSection, &DataOffset, nullptr))
+              Atom.second.dump(OS, nullptr);
+            else
+              OS << "Error extracting the value";
+            OS << "} ";
+          }
+          OS << '\n';
+        }
+      }
+    }
+  }
+}
+}
diff --git a/lib/DebugInfo/DWARFAcceleratorTable.h b/lib/DebugInfo/DWARFAcceleratorTable.h
new file mode 100644 (file)
index 0000000..bb25917
--- /dev/null
@@ -0,0 +1,38 @@
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DWARFFormValue.h"
+
+#include <cstdint>
+
+namespace llvm {
+
+class DWARFAcceleratorTable {
+
+  struct Header {
+    uint32_t Magic;
+    uint16_t Version;
+    uint16_t HashFunction;
+    uint32_t NumBuckets;
+    uint32_t NumHashes;
+    uint32_t HeaderDataLength;
+  };
+
+  struct HeaderData {
+    typedef uint16_t AtomType;
+    uint32_t DIEOffsetBase;
+    SmallVector<std::pair<AtomType, DWARFFormValue>, 1> Atoms;
+  };
+
+  struct Header Hdr;
+  struct HeaderData HdrData;
+  DataExtractor AccelSection;
+  DataExtractor StringSection;
+public:
+  DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection)
+    : AccelSection(AccelSection), StringSection(StringSection) {}
+
+  bool extract();
+  void dump(raw_ostream &OS);
+};
+
+}
index aa86f6aac0312b47bad723460d8d1dde69c177f5..845718d195d3c0f7af84bd9f59abad5a81ab3a5a 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "DWARFContext.h"
 #include "DWARFDebugArangeSet.h"
+#include "DWARFAcceleratorTable.h"
 
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -59,6 +60,17 @@ static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
   }
 }
 
+static void dumpAccelSection(raw_ostream &OS, StringRef Name, StringRef Data,
+                             StringRef StringSection, bool LittleEndian) {
+  DataExtractor AccelSection(Data, LittleEndian, 0);
+  DataExtractor StrData(StringSection, LittleEndian, 0);
+  OS << "\n." << Name << " contents:\n";
+  DWARFAcceleratorTable Accel(AccelSection, StrData);
+  if (!Accel.extract())
+    return;
+  Accel.dump(OS);
+}
+
 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
     OS << ".debug_abbrev contents:\n";
@@ -218,6 +230,22 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
     }
   }
+
+  if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
+    dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
+                     getStringSection(), isLittleEndian());
+
+  if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
+    dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
+                     getStringSection(), isLittleEndian());
+
+  if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
+    dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
+                     getStringSection(), isLittleEndian());
+
+  if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
+    dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
+                     getStringSection(), isLittleEndian());
 }
 
 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
@@ -565,6 +593,11 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj)
             .Case("debug_str.dwo", &StringDWOSection)
             .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
             .Case("debug_addr", &AddrSection)
+            .Case("apple_names", &AppleNamesSection)
+            .Case("apple_types", &AppleTypesSection)
+            .Case("apple_namespaces", &AppleNamespacesSection)
+            .Case("apple_namespac", &AppleNamespacesSection)
+            .Case("apple_objc", &AppleObjCSection)
             // Any more debug info sections go here.
             .Default(nullptr);
     if (SectionData) {
index c4586b0d4c1f7a703b31f9bf41b95799aa2f2263..926f7c39bd36ff727557647041a68a2400f6bae7 100644 (file)
@@ -192,6 +192,10 @@ public:
   virtual StringRef getStringOffsetDWOSection() = 0;
   virtual StringRef getRangeDWOSection() = 0;
   virtual StringRef getAddrSection() = 0;
+  virtual StringRef getAppleNamesSection() = 0;
+  virtual StringRef getAppleTypesSection() = 0;
+  virtual StringRef getAppleNamespacesSection() = 0;
+  virtual StringRef getAppleObjCSection() = 0;
 
   static bool isSupportedVersion(unsigned version) {
     return version == 2 || version == 3 || version == 4;
@@ -236,6 +240,10 @@ class DWARFContextInMemory : public DWARFContext {
   StringRef StringOffsetDWOSection;
   StringRef RangeDWOSection;
   StringRef AddrSection;
+  StringRef AppleNamesSection;
+  StringRef AppleTypesSection;
+  StringRef AppleNamespacesSection;
+  StringRef AppleObjCSection;
 
   SmallVector<SmallString<32>, 4> UncompressedSections;
 
@@ -256,6 +264,10 @@ public:
   StringRef getPubTypesSection() override { return PubTypesSection; }
   StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
   StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
+  StringRef getAppleNamesSection() override { return AppleNamesSection; }
+  StringRef getAppleTypesSection() override { return AppleTypesSection; }
+  StringRef getAppleNamespacesSection() override { return AppleNamespacesSection; }
+  StringRef getAppleObjCSection() override { return AppleObjCSection; }
 
   // Sections for DWARF5 split dwarf proposal.
   const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
index 8de03decd7646f865836be3ef49aed0cf49ee8a1..ba8d11342aeb5a679dda5fbff21e90ad823235b2 100644 (file)
@@ -95,6 +95,8 @@
 ; CHECK: .debug_pubtypes contents:
 ; CHECK-NOT: Offset
 
+; CHECK: .apple{{.*}} contents:
+
 ; Function Attrs: nounwind uwtable
 define void @_Z2f1v() #0 {
 entry:
diff --git a/test/DebugInfo/dwarfdump-accel.test b/test/DebugInfo/dwarfdump-accel.test
new file mode 100644 (file)
index 0000000..e0205f6
--- /dev/null
@@ -0,0 +1,154 @@
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-objc.x86_64.o | FileCheck %s
+
+CHECK: .apple_names contents:
+CHECK: Magic = 0x48415348
+CHECK: Version = 0x0001
+CHECK: Hash function = 0x00000000
+CHECK: Bucket count = 11
+CHECK: Hashes count = 22
+CHECK: HeaderData length = 12
+CHECK: DIE offset base = 0
+CHECK: Number of atoms = 1
+CHECK: Atom[0]  Type: DW_ATOM_die_offset Form: DW_FORM_data4
+CHECK: Bucket[0]
+CHECK:   Hash = 0x248050fe Offset = 0x000000fc
+CHECK:     Name: 00000165 "-[TestInterface Retain]"
+CHECK:     Data[0] => {Atom[0]: 0x0000024f} 
+CHECK: Bucket[1]
+CHECK:   Hash = 0x926d42cc Offset = 0x0000010c
+CHECK:     Name: 00000057 "ReadWrite"
+CHECK:     Data[0] => {Atom[0]: 0x000001cb} 
+CHECK: Bucket[2]
+CHECK:   EMPTY
+CHECK: Bucket[3]
+CHECK:   Hash = 0x99254268 Offset = 0x0000011c
+CHECK:     Name: 0000013f "-[TestInterface setReadWrite:]"
+CHECK:     Data[0] => {Atom[0]: 0x00000209} 
+CHECK:   Hash = 0x946f52b9 Offset = 0x0000012c
+CHECK:     Name: 000000c6 "-[TestInterface ReadOnly]"
+CHECK:     Data[0] => {Atom[0]: 0x00000109} 
+CHECK: Bucket[4]
+CHECK:   EMPTY
+CHECK: Bucket[5]
+CHECK:   EMPTY
+CHECK: Bucket[6]
+CHECK:   Hash = 0x6e8e91a3 Offset = 0x0000013c
+CHECK:     Name: 000001e0 "-[TestInterface NonAtomic]"
+CHECK:     Data[0] => {Atom[0]: 0x00000357} 
+CHECK:   Hash = 0x7d1a5012 Offset = 0x0000014c
+CHECK:     Name: 0000014d "setReadWrite:"
+CHECK:     Data[0] => {Atom[0]: 0x00000209} 
+CHECK:   Hash = 0xb65f49d3 Offset = 0x0000015c
+CHECK:     Name: 0000020d "setNonAtomic:"
+CHECK:     Data[0] => {Atom[0]: 0x00000395} 
+CHECK:   Hash = 0x354997e2 Offset = 0x0000016c
+CHECK:     Name: 00000120 "-[TestInterface ReadWrite]"
+CHECK:     Data[0] => {Atom[0]: 0x000001cb} 
+CHECK: Bucket[7]
+CHECK:   Hash = 0xce8af9c8 Offset = 0x0000017c
+CHECK:     Name: 0000005e "Retain"
+CHECK:     Data[0] => {Atom[0]: 0x0000024f} 
+CHECK:   Hash = 0xa7e0338a Offset = 0x0000018c
+CHECK:     Name: 0000004d "Assign"
+CHECK:     Data[0] => {Atom[0]: 0x00000147} 
+CHECK:   Hash = 0xa9812410 Offset = 0x0000019c
+CHECK:     Name: 00000105 "setAssign:"
+CHECK:     Data[0] => {Atom[0]: 0x00000185} 
+CHECK:   Hash = 0x218d07f6 Offset = 0x000001ac
+CHECK:     Name: 000001a2 "-[TestInterface Copy]"
+CHECK:     Data[0] => {Atom[0]: 0x000002d3} 
+CHECK:   Hash = 0x0456817c Offset = 0x000001bc
+CHECK:     Name: 000001bc "-[TestInterface setCopy:]"
+CHECK:     Data[0] => {Atom[0]: 0x00000311} 
+CHECK:   Hash = 0x7c83b400 Offset = 0x000001cc
+CHECK:     Name: 0000006c "Copy"
+CHECK:     Data[0] => {Atom[0]: 0x000002d3} 
+CHECK: Bucket[8]
+CHECK:   Hash = 0x0f918046 Offset = 0x000001dc
+CHECK:     Name: 000001c5 "setCopy:"
+CHECK:     Data[0] => {Atom[0]: 0x00000311} 
+CHECK:   Hash = 0xfb097449 Offset = 0x000001ec
+CHECK:     Name: 000001ff "-[TestInterface setNonAtomic:]"
+CHECK:     Data[0] => {Atom[0]: 0x00000395} 
+CHECK:   Hash = 0x71069de3 Offset = 0x000001fc
+CHECK:     Name: 00000042 "ReadOnly"
+CHECK:     Data[0] => {Atom[0]: 0x00000109} 
+CHECK: Bucket[9]
+CHECK:   Hash = 0xd55908c6 Offset = 0x0000020c
+CHECK:     Name: 000000fa "-[TestInterface setAssign:]"
+CHECK:     Data[0] => {Atom[0]: 0x00000185} 
+CHECK:   Hash = 0xa584b20e Offset = 0x0000021c
+CHECK:     Name: 0000018c "setRetain:"
+CHECK:     Data[0] => {Atom[0]: 0x0000028d} 
+CHECK:   Hash = 0x9429886d Offset = 0x0000022c
+CHECK:     Name: 00000076 "NonAtomic"
+CHECK:     Data[0] => {Atom[0]: 0x00000357} 
+CHECK:   Hash = 0x287cc300 Offset = 0x0000023c
+CHECK:     Name: 000000de "-[TestInterface Assign]"
+CHECK:     Data[0] => {Atom[0]: 0x00000147} 
+CHECK:   Hash = 0x51ce5684 Offset = 0x0000024c
+CHECK:     Name: 00000181 "-[TestInterface setRetain:]"
+CHECK:     Data[0] => {Atom[0]: 0x0000028d} 
+CHECK: Bucket[10]
+CHECK:   EMPTY
+
+
+CHECK: .apple_types contents:
+CHECK: Magic = 0x48415348
+CHECK: Version = 0x0001
+CHECK: Hash function = 0x00000000
+CHECK: Bucket count = 4
+CHECK: Hashes count = 4
+CHECK: HeaderData length = 20
+CHECK: DIE offset base = 0
+CHECK: Number of atoms = 3
+CHECK: Atom[0]  Type: DW_ATOM_die_offset Form: DW_FORM_data4
+CHECK: Atom[1]  Type: DW_ATOM_die_tag Form: DW_FORM_data2
+CHECK: Atom[2]  Type: DW_ATOM_type_flags Form: DW_FORM_data1
+CHECK: Bucket[0]
+CHECK:   Hash = 0x0b888030 Offset = 0x00000058
+CHECK:     Name: 00000046 "int"
+CHECK:     Data[0] => {Atom[0]: 0x000000f4} {Atom[1]: 0x0024} {Atom[2]: 0x00} 
+CHECK: Bucket[1]
+CHECK:   Hash = 0x0b881d29 Offset = 0x0000006b
+CHECK:     Name: 0000021b "SEL"
+CHECK:     Data[0] => {Atom[0]: 0x000003e0} {Atom[1]: 0x0016} {Atom[2]: 0x00} 
+CHECK:   Hash = 0x2c549f3d Offset = 0x0000007e
+CHECK:     Name: 00000067 "NSObject"
+CHECK:     Data[0] => {Atom[0]: 0x00000100} {Atom[1]: 0x0013} {Atom[2]: 0x00} 
+CHECK: Bucket[2]
+CHECK:   Hash = 0x16a83cb6 Offset = 0x00000091
+CHECK:     Name: 00000039 "TestInterface"
+CHECK:     Data[0] => {Atom[0]: 0x0000002f} {Atom[1]: 0x0013} {Atom[2]: 0x00} 
+CHECK: Bucket[3]
+CHECK:   EMPTY
+
+
+CHECK: .apple_namespaces contents:
+CHECK-NOT: Magic
+
+CHECK: .apple_objc contents:
+CHECK: Magic = 0x48415348
+CHECK: Version = 0x0001
+CHECK: Hash function = 0x00000000
+CHECK: Bucket count = 1
+CHECK: Hashes count = 1
+CHECK: HeaderData length = 12
+CHECK: DIE offset base = 0
+CHECK: Number of atoms = 1
+CHECK: Atom[0]  Type: DW_ATOM_die_offset Form: DW_FORM_data4
+CHECK: Bucket[0]
+CHECK:   Hash = 0x16a83cb6 Offset = 0x0000002c
+CHECK:     Name: 00000039 "TestInterface"
+CHECK:     Data[0] => {Atom[0]: 0x00000109} 
+CHECK:     Data[1] => {Atom[0]: 0x00000147} 
+CHECK:     Data[2] => {Atom[0]: 0x00000185} 
+CHECK:     Data[3] => {Atom[0]: 0x000001cb} 
+CHECK:     Data[4] => {Atom[0]: 0x00000209} 
+CHECK:     Data[5] => {Atom[0]: 0x0000024f} 
+CHECK:     Data[6] => {Atom[0]: 0x0000028d} 
+CHECK:     Data[7] => {Atom[0]: 0x000002d3} 
+CHECK:     Data[8] => {Atom[0]: 0x00000311} 
+CHECK:     Data[9] => {Atom[0]: 0x00000357} 
+CHECK:     Data[10] => {Atom[0]: 0x00000395} 
\ No newline at end of file
index b4aeb6b8d4aa2ae48c808ee9cff680751283b01c..1c540c988421f6c783013d934e1ba38928e50a05 100644 (file)
@@ -45,6 +45,10 @@ DumpType("debug-dump", cl::init(DIDT_All),
         clEnumValN(DIDT_All, "all", "Dump all debug sections"),
         clEnumValN(DIDT_Abbrev, "abbrev", ".debug_abbrev"),
         clEnumValN(DIDT_AbbrevDwo, "abbrev.dwo", ".debug_abbrev.dwo"),
+        clEnumValN(DIDT_AppleNames, "apple_names", ".apple_names"),
+        clEnumValN(DIDT_AppleTypes, "apple_types", ".apple_types"),
+        clEnumValN(DIDT_AppleNamespaces, "apple_namespaces", ".apple_namespaces"),
+        clEnumValN(DIDT_AppleObjC, "apple_objc", ".apple_objc"),
         clEnumValN(DIDT_Aranges, "aranges", ".debug_aranges"),
         clEnumValN(DIDT_Info, "info", ".debug_info"),
         clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),