Skip to content

Reapply "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#… (#145959) #146112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 27, 2025

Conversation

Sterling-Augustine
Copy link
Contributor

Reapply "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#… (#145959)

This reapplies cbf781f, with fixes for the shared-library build and the unconventional sanitizer-runtime build.

Original Description:

This is the culmination of a series of changes described in [1].

Although somewhat large by line count, it is almost entirely mechanical, creating a new library in DebugInfo/DWARF/LowLevel. This new library has very minimal dependencies, allowing it to be used from more places than the normal DebugInfo/DWARF library--in particular from MC.

  1. https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2

@llvmbot
Copy link
Member

llvmbot commented Jun 27, 2025

@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-lldb
@llvm/pr-subscribers-compiler-rt-sanitizer
@llvm/pr-subscribers-debuginfo
@llvm/pr-subscribers-pgo

@llvm/pr-subscribers-bolt

Author: None (Sterling-Augustine)

Changes

Reapply "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#… (#145959)

This reapplies cbf781f, with fixes for the shared-library build and the unconventional sanitizer-runtime build.

Original Description:

This is the culmination of a series of changes described in [1].

Although somewhat large by line count, it is almost entirely mechanical, creating a new library in DebugInfo/DWARF/LowLevel. This new library has very minimal dependencies, allowing it to be used from more places than the normal DebugInfo/DWARF library--in particular from MC.

  1. https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2

Patch is 97.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146112.diff

57 Files Affected:

  • (modified) bolt/include/bolt/Core/DIEBuilder.h (+1-1)
  • (modified) bolt/lib/Core/CMakeLists.txt (+1)
  • (modified) bolt/lib/Core/DIEBuilder.cpp (+1-1)
  • (modified) bolt/lib/Core/DebugNames.cpp (+1-1)
  • (modified) bolt/lib/Rewrite/CMakeLists.txt (+1)
  • (modified) bolt/lib/Rewrite/DWARFRewriter.cpp (+1-1)
  • (modified) compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh (+1)
  • (modified) lldb/source/Expression/DWARFExpression.cpp (+3-2)
  • (modified) lldb/source/Symbol/UnwindPlan.cpp (+3-3)
  • (modified) lldb/unittests/Symbol/PostfixExpressionTest.cpp (+3-2)
  • (modified) lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp (+3-2)
  • (modified) llvm/include/llvm/DWARFLinker/AddressesMap.h (+1-1)
  • (modified) llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h (+1-1)
  • (modified) llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h (+1-1)
  • (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h (+1-1)
  • (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h (+1-1)
  • (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h (+2-2)
  • (added) llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h (+66)
  • (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h (+1-1)
  • (renamed) llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h (+146-4)
  • (renamed) llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h ()
  • (renamed) llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h (+1-62)
  • (modified) llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt (+1)
  • (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (+1-1)
  • (modified) llvm/lib/DWARFLinker/Classic/CMakeLists.txt (+1)
  • (modified) llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp (+1-1)
  • (modified) llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp (+1-1)
  • (modified) llvm/lib/DWARFLinker/Parallel/CMakeLists.txt (+1)
  • (modified) llvm/lib/DebugInfo/DWARF/CMakeLists.txt (+4-2)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp (+3-3)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (+4-3)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp (+3-2)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFDie.cpp (+3-2)
  • (removed) llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp (-538)
  • (added) llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp (+311)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp (+1-1)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp (+1-1)
  • (added) llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt (+14)
  • (renamed) llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp (+2-146)
  • (added) llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp (+253)
  • (modified) llvm/lib/DebugInfo/LogicalView/CMakeLists.txt (+2-1)
  • (modified) llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp (+3-3)
  • (modified) llvm/lib/ProfileData/CMakeLists.txt (+1)
  • (modified) llvm/lib/ProfileData/InstrProfCorrelator.cpp (+1-1)
  • (modified) llvm/tools/dsymutil/CMakeLists.txt (+1)
  • (modified) llvm/tools/dsymutil/DwarfLinkerForBinary.cpp (+1-1)
  • (modified) llvm/tools/llvm-dwarfdump/CMakeLists.txt (+1)
  • (modified) llvm/tools/llvm-dwarfdump/Statistics.cpp (+1-1)
  • (modified) llvm/tools/llvm-dwarfutil/CMakeLists.txt (+1)
  • (modified) llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp (+1-1)
  • (modified) llvm/tools/llvm-objdump/CMakeLists.txt (+1)
  • (modified) llvm/tools/llvm-objdump/SourcePrinter.cpp (+3-2)
  • (modified) llvm/unittests/DebugInfo/DWARF/CMakeLists.txt (+1)
  • (modified) llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp (+3-2)
  • (modified) llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp (+1-1)
  • (modified) utils/bazel/llvm-project-overlay/bolt/BUILD.bazel (+2)
  • (modified) utils/bazel/llvm-project-overlay/llvm/BUILD.bazel (+24)
diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h
index 32e455ad3030a..e4a4fc6b2f258 100644
--- a/bolt/include/bolt/Core/DIEBuilder.h
+++ b/bolt/include/bolt/Core/DIEBuilder.h
@@ -20,8 +20,8 @@
 #include "llvm/CodeGen/DIE.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Allocator.h"
 
 #include <list>
diff --git a/bolt/lib/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index 8c1f5d0bb37b5..fc72dc023c590 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -1,5 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   Demangle
   MC
   MCDisassembler
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index d36dbb3459249..b041dc5ea1cce 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -14,11 +14,11 @@
 #include "llvm/CodeGen/DIE.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp
index aa1c8f3d42d4b..a9d98a6ba879b 100644
--- a/bolt/lib/Core/DebugNames.cpp
+++ b/bolt/lib/Core/DebugNames.cpp
@@ -8,8 +8,8 @@
 
 #include "bolt/Core/DebugNames.h"
 #include "bolt/Core/BinaryContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/EndianStream.h"
 #include "llvm/Support/LEB128.h"
 #include <cstdint>
diff --git a/bolt/lib/Rewrite/CMakeLists.txt b/bolt/lib/Rewrite/CMakeLists.txt
index c83cf36982167..775036063dd5a 100644
--- a/bolt/lib/Rewrite/CMakeLists.txt
+++ b/bolt/lib/Rewrite/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   Core
   DebugInfoDWARF
+  DebugInfoDWARFLowLevel
   JITLink
   MC
   Object
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 9c9bdefe08429..0c1a1bac6c72e 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -24,10 +24,10 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCObjectWriter.h"
diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh
index fe49d944d3a2f..4d435976d3a10 100755
--- a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh
+++ b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh
@@ -174,6 +174,7 @@ $LINK $LIBCXX_ARCHIVE_DIR/libc++.a \
       $LLVM_BUILD/lib/libLLVMObject.a \
       $LLVM_BUILD/lib/libLLVMBinaryFormat.a \
       $LLVM_BUILD/lib/libLLVMDebugInfoDWARF.a \
+      $LLVM_BUILD/lib/libLLVMDebugInfoDWARFLowLevel.a \
       $LLVM_BUILD/lib/libLLVMDebugInfoGSYM.a \
       $LLVM_BUILD/lib/libLLVMSupport.a \
       $LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 661324338e801..2df27513a0b3f 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -36,7 +36,8 @@
 #include "lldb/Target/StackID.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -81,7 +82,7 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
   llvm::DIDumpOptions DumpOpts;
   DumpOpts.GetNameForDWARFReg = GetRegName;
   llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
-  llvm::DWARFExpressionPrinter::print(&E, s->AsRawOstream(), DumpOpts, nullptr);
+  llvm::printDwarfExpression(&E, s->AsRawOstream(), DumpOpts, nullptr);
 }
 
 RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index e9ac6b6cde295..9245e52732061 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -17,7 +17,8 @@
 #include "lldb/Utility/Log.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include <optional>
 
 using namespace lldb;
@@ -89,8 +90,7 @@ static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *threa
                              order_and_width->second);
     llvm::DWARFExpression E(data, order_and_width->second,
                             llvm::dwarf::DWARF32);
-    llvm::DWARFExpressionPrinter::print(&E, s.AsRawOstream(),
-                                        llvm::DIDumpOptions(), nullptr);
+    printDwarfExpression(&E, s.AsRawOstream(), llvm::DIDumpOptions(), nullptr);
   } else
     s.PutCString("dwarf-expr");
 }
diff --git a/lldb/unittests/Symbol/PostfixExpressionTest.cpp b/lldb/unittests/Symbol/PostfixExpressionTest.cpp
index 1e437da5133d9..f60b5d2c389ed 100644
--- a/lldb/unittests/Symbol/PostfixExpressionTest.cpp
+++ b/lldb/unittests/Symbol/PostfixExpressionTest.cpp
@@ -11,7 +11,8 @@
 #include "lldb/Utility/StreamString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/raw_ostream.h"
 #include "gmock/gmock.h"
@@ -160,7 +161,7 @@ static std::string ParseAndGenerateDWARF(llvm::StringRef expr) {
   std::string result;
   llvm::raw_string_ostream os(result);
   llvm::DWARFExpression E(extractor, addr_size, llvm::dwarf::DWARF32);
-  llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
+  llvm::printDwarfExpression(&E, os, llvm::DIDumpOptions(), nullptr);
   return result;
 }
 
diff --git a/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp b/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
index d746e04f8a9fc..c60688ef22939 100644
--- a/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
+++ b/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp
@@ -16,7 +16,8 @@
 #include "lldb/Utility/StreamBuffer.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -40,7 +41,7 @@ CheckValidProgramTranslation(llvm::StringRef fpo_program,
   std::string result;
   llvm::raw_string_ostream os(result);
   llvm::DWARFExpression E(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32);
-  llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
+  llvm::printDwarfExpression(&E, os, llvm::DIDumpOptions(), nullptr);
 
   // actual check
   ASSERT_EQ(expected_dwarf_expression, result);
diff --git a/llvm/include/llvm/DWARFLinker/AddressesMap.h b/llvm/include/llvm/DWARFLinker/AddressesMap.h
index a232aafadc5ce..e2215c70dc34e 100644
--- a/llvm/include/llvm/DWARFLinker/AddressesMap.h
+++ b/llvm/include/llvm/DWARFLinker/AddressesMap.h
@@ -12,8 +12,8 @@
 #include "llvm/ADT/AddressRanges.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include <cstdint>
 
 namespace llvm {
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
index b12d96812108e..5b9535380aebf 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
@@ -20,7 +20,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include <map>
 
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
index 17a18c4b029f4..99aeb0df076e6 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h
@@ -16,7 +16,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include <map>
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h
index 4723f00a4d241..7d4bf8d923097 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIPrinter.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
 #define LLVM_DEBUGINFO_DWARF_DWARFCFIPRINTER_H
 
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
 #include "llvm/Support/Compiler.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
index 005ccd208cdda..def291046c7db 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -10,10 +10,10 @@
 #define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H
 
 #include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h"
 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
 #include "llvm/Support/Compiler.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index 3b367009a379d..e0d60f605964f 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -12,8 +12,8 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/iterator.h"
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 #include "llvm/TargetParser/Triple.h"
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
new file mode 100644
index 0000000000000..0aad492d47551
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
@@ -0,0 +1,66 @@
+//===--- DWARFExpressionPRinter.h - DWARF Expression Printing ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
+#define LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+// This functionality is separated from the main data structure so that nothing
+// in DWARFExpression.cpp needs build-time dependencies on DWARFUnit or other
+// higher-level Dwarf structures. This approach creates better layering and
+// allows DWARFExpression to be used from code which can't have dependencies on
+// those higher-level structures.
+
+class DWARFUnit;
+struct DIDumpOptions;
+class raw_ostream;
+
+/// Print a Dwarf expression/
+/// \param E to be printed
+/// \param OS to this stream
+/// \param GetNameForDWARFReg callback to return dwarf register name
+LLVM_ABI void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
+                                   DIDumpOptions DumpOpts, DWARFUnit *U,
+                                   bool IsEH = false);
+
+/// Print the expression in a format intended to be compact and useful to a
+/// user, but not perfectly unambiguous, or capable of representing every
+/// valid DWARF expression. Returns true if the expression was sucessfully
+/// printed.
+///
+/// \param E to be printed
+/// \param OS to this stream
+/// \param GetNameForDWARFReg callback to return dwarf register name
+///
+/// \returns true if the expression was successfully printed
+LLVM_ABI bool printDwarfExpressionCompact(
+    const DWARFExpression *E, raw_ostream &OS,
+    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
+        nullptr);
+
+/// Pretty print a register opcode and operands.
+/// \param U within the context of this Dwarf unit, if any.
+/// \param OS to this stream
+/// \param DumpOpts with these options
+/// \param Opcode to print
+/// \param Operands to the opcode
+///
+/// returns true if the Op was successfully printed
+LLVM_ABI bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
+                                    DIDumpOptions DumpOpts, uint8_t Opcode,
+                                    ArrayRef<uint64_t> Operands);
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSIONPRINTER_H
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
index 8e1b9589a5d76..f667496ab1059 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -14,8 +14,8 @@
 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include <cstdint>
 #include <map>
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIProgram.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
similarity index 50%
rename from llvm/include/llvm/DebugInfo/DWARF/DWARFCFIProgram.h
rename to llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
index 1d89ac3578c10..bdad0b5ad7a5a 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFCFIProgram.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h
@@ -12,8 +12,8 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/iterator.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 #include "llvm/TargetParser/Triple.h"
@@ -78,8 +78,150 @@ class CFIProgram {
   /// starting at *Offset and ending at EndOffset. *Offset is updated
   /// to EndOffset upon successful parsing, or indicates the offset
   /// where a problem occurred in case an error is returned.
-  LLVM_ABI Error parse(DWARFDataExtractor Data, uint64_t *Offset,
-                       uint64_t EndOffset);
+  template <typename T>
+  LLVM_ABI Error parse(DWARFDataExtractorBase<T> &Data, uint64_t *Offset,
+                       uint64_t EndOffset) {
+    // See DWARF standard v3, section 7.23
+    const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
+    const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
+
+    DataExtractor::Cursor C(*Offset);
+    while (C && C.tell() < EndOffset) {
+      uint8_t Opcode = Data.getRelocatedValue(C, 1);
+      if (!C)
+        break;
+
+      // Some instructions have a primary opcode encoded in the top bits.
+      if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
+        // If it's a primary opcode, the first operand is encoded in the
+        // bottom bits of the opcode itself.
+        uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
+        switch (Primary) {
+        case DW_CFA_advance_loc:
+        case DW_CFA_restore:
+          addInstruction(Primary, Op1);
+          break;
+        case DW_CFA_offset:
+          addInstruction(Primary, Op1, Data.getULEB128(C));
+          break;
+        default:
+          llvm_unreachable("invalid primary CFI opcode");
+        }
+        continue;
+      }
+
+      // Extended opcode - its value is Opcode itself.
+      switch (Opcode) {
+      default:
+        return createStringError(errc::illegal_byte_sequence,
+                                 "invalid extended CFI opcode 0x%" PRIx8,
+                                 Opcode);
+      case DW_CFA_nop:
+      case DW_CFA_remember_state:
+      case DW_CFA_restore_state:
+      case DW_CFA_GNU_window_save:
+      case DW_CFA_AARCH64_negate_ra_state_with_pc:
+        // No operands
+        addInstruction(Opcode);
+        break;
+      case DW_CFA_set_loc:
+        // Operands: Address
+        addInstruction(Opcode, Data.getRelocatedAddress(C));
+        break;
+      case DW_CFA_advance_loc1:
+        // Operands: 1-byte delta
+        addInstruction(Opcode, Data.getRelocatedValue(C, 1));
+        break;
+      case DW_CFA_advance_loc2:
+        // Operands: 2-byte delta
+        addInstruction(Opcode, Data.getRelocatedValue(C, 2));
+        break;
+      case DW_CFA_advance_loc4:
+        // Operands: 4-byte delta
+        addInstruction(Opcode, Data.getRelocatedValue(C, 4));
+        break;
+      case DW_CFA_restore_extended:
+      case DW_CFA_undefined:
+      case DW_CFA_same_value:
+      case DW_CFA_def_cfa_register:
+      case DW_CFA_def_cfa_offset:
+      case DW_CFA_GNU_args_size:
+        // Operands: ULEB128
+        addInstruction(Opcode, Data.getULEB128(C));
+        break;
+      case DW_CFA_def_cfa_offset_sf:
+        // Operands: SLEB128
+        addInstruction(Opcode, Data.getSLEB128(C));
+        break;
+      case DW_CFA_LLVM_def_aspace_cfa:
+      case DW_CFA_LLVM_def_aspace_cfa_sf: {
+        auto RegNum = Data.getULEB128(C);
+        auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
+                             ? Data.getULEB128(C)
+                             : Data.getSLEB128(C);
+        auto AddressSpace = Data.getULEB128(C);
+        addInstruction(Opcode, RegNum, CfaOffset, AddressSpace);
+        break;
+      }
+      case DW_CFA_offset_extended:
+      case DW_CFA_register:
+      case DW_CFA_def_cfa:
+      case DW_CFA_val_offset: {
+        // Operands: ULEB128, ULEB128
+        // Note: We can not embed getULEB128 direc...
[truncated]

@Sterling-Augustine Sterling-Augustine merged commit 23f1ba3 into llvm:main Jun 27, 2025
17 checks passed
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Jun 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bazel "Peripheral" support tier build system: utils/bazel BOLT compiler-rt:sanitizer compiler-rt debuginfo lldb llvm:binary-utilities llvm:codegen PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants