[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
Fri Jan 12 13:31:09 PST 2024


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

>From 4ca787f47ef4276c2082d86b580c2a3706d1a2ef 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/5] 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 4d9429bbef51d880448f1beb849976b66d80b093 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/5] 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 65aeee1f9e2c298dbf07c23f5d076a912f60b9ee 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/5] 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

>From a5beb64451b3f86680a565b25de3604524f1ae15 Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Mon, 18 Dec 2023 21:42:08 -0800
Subject: [PATCH 4/5] run clang format.

---
 llvm/lib/DebugInfo/DWARF/DWARFContext.cpp    | 3 ++-
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 1 -
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 1ade9b3852c033..38d21f1c8a8c7a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1030,7 +1030,8 @@ void DWARFContext::dump(
         DWARFDie CUDie = U->getUnitDIE(false);
         DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);
         if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
-          CUNonSkeletonDie.getDwarfUnit()->getDIEForOffset(*DumpOffset)
+          CUNonSkeletonDie.getDwarfUnit()
+              ->getDIEForOffset(*DumpOffset)
               .dump(OS, 0, DumpOpts.noImplicitRecursion());
         }
       }
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 6a633ea9f29a76..1decb5f7a0c288 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -407,7 +407,6 @@ static void filterByName(
       if (const char *Name = Die.getName(DINameKind::LinkageName))
         filterByName(Names, Die, Name, OS, GetNameForDWARFReg);
     }
-
   };
   for (const auto &CU : CUs) {
     filterDieNames(CU.get());

>From dfd5728c253481cc6e2f4686cd8f1e01db9512d5 Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Tue, 19 Dec 2023 14:23:00 -0800
Subject: [PATCH 5/5] Fix review comments:

- Revert changes to `DWARFUnit::getSubroutineForAddress(...)`
- Add a "bool CheckDWO" argument to the `DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address)` function to allow the DWO file to be searched first if needed since the DWO file usually has more information. The parameter is defaulted to `false`.
- Fix the address lookup calls in llvm-dwarfdump to pass the DumpNonSkeleton bool value to `DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address, bool CheckDWO)`
- Add tests that verify --name lookups fail when --dwo is not specified, and succeeds when it is
- Add tests that verify --lookup finds info in the skeleton compile unit when --dwo isn't specified and succeeds when it is in finding info from the split compile unit.
---
 .../llvm/DebugInfo/DWARF/DWARFContext.h       |  8 ++-
 llvm/lib/DebugInfo/DWARF/DWARFContext.cpp     | 29 ++++++++--
 llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp        |  2 +-
 llvm/test/tools/llvm-dwarfdump/dump_dwo.test  | 54 ++++++++++++++-----
 llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp  | 16 +++---
 5 files changed, 84 insertions(+), 25 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index fa98cbcfc4d997..7be65a8b45e2d6 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -372,7 +372,13 @@ class DWARFContext : public DIContext {
   /// given address where applicable.
   /// TODO: change input parameter from "uint64_t Address"
   ///       into "SectionedAddress Address"
-  DIEsForAddress getDIEsForAddress(uint64_t Address);
+  /// \param[in] CheckDWO If this is false then only search for address matches
+  ///            in the current context's DIEs. If this is true, then each
+  ///            DWARFUnit that has a DWO file will have the debug info in the
+  ///            DWO file searched as well. This allows for lookups to succeed
+  ///            by searching the split DWARF debug info when using the main
+  ///            executable's debug info.
+  DIEsForAddress getDIEsForAddress(uint64_t Address, bool CheckDWO = false);
 
   DILineInfo getLineInfoForAddress(
       object::SectionedAddress Address,
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 38d21f1c8a8c7a..e6df590b8dd7a0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1545,15 +1545,38 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
   return nullptr;
 }
 
-DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
+DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address,
+                                                             bool CheckDWO) {
   DIEsForAddress Result;
 
   DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address);
   if (!CU)
     return Result;
 
-  Result.CompileUnit = CU;
-  Result.FunctionDIE = CU->getSubroutineForAddress(Address);
+  if (CheckDWO) {
+    // We were asked to check the DWO file and this debug information is more
+    // complete that any information in the skeleton compile unit, so search the
+    // DWO first to see if we have a match.
+    DWARFDie CUDie = CU->getUnitDIE(false);
+    DWARFDie CUDwoDie = CU->getNonSkeletonUnitDIE(false);
+    if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {
+      // We have a DWO file, lets search it.
+      DWARFCompileUnit *CUDwo =
+          dyn_cast_or_null<DWARFCompileUnit>(CUDwoDie.getDwarfUnit());
+      if (CUDwo) {
+        Result.FunctionDIE = CUDwo->getSubroutineForAddress(Address);
+        if (Result.FunctionDIE)
+          Result.CompileUnit = CUDwo;
+      }
+    }
+  }
+
+  // Search the normal DWARF if we didn't find a match in the DWO file or if
+  // we didn't check the DWO file above.
+  if (!Result) {
+    Result.CompileUnit = CU;
+    Result.FunctionDIE = CU->getSubroutineForAddress(Address);
+  }
 
   std::vector<DWARFDie> Worklist;
   Worklist.push_back(Result.FunctionDIE);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 031d6441d733c1..9f455fa7e96a7e 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(getNonSkeletonUnitDIE(/*ExtractUnitDIEOnly=*/false));
+    updateAddressDieMap(getUnitDIE());
   auto R = AddrDieMap.upper_bound(Address);
   if (R == AddrDieMap.begin())
     return DWARFDie();
diff --git a/llvm/test/tools/llvm-dwarfdump/dump_dwo.test b/llvm/test/tools/llvm-dwarfdump/dump_dwo.test
index 3c233c7bc6c4e5..a42499003dce9a 100644
--- a/llvm/test/tools/llvm-dwarfdump/dump_dwo.test
+++ b/llvm/test/tools/llvm-dwarfdump/dump_dwo.test
@@ -3,11 +3,17 @@
 # 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
+# RUN: cd %T
+# RUN: llvm-dwarfdump --dwo dump_dwo.o | FileCheck %s
+# RUN: llvm-dwarfdump --dwo --name int --name char dump_dwo.o | FileCheck %s --check-prefix=NAMES
+# RUN: llvm-dwarfdump --name int --name char dump_dwo.o | FileCheck %s --check-prefix=NAMES_NO_DWO
+# RUN: llvm-dwarfdump --dwo --lookup 0x10 dump_dwo.o | FileCheck %s --check-prefix=LOOKUP
+# RUN: llvm-dwarfdump --lookup 0x10 dump_dwo.o | FileCheck %s --check-prefix=LOOKUP_NO_DWO
 
 
+## Make sure if we dump dump_dwo.o with the --dwo option that we see the
+## contents of the dump_dwo.o _and_ the dump_dwo.dwo file.
+
 # 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)
 
@@ -86,6 +92,9 @@
 # CHECK: 0x00000067:   NULL
 
 
+## Make sure that if we do specify the --dwo when using --name that we get
+## the expected results form the .dwo file
+
 # NAMES: 0x00000050: DW_TAG_base_type
 # NAMES:               DW_AT_name	("int")
 # NAMES:               DW_AT_encoding	(DW_ATE_signed)
@@ -96,18 +105,22 @@
 # NAMES:               DW_AT_encoding	(DW_ATE_signed_char)
 # NAMES:               DW_AT_byte_size	(0x01)
 
+## Make sure that if we don't specify the --dwo when using --name that we get
+## no results
 
-# 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)
+# NAMES_NO_DWO-NOT:  0x00000050: DW_TAG_base_type
+# NAMES_NO_DWO-NOT:  0x00000063: DW_TAG_base_type
 
-# 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)
+## Make sure address lookups succeed when using the --dwo option and the
+## --lookup option. Verify that we see the information from the .dwo file which
+## means "unit_type = DW_UT_split_compile" and that we see a DW_TAG_compile_unit
+# LOOKUP: 0x00000000: Compile Unit: length = 0x00000064, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = 0x376dd35da7c3c136 (next unit at 0x00000068)
+
+# LOOKUP: 0x00000014: DW_TAG_compile_unit
+# LOOKUP:               DW_AT_producer	("Apple clang version 15.0.0 (clang-1500.1.0.2.5)")
+# LOOKUP:               DW_AT_language	(DW_LANG_C_plus_plus)
+# LOOKUP:               DW_AT_name	("dump_dwo.cpp")
 # 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)
@@ -118,4 +131,19 @@
 # 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
+
+## Make sure address lookups succeed when not using the --dwo option and the
+## --lookup option. Verify that we see the information from the .o file which
+## Means "unit_type = DW_UT_skeleton" and that we see a DW_TAG_skeleton_unit
+
+# LOOKUP_NO_DWO: 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_NO_DWO: 0x00000014: DW_TAG_skeleton_unit
+# LOOKUP_NO_DWO:               DW_AT_stmt_list	(0x00000000)
+# LOOKUP_NO_DWO:               DW_AT_str_offsets_base	(0x00000008)
+# LOOKUP_NO_DWO:               DW_AT_comp_dir	("./")
+# LOOKUP_NO_DWO:               DW_AT_GNU_pubnames	(true)
+# LOOKUP_NO_DWO:               DW_AT_dwo_name	("./dump_dwo.dwo")
+# LOOKUP_NO_DWO:               DW_AT_low_pc	(0x0000000000000000)
+# LOOKUP_NO_DWO:               DW_AT_high_pc	(0x0000000000000033)
+# LOOKUP_NO_DWO:               DW_AT_addr_base	(0x00000008)
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 1decb5f7a0c288..941df4eb184457 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -410,12 +410,14 @@ static void filterByName(
   };
   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 we have a DWO file, we need to search it as well
-    if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie)
-      filterDieNames(CUNonSkeletonDie.getDwarfUnit());
+    if (DumpNonSkeleton) {
+      // 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 we have a DWO file, we need to search it as well
+      if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie)
+        filterDieNames(CUNonSkeletonDie.getDwarfUnit());
+    }
   }
 }
 
@@ -517,7 +519,7 @@ static void findAllApple(
 /// information or probably display all matched entries, or something else...
 static bool lookup(ObjectFile &Obj, DWARFContext &DICtx, uint64_t Address,
                    raw_ostream &OS) {
-  auto DIEsForAddr = DICtx.getDIEsForAddress(Lookup);
+  auto DIEsForAddr = DICtx.getDIEsForAddress(Lookup, DumpNonSkeleton);
 
   if (!DIEsForAddr)
     return false;



More information about the llvm-commits mailing list