[llvm] Allow the dumping of .dwo files contents to show up when dumping an e… (PR #66726)

Greg Clayton via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 18 21:34:38 PST 2023


https://github.com/clayborg updated https://github.com/llvm/llvm-project/pull/66726

>From c4300eba93a4cae6758efe7184e92e2390f8c91e Mon Sep 17 00:00:00 2001
From: Greg Clayton <gclayton at fb.com>
Date: Mon, 18 Sep 2023 18:18:41 -0700
Subject: [PATCH 1/3] Allow the dumping of .dwo files contents to show up when
 dumping an executable with split DWARF.

Currently if you run llvm-dwarfdump on a binary that has skeleton compile units, you only see the skeleton compile units. Since the main binary has the linked addresses it would be nice to be able to dump DWARF from the .dwo files and how the resolved addresses instead of showing the address index and "<unresolved>" in the output. This patch adds an option that can be specified to dump the non skeleton DIEs named --dwo.

Added the ability to use the following options with split dwarf as well:
  --name <name>
  --lookup <addr>
  --debug-info <die-offset>
---
 llvm/include/llvm/DebugInfo/DIContext.h       |  1 +
 llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp | 10 +++++--
 llvm/lib/DebugInfo/DWARF/DWARFContext.cpp     | 10 ++++++-
 llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp        |  2 +-
 .../llvm-dwarfdump/X86/statistics-dwo.test    | 22 ++++++++--------
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp  | 26 ++++++++++++++++++-
 6 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index 9ad27033ec110c..78ac34e5f0d26c 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -204,6 +204,7 @@ struct DIDumpOptions {
   bool Verbose = false;
   bool DisplayRawContents = false;
   bool IsEH = false;
+  bool DumpNonSkeleton = false;
   std::function<llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)>
       GetNameForDWARFReg;
 
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 6461f2ac031d2a..30afa651ffc23a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -35,10 +35,16 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
   OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
      << ")\n";
 
-  if (DWARFDie CUDie = getUnitDIE(false))
+  if (DWARFDie CUDie = getUnitDIE(false)) {
     CUDie.dump(OS, 0, DumpOpts);
-  else
+    if (DumpOpts.DumpNonSkeleton) {
+      DWARFDie NonSkeletonCUDie = getNonSkeletonUnitDIE(false);
+      if (NonSkeletonCUDie && CUDie != NonSkeletonCUDie)
+        NonSkeletonCUDie.dump(OS, 0, DumpOpts);
+    }
+  } else {
     OS << "<compile unit can't be parsed!>\n\n";
+  }
 }
 
 // VTable anchor.
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index c671aedbc9e52b..97cb303d92c172 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1024,9 +1024,17 @@ void DWARFContext::dump(
   auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
     OS << '\n' << Name << " contents:\n";
     if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
-      for (const auto &U : Units)
+      for (const auto &U : Units) {
         U->getDIEForOffset(*DumpOffset)
             .dump(OS, 0, DumpOpts.noImplicitRecursion());
+        DWARFDie CUDie = U->getUnitDIE(false);
+        DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);
+        if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
+          CUNonSkeletonDie.getDwarfUnit()->getDIEForOffset(*DumpOffset)
+              .dump(OS, 0, DumpOpts.noImplicitRecursion());
+
+        }
+      }
     else
       for (const auto &U : Units)
         U->dump(OS, DumpOpts);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 9f455fa7e96a7e..031d6441d733c1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -740,7 +740,7 @@ void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
 DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
   extractDIEsIfNeeded(false);
   if (AddrDieMap.empty())
-    updateAddressDieMap(getUnitDIE());
+    updateAddressDieMap(getNonSkeletonUnitDIE(/*ExtractUnitDIEOnly=*/false));
   auto R = AddrDieMap.upper_bound(Address);
   if (R == AddrDieMap.begin())
     return DWARFDie();
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test b/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test
index 3e39591c46dce1..45fbc5b8945568 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test
@@ -15,39 +15,39 @@ RUN: llvm-dwarfdump --statistics statistics-fib.split-dwarf.o | FileCheck %s
 # real_fib (int x, int answers[11])
 # {
 #   int result;
-# 
+#
 #   if ((answers)[x] != -1)
 #     return (answers)[x];
-# 
+#
 #   result = real_fib(x-1, answers) + real_fib(x-2, answers);
 #   (answers)[x] = result;
-# 
+#
 #   return result;
 # }
-# 
+#
 # int
 # fib (int x)
 # {
 #   int answers[11];
 #   int i;
-# 
+#
 #   if (x > 10)
 #     return -1;
-# 
+#
 #   for (i = 0; i < 11; i++)
 #     answers[i] = -1;
-# 
+#
 #   answers[0] = 0;
 #   answers[1] = 1;
 #   answers[2] = 1;
-# 
+#
 #   return real_fib(x, answers);
 # }
-# 
+#
 # int main (int argc, char **argv)
 # {
 #   int result;
-# 
+#
 #   result = fib(3);
 #   printf ("fibonacci(3) = %d\n", result);
 #   result = fib(4);
@@ -64,7 +64,7 @@ RUN: llvm-dwarfdump --statistics statistics-fib.split-dwarf.o | FileCheck %s
 #   printf ("fibonacci(9) = %d\n", result);
 #   result = fib(10);
 #   printf ("fibonacci(10) = %d\n", result);
-# 
+#
 #   return 0;
 # }
 #
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 8180ad2138f41f..5360cf70b98ebf 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -181,6 +181,14 @@ static opt<bool> FindAllApple(
 static opt<bool> IgnoreCase("ignore-case",
                             desc("Ignore case distinctions when using --name."),
                             value_desc("i"), cat(DwarfDumpCategory));
+static opt<bool> DumpNonSkeleton("dwo",
+                            desc("Dump the non skeleton DIE in the .dwo or "
+                                 ".dwp file after dumping the skeleton DIE "
+                                 "from the main executable. This allows "
+                                 "dumping the .dwo files with resolved "
+                                 "addresses."),
+                            value_desc("d"), cat(DwarfDumpCategory));
+
 static alias IgnoreCaseAlias("i", desc("Alias for --ignore-case."),
                              aliasopt(IgnoreCase), cl::NotHidden);
 static list<std::string> Name(
@@ -315,6 +323,7 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
   DumpOpts.ShowForm = ShowForm;
   DumpOpts.SummarizeTypes = SummarizeTypes;
   DumpOpts.Verbose = Verbose;
+  DumpOpts.DumpNonSkeleton = DumpNonSkeleton;
   DumpOpts.RecoverableErrorHandler = C.getRecoverableErrorHandler();
   // In -verify mode, print DIEs without children in error messages.
   if (Verify) {
@@ -390,7 +399,7 @@ static void filterByName(
     const StringSet<> &Names, DWARFContext::unit_iterator_range CUs,
     raw_ostream &OS,
     std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
-  for (const auto &CU : CUs)
+  for (const auto &CU : CUs) {
     for (const auto &Entry : CU->dies()) {
       DWARFDie Die = {CU.get(), &Entry};
       if (const char *Name = Die.getName(DINameKind::ShortName))
@@ -399,6 +408,21 @@ static void filterByName(
       if (const char *Name = Die.getName(DINameKind::LinkageName))
         filterByName(Names, Die, Name, OS, GetNameForDWARFReg);
     }
+    // If we have split DWARF, then recurse down into the .dwo files as well.
+    DWARFDie CUDie = CU->getUnitDIE(false);
+    DWARFDie CUNonSkeletonDie = CU->getNonSkeletonUnitDIE(false);
+    if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
+      // We have a DWO file, we need to search it as well
+      for (const auto &Entry : CUNonSkeletonDie.getDwarfUnit()->dies()) {
+        DWARFDie Die = {CUNonSkeletonDie.getDwarfUnit(), &Entry};
+        if (const char *Name = Die.getShortName())
+          if (filterByName(Names, Die, Name, OS, GetNameForDWARFReg))
+            continue;
+        if (const char *Name = Die.getLinkageName())
+          filterByName(Names, Die, Name, OS, GetNameForDWARFReg);
+      }
+    }
+  }
 }
 
 static void getDies(DWARFContext &DICtx, const AppleAcceleratorTable &Accel,

>From e664c09a29389d3c1800c37b943f0a5d277a1e56 Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Mon, 18 Dec 2023 21:32:28 -0800
Subject: [PATCH 2/3] Fixed inline comments and added a test.

---
 .../llvm-dwarfdump/Inputs/dump_dwo.dwo.yaml   |  37 +++
 .../llvm-dwarfdump/Inputs/dump_dwo.o.yaml     | 251 ++++++++++++++++++
 .../llvm-dwarfdump/X86/statistics-dwo.test    |  22 +-
 llvm/test/tools/llvm-dwarfdump/dump_dwo.test  | 121 +++++++++
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp  |  37 ++-
 5 files changed, 436 insertions(+), 32 deletions(-)
 create mode 100644 llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.dwo.yaml
 create mode 100644 llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.o.yaml
 create mode 100644 llvm/test/tools/llvm-dwarfdump/dump_dwo.test

diff --git a/llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.dwo.yaml b/llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.dwo.yaml
new file mode 100644
index 00000000000000..5f24586bded069
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.dwo.yaml
@@ -0,0 +1,37 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+  SectionHeaderStringTable: .strtab
+Sections:
+  - Name:            .debug_str_offsets.dwo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_EXCLUDE ]
+    AddressAlign:    0x1
+    Content:         2C0000000500000000000000080000000C00000010000000150000001A0000001F000000240000005400000061000000
+  - Name:            .debug_str.dwo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_EXCLUDE, SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         5F5A33666F6F7600666F6F00696E74006D61696E006172676300617267760063686172004170706C6520636C616E672076657273696F6E2031352E302E302028636C616E672D313530302E312E302E322E35290064756D705F64776F2E637070002E2F64756D705F64776F2E64776F00
+  - Name:            .debug_info.dwo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_EXCLUDE ]
+    AddressAlign:    0x1
+    Content:         64000000050005080000000036C1C3A75DD36D37010704000809020008000000015600010002500000000301230000000156030006500000000402917804000650000000040291700500065400000000050205040659000000065E00000007630000000506060100
+  - Name:            .debug_abbrev.dwo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_EXCLUDE ]
+    AddressAlign:    0x1
+    Content:         01110125251305032576250000022E00111B120640186E2503253A0B3B0B49133F190000032E01111B1206401803253A0B3B0B49133F190000040500021803253A0B3B0B4913000005240003253E0B0B0B0000060F00491300000726004913000000
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            .strtab
+      - Name:            .debug_str_offsets.dwo
+      - Name:            .debug_str.dwo
+      - Name:            .debug_info.dwo
+      - Name:            .debug_abbrev.dwo
+...
diff --git a/llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.o.yaml b/llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.o.yaml
new file mode 100644
index 00000000000000..8b15e0888659c1
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/Inputs/dump_dwo.o.yaml
@@ -0,0 +1,251 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+  SectionHeaderStringTable: .strtab
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x10
+    Content:         554889E531C05DC30F1F840000000000554889E54883EC10C745FC00000000897DF8488975F0E80000000031C04883C4105DC3
+  - Name:            .debug_abbrev
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         014A00101772171B25B442197625111B12067317000000
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         24000000050004080000000036C1C3A75DD36D370100000000000000000001003300000000000000
+  - Name:            .debug_str_offsets
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         0C000000050000000000000000000000
+  - Name:            .debug_gnu_pubnames
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         21000000020000000000280000001A00000030666F6F002A000000306D61696E0000000000
+  - Name:            .debug_gnu_pubtypes
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         '21000000020000000000280000005000000090696E74006300000090636861720000000000'
+  - Name:            .comment
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         004170706C6520636C616E672076657273696F6E2031352E302E302028636C616E672D313530302E312E302E322E352900
+  - Name:            .note.GNU-stack
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+  - Name:            .eh_frame
+    Type:            SHT_X86_64_UNWIND
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x8
+    Content:         1400000000000000017A5200017810011B0C0708900100001C0000001C000000000000000800000000410E108602430D06430C07080000001C0000003C000000000000002300000000410E108602430D065E0C0708000000
+  - Name:            .debug_line
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         5F0000000500080037000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E0100000000004000920BB47E0DDA24E8521F209EDB37040000090200000000000000001305020A4B0500BD05030A0859590208000101
+  - Name:            .debug_line_str
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         2E2F0064756D705F64776F2E63707000
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .text
+    Relocations:
+      - Offset:          0x27
+        Symbol:          _Z3foov
+        Type:            R_X86_64_PLT32
+        Addend:          -4
+  - Name:            .rela.debug_info
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .debug_info
+    Relocations:
+      - Offset:          0x8
+        Symbol:          .debug_abbrev
+        Type:            R_X86_64_32
+      - Offset:          0x15
+        Symbol:          .debug_line
+        Type:            R_X86_64_32
+      - Offset:          0x19
+        Symbol:          .debug_str_offsets
+        Type:            R_X86_64_32
+        Addend:          8
+      - Offset:          0x24
+        Symbol:          .debug_addr
+        Type:            R_X86_64_32
+        Addend:          8
+  - Name:            .rela.debug_str_offsets
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .debug_str_offsets
+    Relocations:
+      - Offset:          0x8
+        Symbol:          .debug_str
+        Type:            R_X86_64_32
+      - Offset:          0xC
+        Symbol:          .debug_str
+        Type:            R_X86_64_32
+        Addend:          3
+  - Name:            .rela.debug_addr
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .debug_addr
+    Relocations:
+      - Offset:          0x8
+        Symbol:          .text
+        Type:            R_X86_64_64
+      - Offset:          0x10
+        Symbol:          .text
+        Type:            R_X86_64_64
+        Addend:          16
+  - Name:            .rela.debug_gnu_pubnames
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .debug_gnu_pubnames
+    Relocations:
+      - Offset:          0x6
+        Symbol:          .debug_info
+        Type:            R_X86_64_32
+  - Name:            .rela.debug_gnu_pubtypes
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .debug_gnu_pubtypes
+    Relocations:
+      - Offset:          0x6
+        Symbol:          .debug_info
+        Type:            R_X86_64_32
+  - Name:            .rela.eh_frame
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .eh_frame
+    Relocations:
+      - Offset:          0x20
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+      - Offset:          0x40
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+        Addend:          16
+  - Name:            .rela.debug_line
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x8
+    Info:            .debug_line
+    Relocations:
+      - Offset:          0x22
+        Symbol:          .debug_line_str
+        Type:            R_X86_64_32
+      - Offset:          0x2E
+        Symbol:          .debug_line_str
+        Type:            R_X86_64_32
+        Addend:          3
+      - Offset:          0x48
+        Symbol:          .text
+        Type:            R_X86_64_64
+  - Name:            .llvm_addrsig
+    Type:            SHT_LLVM_ADDRSIG
+    Flags:           [ SHF_EXCLUDE ]
+    Link:            .symtab
+    AddressAlign:    0x1
+    Symbols:         [ _Z3foov ]
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            .strtab
+      - Name:            .text
+      - Name:            .rela.text
+      - Name:            .debug_abbrev
+      - Name:            .debug_info
+      - Name:            .rela.debug_info
+      - Name:            .debug_str_offsets
+      - Name:            .rela.debug_str_offsets
+      - Name:            .debug_str
+      - Name:            .debug_addr
+      - Name:            .rela.debug_addr
+      - Name:            .debug_gnu_pubnames
+      - Name:            .rela.debug_gnu_pubnames
+      - Name:            .debug_gnu_pubtypes
+      - Name:            .rela.debug_gnu_pubtypes
+      - Name:            .comment
+      - Name:            .note.GNU-stack
+      - Name:            .eh_frame
+      - Name:            .rela.eh_frame
+      - Name:            .debug_line
+      - Name:            .rela.debug_line
+      - Name:            .debug_line_str
+      - Name:            .llvm_addrsig
+      - Name:            .symtab
+Symbols:
+  - Name:            dump_dwo.cpp
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            .text
+    Type:            STT_SECTION
+    Section:         .text
+  - Name:            .debug_abbrev
+    Type:            STT_SECTION
+    Section:         .debug_abbrev
+  - Name:            .debug_info
+    Type:            STT_SECTION
+    Section:         .debug_info
+  - Name:            .debug_str_offsets
+    Type:            STT_SECTION
+    Section:         .debug_str_offsets
+  - Name:            .debug_str
+    Type:            STT_SECTION
+    Section:         .debug_str
+  - Name:            .debug_addr
+    Type:            STT_SECTION
+    Section:         .debug_addr
+  - Name:            .debug_line
+    Type:            STT_SECTION
+    Section:         .debug_line
+  - Name:            .debug_line_str
+    Type:            STT_SECTION
+    Section:         .debug_line_str
+  - Name:            _Z3foov
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Size:            0x8
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x10
+    Size:            0x23
+DWARF:
+  debug_str:
+    - './'
+    - './dump_dwo.dwo'
+  debug_addr:
+    - Length:          0x14
+      Version:         0x5
+      AddressSize:     0x8
+      Entries:
+        - {}
+        - Address:         0x10
+...
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test b/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test
index 45fbc5b8945568..3e39591c46dce1 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test
@@ -15,39 +15,39 @@ RUN: llvm-dwarfdump --statistics statistics-fib.split-dwarf.o | FileCheck %s
 # real_fib (int x, int answers[11])
 # {
 #   int result;
-#
+# 
 #   if ((answers)[x] != -1)
 #     return (answers)[x];
-#
+# 
 #   result = real_fib(x-1, answers) + real_fib(x-2, answers);
 #   (answers)[x] = result;
-#
+# 
 #   return result;
 # }
-#
+# 
 # int
 # fib (int x)
 # {
 #   int answers[11];
 #   int i;
-#
+# 
 #   if (x > 10)
 #     return -1;
-#
+# 
 #   for (i = 0; i < 11; i++)
 #     answers[i] = -1;
-#
+# 
 #   answers[0] = 0;
 #   answers[1] = 1;
 #   answers[2] = 1;
-#
+# 
 #   return real_fib(x, answers);
 # }
-#
+# 
 # int main (int argc, char **argv)
 # {
 #   int result;
-#
+# 
 #   result = fib(3);
 #   printf ("fibonacci(3) = %d\n", result);
 #   result = fib(4);
@@ -64,7 +64,7 @@ RUN: llvm-dwarfdump --statistics statistics-fib.split-dwarf.o | FileCheck %s
 #   printf ("fibonacci(9) = %d\n", result);
 #   result = fib(10);
 #   printf ("fibonacci(10) = %d\n", result);
-#
+# 
 #   return 0;
 # }
 #
diff --git a/llvm/test/tools/llvm-dwarfdump/dump_dwo.test b/llvm/test/tools/llvm-dwarfdump/dump_dwo.test
new file mode 100644
index 00000000000000..3c233c7bc6c4e5
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/dump_dwo.test
@@ -0,0 +1,121 @@
+## Check that llvm-dwarfdump works when dumping .o files with .dwo files.
+
+# RUN: yaml2obj %p/Inputs/dump_dwo.o.yaml -o %T/dump_dwo.o
+# RUN: yaml2obj %p/Inputs/dump_dwo.dwo.yaml -o %T/dump_dwo.dwo
+## We need to be in the same directory so we can find .dwo file
+# RUN: cd %T && llvm-dwarfdump --dwo %T/dump_dwo.o | FileCheck %s
+# RUN: cd %T && llvm-dwarfdump --name int --name char %T/dump_dwo.o | FileCheck %s --check-prefix=NAMES
+# RUN: cd %T && llvm-dwarfdump --lookup 0x10 %T/dump_dwo.o | FileCheck %s --check-prefix=LOOKUP
+
+
+# CHECK: .debug_info contents:
+# CHECK: 0x00000000: Compile Unit: length = 0x00000024, format = DWARF32, version = 0x0005, unit_type = DW_UT_skeleton, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = 0x376dd35da7c3c136 (next unit at 0x00000028)
+
+# CHECK: 0x00000014: DW_TAG_skeleton_unit
+# CHECK:               DW_AT_stmt_list	(0x00000000)
+# CHECK:               DW_AT_str_offsets_base	(0x00000008)
+# CHECK:               DW_AT_comp_dir	("./")
+# CHECK:               DW_AT_GNU_pubnames	(true)
+# CHECK:               DW_AT_dwo_name	("./dump_dwo.dwo")
+# CHECK:               DW_AT_low_pc	(0x0000000000000000)
+# CHECK:               DW_AT_high_pc	(0x0000000000000033)
+# CHECK:               DW_AT_addr_base	(0x00000008)
+
+# CHECK: 0x00000014: DW_TAG_compile_unit
+# CHECK:               DW_AT_producer	("Apple clang version 15.0.0 (clang-1500.1.0.2.5)")
+# CHECK:               DW_AT_language	(DW_LANG_C_plus_plus)
+# CHECK:               DW_AT_name	("dump_dwo.cpp")
+# CHECK:               DW_AT_dwo_name	("./dump_dwo.dwo")
+
+# CHECK: 0x0000001a:   DW_TAG_subprogram
+# CHECK:                 DW_AT_low_pc	(0x0000000000000000)
+# CHECK:                 DW_AT_high_pc	(0x0000000000000008)
+# CHECK:                 DW_AT_frame_base	(DW_OP_reg6 RBP)
+# CHECK:                 DW_AT_linkage_name	("_Z3foov")
+# CHECK:                 DW_AT_name	("foo")
+# CHECK:                 DW_AT_decl_file	(0x00)
+# CHECK:                 DW_AT_decl_line	(2)
+# CHECK:                 DW_AT_type	(0x00000050 "int")
+# CHECK:                 DW_AT_external	(true)
+
+# CHECK: 0x0000002a:   DW_TAG_subprogram
+# CHECK:                 DW_AT_low_pc	(0x0000000000000010)
+# CHECK:                 DW_AT_high_pc	(0x0000000000000033)
+# CHECK:                 DW_AT_frame_base	(DW_OP_reg6 RBP)
+# CHECK:                 DW_AT_name	("main")
+# CHECK:                 DW_AT_decl_file	(0x00)
+# CHECK:                 DW_AT_decl_line	(6)
+# CHECK:                 DW_AT_type	(0x00000050 "int")
+# CHECK:                 DW_AT_external	(true)
+
+# CHECK: 0x00000039:     DW_TAG_formal_parameter
+# CHECK:                   DW_AT_location	(DW_OP_fbreg -8)
+# CHECK:                   DW_AT_name	("argc")
+# CHECK:                   DW_AT_decl_file	(0x00)
+# CHECK:                   DW_AT_decl_line	(6)
+# CHECK:                   DW_AT_type	(0x00000050 "int")
+
+# CHECK: 0x00000044:     DW_TAG_formal_parameter
+# CHECK:                   DW_AT_location	(DW_OP_fbreg -16)
+# CHECK:                   DW_AT_name	("argv")
+# CHECK:                   DW_AT_decl_file	(0x00)
+# CHECK:                   DW_AT_decl_line	(6)
+# CHECK:                   DW_AT_type	(0x00000054 "const char **")
+
+# CHECK: 0x0000004f:     NULL
+
+# CHECK: 0x00000050:   DW_TAG_base_type
+# CHECK:                 DW_AT_name	("int")
+# CHECK:                 DW_AT_encoding	(DW_ATE_signed)
+# CHECK:                 DW_AT_byte_size	(0x04)
+
+# CHECK: 0x00000054:   DW_TAG_pointer_type
+# CHECK:                 DW_AT_type	(0x00000059 "const char *")
+
+# CHECK: 0x00000059:   DW_TAG_pointer_type
+# CHECK:                 DW_AT_type	(0x0000005e "const char")
+
+# CHECK: 0x0000005e:   DW_TAG_const_type
+# CHECK:                 DW_AT_type	(0x00000063 "char")
+
+# CHECK: 0x00000063:   DW_TAG_base_type
+# CHECK:                 DW_AT_name	("char")
+# CHECK:                 DW_AT_encoding	(DW_ATE_signed_char)
+# CHECK:                 DW_AT_byte_size	(0x01)
+
+# CHECK: 0x00000067:   NULL
+
+
+# NAMES: 0x00000050: DW_TAG_base_type
+# NAMES:               DW_AT_name	("int")
+# NAMES:               DW_AT_encoding	(DW_ATE_signed)
+# NAMES:               DW_AT_byte_size	(0x04)
+
+# NAMES: 0x00000063: DW_TAG_base_type
+# NAMES:               DW_AT_name	("char")
+# NAMES:               DW_AT_encoding	(DW_ATE_signed_char)
+# NAMES:               DW_AT_byte_size	(0x01)
+
+
+# LOOKUP: 0x00000000: Compile Unit: length = 0x00000024, format = DWARF32, version = 0x0005, unit_type = DW_UT_skeleton, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = 0x376dd35da7c3c136 (next unit at 0x00000028)
+
+# LOOKUP: 0x00000014: DW_TAG_skeleton_unit
+# LOOKUP:               DW_AT_stmt_list	(0x00000000)
+# LOOKUP:               DW_AT_str_offsets_base	(0x00000008)
+# LOOKUP:               DW_AT_comp_dir	("./")
+# LOOKUP:               DW_AT_GNU_pubnames	(true)
+# LOOKUP:               DW_AT_dwo_name	("./dump_dwo.dwo")
+# LOOKUP:               DW_AT_low_pc	(0x0000000000000000)
+# LOOKUP:               DW_AT_high_pc	(0x0000000000000033)
+# LOOKUP:               DW_AT_addr_base	(0x00000008)
+
+# LOOKUP: 0x0000002a:   DW_TAG_subprogram
+# LOOKUP:                 DW_AT_low_pc	(0x0000000000000010)
+# LOOKUP:                 DW_AT_high_pc	(0x0000000000000033)
+# LOOKUP:                 DW_AT_frame_base	(DW_OP_reg6)
+# LOOKUP:                 DW_AT_name	("main")
+# LOOKUP:                 DW_AT_decl_file	(0x00)
+# LOOKUP:                 DW_AT_decl_line	(6)
+# LOOKUP:                 DW_AT_type	(0x00000050 "int")
+# LOOKUP:                 DW_AT_external	(true)
+# LOOKUP: Line info: line 0, column 0, start file 'dump_dwo.cpp', start line 6
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 5360cf70b98ebf..6a633ea9f29a76 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -181,13 +181,12 @@ static opt<bool> FindAllApple(
 static opt<bool> IgnoreCase("ignore-case",
                             desc("Ignore case distinctions when using --name."),
                             value_desc("i"), cat(DwarfDumpCategory));
-static opt<bool> DumpNonSkeleton("dwo",
-                            desc("Dump the non skeleton DIE in the .dwo or "
-                                 ".dwp file after dumping the skeleton DIE "
-                                 "from the main executable. This allows "
-                                 "dumping the .dwo files with resolved "
-                                 "addresses."),
-                            value_desc("d"), cat(DwarfDumpCategory));
+static opt<bool> DumpNonSkeleton(
+    "dwo",
+    desc("Dump the non skeleton DIE in the .dwo or .dwp file after dumping the "
+         "skeleton DIE from the main executable. This allows dumping the .dwo "
+         "files with resolved addresses."),
+    value_desc("d"), cat(DwarfDumpCategory));
 
 static alias IgnoreCaseAlias("i", desc("Alias for --ignore-case."),
                              aliasopt(IgnoreCase), cl::NotHidden);
@@ -399,29 +398,25 @@ static void filterByName(
     const StringSet<> &Names, DWARFContext::unit_iterator_range CUs,
     raw_ostream &OS,
     std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
-  for (const auto &CU : CUs) {
-    for (const auto &Entry : CU->dies()) {
-      DWARFDie Die = {CU.get(), &Entry};
+  auto filterDieNames = [&](DWARFUnit *Unit) {
+    for (const auto &Entry : Unit->dies()) {
+      DWARFDie Die = {Unit, &Entry};
       if (const char *Name = Die.getName(DINameKind::ShortName))
         if (filterByName(Names, Die, Name, OS, GetNameForDWARFReg))
           continue;
       if (const char *Name = Die.getName(DINameKind::LinkageName))
         filterByName(Names, Die, Name, OS, GetNameForDWARFReg);
     }
+
+  };
+  for (const auto &CU : CUs) {
+    filterDieNames(CU.get());
     // If we have split DWARF, then recurse down into the .dwo files as well.
     DWARFDie CUDie = CU->getUnitDIE(false);
     DWARFDie CUNonSkeletonDie = CU->getNonSkeletonUnitDIE(false);
-    if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
-      // We have a DWO file, we need to search it as well
-      for (const auto &Entry : CUNonSkeletonDie.getDwarfUnit()->dies()) {
-        DWARFDie Die = {CUNonSkeletonDie.getDwarfUnit(), &Entry};
-        if (const char *Name = Die.getShortName())
-          if (filterByName(Names, Die, Name, OS, GetNameForDWARFReg))
-            continue;
-        if (const char *Name = Die.getLinkageName())
-          filterByName(Names, Die, Name, OS, GetNameForDWARFReg);
-      }
-    }
+    // If we have a DWO file, we need to search it as well
+    if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie)
+      filterDieNames(CUNonSkeletonDie.getDwarfUnit());
   }
 }
 

>From d456d5cb24387a7649e2d6ee7816313228e6b81e Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Mon, 18 Dec 2023 21:34:16 -0800
Subject: [PATCH 3/3] Remove extra whitespace.

---
 llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 97cb303d92c172..1ade9b3852c033 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1032,7 +1032,6 @@ void DWARFContext::dump(
         if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
           CUNonSkeletonDie.getDwarfUnit()->getDIEForOffset(*DumpOffset)
               .dump(OS, 0, DumpOpts.noImplicitRecursion());
-
         }
       }
     else



More information about the llvm-commits mailing list