Unit testing for GDB-side remote memory tagging handling

Include some unit testing for the functions handling the new qMemTags and
QMemTags packets.

gdb/ChangeLog:

2021-03-24  Luis Machado  <luis.machado@linaro.org>

	* remote: Include gdbsupport/selftest.h.
	(test_memory_tagging_functions): New function.
	(_initialize_remote): Register test_memory_tagging_functions.
This commit is contained in:
Luis Machado 2020-06-15 15:22:13 -03:00
parent 2c2e7f87a8
commit 754487e200
2 changed files with 98 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2021-03-24 Luis Machado <luis.machado@linaro.org>
* remote: Include gdbsupport/selftest.h.
(test_memory_tagging_functions): New function.
(_initialize_remote): Register test_memory_tagging_functions.
2021-03-24 Luis Machado <luis.machado@linaro.org>
* remote.c (PACKET_memory_tagging_feature): New enum.

View File

@ -79,6 +79,7 @@
#include <algorithm>
#include <unordered_map>
#include "async-event.h"
#include "gdbsupport/selftest.h"
/* The remote target. */
@ -14620,6 +14621,92 @@ remote_target::store_memtags (CORE_ADDR address, size_t len,
return packet_check_result (rs->buf.data ()) == PACKET_OK;
}
#if GDB_SELF_TEST
namespace selftests {
static void
test_memory_tagging_functions ()
{
remote_target remote;
struct packet_config *config
= &remote_protocol_packets[PACKET_memory_tagging_feature];
scoped_restore restore_memtag_support_
= make_scoped_restore (&config->support);
/* Test memory tagging packet support. */
config->support = PACKET_SUPPORT_UNKNOWN;
SELF_CHECK (remote.supports_memory_tagging () == false);
config->support = PACKET_DISABLE;
SELF_CHECK (remote.supports_memory_tagging () == false);
config->support = PACKET_ENABLE;
SELF_CHECK (remote.supports_memory_tagging () == true);
/* Setup testing. */
gdb::char_vector packet;
gdb::byte_vector tags, bv;
std::string expected, reply;
packet.resize (32000);
/* Test creating a qMemTags request. */
expected = "qMemTags:0,0:0";
create_fetch_memtags_request (packet, 0x0, 0x0, 0);
SELF_CHECK (strcmp (packet.data (), expected.c_str ()) == 0);
expected = "qMemTags:deadbeef,10:1";
create_fetch_memtags_request (packet, 0xdeadbeef, 16, 1);
SELF_CHECK (strcmp (packet.data (), expected.c_str ()) == 0);
/* Test parsing a qMemTags reply. */
/* Error reply, tags vector unmodified. */
reply = "E00";
strcpy (packet.data (), reply.c_str ());
tags.resize (0);
SELF_CHECK (parse_fetch_memtags_reply (packet, tags) == false);
SELF_CHECK (tags.size () == 0);
/* Valid reply, tags vector updated. */
tags.resize (0);
bv.resize (0);
for (int i = 0; i < 5; i++)
bv.push_back (i);
reply = "m" + bin2hex (bv.data (), bv.size ());
strcpy (packet.data (), reply.c_str ());
SELF_CHECK (parse_fetch_memtags_reply (packet, tags) == true);
SELF_CHECK (tags.size () == 5);
for (int i = 0; i < 5; i++)
SELF_CHECK (tags[i] == i);
/* Test creating a QMemTags request. */
/* Empty tag data. */
tags.resize (0);
expected = "QMemTags:0,0:0:";
create_store_memtags_request (packet, 0x0, 0x0, 0, tags);
SELF_CHECK (memcmp (packet.data (), expected.c_str (),
expected.length ()) == 0);
/* Non-empty tag data. */
tags.resize (0);
for (int i = 0; i < 5; i++)
tags.push_back (i);
expected = "QMemTags:deadbeef,ff:1:0001020304";
create_store_memtags_request (packet, 0xdeadbeef, 255, 1, tags);
SELF_CHECK (memcmp (packet.data (), expected.c_str (),
expected.length ()) == 0);
}
} // namespace selftests
#endif /* GDB_SELF_TEST */
void _initialize_remote ();
void
_initialize_remote ()
@ -15153,4 +15240,9 @@ from the target."),
/* Eventually initialize fileio. See fileio.c */
initialize_remote_fileio (&remote_set_cmdlist, &remote_show_cmdlist);
#if GDB_SELF_TEST
selftests::register_test ("remote_memory_tagging",
selftests::test_memory_tagging_functions);
#endif
}