• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Révision47b87d151e5b7a94a0f3df6e46c7326f58a41f9f (tree)
l'heure2020-06-16 21:58:33
AuteurLuis Machado <luis.machado@lina...>
CommiterLuis Machado

Message de Log

Extend "x" and "print" commands to support memory tagging

Extend the "x" and "print" commands to make use of memory tagging
functionality, if supported by the architecture.

The "print" command will point our any possible tag mismatches it finds
when dealing with pointers and such a pointer is tagged. No additional
modifiers are needed.

The "x" command has a new 'm' modifier that will enable displaying of
allocation tags alongside the data dump. It will display one allocation
tag per line.

gdb/ChangeLog:

YYYY-MM-DD Luis Machado <luis.machado@linaro.org>

* printcmd.c (decode_format): Handle the 'm' modifier.
(do_examine): Display allocation tags when required/supported.
(should_validate_memtags): New function.
(print_command_1): Display memory tag mismatches.
* valprint.h (struct format_data) <print_tags>: New field.

Change Summary

Modification

--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -54,6 +54,7 @@
5454 #include "gdbsupport/byte-vector.h"
5555 #include "gdbsupport/gdb_optional.h"
5656 #include "gdbsupport/rsp-low.h"
57+#include "infrun.h" /* For memtag setting. */
5758
5859 /* Chain containing all defined mtag subcommands. */
5960
@@ -210,6 +211,7 @@ decode_format (const char **string_ptr, int oformat, int osize)
210211 val.size = '?';
211212 val.count = 1;
212213 val.raw = 0;
214+ val.print_tags = false;
213215
214216 if (*p == '-')
215217 {
@@ -232,6 +234,11 @@ decode_format (const char **string_ptr, int oformat, int osize)
232234 val.raw = 1;
233235 p++;
234236 }
237+ else if (*p == 'm')
238+ {
239+ val.print_tags = true;
240+ p++;
241+ }
235242 else if (*p >= 'a' && *p <= 'z')
236243 val.format = *p++;
237244 else
@@ -1106,12 +1113,43 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
11061113 need_to_update_next_address = 1;
11071114 }
11081115
1116+ /* Whether we need to print the memory tag information for the current
1117+ address range. */
1118+ bool print_range_tag = true;
1119+ uint32_t gsize = gdbarch_memtag_granule_size (gdbarch);
1120+
11091121 /* Print as many objects as specified in COUNT, at most maxelts per line,
11101122 with the address of the next one at the start of each line. */
11111123
11121124 while (count > 0)
11131125 {
11141126 QUIT;
1127+
1128+ CORE_ADDR tag_laddr = 0, tag_haddr = 0;
1129+
1130+ /* Print the memory tag information if requested. */
1131+ if (memtag && target_supports_memory_tagging ()
1132+ && fmt.print_tags && print_range_tag)
1133+ {
1134+ tag_laddr = align_down (next_address, gsize);
1135+ tag_haddr = align_down (next_address + gsize, gsize);
1136+
1137+ struct value *v_addr
1138+ = value_from_ulongest (builtin_type (gdbarch)->builtin_data_ptr,
1139+ tag_laddr);
1140+ std::string atag = gdbarch_memtag_to_string (gdbarch, v_addr,
1141+ tag_allocation);
1142+
1143+ if (!atag.empty ())
1144+ {
1145+ printf_filtered (_("<Allocation Tag %s for range [%s,%s)>\n"),
1146+ atag.c_str (),
1147+ paddress (gdbarch, tag_laddr),
1148+ paddress (gdbarch, tag_haddr));
1149+ }
1150+ print_range_tag = false;
1151+ }
1152+
11151153 if (format == 'i')
11161154 fputs_filtered (pc_prefix (next_address), gdb_stdout);
11171155 print_address (next_gdbarch, next_address, gdb_stdout);
@@ -1142,6 +1180,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
11421180 /* Display any branch delay slots following the final insn. */
11431181 if (format == 'i' && count == 1)
11441182 count += branch_delay_insns;
1183+
1184+ /* Update the tag range based on the current address being
1185+ processed. */
1186+ if (tag_haddr <= next_address)
1187+ print_range_tag = true;
11451188 }
11461189 printf_filtered ("\n");
11471190 }
@@ -1214,6 +1257,25 @@ print_value (value *val, const value_print_options &opts)
12141257 annotate_value_history_end ();
12151258 }
12161259
1260+/* Returns true if memory tags should be validated. False otherwise. */
1261+
1262+static bool
1263+should_validate_memtags (struct value *value)
1264+{
1265+ if (memtag && target_supports_memory_tagging ())
1266+ {
1267+ gdb_assert (value && value_type (value));
1268+
1269+ enum type_code code = value_type (value)->code ();
1270+
1271+ return (code == TYPE_CODE_PTR
1272+ || code == TYPE_CODE_REF
1273+ || code == TYPE_CODE_METHODPTR
1274+ || code == TYPE_CODE_MEMBERPTR);
1275+ }
1276+ return false;
1277+}
1278+
12171279 /* Helper for parsing arguments for print_command_1. */
12181280
12191281 static struct value *
@@ -1249,7 +1311,21 @@ print_command_1 (const char *args, int voidprint)
12491311
12501312 if (voidprint || (val && value_type (val) &&
12511313 value_type (val)->code () != TYPE_CODE_VOID))
1252- print_value (val, print_opts);
1314+ {
1315+ /* If memory tagging validation is on, check if the tag is valid. */
1316+ if (should_validate_memtags (val)
1317+ && gdbarch_memtag_mismatch_p (target_gdbarch (), val))
1318+ {
1319+ std::string ltag = gdbarch_memtag_to_string (target_gdbarch (),
1320+ val, tag_logical);
1321+ std::string atag = gdbarch_memtag_to_string (target_gdbarch (),
1322+ val, tag_allocation);
1323+ printf_filtered (_("Logical tag (%s) does not match the "
1324+ "allocation tag (%s).\n"),
1325+ ltag.c_str (), atag.c_str ());
1326+ }
1327+ print_value (val, print_opts);
1328+ }
12531329 }
12541330
12551331 /* See valprint.h. */
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -241,6 +241,7 @@ struct format_data
241241 int count;
242242 char format;
243243 char size;
244+ bool print_tags;
244245
245246 /* True if the value should be printed raw -- that is, bypassing
246247 python-based formatters. */