forked from OSchip/llvm-project
[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
This commit is contained in:
parent
d57a5879ab
commit
8d58fbd09e
|
@ -243,8 +243,9 @@ public:
|
|||
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 {
|
||||
|
|
|
@ -2721,6 +2721,13 @@ protected:
|
|||
/// 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;
|
||||
|
|
|
@ -858,6 +858,7 @@ class GdbRemoteTestCaseBase(Base):
|
|||
"multiprocess",
|
||||
"fork-events",
|
||||
"vfork-events",
|
||||
"memory-tagging",
|
||||
]
|
||||
|
||||
def parse_qSupported_response(self, context):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -451,6 +451,8 @@ public:
|
|||
|
||||
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 @@ protected:
|
|||
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,
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -235,6 +235,8 @@ protected:
|
|||
friend class GDBRemoteCommunicationClient;
|
||||
friend class GDBRemoteRegisterContext;
|
||||
|
||||
bool SupportsMemoryTagging() override;
|
||||
|
||||
/// Broadcaster event bits definitions.
|
||||
enum {
|
||||
eBroadcastBitAsyncContinue = (1 << 0),
|
||||
|
|
|
@ -1025,6 +1025,14 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcod
|
|||
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()
|
||||
|
|
Loading…
Reference in New Issue