• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

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

Revisión4167e8660e929fc8d20e3ec578713ecff6a9d1ec (tree)
Tiempo2020-06-26 01:23:39
AutorLuis Machado <luis.machado@lina...>
CommiterLuis Machado

Log Message

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 out any possible tag mismatches it finds
when dealing with pointers, in case such a pointer is tagged. No additional
modifiers are needed.

Suppose we have a pointer "p" with value 0x1234 (logical tag 0x0) and that we
have an allocation tag of 0x1 for that particular area of memory. This is the
expected output:

(gdb) p/x p
Logical tag (0x0) does not match the allocation tag (0x1).
$1 = 0x1234

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.

AArch64 has a tag granule of 16 bytes, which means we can have one tag for
every 16 bytes of memory. In this case, this is what the "x" command will
display with the new 'm' modifier:

(gdb) x/32bxm p
<Allocation Tag 0x1 for range [0x1230,0x1240)>
0x1234: 0x01 0x02 0x00 0x00 0x00 0x00 0x00 0x00
0x123c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
<Allocation Tag 0x1 for range [0x1240,0x1250)>
0x1244: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x124c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

(gdb) x/4gxm a
<Allocation Tag 0x1 for range [0x1230,0x1240)>
0x1234: 0x0000000000000201 0x0000000000000000
<Allocation Tag 0x1 for range [0x1240,0x1250)>
0x1244: 0x0000000000000000 0x0000000000000000

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.

Cambiar Resumen

Diferencia incremental

--- 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,47 @@ 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 (fmt.print_tags && print_range_tag && memtag
1132+ && target_supports_memory_tagging ())
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+
1141+ if (gdbarch_tagged_address_p (target_gdbarch (), v_addr))
1142+ {
1143+ std::string atag = gdbarch_memtag_to_string (gdbarch, v_addr,
1144+ tag_allocation);
1145+
1146+ if (!atag.empty ())
1147+ {
1148+ printf_filtered (_("<Allocation Tag %s for range [%s,%s)>\n"),
1149+ atag.c_str (),
1150+ paddress (gdbarch, tag_laddr),
1151+ paddress (gdbarch, tag_haddr));
1152+ }
1153+ }
1154+ print_range_tag = false;
1155+ }
1156+
11151157 if (format == 'i')
11161158 fputs_filtered (pc_prefix (next_address), gdb_stdout);
11171159 print_address (next_gdbarch, next_address, gdb_stdout);
@@ -1142,6 +1184,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
11421184 /* Display any branch delay slots following the final insn. */
11431185 if (format == 'i' && count == 1)
11441186 count += branch_delay_insns;
1187+
1188+ /* Update the tag range based on the current address being
1189+ processed. */
1190+ if (tag_haddr <= next_address)
1191+ print_range_tag = true;
11451192 }
11461193 printf_filtered ("\n");
11471194 }
@@ -1214,6 +1261,26 @@ print_value (value *val, const value_print_options &opts)
12141261 annotate_value_history_end ();
12151262 }
12161263
1264+/* Returns true if memory tags should be validated. False otherwise. */
1265+
1266+static bool
1267+should_validate_memtags (struct value *value)
1268+{
1269+ if (memtag && target_supports_memory_tagging ()
1270+ && gdbarch_tagged_address_p (target_gdbarch (), value))
1271+ {
1272+ gdb_assert (value && value_type (value));
1273+
1274+ enum type_code code = value_type (value)->code ();
1275+
1276+ return (code == TYPE_CODE_PTR
1277+ || code == TYPE_CODE_REF
1278+ || code == TYPE_CODE_METHODPTR
1279+ || code == TYPE_CODE_MEMBERPTR);
1280+ }
1281+ return false;
1282+}
1283+
12171284 /* Helper for parsing arguments for print_command_1. */
12181285
12191286 static struct value *
@@ -1249,7 +1316,21 @@ print_command_1 (const char *args, int voidprint)
12491316
12501317 if (voidprint || (val && value_type (val) &&
12511318 value_type (val)->code () != TYPE_CODE_VOID))
1252- print_value (val, print_opts);
1319+ {
1320+ /* If memory tagging validation is on, check if the tag is valid. */
1321+ if (should_validate_memtags (val)
1322+ && gdbarch_memtag_mismatch_p (target_gdbarch (), val))
1323+ {
1324+ std::string ltag = gdbarch_memtag_to_string (target_gdbarch (),
1325+ val, tag_logical);
1326+ std::string atag = gdbarch_memtag_to_string (target_gdbarch (),
1327+ val, tag_allocation);
1328+ printf_filtered (_("Logical tag (%s) does not match the "
1329+ "allocation tag (%s).\n"),
1330+ ltag.c_str (), atag.c_str ());
1331+ }
1332+ print_value (val, print_opts);
1333+ }
12531334 }
12541335
12551336 /* 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. */