[llvm-branch-commits] [lldb] [lldb] Allow multiple ABI runtimes for C++ (PR #212015)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jul 25 04:21:24 PDT 2026
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/212015
>From dc8a018400eb48fcf211eec8c43b5587e863e2ea Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 1 Jul 2026 17:08:30 +0200
Subject: [PATCH] [lldb] Allow multiple ABI runtimes for C++
---
.../CPlusPlus/CPPLanguageRuntime.cpp | 52 +++++++++++++------
.../CPlusPlus/CPPLanguageRuntime.h | 5 +-
.../CPlusPlus/CommonABIRuntime.cpp | 21 ++++++++
.../CPlusPlus/CommonABIRuntime.h | 22 ++++++++
.../CPlusPlus/ItaniumABIRuntime.cpp | 7 ++-
.../CPlusPlus/ItaniumABIRuntime.h | 14 ++---
6 files changed, 95 insertions(+), 26 deletions(-)
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 1db208366fc55..23ffd1d67f163 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -13,6 +13,7 @@
#include "CPPLanguageRuntime.h"
#include "CommandObjectCPlusPlus.h"
+#include "ItaniumABIRuntime.h"
#include "VerboseTrapFrameRecognizer.h"
#include "llvm/ADT/StringRef.h"
@@ -32,6 +33,7 @@
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Timer.h"
using namespace lldb;
@@ -110,7 +112,7 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer {
};
CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
- : LanguageRuntime(process), m_itanium_runtime(process) {
+ : LanguageRuntime(process) {
if (process) {
process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
StackFrameRecognizerSP(new LibCXXFrameRecognizer()), {},
@@ -120,6 +122,8 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
RegisterVerboseTrapFrameRecognizer(*process);
}
+
+ m_abi_runtimes.emplace_back(new ItaniumABIRuntime(process));
}
bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
@@ -548,9 +552,8 @@ bool CPPLanguageRuntime::GetDynamicTypeAndAddress(
return false;
}
- return m_itanium_runtime.GetDynamicTypeAndAddress(
- in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address,
- value_type);
+ return entry->runtime->GetDynamicTypeAndAddress(
+ in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address);
}
TypeAndOrName
@@ -631,8 +634,9 @@ CPPLanguageRuntime::CreateExceptionResolver(const BreakpointSP &bkpt,
bool catch_bp, bool throw_bp,
bool for_expressions) {
std::vector<const char *> exception_names;
- m_itanium_runtime.AppendExceptionBreakpointFunctions(
- exception_names, catch_bp, throw_bp, for_expressions);
+ for (const auto &runtime : m_abi_runtimes)
+ runtime->AppendExceptionBreakpointFunctions(exception_names, catch_bp,
+ throw_bp, for_expressions);
BreakpointResolverSP resolver_sp(new BreakpointResolverName(
bkpt, exception_names.data(), exception_names.size(),
@@ -645,8 +649,9 @@ lldb::SearchFilterSP CPPLanguageRuntime::CreateExceptionSearchFilter() {
Target &target = m_process->GetTarget();
FileSpecList filter_modules;
- m_itanium_runtime.AppendExceptionBreakpointFilterModules(filter_modules,
- target);
+ for (const auto &runtime : m_abi_runtimes)
+ runtime->AppendExceptionBreakpointFilterModules(filter_modules, target);
+
return target.GetSearchFilterForModuleList(&filter_modules);
}
@@ -713,7 +718,12 @@ bool CPPLanguageRuntime::ExceptionBreakpointsExplainStop(
lldb::ValueObjectSP
CPPLanguageRuntime::GetExceptionObjectForThread(lldb::ThreadSP thread_sp) {
- return m_itanium_runtime.GetExceptionObjectForThread(std::move(thread_sp));
+ for (const auto &runtime : m_abi_runtimes) {
+ ValueObjectSP valobj = runtime->GetExceptionObjectForThread(thread_sp);
+ if (valobj)
+ return valobj;
+ }
+ return {};
}
static llvm::Error TypeHasVTable(CompilerType type) {
@@ -807,13 +817,23 @@ CPPLanguageRuntime::GetVTableInfoEntry(ValueObject &in_value, bool check_type) {
return llvm::createStringError(std::errc::invalid_argument,
"no symbol found for 0x%" PRIx64,
vtable_load_addr);
- if (m_itanium_runtime.IsVTableSymbol(symbol->GetMangled())) {
- VTableInfoEntry entry{
- /*info=*/VTableInfo{vtable_addr, symbol},
- };
- std::lock_guard<std::mutex> locker(m_vtable_mutex);
- m_vtable_info_map[vtable_addr] = entry;
- return entry;
+
+ Mangled &mangled = symbol->GetMangled();
+ Log *log = GetLog(LLDBLog::Object);
+ for (const auto &runtime : m_abi_runtimes) {
+ if (runtime->IsVTableSymbol(symbol->GetMangled())) {
+ LLDB_LOG(log, "{0:x16} ({1}): symbol='{2}' matches {3}", original_ptr,
+ in_value.GetTypeName(), mangled.GetDemangledName(),
+ runtime->GetName());
+
+ VTableInfoEntry entry{
+ /*info=*/VTableInfo{vtable_addr, symbol},
+ /*runtime=*/runtime.get(),
+ };
+ std::lock_guard<std::mutex> locker(m_vtable_mutex);
+ m_vtable_info_map[vtable_addr] = entry;
+ return entry;
+ }
}
return llvm::createStringError(std::errc::invalid_argument,
"symbol found that contains 0x%" PRIx64
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
index 0ed1a71b976be..823a968cbad8c 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
@@ -13,7 +13,7 @@
#include "llvm/ADT/StringMap.h"
-#include "ItaniumABIRuntime.h"
+#include "CommonABIRuntime.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/lldb-private.h"
@@ -143,10 +143,11 @@ class CPPLanguageRuntime : public LanguageRuntime {
OperatorStringToCallableInfoMap CallableLookupCache;
lldb::BreakpointSP m_cxx_exception_bp_sp;
- ItaniumABIRuntime m_itanium_runtime;
+ std::vector<std::unique_ptr<CommonABIRuntime>> m_abi_runtimes;
struct VTableInfoEntry {
VTableInfo info;
+ CommonABIRuntime *runtime;
};
llvm::Expected<VTableInfoEntry> GetVTableInfoEntry(ValueObject &in_value,
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp
index a8ed0e810b700..eecaed18f9103 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp
@@ -17,6 +17,27 @@ using namespace lldb_private;
CommonABIRuntime::CommonABIRuntime(Process *process) : m_process(process) {}
+bool CommonABIRuntime::IsVTableSymbol(Mangled &mangled) const { return false; }
+
+bool CommonABIRuntime::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ const LanguageRuntime::VTableInfo &vtable_info,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address) {
+ return false;
+}
+
+void CommonABIRuntime::AppendExceptionBreakpointFunctions(
+ std::vector<const char *> &names, bool catch_bp, bool throw_bp,
+ bool for_expressions) {}
+
+void CommonABIRuntime::AppendExceptionBreakpointFilterModules(
+ FileSpecList &list, const Target &target) {}
+
+lldb::ValueObjectSP
+CommonABIRuntime::GetExceptionObjectForThread(lldb::ThreadSP thread_sp) {
+ return {};
+}
+
lldb::TypeSP
CommonABIRuntime::LookupTypeByName(llvm::StringRef type_name,
lldb::ModuleSP preferred_module) const {
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h
index 7fc8248c3e192..b387ff0f8da8e 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h
@@ -9,7 +9,9 @@
#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_COMMONABIRUNTIME_H
#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_COMMONABIRUNTIME_H
+#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
+#include "lldb/ValueObject/ValueObject.h"
#include <map>
#include <mutex>
@@ -20,6 +22,26 @@ class CommonABIRuntime {
public:
virtual ~CommonABIRuntime() = default;
+ virtual llvm::StringRef GetName() const = 0;
+
+ virtual bool IsVTableSymbol(Mangled &mangled) const;
+
+ virtual bool GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ const LanguageRuntime::VTableInfo &vtable_info,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address);
+
+ virtual void
+ AppendExceptionBreakpointFunctions(std::vector<const char *> &names,
+ bool catch_bp, bool throw_bp,
+ bool for_expressions);
+
+ virtual void AppendExceptionBreakpointFilterModules(FileSpecList &list,
+ const Target &target);
+
+ virtual lldb::ValueObjectSP
+ GetExceptionObjectForThread(lldb::ThreadSP thread_sp);
+
protected:
CommonABIRuntime(Process *process);
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
index db1c2a62681d3..7ace3e2e8aebb 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
@@ -22,6 +22,10 @@ static const char *vtable_demangled_prefix = "vtable for ";
ItaniumABIRuntime::ItaniumABIRuntime(Process *process)
: CommonABIRuntime(process) {}
+llvm::StringRef ItaniumABIRuntime::GetName() const {
+ return "Itanium ABI runtime";
+}
+
bool ItaniumABIRuntime::IsVTableSymbol(Mangled &mangled) const {
return mangled.GetDemangledName().GetStringRef().starts_with(
vtable_demangled_prefix);
@@ -78,8 +82,7 @@ ItaniumABIRuntime::GetTypeInfo(ValueObject &in_value,
bool ItaniumABIRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
const LanguageRuntime::VTableInfo &vtable_info,
- TypeAndOrName &class_type_or_name, Address &dynamic_address,
- Value::ValueType &value_type) {
+ TypeAndOrName &class_type_or_name, Address &dynamic_address) {
// For Itanium, if the type has a vtable pointer in the object, it will be at
// offset 0 in the object. That will point to the "address point" within the
// vtable (not the beginning of the vtable.) We can then look up the symbol
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h
index 7c4cf019ee975..af0eb5e0c6603 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h
@@ -21,23 +21,25 @@ class ItaniumABIRuntime : public CommonABIRuntime {
public:
ItaniumABIRuntime(Process *process);
- bool IsVTableSymbol(Mangled &manged) const;
+ llvm::StringRef GetName() const override;
+
+ bool IsVTableSymbol(Mangled &manged) const override;
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
const LanguageRuntime::VTableInfo &vtable_info,
TypeAndOrName &class_type_or_name,
- Address &dynamic_address,
- Value::ValueType &value_type);
+ Address &dynamic_address) override;
void AppendExceptionBreakpointFunctions(std::vector<const char *> &names,
bool catch_bp, bool throw_bp,
- bool for_expressions);
+ bool for_expressions) override;
void AppendExceptionBreakpointFilterModules(FileSpecList &list,
- const Target &target);
+ const Target &target) override;
- lldb::ValueObjectSP GetExceptionObjectForThread(lldb::ThreadSP thread_sp);
+ lldb::ValueObjectSP
+ GetExceptionObjectForThread(lldb::ThreadSP thread_sp) override;
private:
TypeAndOrName GetTypeInfo(ValueObject &in_value,
More information about the llvm-branch-commits
mailing list