[Lldb-commits] [lldb] 8d58fbd - [lldb][AArch64] Add memory-tagging qSupported feature
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 24 07:43:28 PDT 2021
Author: David Spickett
Date: 2021-06-24T15:43:20+01:00
New Revision: 8d58fbd09efb443d92842a0d101348cda06d7253
URL: https://github.com/llvm/llvm-project/commit/8d58fbd09efb443d92842a0d101348cda06d7253
DIFF: https://github.com/llvm/llvm-project/commit/8d58fbd09efb443d92842a0d101348cda06d7253.diff
LOG: [lldb][AArch64] Add memory-tagging qSupported feature
This feature "memory-tagging+" indicates that lldb-server
supports memory tagging packets. (added in a later patch)
We check HWCAP2_MTE to decide whether to enable this
feature for Linux.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D97282
Added:
Modified:
lldb/include/lldb/Host/common/NativeProcessProtocol.h
lldb/include/lldb/Target/Process.h
lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
Removed:
################################################################################
diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
index a8ec6306e1d5a..fc5435cf4074f 100644
--- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -243,8 +243,9 @@ class NativeProcessProtocol {
pass_signals = (1u << 3),
auxv = (1u << 4),
libraries_svr4 = (1u << 5),
+ memory_tagging = (1u << 6),
- LLVM_MARK_AS_BITMASK_ENUM(libraries_svr4)
+ LLVM_MARK_AS_BITMASK_ENUM(memory_tagging)
};
class Factory {
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 65806084a7ae1..c849bd7766018 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2721,6 +2721,13 @@ void PruneThreadPlans();
/// false.
bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp);
+ /// Check whether the process supports memory tagging.
+ ///
+ /// \return
+ /// true if the process supports memory tagging,
+ /// false otherwise.
+ virtual bool SupportsMemoryTagging() { return false; }
+
// Type definitions
typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP>
LanguageRuntimeCollection;
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
index 67bffdd5931a8..b6243af54350a 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
@@ -858,6 +858,7 @@ def add_qSupported_packets(self, client_features=[]):
"multiprocess",
"fork-events",
"vfork-events",
+ "memory-tagging",
]
def parse_qSupported_response(self, context):
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 62c2a725779ee..2d53972b69b74 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -53,11 +53,20 @@
#include <sys/user.h>
#include <sys/wait.h>
+#ifdef __aarch64__
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+#endif
+
// Support hardware breakpoints in case it has not been defined
#ifndef TRAP_HWBKPT
#define TRAP_HWBKPT 4
#endif
+#ifndef HWCAP2_MTE
+#define HWCAP2_MTE (1 << 18)
+#endif
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_linux;
@@ -283,8 +292,17 @@ NativeProcessLinux::Factory::Attach(
NativeProcessLinux::Extension
NativeProcessLinux::Factory::GetSupportedExtensions() const {
- return Extension::multiprocess | Extension::fork | Extension::vfork |
- Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+ NativeProcessLinux::Extension supported =
+ Extension::multiprocess | Extension::fork | Extension::vfork |
+ Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+
+#ifdef __aarch64__
+ // At this point we do not have a process so read auxv directly.
+ if ((getauxval(AT_HWCAP2) & HWCAP2_MTE))
+ supported |= Extension::memory_tagging;
+#endif
+
+ return supported;
}
// Public Instance Methods
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 78da9a060a754..db50afcfa33da 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -311,6 +311,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_multiprocess = eLazyBoolNo;
m_supports_qEcho = eLazyBoolNo;
m_supports_QPassSignals = eLazyBoolNo;
+ m_supports_memory_tagging = eLazyBoolNo;
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
// not, we assume no limit
@@ -356,6 +357,8 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_QPassSignals = eLazyBoolYes;
else if (x == "multiprocess+")
m_supports_multiprocess = eLazyBoolYes;
+ else if (x == "memory-tagging+")
+ m_supports_memory_tagging = eLazyBoolYes;
// Look for a list of compressions in the features list e.g.
// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
// deflate,lzma
@@ -576,6 +579,13 @@ bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
return m_supports_jGetSharedCacheInfo;
}
+bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
+ if (m_supports_memory_tagging == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_memory_tagging == eLazyBoolYes;
+}
+
bool GDBRemoteCommunicationClient::GetxPacketSupported() {
if (m_supports_x == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 50ac5c5fccdfa..599020e4e78fa 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -451,6 +451,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
bool GetSharedCacheInfoSupported();
+ bool GetMemoryTaggingSupported();
+
/// Use qOffsets to query the offset used when relocating the target
/// executable. If successful, the returned structure will contain at least
/// one value in the offsets field.
@@ -558,6 +560,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
LazyBool m_supports_QPassSignals = eLazyBoolCalculate;
LazyBool m_supports_error_string_reply = eLazyBoolCalculate;
LazyBool m_supports_multiprocess = eLazyBoolCalculate;
+ LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
m_supports_qUserName : 1, m_supports_qGroupName : 1,
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index b6982f47df93b..71c64672e4fce 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -3608,6 +3608,8 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
ret.push_back("qXfer:auxv:read+");
if (bool(plugin_features & Extension::libraries_svr4))
ret.push_back("qXfer:libraries-svr4:read+");
+ if (bool(plugin_features & Extension::memory_tagging))
+ ret.push_back("memory-tagging+");
// check for client features
m_extensions_supported = {};
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index dbae76e99b3d7..bd6c548f708a9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -2767,6 +2767,10 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
return 0;
}
+bool ProcessGDBRemote::SupportsMemoryTagging() {
+ return m_gdb_comm.GetMemoryTaggingSupported();
+}
+
Status ProcessGDBRemote::WriteObjectFile(
std::vector<ObjectFile::LoadableData> entries) {
Status error;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 032067eaafdc7..b69016ab5ae6b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -235,6 +235,8 @@ class ProcessGDBRemote : public Process,
friend class GDBRemoteCommunicationClient;
friend class GDBRemoteRegisterContext;
+ bool SupportsMemoryTagging() override;
+
/// Broadcaster event bits definitions.
enum {
eBroadcastBitAsyncContinue = (1 << 0),
diff --git a/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py b/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
index 93e9ec61a0432..96337e46aaace 100644
--- a/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
+++ b/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
@@ -1025,6 +1025,14 @@ def test_qSupported_vfork_events_without_multiprocess(self):
self.assertEqual(supported_dict.get('fork-events', '-'), '-')
self.assertEqual(supported_dict.get('vfork-events', '-'), '-')
+ # We need to be able to self.runCmd to get cpuinfo,
+ # which is not possible when using a remote platform.
+ @skipIfRemote
+ def test_qSupported_memory_tagging(self):
+ supported_dict = self.get_qSupported_dict()
+ self.assertEqual(supported_dict.get("memory-tagging", '-'),
+ '+' if self.isAArch64MTE() else '-')
+
@skipIfWindows # No pty support to test any inferior output
def test_written_M_content_reads_back_correctly(self):
self.build()
More information about the lldb-commits
mailing list