Skip to content

Commit 8d58fbd

Browse files
committed
[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
1 parent d57a587 commit 8d58fbd

File tree

10 files changed

+59
-3
lines changed

10 files changed

+59
-3
lines changed

lldb/include/lldb/Host/common/NativeProcessProtocol.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,9 @@ class NativeProcessProtocol {
243243
pass_signals = (1u << 3),
244244
auxv = (1u << 4),
245245
libraries_svr4 = (1u << 5),
246+
memory_tagging = (1u << 6),
246247

247-
LLVM_MARK_AS_BITMASK_ENUM(libraries_svr4)
248+
LLVM_MARK_AS_BITMASK_ENUM(memory_tagging)
248249
};
249250

250251
class Factory {

lldb/include/lldb/Target/Process.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,6 +2721,13 @@ void PruneThreadPlans();
27212721
/// false.
27222722
bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp);
27232723

2724+
/// Check whether the process supports memory tagging.
2725+
///
2726+
/// \return
2727+
/// true if the process supports memory tagging,
2728+
/// false otherwise.
2729+
virtual bool SupportsMemoryTagging() { return false; }
2730+
27242731
// Type definitions
27252732
typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP>
27262733
LanguageRuntimeCollection;

lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ def add_qSupported_packets(self, client_features=[]):
858858
"multiprocess",
859859
"fork-events",
860860
"vfork-events",
861+
"memory-tagging",
861862
]
862863

863864
def parse_qSupported_response(self, context):

lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,20 @@
5353
#include <sys/user.h>
5454
#include <sys/wait.h>
5555

56+
#ifdef __aarch64__
57+
#include <asm/hwcap.h>
58+
#include <sys/auxv.h>
59+
#endif
60+
5661
// Support hardware breakpoints in case it has not been defined
5762
#ifndef TRAP_HWBKPT
5863
#define TRAP_HWBKPT 4
5964
#endif
6065

66+
#ifndef HWCAP2_MTE
67+
#define HWCAP2_MTE (1 << 18)
68+
#endif
69+
6170
using namespace lldb;
6271
using namespace lldb_private;
6372
using namespace lldb_private::process_linux;
@@ -283,8 +292,17 @@ NativeProcessLinux::Factory::Attach(
283292

284293
NativeProcessLinux::Extension
285294
NativeProcessLinux::Factory::GetSupportedExtensions() const {
286-
return Extension::multiprocess | Extension::fork | Extension::vfork |
287-
Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
295+
NativeProcessLinux::Extension supported =
296+
Extension::multiprocess | Extension::fork | Extension::vfork |
297+
Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
298+
299+
#ifdef __aarch64__
300+
// At this point we do not have a process so read auxv directly.
301+
if ((getauxval(AT_HWCAP2) & HWCAP2_MTE))
302+
supported |= Extension::memory_tagging;
303+
#endif
304+
305+
return supported;
288306
}
289307

290308
// Public Instance Methods

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
311311
m_supports_multiprocess = eLazyBoolNo;
312312
m_supports_qEcho = eLazyBoolNo;
313313
m_supports_QPassSignals = eLazyBoolNo;
314+
m_supports_memory_tagging = eLazyBoolNo;
314315

315316
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
316317
// not, we assume no limit
@@ -356,6 +357,8 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
356357
m_supports_QPassSignals = eLazyBoolYes;
357358
else if (x == "multiprocess+")
358359
m_supports_multiprocess = eLazyBoolYes;
360+
else if (x == "memory-tagging+")
361+
m_supports_memory_tagging = eLazyBoolYes;
359362
// Look for a list of compressions in the features list e.g.
360363
// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
361364
// deflate,lzma
@@ -576,6 +579,13 @@ bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
576579
return m_supports_jGetSharedCacheInfo;
577580
}
578581

582+
bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
583+
if (m_supports_memory_tagging == eLazyBoolCalculate) {
584+
GetRemoteQSupported();
585+
}
586+
return m_supports_memory_tagging == eLazyBoolYes;
587+
}
588+
579589
bool GDBRemoteCommunicationClient::GetxPacketSupported() {
580590
if (m_supports_x == eLazyBoolCalculate) {
581591
StringExtractorGDBRemote response;

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
451451

452452
bool GetSharedCacheInfoSupported();
453453

454+
bool GetMemoryTaggingSupported();
455+
454456
/// Use qOffsets to query the offset used when relocating the target
455457
/// executable. If successful, the returned structure will contain at least
456458
/// one value in the offsets field.
@@ -558,6 +560,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
558560
LazyBool m_supports_QPassSignals = eLazyBoolCalculate;
559561
LazyBool m_supports_error_string_reply = eLazyBoolCalculate;
560562
LazyBool m_supports_multiprocess = eLazyBoolCalculate;
563+
LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
561564

562565
bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
563566
m_supports_qUserName : 1, m_supports_qGroupName : 1,

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,8 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
36083608
ret.push_back("qXfer:auxv:read+");
36093609
if (bool(plugin_features & Extension::libraries_svr4))
36103610
ret.push_back("qXfer:libraries-svr4:read+");
3611+
if (bool(plugin_features & Extension::memory_tagging))
3612+
ret.push_back("memory-tagging+");
36113613

36123614
// check for client features
36133615
m_extensions_supported = {};

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,6 +2767,10 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
27672767
return 0;
27682768
}
27692769

2770+
bool ProcessGDBRemote::SupportsMemoryTagging() {
2771+
return m_gdb_comm.GetMemoryTaggingSupported();
2772+
}
2773+
27702774
Status ProcessGDBRemote::WriteObjectFile(
27712775
std::vector<ObjectFile::LoadableData> entries) {
27722776
Status error;

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ class ProcessGDBRemote : public Process,
235235
friend class GDBRemoteCommunicationClient;
236236
friend class GDBRemoteRegisterContext;
237237

238+
bool SupportsMemoryTagging() override;
239+
238240
/// Broadcaster event bits definitions.
239241
enum {
240242
eBroadcastBitAsyncContinue = (1 << 0),

lldb/test/API/tools/lldb-server/TestLldbGdbServer.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,14 @@ def test_qSupported_vfork_events_without_multiprocess(self):
10251025
self.assertEqual(supported_dict.get('fork-events', '-'), '-')
10261026
self.assertEqual(supported_dict.get('vfork-events', '-'), '-')
10271027

1028+
# We need to be able to self.runCmd to get cpuinfo,
1029+
# which is not possible when using a remote platform.
1030+
@skipIfRemote
1031+
def test_qSupported_memory_tagging(self):
1032+
supported_dict = self.get_qSupported_dict()
1033+
self.assertEqual(supported_dict.get("memory-tagging", '-'),
1034+
'+' if self.isAArch64MTE() else '-')
1035+
10281036
@skipIfWindows # No pty support to test any inferior output
10291037
def test_written_M_content_reads_back_correctly(self):
10301038
self.build()

0 commit comments

Comments
 (0)