From 5ea091a8174bcce78839156bd044831cb5211d06 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 31 Mar 2021 14:57:35 +0100 Subject: [lldb][AArch64] Add memory tag writing to lldb This adds memory tag writing to Process and the GDB remote code. Supporting work for the "memory tag write" command. (to follow) Process WriteMemoryTags is similair to ReadMemoryTags. It will pack the tags then call DoWriteMemoryTags. That function will send the QMemTags packet to the gdb-remote. The QMemTags packet follows the GDB specification in: https://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html#General-Query-Packets Note that lldb-server will be treating partial writes as complete failures. So lldb doesn't need to handle the partial write case in any special way. Reviewed By: omjavaid Differential Revision: https://reviews.llvm.org/D105181 --- .../GDBRemoteCommunicationClientTest.cpp | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp') diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp index 0773396..37ed0f7 100644 --- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -17,6 +17,7 @@ #include "llvm/Testing/Support/Error.h" #include "gmock/gmock.h" #include +#include using namespace lldb_private::process_gdb_remote; using namespace lldb_private; @@ -531,3 +532,51 @@ TEST_F(GDBRemoteCommunicationClientTest, ReadMemoryTags) { check_qmemtags(client, server, 32, "qMemTags:def0,20:1", "m01020", llvm::None); } + +static void check_Qmemtags(TestClient &client, MockServer &server, + lldb::addr_t addr, size_t len, int32_t type, + const std::vector &tags, const char *packet, + llvm::StringRef response, bool should_succeed) { + const auto &WriteMemoryTags = [&]() { + std::future result = std::async(std::launch::async, [&] { + return client.WriteMemoryTags(addr, len, type, tags); + }); + + HandlePacket(server, packet, response); + return result.get(); + }; + + auto result = WriteMemoryTags(); + if (should_succeed) + ASSERT_TRUE(result.Success()); + else + ASSERT_TRUE(result.Fail()); +} + +TEST_F(GDBRemoteCommunicationClientTest, WriteMemoryTags) { + check_Qmemtags(client, server, 0xABCD, 0x20, 1, + std::vector{0x12, 0x34}, "QMemTags:abcd,20:1:1234", + "OK", true); + + // The GDB layer doesn't care that the number of tags != + // the length of the write. + check_Qmemtags(client, server, 0x4321, 0x20, 9, std::vector{}, + "QMemTags:4321,20:9:", "OK", true); + + check_Qmemtags(client, server, 0x8877, 0x123, 0x34, + std::vector{0x55, 0x66, 0x77}, + "QMemTags:8877,123:34:556677", "E01", false); + + // Type is a signed integer but is packed as its raw bytes, + // instead of having a +/-. + check_Qmemtags(client, server, 0x456789, 0, -1, std::vector{0x99}, + "QMemTags:456789,0:ffffffff:99", "E03", false); + check_Qmemtags(client, server, 0x456789, 0, + std::numeric_limits::max(), + std::vector{0x99}, "QMemTags:456789,0:7fffffff:99", + "E03", false); + check_Qmemtags(client, server, 0x456789, 0, + std::numeric_limits::min(), + std::vector{0x99}, "QMemTags:456789,0:80000000:99", + "E03", false); +} -- cgit v1.1