[Lldb-commits] [compiler-rt] [lldb] [llvm] Add missing dependencies from bazel build (PR #146138)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jun 27 11:54:28 PDT 2025
https://github.com/Sterling-Augustine created https://github.com/llvm/llvm-project/pull/146138
As in the description.
>From 031cc5cf22fb2998207e9d9c85d04e9f829fd06e Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Thu, 26 Jun 2025 13:47:04 -0700
Subject: [PATCH 1/2] =?UTF-8?q?Reapply=20"[NFC][DebugInfo][DWARF]=20Create?=
=?UTF-8?q?=20new=20low-level=20dwarf=20library=20(#=E2=80=A6=20(#145959)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit 5d03e7a2047c0927037275418ae340d83f5c70fb, with several fixes
for additional breakage.
---
bolt/include/bolt/Core/DIEBuilder.h | 2 +-
bolt/lib/Core/CMakeLists.txt | 1 +
bolt/lib/Core/DIEBuilder.cpp | 2 +-
bolt/lib/Core/DebugNames.cpp | 2 +-
bolt/lib/Rewrite/CMakeLists.txt | 1 +
bolt/lib/Rewrite/DWARFRewriter.cpp | 2 +-
lldb/source/Expression/DWARFExpression.cpp | 5 +-
lldb/source/Symbol/UnwindPlan.cpp | 6 +-
.../Symbol/PostfixExpressionTest.cpp | 5 +-
.../PdbFPOProgramToDWARFExpressionTests.cpp | 5 +-
llvm/include/llvm/DWARFLinker/AddressesMap.h | 2 +-
.../llvm/DWARFLinker/Classic/DWARFLinker.h | 2 +-
.../llvm/DWARFLinker/DWARFLinkerBase.h | 2 +-
.../llvm/DebugInfo/DWARF/DWARFCFIPrinter.h | 2 +-
.../llvm/DebugInfo/DWARF/DWARFDataExtractor.h | 2 +-
.../llvm/DebugInfo/DWARF/DWARFDebugFrame.h | 4 +-
.../DebugInfo/DWARF/DWARFExpressionPrinter.h | 66 +++
.../llvm/DebugInfo/DWARF/DWARFVerifier.h | 2 +-
.../DWARF/{ => LowLevel}/DWARFCFIProgram.h | 150 ++++-
.../{ => LowLevel}/DWARFDataExtractorSimple.h | 0
.../DWARF/{ => LowLevel}/DWARFExpression.h | 63 +-
llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt | 1 +
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 2 +-
llvm/lib/DWARFLinker/Classic/CMakeLists.txt | 1 +
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 2 +-
.../Classic/DWARFLinkerCompileUnit.cpp | 2 +-
llvm/lib/DebugInfo/DWARF/CMakeLists.txt | 6 +-
llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp | 6 +-
llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 7 +-
llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 5 +-
llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 5 +-
llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp | 538 ------------------
.../DWARF/DWARFExpressionPrinter.cpp | 311 ++++++++++
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 2 +-
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 2 +-
.../DebugInfo/DWARF/LowLevel/CMakeLists.txt | 14 +
.../DWARF/{ => LowLevel}/DWARFCFIProgram.cpp | 148 +----
.../DWARF/LowLevel/DWARFExpression.cpp | 253 ++++++++
.../LogicalView/Readers/LVDWARFReader.cpp | 6 +-
llvm/lib/ProfileData/CMakeLists.txt | 1 +
llvm/lib/ProfileData/InstrProfCorrelator.cpp | 2 +-
llvm/tools/dsymutil/CMakeLists.txt | 1 +
llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 2 +-
llvm/tools/llvm-dwarfdump/CMakeLists.txt | 1 +
llvm/tools/llvm-dwarfdump/Statistics.cpp | 2 +-
llvm/tools/llvm-dwarfutil/CMakeLists.txt | 1 +
llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 2 +-
llvm/tools/llvm-objdump/CMakeLists.txt | 1 +
llvm/tools/llvm-objdump/SourcePrinter.cpp | 5 +-
llvm/unittests/DebugInfo/DWARF/CMakeLists.txt | 1 +
.../DWARFExpressionCompactPrinterTest.cpp | 5 +-
.../DWARF/DWARFExpressionCopyBytesTest.cpp | 2 +-
.../llvm-project-overlay/bolt/BUILD.bazel | 2 +
.../llvm-project-overlay/llvm/BUILD.bazel | 24 +
54 files changed, 889 insertions(+), 800 deletions(-)
create mode 100644 llvm/include/llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h
rename llvm/include/llvm/DebugInfo/DWARF/{ => LowLevel}/DWARFCFIProgram.h (50%)
rename llvm/include/llvm/DebugInfo/DWARF/{ => LowLevel}/DWARFDataExtractorSimple.h (100%)
rename llvm/include/llvm/DebugInfo/DWARF/{ => LowLevel}/DWARFExpression.h (67%)
delete mode 100644 llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
create mode 100644 llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
create mode 100644 llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
rename llvm/lib/DebugInfo/DWARF/{ => LowLevel}/DWARFCFIProgram.cpp (60%)
create mode 100644 llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
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/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 directly into function
+ // argument list. getULEB128 changes Offset and order of evaluation
+ // for arguments is unspecified.
+ uint64_t op1 = Data.getULEB128(C);
+ uint64_t op2 = Data.getULEB128(C);
+ addInstruction(Opcode, op1, op2);
+ break;
+ }
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_val_offset_sf: {
+ // Operands: ULEB128, SLEB128
+ // Note: see comment for the previous case
+ uint64_t op1 = Data.getULEB128(C);
+ uint64_t op2 = (uint64_t)Data.getSLEB128(C);
+ addInstruction(Opcode, op1, op2);
+ break;
+ }
+ case DW_CFA_def_cfa_expression: {
+ uint64_t ExprLength = Data.getULEB128(C);
+ addInstruction(Opcode, 0);
+ StringRef Expression = Data.getBytes(C, ExprLength);
+
+ DataExtractor Extractor(Expression, Data.isLittleEndian(),
+ Data.getAddressSize());
+ // Note. We do not pass the DWARF format to DWARFExpression, because
+ // DW_OP_call_ref, the only operation which depends on the format, is
+ // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
+ Instructions.back().Expression =
+ DWARFExpression(Extractor, Data.getAddressSize());
+ break;
+ }
+ case DW_CFA_expression:
+ case DW_CFA_val_expression: {
+ uint64_t RegNum = Data.getULEB128(C);
+ addInstruction(Opcode, RegNum, 0);
+
+ uint64_t BlockLength = Data.getULEB128(C);
+ StringRef Expression = Data.getBytes(C, BlockLength);
+ DataExtractor Extractor(Expression, Data.isLittleEndian(),
+ Data.getAddressSize());
+ // Note. We do not pass the DWARF format to DWARFExpression, because
+ // DW_OP_call_ref, the only operation which depends on the format, is
+ // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
+ Instructions.back().Expression =
+ DWARFExpression(Extractor, Data.getAddressSize());
+ break;
+ }
+ }
+ }
+
+ *Offset = C.tell();
+ return C.takeError();
+ }
void addInstruction(const Instruction &I) { Instructions.push_back(I); }
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h
similarity index 100%
rename from llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractorSimple.h
rename to llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
similarity index 67%
rename from llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
rename to llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
index ea414278c35d6..06840b20f9690 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
@@ -65,7 +65,7 @@ class DWARFExpression {
/// Description of the encoding of one expression Op.
struct Description {
- DwarfVersion Version; ///< Dwarf version where the Op was introduced.
+ DwarfVersion Version; ///< Dwarf version where the Op was introduced.
SmallVector<Encoding> Op; ///< Encoding for Op operands.
template <typename... Ts>
@@ -77,7 +77,6 @@ class DWARFExpression {
private:
friend class DWARFExpression::iterator;
- friend class DWARFExpressionPrinter;
friend class DWARFVerifier;
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
@@ -156,7 +155,6 @@ class DWARFExpression {
StringRef getData() const { return Data.getData(); }
- friend class DWARFExpressionPrinter;
friend class DWARFVerifier;
private:
@@ -170,65 +168,6 @@ inline bool operator==(const DWARFExpression::iterator &LHS,
return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
}
-// 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;
-
-class DWARFExpressionPrinter {
-public:
- /// Print a Dwarf expression/
- /// \param E to be printed
- /// \param OS to this stream
- /// \param GetNameForDWARFReg callback to return dwarf register name
- LLVM_ABI static void print(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 static bool printCompact(
- 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 static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
- DIDumpOptions DumpOpts,
- uint8_t Opcode,
- ArrayRef<uint64_t> Operands);
-
-private:
- static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
- DIDumpOptions DumpOpts, const DWARFExpression *Expr,
- DWARFUnit *U);
-
- static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
- DIDumpOptions DumpOpts,
- ArrayRef<uint64_t> Operands,
- unsigned Operand);
-};
-
} // end namespace llvm
#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
diff --git a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
index 0fe4b905831ff..34969d7524890 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -38,6 +38,7 @@ add_llvm_component_library(LLVMAsmPrinter
Core
DebugInfoCodeView
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
MC
MCParser
Remarks
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 0edfca78b0886..ca419a8db18ae 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -32,7 +32,7 @@
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
diff --git a/llvm/lib/DWARFLinker/Classic/CMakeLists.txt b/llvm/lib/DWARFLinker/Classic/CMakeLists.txt
index 5d3b259e4a33a..4e5cb3c6dfb51 100644
--- a/llvm/lib/DWARFLinker/Classic/CMakeLists.txt
+++ b/llvm/lib/DWARFLinker/Classic/CMakeLists.txt
@@ -19,6 +19,7 @@ add_llvm_component_library(LLVMDWARFLinkerClassic
CodeGen
CodeGenTypes
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
DWARFLinker
MC
Object
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index ae4cc6d85c120..222dc88098102 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -23,10 +23,10 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
index 66bf158e60f1d..027363aa394e0 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
@@ -10,7 +10,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Support/FormatVariadic.h"
namespace llvm {
diff --git a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
index 86e74110b15ea..ce426aeba3f3f 100644
--- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
@@ -1,9 +1,10 @@
+add_subdirectory(LowLevel)
+
add_llvm_component_library(LLVMDebugInfoDWARF
DWARFAbbreviationDeclaration.cpp
DWARFAddressRange.cpp
DWARFAcceleratorTable.cpp
DWARFCFIPrinter.cpp
- DWARFCFIProgram.cpp
DWARFCompileUnit.cpp
DWARFContext.cpp
DWARFDebugAbbrev.cpp
@@ -19,7 +20,7 @@ add_llvm_component_library(LLVMDebugInfoDWARF
DWARFDebugRangeList.cpp
DWARFDebugRnglists.cpp
DWARFDie.cpp
- DWARFExpression.cpp
+ DWARFExpressionPrinter.cpp
DWARFFormValue.cpp
DWARFGdbIndex.cpp
DWARFListTable.cpp
@@ -35,6 +36,7 @@ add_llvm_component_library(LLVMDebugInfoDWARF
LINK_COMPONENTS
BinaryFormat
+ DebugInfoDWARFLowLevel
Object
Support
TargetParser
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
index e52f671e4fa1c..2abab0277a9f6 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCFIPrinter.cpp
@@ -8,8 +8,9 @@
#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
@@ -100,8 +101,7 @@ static void printOperand(raw_ostream &OS, const DIDumpOptions &DumpOpts,
case CFIProgram::OT_Expression:
assert(Instr.Expression && "missing DWARFExpression object");
OS << " ";
- DWARFExpressionPrinter::print(&Instr.Expression.value(), OS, DumpOpts,
- nullptr);
+ printDwarfExpression(&Instr.Expression.value(), OS, DumpOpts, nullptr);
break;
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 9184502adc7cf..2bf88c9574c2d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -13,9 +13,10 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
@@ -114,7 +115,7 @@ void UnwindLocation::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
break;
case DWARFExpr: {
if (Expr)
- DWARFExpressionPrinter::print(&(*Expr), OS, DumpOpts, nullptr);
+ printDwarfExpression(&Expr.value(), OS, DumpOpts, nullptr);
break;
}
case Constant:
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index fc71be32fdd79..5bd2427da7d73 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -11,10 +11,11 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -117,7 +118,7 @@ static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
if (U)
Format = U->getFormat();
DWARFExpression E(Extractor, AddressSize, Format);
- DWARFExpressionPrinter::print(&E, OS, DumpOpts, U);
+ printDwarfExpression(&E, OS, DumpOpts, U);
}
bool DWARFLocationTable::dumpLocationList(
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 08dd9d30812d1..edc69a36cdff2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -15,11 +15,12 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
@@ -99,7 +100,7 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
Ctx.isLittleEndian(), 0);
DWARFExpression DE(Data, U->getAddressByteSize(), U->getFormParams().Format);
- DWARFExpressionPrinter::print(&DE, OS, DumpOpts, U);
+ printDwarfExpression(&DE, OS, DumpOpts, U);
}
static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
deleted file mode 100644
index 8255e013a2d79..0000000000000
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-//===-- DWARFExpression.cpp -----------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/Format.h"
-#include <cassert>
-#include <cstdint>
-#include <vector>
-
-using namespace llvm;
-using namespace dwarf;
-
-namespace llvm {
-
-typedef DWARFExpression::Operation Op;
-typedef Op::Description Desc;
-
-static std::vector<Desc> getOpDescriptions() {
- std::vector<Desc> Descriptions;
- Descriptions.resize(0xff);
- Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
- Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
- Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
- Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
- Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
- Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
- Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
- Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
- Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
- Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
- Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
- for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
- Descriptions[LA] = Desc(Op::Dwarf2);
- for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
- Descriptions[LA] = Desc(Op::Dwarf2);
- for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
- Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
- Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
- Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
- Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
- Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
- Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
- Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
- Descriptions[DW_OP_implicit_value] =
- Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeBlock);
- Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf4);
- Descriptions[DW_OP_implicit_pointer] =
- Desc(Op::Dwarf5, Op::SizeRefAddr, Op::SignedSizeLEB);
- Descriptions[DW_OP_addrx] = Desc(Op::Dwarf5, Op::SizeLEB);
- Descriptions[DW_OP_constx] = Desc(Op::Dwarf5, Op::SizeLEB);
- Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB);
- Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
- Descriptions[DW_OP_regval_type] =
- Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef);
- Descriptions[DW_OP_WASM_location] =
- Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
- Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
- Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
- Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
- Descriptions[DW_OP_GNU_implicit_pointer] =
- Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB);
- // This Description acts as a marker that getSubOpDesc must be called
- // to fetch the final Description for the operation. Each such final
- // Description must share the same first SizeSubOpLEB operand.
- Descriptions[DW_OP_LLVM_user] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
- return Descriptions;
-}
-
-static Desc getDescImpl(ArrayRef<Desc> Descriptions, unsigned Opcode) {
- // Handle possible corrupted or unsupported operation.
- if (Opcode >= Descriptions.size())
- return {};
- return Descriptions[Opcode];
-}
-
-static Desc getOpDesc(unsigned Opcode) {
- static std::vector<Desc> Descriptions = getOpDescriptions();
- return getDescImpl(Descriptions, Opcode);
-}
-
-static std::vector<Desc> getSubOpDescriptions() {
- static constexpr unsigned LlvmUserDescriptionsSize = 1
-#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1
-#include "llvm/BinaryFormat/Dwarf.def"
- ;
- std::vector<Desc> Descriptions;
- Descriptions.resize(LlvmUserDescriptionsSize);
- Descriptions[DW_OP_LLVM_nop] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
- return Descriptions;
-}
-
-static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode) {
- assert(Opcode == DW_OP_LLVM_user);
- static std::vector<Desc> Descriptions = getSubOpDescriptions();
- return getDescImpl(Descriptions, SubOpcode);
-}
-
-bool DWARFExpression::Operation::extract(DataExtractor Data,
- uint8_t AddressSize, uint64_t Offset,
- std::optional<DwarfFormat> Format) {
- EndOffset = Offset;
- Opcode = Data.getU8(&Offset);
-
- Desc = getOpDesc(Opcode);
- if (Desc.Version == Operation::DwarfNA)
- return false;
-
- Operands.resize(Desc.Op.size());
- OperandEndOffsets.resize(Desc.Op.size());
- for (unsigned Operand = 0; Operand < Desc.Op.size(); ++Operand) {
- unsigned Size = Desc.Op[Operand];
- unsigned Signed = Size & Operation::SignBit;
-
- switch (Size & ~Operation::SignBit) {
- case Operation::SizeSubOpLEB:
- assert(Operand == 0 && "SubOp operand must be the first operand");
- Operands[Operand] = Data.getULEB128(&Offset);
- Desc = getSubOpDesc(Opcode, Operands[Operand]);
- if (Desc.Version == Operation::DwarfNA)
- return false;
- assert(Desc.Op[Operand] == Operation::SizeSubOpLEB &&
- "SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
- break;
- case Operation::Size1:
- Operands[Operand] = Data.getU8(&Offset);
- if (Signed)
- Operands[Operand] = (int8_t)Operands[Operand];
- break;
- case Operation::Size2:
- Operands[Operand] = Data.getU16(&Offset);
- if (Signed)
- Operands[Operand] = (int16_t)Operands[Operand];
- break;
- case Operation::Size4:
- Operands[Operand] = Data.getU32(&Offset);
- if (Signed)
- Operands[Operand] = (int32_t)Operands[Operand];
- break;
- case Operation::Size8:
- Operands[Operand] = Data.getU64(&Offset);
- break;
- case Operation::SizeAddr:
- Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
- break;
- case Operation::SizeRefAddr:
- if (!Format)
- return false;
- Operands[Operand] =
- Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
- break;
- case Operation::SizeLEB:
- if (Signed)
- Operands[Operand] = Data.getSLEB128(&Offset);
- else
- Operands[Operand] = Data.getULEB128(&Offset);
- break;
- case Operation::BaseTypeRef:
- Operands[Operand] = Data.getULEB128(&Offset);
- break;
- case Operation::WasmLocationArg:
- assert(Operand == 1);
- switch (Operands[0]) {
- case 0:
- case 1:
- case 2:
- case 4:
- Operands[Operand] = Data.getULEB128(&Offset);
- break;
- case 3: // global as uint32
- Operands[Operand] = Data.getU32(&Offset);
- break;
- default:
- return false; // Unknown Wasm location
- }
- break;
- case Operation::SizeBlock:
- // We need a size, so this cannot be the first operand
- if (Operand == 0)
- return false;
- // Store the offset of the block as the value.
- Operands[Operand] = Offset;
- Offset += Operands[Operand - 1];
- break;
- default:
- llvm_unreachable("Unknown DWARFExpression Op size");
- }
-
- OperandEndOffsets[Operand] = Offset;
- }
-
- EndOffset = Offset;
- return true;
-}
-
-std::optional<unsigned> DWARFExpression::Operation::getSubCode() const {
- if (!Desc.Op.size() || Desc.Op[0] != Operation::SizeSubOpLEB)
- return std::nullopt;
- return Operands[0];
-}
-
-bool DWARFExpression::operator==(const DWARFExpression &RHS) const {
- if (AddressSize != RHS.AddressSize || Format != RHS.Format)
- return false;
- return Data.getData() == RHS.Data.getData();
-}
-
-void DWARFExpressionPrinter::prettyPrintBaseTypeRef(DWARFUnit *U,
- raw_ostream &OS,
- DIDumpOptions DumpOpts,
- ArrayRef<uint64_t> Operands,
- unsigned Operand) {
- assert(Operand < Operands.size() && "operand out of bounds");
- if (!U) {
- OS << format(" <base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
- return;
- }
- auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
- if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
- OS << " (";
- if (DumpOpts.Verbose)
- OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
- OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
- if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
- OS << " \"" << *Name << "\"";
- } else {
- OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
- }
-}
-
-bool DWARFExpressionPrinter::prettyPrintRegisterOp(
- DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode,
- ArrayRef<uint64_t> Operands) {
- if (!DumpOpts.GetNameForDWARFReg)
- return false;
-
- uint64_t DwarfRegNum;
- unsigned OpNum = 0;
-
- if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
- Opcode == DW_OP_regval_type)
- DwarfRegNum = Operands[OpNum++];
- else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
- DwarfRegNum = Opcode - DW_OP_breg0;
- else
- DwarfRegNum = Opcode - DW_OP_reg0;
-
- auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
- if (!RegName.empty()) {
- if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
- Opcode == DW_OP_bregx)
- OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
- else
- OS << ' ' << RegName.data();
-
- if (Opcode == DW_OP_regval_type)
- prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
- return true;
- }
-
- return false;
-}
-
-bool DWARFExpressionPrinter::printOp(const DWARFExpression::Operation *Op,
- raw_ostream &OS, DIDumpOptions DumpOpts,
- const DWARFExpression *Expr,
- DWARFUnit *U) {
- if (Op->Error) {
- OS << "<decoding error>";
- return false;
- }
-
- StringRef Name = OperationEncodingString(Op->Opcode);
- assert(!Name.empty() && "DW_OP has no name!");
- OS << Name;
-
- if ((Op->Opcode >= DW_OP_breg0 && Op->Opcode <= DW_OP_breg31) ||
- (Op->Opcode >= DW_OP_reg0 && Op->Opcode <= DW_OP_reg31) ||
- Op->Opcode == DW_OP_bregx || Op->Opcode == DW_OP_regx ||
- Op->Opcode == DW_OP_regval_type)
- if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->Opcode, Op->Operands))
- return true;
-
- for (unsigned Operand = 0; Operand < Op->Desc.Op.size(); ++Operand) {
- unsigned Size = Op->Desc.Op[Operand];
- unsigned Signed = Size & DWARFExpression::Operation::SignBit;
-
- if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
- StringRef SubName =
- SubOperationEncodingString(Op->Opcode, Op->Operands[Operand]);
- assert(!SubName.empty() && "DW_OP SubOp has no name!");
- OS << " " << SubName;
- } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
- // For DW_OP_convert the operand may be 0 to indicate that conversion to
- // the generic type should be done. The same holds for DW_OP_reinterpret,
- // which is currently not supported.
- if (Op->Opcode == DW_OP_convert && Op->Operands[Operand] == 0)
- OS << " 0x0";
- else
- prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->Operands, Operand);
- } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
- assert(Operand == 1);
- switch (Op->Operands[0]) {
- case 0:
- case 1:
- case 2:
- case 3: // global as uint32
- case 4:
- OS << format(" 0x%" PRIx64, Op->Operands[Operand]);
- break;
- default: assert(false);
- }
- } else if (Size == DWARFExpression::Operation::SizeBlock) {
- uint64_t Offset = Op->Operands[Operand];
- for (unsigned i = 0; i < Op->Operands[Operand - 1]; ++i)
- OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
- } else {
- if (Signed)
- OS << format(" %+" PRId64, (int64_t)Op->Operands[Operand]);
- else if (Op->Opcode != DW_OP_entry_value &&
- Op->Opcode != DW_OP_GNU_entry_value)
- OS << format(" 0x%" PRIx64, Op->Operands[Operand]);
- }
- }
- return true;
-}
-
-void DWARFExpressionPrinter::print(const DWARFExpression *E, raw_ostream &OS,
- DIDumpOptions DumpOpts, DWARFUnit *U,
- bool IsEH) {
- uint32_t EntryValExprSize = 0;
- uint64_t EntryValStartOffset = 0;
- if (E->Data.getData().empty())
- OS << "<empty>";
-
- for (auto &Op : *E) {
- DumpOpts.IsEH = IsEH;
- if (!printOp(&Op, OS, DumpOpts, E, U)) {
- uint64_t FailOffset = Op.getEndOffset();
- while (FailOffset < E->Data.getData().size())
- OS << format(" %02x", E->Data.getU8(&FailOffset));
- return;
- }
-
- if (Op.getCode() == DW_OP_entry_value ||
- Op.getCode() == DW_OP_GNU_entry_value) {
- OS << "(";
- EntryValExprSize = Op.getRawOperand(0);
- EntryValStartOffset = Op.getEndOffset();
- continue;
- }
-
- if (EntryValExprSize) {
- EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
- if (EntryValExprSize == 0)
- OS << ")";
- }
-
- if (Op.getEndOffset() < E->Data.getData().size())
- OS << ", ";
- }
-}
-
-/// A user-facing string representation of a DWARF expression. This might be an
-/// Address expression, in which case it will be implicitly dereferenced, or a
-/// Value expression.
-struct PrintedExpr {
- enum ExprKind {
- Address,
- Value,
- };
- ExprKind Kind;
- SmallString<16> String;
-
- PrintedExpr(ExprKind K = Address) : Kind(K) {}
-};
-
-static bool printCompactDWARFExpr(
- raw_ostream &OS, DWARFExpression::iterator I,
- const DWARFExpression::iterator E,
- std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
- nullptr) {
- SmallVector<PrintedExpr, 4> Stack;
-
- while (I != E) {
- const DWARFExpression::Operation &Op = *I;
- uint8_t Opcode = Op.getCode();
- switch (Opcode) {
- case dwarf::DW_OP_regx: {
- // DW_OP_regx: A register, with the register num given as an operand.
- // Printed as the plain register name.
- uint64_t DwarfRegNum = Op.getRawOperand(0);
- auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
- if (RegName.empty())
- return false;
- raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
- S << RegName;
- break;
- }
- case dwarf::DW_OP_bregx: {
- int DwarfRegNum = Op.getRawOperand(0);
- int64_t Offset = Op.getRawOperand(1);
- auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
- if (RegName.empty())
- return false;
- raw_svector_ostream S(Stack.emplace_back().String);
- S << RegName;
- if (Offset)
- S << format("%+" PRId64, Offset);
- break;
- }
- case dwarf::DW_OP_entry_value:
- case dwarf::DW_OP_GNU_entry_value: {
- // DW_OP_entry_value contains a sub-expression which must be rendered
- // separately.
- uint64_t SubExprLength = Op.getRawOperand(0);
- DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
- ++I;
- raw_svector_ostream S(Stack.emplace_back().String);
- S << "entry(";
- printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
- S << ")";
- I = SubExprEnd;
- continue;
- }
- case dwarf::DW_OP_stack_value: {
- // The top stack entry should be treated as the actual value of tne
- // variable, rather than the address of the variable in memory.
- assert(!Stack.empty());
- Stack.back().Kind = PrintedExpr::Value;
- break;
- }
- case dwarf::DW_OP_nop: {
- break;
- }
- case dwarf::DW_OP_LLVM_user: {
- assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
- break;
- }
- default:
- if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
- // DW_OP_reg<N>: A register, with the register num implied by the
- // opcode. Printed as the plain register name.
- uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
- auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
- if (RegName.empty())
- return false;
- raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
- S << RegName;
- } else if (Opcode >= dwarf::DW_OP_breg0 &&
- Opcode <= dwarf::DW_OP_breg31) {
- int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
- int64_t Offset = Op.getRawOperand(0);
- auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
- if (RegName.empty())
- return false;
- raw_svector_ostream S(Stack.emplace_back().String);
- S << RegName;
- if (Offset)
- S << format("%+" PRId64, Offset);
- } else {
- // If we hit an unknown operand, we don't know its effect on the stack,
- // so bail out on the whole expression.
- OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
- << (int)Opcode << ")>";
- return false;
- }
- break;
- }
- ++I;
- }
-
- if (Stack.size() != 1) {
- OS << "<stack of size " << Stack.size() << ", expected 1>";
- return false;
- }
-
- if (Stack.front().Kind == PrintedExpr::Address)
- OS << "[" << Stack.front().String << "]";
- else
- OS << Stack.front().String;
-
- return true;
-}
-
-bool DWARFExpressionPrinter::printCompact(
- const DWARFExpression *E, raw_ostream &OS,
- std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
- return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
-}
-
-} // namespace llvm
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
new file mode 100644
index 0000000000000..16133b637e875
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
@@ -0,0 +1,311 @@
+//===-- DWARFExpression.cpp -----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
+#include "llvm/Support/Format.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+
+namespace llvm {
+
+typedef DWARFExpression::Operation Op;
+typedef Op::Description Desc;
+
+static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ ArrayRef<uint64_t> Operands,
+ unsigned Operand) {
+ assert(Operand < Operands.size() && "operand out of bounds");
+ if (!U) {
+ OS << format(" <base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
+ return;
+ }
+ auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
+ if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
+ OS << " (";
+ if (DumpOpts.Verbose)
+ OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
+ OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
+ if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
+ OS << " \"" << *Name << "\"";
+ } else {
+ OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", Operands[Operand]);
+ }
+}
+
+static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
+ DIDumpOptions DumpOpts, const DWARFExpression *Expr,
+ DWARFUnit *U) {
+ if (Op->isError()) {
+ OS << "<decoding error>";
+ return false;
+ }
+
+ StringRef Name = OperationEncodingString(Op->getCode());
+ assert(!Name.empty() && "DW_OP has no name!");
+ OS << Name;
+
+ if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
+ (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
+ Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
+ Op->getCode() == DW_OP_regval_type)
+ if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
+ Op->getRawOperands()))
+ return true;
+
+ for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
+ ++Operand) {
+ unsigned Size = Op->getDescription().Op[Operand];
+ unsigned Signed = Size & DWARFExpression::Operation::SignBit;
+
+ if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
+ StringRef SubName =
+ SubOperationEncodingString(Op->getCode(), Op->getRawOperand(Operand));
+ assert(!SubName.empty() && "DW_OP SubOp has no name!");
+ OS << " " << SubName;
+ } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
+ // For DW_OP_convert the operand may be 0 to indicate that conversion to
+ // the generic type should be done. The same holds for DW_OP_reinterpret,
+ // which is currently not supported.
+ if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
+ OS << " 0x0";
+ else
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(), Operand);
+ } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
+ assert(Operand == 1);
+ switch (Op->getRawOperand(0)) {
+ case 0:
+ case 1:
+ case 2:
+ case 3: // global as uint32
+ case 4:
+ OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
+ break;
+ default:
+ assert(false);
+ }
+ } else if (Size == DWARFExpression::Operation::SizeBlock) {
+ uint64_t Offset = Op->getRawOperand(Operand);
+ for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
+ OS << format(" 0x%02x",
+ static_cast<uint8_t>(Expr->getData()[Offset++]));
+ } else {
+ if (Signed)
+ OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
+ else if (Op->getCode() != DW_OP_entry_value &&
+ Op->getCode() != DW_OP_GNU_entry_value)
+ OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
+ }
+ }
+ return true;
+}
+
+void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
+ DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH) {
+ uint32_t EntryValExprSize = 0;
+ uint64_t EntryValStartOffset = 0;
+ if (E->getData().empty())
+ OS << "<empty>";
+
+ for (auto &Op : *E) {
+ DumpOpts.IsEH = IsEH;
+ if (!printOp(&Op, OS, DumpOpts, E, U)) {
+ uint64_t FailOffset = Op.getEndOffset();
+ while (FailOffset < E->getData().size())
+ OS << format(" %02x", static_cast<uint8_t>(E->getData()[FailOffset++]));
+ return;
+ }
+
+ if (Op.getCode() == DW_OP_entry_value ||
+ Op.getCode() == DW_OP_GNU_entry_value) {
+ OS << "(";
+ EntryValExprSize = Op.getRawOperand(0);
+ EntryValStartOffset = Op.getEndOffset();
+ continue;
+ }
+
+ if (EntryValExprSize) {
+ EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
+ if (EntryValExprSize == 0)
+ OS << ")";
+ }
+
+ if (Op.getEndOffset() < E->getData().size())
+ OS << ", ";
+ }
+}
+
+/// A user-facing string representation of a DWARF expression. This might be an
+/// Address expression, in which case it will be implicitly dereferenced, or a
+/// Value expression.
+struct PrintedExpr {
+ enum ExprKind {
+ Address,
+ Value,
+ };
+ ExprKind Kind;
+ SmallString<16> String;
+
+ PrintedExpr(ExprKind K = Address) : Kind(K) {}
+};
+
+static bool printCompactDWARFExpr(
+ raw_ostream &OS, DWARFExpression::iterator I,
+ const DWARFExpression::iterator E,
+ std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
+ nullptr) {
+ SmallVector<PrintedExpr, 4> Stack;
+
+ while (I != E) {
+ const DWARFExpression::Operation &Op = *I;
+ uint8_t Opcode = Op.getCode();
+ switch (Opcode) {
+ case dwarf::DW_OP_regx: {
+ // DW_OP_regx: A register, with the register num given as an operand.
+ // Printed as the plain register name.
+ uint64_t DwarfRegNum = Op.getRawOperand(0);
+ auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+ if (RegName.empty())
+ return false;
+ raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+ S << RegName;
+ break;
+ }
+ case dwarf::DW_OP_bregx: {
+ int DwarfRegNum = Op.getRawOperand(0);
+ int64_t Offset = Op.getRawOperand(1);
+ auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+ if (RegName.empty())
+ return false;
+ raw_svector_ostream S(Stack.emplace_back().String);
+ S << RegName;
+ if (Offset)
+ S << format("%+" PRId64, Offset);
+ break;
+ }
+ case dwarf::DW_OP_entry_value:
+ case dwarf::DW_OP_GNU_entry_value: {
+ // DW_OP_entry_value contains a sub-expression which must be rendered
+ // separately.
+ uint64_t SubExprLength = Op.getRawOperand(0);
+ DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
+ ++I;
+ raw_svector_ostream S(Stack.emplace_back().String);
+ S << "entry(";
+ printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
+ S << ")";
+ I = SubExprEnd;
+ continue;
+ }
+ case dwarf::DW_OP_stack_value: {
+ // The top stack entry should be treated as the actual value of tne
+ // variable, rather than the address of the variable in memory.
+ assert(!Stack.empty());
+ Stack.back().Kind = PrintedExpr::Value;
+ break;
+ }
+ case dwarf::DW_OP_nop: {
+ break;
+ }
+ case dwarf::DW_OP_LLVM_user: {
+ assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
+ break;
+ }
+ default:
+ if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
+ // DW_OP_reg<N>: A register, with the register num implied by the
+ // opcode. Printed as the plain register name.
+ uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
+ auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+ if (RegName.empty())
+ return false;
+ raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+ S << RegName;
+ } else if (Opcode >= dwarf::DW_OP_breg0 &&
+ Opcode <= dwarf::DW_OP_breg31) {
+ int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
+ int64_t Offset = Op.getRawOperand(0);
+ auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
+ if (RegName.empty())
+ return false;
+ raw_svector_ostream S(Stack.emplace_back().String);
+ S << RegName;
+ if (Offset)
+ S << format("%+" PRId64, Offset);
+ } else {
+ // If we hit an unknown operand, we don't know its effect on the stack,
+ // so bail out on the whole expression.
+ OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
+ << (int)Opcode << ")>";
+ return false;
+ }
+ break;
+ }
+ ++I;
+ }
+
+ if (Stack.size() != 1) {
+ OS << "<stack of size " << Stack.size() << ", expected 1>";
+ return false;
+ }
+
+ if (Stack.front().Kind == PrintedExpr::Address)
+ OS << "[" << Stack.front().String << "]";
+ else
+ OS << Stack.front().String;
+
+ return true;
+}
+
+bool printDwarfExpressionCompact(
+ const DWARFExpression *E, raw_ostream &OS,
+ std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
+ return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
+}
+
+bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
+ DIDumpOptions DumpOpts, uint8_t Opcode,
+ ArrayRef<uint64_t> Operands) {
+ if (!DumpOpts.GetNameForDWARFReg)
+ return false;
+
+ uint64_t DwarfRegNum;
+ unsigned OpNum = 0;
+
+ if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
+ Opcode == DW_OP_regval_type)
+ DwarfRegNum = Operands[OpNum++];
+ else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
+ DwarfRegNum = Opcode - DW_OP_breg0;
+ else
+ DwarfRegNum = Opcode - DW_OP_reg0;
+
+ auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
+ if (!RegName.empty()) {
+ if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
+ Opcode == DW_OP_bregx)
+ OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
+ else
+ OS << ' ' << RegName.data();
+
+ if (Opcode == DW_OP_regval_type)
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace llvm
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index d719a47c84072..ef59c82fc6a01 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -19,12 +19,12 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index c12786cac8686..8ec3f1729b974 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -19,13 +19,13 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/DJB.h"
#include "llvm/Support/Error.h"
diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
new file mode 100644
index 0000000000000..c11a2589a552d
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_llvm_component_library(LLVMDebugInfoDWARFLowLevel
+ DWARFCFIProgram.cpp
+ DWARFExpression.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/DWARF/LowLevel
+
+ // This code should have almost no dependencies. Anything that needs
+ // more should use the higher-level DebugInfo/DWARF/ library.
+ LINK_COMPONENTS
+ BinaryFormat
+ Support
+ TargetParser
+ )
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCFIProgram.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
similarity index 60%
rename from llvm/lib/DebugInfo/DWARF/DWARFCFIProgram.cpp
rename to llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
index 365b26b98a1e3..25a0ccb50c8a9 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCFIProgram.cpp
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/DWARF/DWARFCFIProgram.h"
-#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
@@ -23,149 +22,6 @@
using namespace llvm;
using namespace dwarf;
-// 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;
-
-Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
- uint64_t EndOffset) {
- 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 directly into function
- // argument list. getULEB128 changes Offset and order of evaluation
- // for arguments is unspecified.
- uint64_t op1 = Data.getULEB128(C);
- uint64_t op2 = Data.getULEB128(C);
- addInstruction(Opcode, op1, op2);
- break;
- }
- case DW_CFA_offset_extended_sf:
- case DW_CFA_def_cfa_sf:
- case DW_CFA_val_offset_sf: {
- // Operands: ULEB128, SLEB128
- // Note: see comment for the previous case
- uint64_t op1 = Data.getULEB128(C);
- uint64_t op2 = (uint64_t)Data.getSLEB128(C);
- addInstruction(Opcode, op1, op2);
- break;
- }
- case DW_CFA_def_cfa_expression: {
- uint64_t ExprLength = Data.getULEB128(C);
- addInstruction(Opcode, 0);
- StringRef Expression = Data.getBytes(C, ExprLength);
-
- DataExtractor Extractor(Expression, Data.isLittleEndian(),
- Data.getAddressSize());
- // Note. We do not pass the DWARF format to DWARFExpression, because
- // DW_OP_call_ref, the only operation which depends on the format, is
- // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
- Instructions.back().Expression =
- DWARFExpression(Extractor, Data.getAddressSize());
- break;
- }
- case DW_CFA_expression:
- case DW_CFA_val_expression: {
- uint64_t RegNum = Data.getULEB128(C);
- addInstruction(Opcode, RegNum, 0);
-
- uint64_t BlockLength = Data.getULEB128(C);
- StringRef Expression = Data.getBytes(C, BlockLength);
- DataExtractor Extractor(Expression, Data.isLittleEndian(),
- Data.getAddressSize());
- // Note. We do not pass the DWARF format to DWARFExpression, because
- // DW_OP_call_ref, the only operation which depends on the format, is
- // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
- Instructions.back().Expression =
- DWARFExpression(Extractor, Data.getAddressSize());
- break;
- }
- }
- }
-
- *Offset = C.tell();
- return C.takeError();
-}
-
StringRef CFIProgram::callFrameString(unsigned Opcode) const {
return dwarf::CallFrameString(Opcode, Arch);
}
diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
new file mode 100644
index 0000000000000..70724185463b0
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp
@@ -0,0 +1,253 @@
+//===-- DWARFExpression.cpp -----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Format.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+
+namespace llvm {
+
+typedef DWARFExpression::Operation Op;
+typedef Op::Description Desc;
+
+static std::vector<Desc> getOpDescriptions() {
+ std::vector<Desc> Descriptions;
+ Descriptions.resize(0xff);
+ Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
+ Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
+ Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
+ Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
+ Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
+ Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
+ Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
+ Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
+ Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
+ Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
+ Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
+ for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
+ Descriptions[LA] = Desc(Op::Dwarf2);
+ for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
+ Descriptions[LA] = Desc(Op::Dwarf2);
+ for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
+ Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
+ Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
+ Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
+ Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
+ Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
+ Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
+ Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
+ Descriptions[DW_OP_implicit_value] =
+ Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeBlock);
+ Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf4);
+ Descriptions[DW_OP_implicit_pointer] =
+ Desc(Op::Dwarf5, Op::SizeRefAddr, Op::SignedSizeLEB);
+ Descriptions[DW_OP_addrx] = Desc(Op::Dwarf5, Op::SizeLEB);
+ Descriptions[DW_OP_constx] = Desc(Op::Dwarf5, Op::SizeLEB);
+ Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB);
+ Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
+ Descriptions[DW_OP_regval_type] =
+ Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef);
+ Descriptions[DW_OP_WASM_location] =
+ Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
+ Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
+ Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
+ Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
+ Descriptions[DW_OP_GNU_implicit_pointer] =
+ Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB);
+ // This Description acts as a marker that getSubOpDesc must be called
+ // to fetch the final Description for the operation. Each such final
+ // Description must share the same first SizeSubOpLEB operand.
+ Descriptions[DW_OP_LLVM_user] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
+ return Descriptions;
+}
+
+static Desc getDescImpl(ArrayRef<Desc> Descriptions, unsigned Opcode) {
+ // Handle possible corrupted or unsupported operation.
+ if (Opcode >= Descriptions.size())
+ return {};
+ return Descriptions[Opcode];
+}
+
+static Desc getOpDesc(unsigned Opcode) {
+ static std::vector<Desc> Descriptions = getOpDescriptions();
+ return getDescImpl(Descriptions, Opcode);
+}
+
+static std::vector<Desc> getSubOpDescriptions() {
+ static constexpr unsigned LlvmUserDescriptionsSize = 1
+#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1
+#include "llvm/BinaryFormat/Dwarf.def"
+ ;
+ std::vector<Desc> Descriptions;
+ Descriptions.resize(LlvmUserDescriptionsSize);
+ Descriptions[DW_OP_LLVM_nop] = Desc(Op::Dwarf5, Op::SizeSubOpLEB);
+ return Descriptions;
+}
+
+static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode) {
+ assert(Opcode == DW_OP_LLVM_user);
+ static std::vector<Desc> Descriptions = getSubOpDescriptions();
+ return getDescImpl(Descriptions, SubOpcode);
+}
+
+bool DWARFExpression::Operation::extract(DataExtractor Data,
+ uint8_t AddressSize, uint64_t Offset,
+ std::optional<DwarfFormat> Format) {
+ EndOffset = Offset;
+ Opcode = Data.getU8(&Offset);
+
+ Desc = getOpDesc(Opcode);
+ if (Desc.Version == Operation::DwarfNA)
+ return false;
+
+ Operands.resize(Desc.Op.size());
+ OperandEndOffsets.resize(Desc.Op.size());
+ for (unsigned Operand = 0; Operand < Desc.Op.size(); ++Operand) {
+ unsigned Size = Desc.Op[Operand];
+ unsigned Signed = Size & Operation::SignBit;
+
+ switch (Size & ~Operation::SignBit) {
+ case Operation::SizeSubOpLEB:
+ assert(Operand == 0 && "SubOp operand must be the first operand");
+ Operands[Operand] = Data.getULEB128(&Offset);
+ Desc = getSubOpDesc(Opcode, Operands[Operand]);
+ if (Desc.Version == Operation::DwarfNA)
+ return false;
+ assert(Desc.Op[Operand] == Operation::SizeSubOpLEB &&
+ "SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
+ break;
+ case Operation::Size1:
+ Operands[Operand] = Data.getU8(&Offset);
+ if (Signed)
+ Operands[Operand] = (int8_t)Operands[Operand];
+ break;
+ case Operation::Size2:
+ Operands[Operand] = Data.getU16(&Offset);
+ if (Signed)
+ Operands[Operand] = (int16_t)Operands[Operand];
+ break;
+ case Operation::Size4:
+ Operands[Operand] = Data.getU32(&Offset);
+ if (Signed)
+ Operands[Operand] = (int32_t)Operands[Operand];
+ break;
+ case Operation::Size8:
+ Operands[Operand] = Data.getU64(&Offset);
+ break;
+ case Operation::SizeAddr:
+ Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
+ break;
+ case Operation::SizeRefAddr:
+ if (!Format)
+ return false;
+ Operands[Operand] =
+ Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
+ break;
+ case Operation::SizeLEB:
+ if (Signed)
+ Operands[Operand] = Data.getSLEB128(&Offset);
+ else
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
+ case Operation::BaseTypeRef:
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
+ case Operation::WasmLocationArg:
+ assert(Operand == 1);
+ switch (Operands[0]) {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
+ case 3: // global as uint32
+ Operands[Operand] = Data.getU32(&Offset);
+ break;
+ default:
+ return false; // Unknown Wasm location
+ }
+ break;
+ case Operation::SizeBlock:
+ // We need a size, so this cannot be the first operand
+ if (Operand == 0)
+ return false;
+ // Store the offset of the block as the value.
+ Operands[Operand] = Offset;
+ Offset += Operands[Operand - 1];
+ break;
+ default:
+ llvm_unreachable("Unknown DWARFExpression Op size");
+ }
+
+ OperandEndOffsets[Operand] = Offset;
+ }
+
+ EndOffset = Offset;
+ return true;
+}
+
+std::optional<unsigned> DWARFExpression::Operation::getSubCode() const {
+ if (!Desc.Op.size() || Desc.Op[0] != Operation::SizeSubOpLEB)
+ return std::nullopt;
+ return Operands[0];
+}
+
+bool DWARFExpression::operator==(const DWARFExpression &RHS) const {
+ if (AddressSize != RHS.AddressSize || Format != RHS.Format)
+ return false;
+ return Data.getData() == RHS.Data.getData();
+}
+
+} // namespace llvm
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 95b7007d119bc..696e2bc948a2e 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -14,7 +14,8 @@
#include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
@@ -594,8 +595,7 @@ std::string LVDWARFReader::getRegisterName(LVSmall Opcode,
return {};
};
DumpOpts.GetNameForDWARFReg = GetRegName;
- DWARFExpressionPrinter::prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts,
- Opcode, Operands);
+ prettyPrintRegisterOp(/*U=*/nullptr, Stream, DumpOpts, Opcode, Operands);
return Stream.str();
}
diff --git a/llvm/lib/ProfileData/CMakeLists.txt b/llvm/lib/ProfileData/CMakeLists.txt
index d26af1c3d5547..c2366dc0ae03e 100644
--- a/llvm/lib/ProfileData/CMakeLists.txt
+++ b/llvm/lib/ProfileData/CMakeLists.txt
@@ -35,6 +35,7 @@ add_llvm_component_library(LLVMProfileData
Demangle
Symbolize
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
TargetParser
)
diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index d92107f93dc56..07b69e9fad3ec 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -10,10 +10,10 @@
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt
index 366b63b2a8695..d3cdbe466de08 100644
--- a/llvm/tools/dsymutil/CMakeLists.txt
+++ b/llvm/tools/dsymutil/CMakeLists.txt
@@ -15,6 +15,7 @@ set(LLVM_LINK_COMPONENTS
DWARFLinkerClassic
DWARFLinkerParallel
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
MC
Object
Option
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index e88e076dca996..138c5d0a513ed 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -39,10 +39,10 @@
#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/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
diff --git a/llvm/tools/llvm-dwarfdump/CMakeLists.txt b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
index 7c68aaac05d98..aeb1b8f14d830 100644
--- a/llvm/tools/llvm-dwarfdump/CMakeLists.txt
+++ b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
@@ -1,5 +1,6 @@
set(LLVM_LINK_COMPONENTS
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
AllTargetsDescs
AllTargetsInfos
MC
diff --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp
index af9a93ad35b9c..f92b2b55fa8dc 100644
--- a/llvm/tools/llvm-dwarfdump/Statistics.cpp
+++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp
@@ -12,7 +12,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/JSON.h"
diff --git a/llvm/tools/llvm-dwarfutil/CMakeLists.txt b/llvm/tools/llvm-dwarfutil/CMakeLists.txt
index 23a526782dd7b..88335928b68dd 100644
--- a/llvm/tools/llvm-dwarfutil/CMakeLists.txt
+++ b/llvm/tools/llvm-dwarfutil/CMakeLists.txt
@@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
DWARFLinkerClassic
DWARFLinkerParallel
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
MC
ObjCopy
Object
diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
index 285dcf75ecd9d..ccc1324bc66d7 100644
--- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
+++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
@@ -13,7 +13,7 @@
#include "llvm/DWARFLinker/Classic/DWARFStreamer.h"
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
#include <memory>
#include <vector>
diff --git a/llvm/tools/llvm-objdump/CMakeLists.txt b/llvm/tools/llvm-objdump/CMakeLists.txt
index 0306736388979..7e3197f0a0bd3 100644
--- a/llvm/tools/llvm-objdump/CMakeLists.txt
+++ b/llvm/tools/llvm-objdump/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
BinaryFormat
DebugInfoBTF
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
Demangle
MC
MCDisassembler
diff --git a/llvm/tools/llvm-objdump/SourcePrinter.cpp b/llvm/tools/llvm-objdump/SourcePrinter.cpp
index bf3363795a4d9..3630502172977 100644
--- a/llvm/tools/llvm-objdump/SourcePrinter.cpp
+++ b/llvm/tools/llvm-objdump/SourcePrinter.cpp
@@ -15,7 +15,8 @@
#include "SourcePrinter.h"
#include "llvm-objdump.h"
#include "llvm/ADT/SmallSet.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"
#define DEBUG_TYPE "objdump"
@@ -45,7 +46,7 @@ void LiveVariable::print(raw_ostream &OS, const MCRegisterInfo &MRI) const {
return {};
};
- DWARFExpressionPrinter::printCompact(&Expression, OS, GetRegName);
+ printDwarfExpressionCompact(&Expression, OS, GetRegName);
}
void LiveVariablePrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
diff --git a/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt b/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
index 0c5b3f28ca3d5..dc8240f904b4c 100644
--- a/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
BinaryFormat
CodeGenTypes
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
MC
Object
ObjectYAML
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
index 9225ab0125f2f..3e0cc8fed84c0 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp
@@ -10,7 +10,8 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/TargetRegistry.h"
@@ -70,7 +71,7 @@ void DWARFExpressionCompactPrinterTest::TestExprPrinter(
return {};
};
- DWARFExpressionPrinter::printCompact(&Expr, OS, GetRegName);
+ printDwarfExpressionCompact(&Expr, OS, GetRegName);
EXPECT_EQ(OS.str(), Expected);
}
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp
index ec9c0dddcbc0c..78d383ed0b22e 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCopyBytesTest.cpp
@@ -11,7 +11,7 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
diff --git a/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel b/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
index b5cd6dbcbd4f9..97c25bcdece7b 100644
--- a/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/bolt/BUILD.bazel
@@ -106,6 +106,7 @@ cc_library(
"//llvm:DWARFLinker",
"//llvm:DWP",
"//llvm:DebugInfoDWARF",
+ "//llvm:DebugInfoDWARFLowLevel",
"//llvm:Demangle",
"//llvm:JITLink",
"//llvm:MC",
@@ -296,6 +297,7 @@ cc_library(
"//llvm:BinaryFormat",
"//llvm:CodeGen",
"//llvm:DebugInfoDWARF",
+ "//llvm:DebugInfoDWARFLowLevel",
"//llvm:Demangle",
"//llvm:ExecutionEngine",
"//llvm:MC",
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index d5a7fdb747f86..c28d637cea656 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -493,6 +493,7 @@ cc_library(
":DebugInfo",
":DebugInfoCodeView",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":DebugInfoPDB",
":Demangle",
":MC",
@@ -572,6 +573,7 @@ cc_library(
deps = [
":BinaryFormat",
":DebugInfo",
+ ":DebugInfoDWARFLowLevel",
":MC",
":Object",
":Support",
@@ -579,6 +581,20 @@ cc_library(
],
)
+cc_library(
+ name = "DebugInfoDWARFLowLevel",
+ srcs = glob([
+ "lib/DebugInfo/DWARF/LowLevel/*.cpp",
+ ]),
+ hdrs = glob(["include/llvm/DebugInfo/DWARF/LowLevel/*.h"]),
+ copts = llvm_copts,
+ deps = [
+ ":BinaryFormat",
+ ":Support",
+ ":TargetParser",
+ ],
+)
+
cc_library(
name = "DebugInfoGSYM",
srcs = glob([
@@ -1154,6 +1170,7 @@ cc_library(
":Core",
":DebugInfo",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":Demangle",
":Object",
":Support",
@@ -2081,6 +2098,7 @@ cc_library(
":Core",
":DebugInfoCodeView",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":IPO",
":IRPrinter",
":Instrumentation",
@@ -3222,6 +3240,7 @@ cc_library(
":CodeGenTypes",
":DWARFLinkerBase",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":MC",
":Support",
":Target",
@@ -3240,6 +3259,7 @@ cc_library(
":BinaryFormat",
":CodeGen",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":Support",
":Target",
],
@@ -3540,6 +3560,7 @@ cc_library(
":DWARFLinkerParallel",
":DebugInfo",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":DsymutilTableGen",
":MC",
":Object",
@@ -3957,6 +3978,7 @@ cc_binary(
":BinaryFormat",
":DebugInfo",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":MC",
":Object",
":Support",
@@ -3988,6 +4010,7 @@ cc_binary(
":DWARFLinker",
":DWARFLinkerParallel",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":DwarfutilOptionsTableGen",
":MC",
":ObjCopy",
@@ -4605,6 +4628,7 @@ cc_library(
":DebugInfo",
":DebugInfoBTF",
":DebugInfoDWARF",
+ ":DebugInfoDWARFLowLevel",
":Debuginfod",
":Demangle",
":MC",
>From f0c20e0d22e863a0471a55f96c2a0967057171f0 Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Fri, 27 Jun 2025 09:26:53 -0700
Subject: [PATCH 2/2] Fix non-cmake-based sanitizer dependencies.
---
.../sanitizer_common/symbolizer/scripts/build_symbolizer.sh | 1 +
llvm/lib/DWARFLinker/Parallel/CMakeLists.txt | 1 +
llvm/lib/DebugInfo/LogicalView/CMakeLists.txt | 3 ++-
3 files changed, 4 insertions(+), 1 deletion(-)
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/llvm/lib/DWARFLinker/Parallel/CMakeLists.txt b/llvm/lib/DWARFLinker/Parallel/CMakeLists.txt
index 1e7ff0703d135..29d8028b33fb4 100644
--- a/llvm/lib/DWARFLinker/Parallel/CMakeLists.txt
+++ b/llvm/lib/DWARFLinker/Parallel/CMakeLists.txt
@@ -25,6 +25,7 @@ add_llvm_component_library(LLVMDWARFLinkerParallel
BinaryFormat
CodeGen
DebugInfoDWARF
+ DebugInfoDWARFLowLevel
DWARFLinker
MC
Object
diff --git a/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt b/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt
index 67ee7698a3825..462857ef93063 100644
--- a/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt
@@ -47,7 +47,8 @@ add_llvm_component_library(LLVMDebugInfoLogicalView
MC
Support
TargetParser
- DebugInfoDWARF
DebugInfoCodeView
+ DebugInfoDWARF
+ DebugInfoDWARFLowLevel
DebugInfoPDB
)
More information about the lldb-commits
mailing list