-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[LLDB] Add empty Microsoft ABI language runtime #168941
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-lldb Author: nerix (Nerixyz) ChangesTo support dynamic values and C++ exception breakpoints with the MSVC/Microsoft ABI in the future, this PR adds a minimal/empty language runtime. Since the Itanium ABI didn't resolve any types or create exception breakpoints on windows-msvc, it shouldn't change any behavior. The Microsoft ABI is used in processes with the windows-msvc target. MinGW uses windows-gnu, so it should be unaffected. Full diff: https://github.com/llvm/llvm-project/pull/168941.diff 7 Files Affected:
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
index 727c8290bceb4..699d028151f86 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
@@ -11,4 +11,4 @@ add_lldb_library(lldbPluginCPPRuntime
)
add_subdirectory(ItaniumABI)
-#add_subdirectory(MicrosoftABI)
+add_subdirectory(MicrosoftABI)
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 913678b629f2f..074af4202e658 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -491,3 +491,10 @@ bool CPPLanguageRuntime::IsSymbolARuntimeThunk(const Symbol &symbol) {
return mangled_name.starts_with("_ZTh") || mangled_name.starts_with("_ZTv") ||
mangled_name.starts_with("_ZTc");
}
+
+bool CPPLanguageRuntime::ShouldUseMicrosoftABI(Process *process) {
+ return process->GetTarget()
+ .GetArchitecture()
+ .GetTriple()
+ .isWindowsMSVCEnvironment();
+}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
index 05639e9798917..fc1dd7d249212 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
@@ -81,6 +81,8 @@ class CPPLanguageRuntime : public LanguageRuntime {
bool IsSymbolARuntimeThunk(const Symbol &symbol) override;
+ static bool ShouldUseMicrosoftABI(Process *process);
+
protected:
// Classes that inherit from CPPLanguageRuntime can see and modify these
CPPLanguageRuntime(Process *process);
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 75b00518aac53..cc810c0c837a0 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -397,9 +397,9 @@ TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType(
LanguageRuntime *
ItaniumABILanguageRuntime::CreateInstance(Process *process,
lldb::LanguageType language) {
- // FIXME: We have to check the process and make sure we actually know that
- // this process supports
- // the Itanium ABI.
+ if (ShouldUseMicrosoftABI(process))
+ return nullptr;
+
if (language == eLanguageTypeC_plus_plus ||
language == eLanguageTypeC_plus_plus_03 ||
language == eLanguageTypeC_plus_plus_11 ||
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/CMakeLists.txt b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/CMakeLists.txt
new file mode 100644
index 0000000000000..21e75d3d5b099
--- /dev/null
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_lldb_library(lldbPluginCXXMicrosoftABI PLUGIN
+ MicrosoftABILanguageRuntime.cpp
+
+ LINK_LIBS
+ lldbPluginCPPRuntime
+)
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/MicrosoftABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/MicrosoftABILanguageRuntime.cpp
new file mode 100644
index 0000000000000..bc45b3016a3fe
--- /dev/null
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/MicrosoftABILanguageRuntime.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "MicrosoftABILanguageRuntime.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(MicrosoftABILanguageRuntime, CXXMicrosoftABI)
+
+char MicrosoftABILanguageRuntime::ID = 0;
+
+void MicrosoftABILanguageRuntime::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "Microsoft ABI for the C++ language",
+ CreateInstance);
+}
+
+void MicrosoftABILanguageRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+LanguageRuntime *
+MicrosoftABILanguageRuntime::CreateInstance(Process *process,
+ lldb::LanguageType language) {
+ if (!ShouldUseMicrosoftABI(process))
+ return nullptr;
+
+ if (!(language == eLanguageTypeC_plus_plus ||
+ language == eLanguageTypeC_plus_plus_03 ||
+ language == eLanguageTypeC_plus_plus_11 ||
+ language == eLanguageTypeC_plus_plus_14))
+ return nullptr;
+
+ return new MicrosoftABILanguageRuntime(process);
+}
+
+llvm::Expected<LanguageRuntime::VTableInfo>
+MicrosoftABILanguageRuntime::GetVTableInfo(ValueObject &in_value,
+ bool check_type) {
+ return llvm::createStringError("Not implemented");
+}
+
+bool MicrosoftABILanguageRuntime::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
+ return false;
+}
+
+TypeAndOrName MicrosoftABILanguageRuntime::FixUpDynamicType(
+ const TypeAndOrName &type_and_or_name, ValueObject &static_value) {
+ return type_and_or_name;
+}
+
+bool MicrosoftABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
+ return false;
+}
+
+lldb::BreakpointResolverSP MicrosoftABILanguageRuntime::CreateExceptionResolver(
+ const lldb::BreakpointSP &bkpt, bool catch_bp, bool throw_bp) {
+ return nullptr;
+}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/MicrosoftABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/MicrosoftABILanguageRuntime.h
new file mode 100644
index 0000000000000..20555f9855ec3
--- /dev/null
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/MicrosoftABI/MicrosoftABILanguageRuntime.h
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_MICROSOFTABI_MICROSOFTABILANGUAGERUNTIME_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_MICROSOFTABI_MICROSOFTABILANGUAGERUNTIME_H
+
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/LanguageRuntime.h"
+
+#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
+
+namespace lldb_private {
+
+class MicrosoftABILanguageRuntime : public CPPLanguageRuntime {
+public:
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
+
+ static llvm::StringRef GetPluginNameStatic() { return "microsoft-abi"; }
+
+ static char ID;
+
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || CPPLanguageRuntime::isA(ClassID);
+ }
+
+ static bool classof(const LanguageRuntime *runtime) {
+ return runtime->isA(&ID);
+ }
+
+ llvm::Expected<LanguageRuntime::VTableInfo>
+ GetVTableInfo(ValueObject &in_value, bool check_type) override;
+
+ bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address, Value::ValueType &value_type,
+ llvm::ArrayRef<uint8_t> &local_buffer) override;
+
+ TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) override;
+
+ bool CouldHaveDynamicValue(ValueObject &in_value) override;
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
+ bool throw_bp) override;
+
+private:
+ MicrosoftABILanguageRuntime(Process *process) : CPPLanguageRuntime(process) {}
+};
+
+} // namespace lldb_private
+
+#endif
|
🐧 Linux x64 Test Results
|
| return process->GetTarget() | ||
| .GetArchitecture() | ||
| .GetTriple() | ||
| .isWindowsMSVCEnvironment(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this distinguish whether the target process to be debugged is mingw or msvc style? Does this in the end just determine the style based on which flavour LLDB itself was built as?
Note that one process may include multiple DLLs that use both ABIs. (In particular, most mingw executables link in a bunch of MS DLLs that internally use their C++ ABI - even though we perhaps don't have debug info for them normally.)
And one may want to use a MSVC built LLDB for debugging mingw executables, or vice versa.
See 25c8a06 and 3c86789 for existing options that allow controlling which C++ ABI to use for interpreting things; these options allow controlling this on the level of each individual DLL. Can't the information from those preexisting options be used here, instead of inventing a new and less flexible approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this inherits the style LLDB was built as. The language runtime being tied to a process and language is too coarse for allowing mixed ABIs in different DLLs.
An alternative could be to handle both ABIs in the Itanium plugin (but rename it). So for dynamic types, it could check the module or determine the ABI based on the mangled symbol name. For exception breakpoints, all function names would need to be registered. Would that be a better idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I'm too unfamiliar with the LLDB aspects involved here to be able to have any clue about what you're suggesting (and how much extra complexity it would add) unfortunately... Also, can you give a quick high level explanation of which ABI aspects were covered by the existing switches added in 25c8a06, compared with what aspects of debugging this newly added code covers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, then the changes in 25c8a06 mostly affected how the clang AST is created for modules.
By adding a language runtime that supports the MS ABI, I'm trying to add the capability to downcast references to a base class when using virtual inheritance and to break when C++ exceptions are thrown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see - thanks for the explanation! So whichever way we deal with this, the old option for switching mode for the Clang AST should keep working to the extent it did before. Also CC @alvinhochun.
If it is possible to handle this in a more granular way (tied either to the same options as above) then that's certainly very much appreciated, but I guess it's not a blocker. I'd leave that judgement up to you, if you feel it'd be doable or if it'd be too much mess for a potentially uncommon case.
Btw, I occasionally try to get the LLDB tests running in mingw mode as well. I haven't got that finished up to a state where all tests pass, I'm currently at around 16 tests failing and 1 unexpectedly passing, but haven't had much time to devote to it lately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do want to keep LLDB's ability to debug mixed DLLs from different ABIs simultaneously. Having separate plugins for each ABI won't work here (I think?), because they'd be tied to the same language.
Currently, ItaniumABILanguageRuntime inherits from CPPLanguageRuntime. What about moving the methods from the Itanium ABI to the C++ language runtime plugin? GetDynamicTypeAndAddress and GetVTableInfo would then check for the value's module and branch based on that (to account for 25c8a06). @JDevlieghere do you have any thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you're suggesting is the most pragmatic solution. The alternative is detangling the two and everywhere where we obtain a language runtime today, you would have to specify a language and an ABI and the ABI would be tied (and potentially shared) across modules. I think that's probably a lot of work for little benefit, so I'm fine with going with the more pragmatic approach.
|
|
||
| bool IsSymbolARuntimeThunk(const Symbol &symbol) override; | ||
|
|
||
| static bool ShouldUseMicrosoftABI(Process *process); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than returning a bool, can we have an enum for the C++ runtime ABIs and have this return either Itanium or Microsoft?
To support dynamic values and C++ exception breakpoints with the MSVC/Microsoft ABI in the future, this PR adds a minimal/empty language runtime. Since the Itanium ABI didn't resolve any types or create exception breakpoints on windows-msvc, it shouldn't change any behavior.
The Microsoft ABI is used in processes with the windows-msvc target. MinGW uses windows-gnu, so it should be unaffected.