GNU Binutils with patches for OS216
修订版 | 193b2822035263a2c4bb5118a470fc1d0281eb84 (tree) |
---|---|
时间 | 2020-06-26 01:23:38 |
作者 | Luis Machado <luis.machado@lina...> |
Commiter | Luis Machado |
New target methods for memory tagging support
This patch starts adding some of the generic pieces to accomodate memory
tagging.
We have three new target methods:
- supports_memory_tagging: Checks if the target supports memory tagging. This
- fetch_memtags: Fetches the allocation tags associated with a particular
- store_memtags: Stores a set of allocation tags for a particular memory
It also adds a control option for enabling/disabling memory tagging
manually: set memory-tagging on/off.
The default is "on", with GDB making its use conditional to the
architecture supporting memory tagging.
gdb/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org>
* printcmd.c (memtag): New static global.
(show_memtag): New function.
(_initialize_printcmd): Add set/show memory-tagging command.
* remote.c (remote_target) <supports_memory_tagging>: New method
override.
<fetch_memtags>: New method override.
<store_memtags>: New method override.
(remote_target::supports_memory_tagging): New method.
(remote_target::fetch_memtags): New method.
(remote_target::store_memtags): New method.
* target-delegates.c
(dummy_target) <supports_memory_tagging>: New method override.
<fetch_memtags>: New method override.
<store_memtags>: New method override.
(debug_target) <supports_memory_tagging>: New method override.
<fetch_memtags>: New method override.
<store_memtags>: New method override.
(target_ops::supports_memory_tagging): New method.
(target_ops::fetch_memtags): New method.
(target_ops::store_memtags): New method.
(dummy_target::supports_memory_tagging): New method.
(dummy_target::fetch_memtags): New method.
(dummy_target::store_memtags): New method.
(debug_target::supports_memory_tagging): New method.
(debug_target::fetch_memtags): New method.
(debug_target::store_memtags): New method.
* target.h (struct target_ops) <supports_memory_tagging>: New virtual
method.
<fetch_memtags: New virtual method.
<store_memtags>: New virtual method.
(target_supports_memory_tagging): Define.
(target_fetch_memtags): Define.
(target_store_memtags): Define.
@@ -84,6 +84,24 @@ static CORE_ADDR last_examine_address; | ||
84 | 84 | |
85 | 85 | static value_ref_ptr last_examine_value; |
86 | 86 | |
87 | +/* If TRUE (default), and the architecture supports it, GDB will attempt to use | |
88 | + the memory tagging infrastructure to validate certain memory accesses. It | |
89 | + will also report memory tag violations alongside a SIGSEGV signal. | |
90 | + | |
91 | + If FALSE, GDB will not use memory tagging in any way, and debugging will work | |
92 | + in the standard way. */ | |
93 | +static bool memtag = true; | |
94 | + | |
95 | +static void | |
96 | +show_memtag (struct ui_file *file, int from_tty, | |
97 | + struct cmd_list_element *c, | |
98 | + const char *value) | |
99 | +{ | |
100 | + fprintf_filtered (file, | |
101 | + _("Use of memory tagging infrastructure is \"%s\".\n"), | |
102 | + value); | |
103 | +} | |
104 | + | |
87 | 105 | /* Largest offset between a symbolic value and an address, that will be |
88 | 106 | printed as `0x1234 <symbol+offset>'. */ |
89 | 107 |
@@ -2883,4 +2901,14 @@ Construct a GDB command and then evaluate it.\n\ | ||
2883 | 2901 | Usage: eval \"format string\", ARG1, ARG2, ARG3, ..., ARGN\n\ |
2884 | 2902 | Convert the arguments to a string as \"printf\" would, but then\n\ |
2885 | 2903 | treat this string as a command line, and evaluate it.")); |
2904 | + | |
2905 | + add_setshow_boolean_cmd ("memory-tagging", class_support, | |
2906 | + &memtag, _("\ | |
2907 | +Set whether the debugger should use memory tagging infrastructure."), _("\ | |
2908 | +Show whether the debugger should use memory tagging infrastructure."), _("\ | |
2909 | +If on, gdb will attempt to validate memory tags and will warn the user if\n\ | |
2910 | +certain operations have illegal tags."), | |
2911 | + NULL, | |
2912 | + show_memtag, | |
2913 | + &setlist, &showlist); | |
2886 | 2914 | } |
@@ -685,6 +685,16 @@ public: | ||
685 | 685 | int remove_exec_catchpoint (int) override; |
686 | 686 | enum exec_direction_kind execution_direction () override; |
687 | 687 | |
688 | + bool supports_memory_tagging () override; | |
689 | + | |
690 | + /* Read memory tags via the qMemTags packet */ | |
691 | + int fetch_memtags (CORE_ADDR address, size_t len, | |
692 | + gdb::byte_vector &tags) override; | |
693 | + | |
694 | + /* Write allocation tags via the QMemTags packet. */ | |
695 | + int store_memtags (CORE_ADDR address, size_t len, | |
696 | + const gdb::byte_vector &tags) override; | |
697 | + | |
688 | 698 | public: /* Remote specific methods. */ |
689 | 699 | |
690 | 700 | void remote_download_command_source (int num, ULONGEST addr, |
@@ -14366,6 +14376,32 @@ set_range_stepping (const char *ignore_args, int from_tty, | ||
14366 | 14376 | } |
14367 | 14377 | } |
14368 | 14378 | |
14379 | +/* Implement the "supports_memory_tagging" target_ops method. */ | |
14380 | + | |
14381 | +bool | |
14382 | +remote_target::supports_memory_tagging () | |
14383 | +{ | |
14384 | + return false; | |
14385 | +} | |
14386 | + | |
14387 | +/* Implement the "fetch_memtags" target_ops method. */ | |
14388 | + | |
14389 | +int | |
14390 | +remote_target::fetch_memtags (CORE_ADDR address, size_t len, | |
14391 | + gdb::byte_vector &tags) | |
14392 | +{ | |
14393 | + return 0; | |
14394 | +} | |
14395 | + | |
14396 | +/* Implement the "store_memtags" target_ops method. */ | |
14397 | + | |
14398 | +int | |
14399 | +remote_target::store_memtags (CORE_ADDR address, size_t len, | |
14400 | + const gdb::byte_vector &tags) | |
14401 | +{ | |
14402 | + return 0; | |
14403 | +} | |
14404 | + | |
14369 | 14405 | void _initialize_remote (); |
14370 | 14406 | void |
14371 | 14407 | _initialize_remote () |
@@ -171,6 +171,11 @@ struct dummy_target : public target_ops | ||
171 | 171 | const struct frame_unwind *get_tailcall_unwinder () override; |
172 | 172 | void prepare_to_generate_core () override; |
173 | 173 | void done_generating_core () override; |
174 | + bool supports_memory_tagging () override; | |
175 | + int fetch_memtags (CORE_ADDR address, size_t len, | |
176 | + gdb::byte_vector &tags) override; | |
177 | + int store_memtags (CORE_ADDR address, size_t len, | |
178 | + const gdb::byte_vector &tags) override; | |
174 | 179 | }; |
175 | 180 | |
176 | 181 | struct debug_target : public target_ops |
@@ -340,6 +345,11 @@ struct debug_target : public target_ops | ||
340 | 345 | const struct frame_unwind *get_tailcall_unwinder () override; |
341 | 346 | void prepare_to_generate_core () override; |
342 | 347 | void done_generating_core () override; |
348 | + bool supports_memory_tagging () override; | |
349 | + int fetch_memtags (CORE_ADDR address, size_t len, | |
350 | + gdb::byte_vector &tags) override; | |
351 | + int store_memtags (CORE_ADDR address, size_t len, | |
352 | + const gdb::byte_vector &tags) override; | |
343 | 353 | }; |
344 | 354 | |
345 | 355 | void |
@@ -4363,3 +4373,77 @@ debug_target::done_generating_core () | ||
4363 | 4373 | fputs_unfiltered (")\n", gdb_stdlog); |
4364 | 4374 | } |
4365 | 4375 | |
4376 | +bool | |
4377 | +target_ops::supports_memory_tagging () | |
4378 | +{ | |
4379 | + return this->beneath ()->supports_memory_tagging (); | |
4380 | +} | |
4381 | + | |
4382 | +int | |
4383 | +target_ops::fetch_memtags (CORE_ADDR address, size_t len, | |
4384 | + gdb::byte_vector &tags) | |
4385 | +{ | |
4386 | + return this->beneath ()->fetch_memtags (address, len, tags); | |
4387 | +} | |
4388 | + | |
4389 | +int | |
4390 | +target_ops::store_memtags (CORE_ADDR address, size_t len, | |
4391 | + const gdb::byte_vector &tags) | |
4392 | +{ | |
4393 | + return this->beneath ()->store_memtags (address, len, tags); | |
4394 | +} | |
4395 | + | |
4396 | +bool | |
4397 | +dummy_target::supports_memory_tagging () | |
4398 | +{ | |
4399 | + return false; | |
4400 | +} | |
4401 | + | |
4402 | +int | |
4403 | +dummy_target::fetch_memtags (CORE_ADDR address, size_t len, | |
4404 | + gdb::byte_vector &tags) | |
4405 | +{ | |
4406 | + return 0; | |
4407 | +} | |
4408 | + | |
4409 | +int | |
4410 | +dummy_target::store_memtags (CORE_ADDR address, size_t len, | |
4411 | + const gdb::byte_vector &tags) | |
4412 | +{ | |
4413 | + return 0; | |
4414 | +} | |
4415 | + | |
4416 | +bool | |
4417 | +debug_target::supports_memory_tagging () | |
4418 | +{ | |
4419 | + bool result; | |
4420 | + fprintf_unfiltered (gdb_stdlog, "-> %s->supports_memory_tagging (...)\n", this->beneath ()->shortname ()); | |
4421 | + result = this->beneath ()->supports_memory_tagging (); | |
4422 | + fprintf_unfiltered (gdb_stdlog, "<- %s->supports_memory_tagging (", this->beneath ()->shortname ()); | |
4423 | + fputs_unfiltered (") = ", gdb_stdlog); | |
4424 | + target_debug_print_bool (result); | |
4425 | + fputs_unfiltered ("\n", gdb_stdlog); | |
4426 | + return result; | |
4427 | +} | |
4428 | + | |
4429 | +int | |
4430 | +debug_target::fetch_memtags (CORE_ADDR address, size_t len, | |
4431 | + gdb::byte_vector &tags) | |
4432 | +{ | |
4433 | + fprintf_unfiltered (gdb_stdlog, "-> %s->fetch_memtags (...)\n", this->beneath ()->shortname ()); | |
4434 | + int result = this->beneath ()->fetch_memtags (address, len, tags); | |
4435 | + fprintf_unfiltered (gdb_stdlog, "<- %s->fetch_memtags (", this->beneath ()->shortname ()); | |
4436 | + fputs_unfiltered (")\n", gdb_stdlog); | |
4437 | + return result; | |
4438 | +} | |
4439 | + | |
4440 | +int | |
4441 | +debug_target::store_memtags (CORE_ADDR address, size_t len, | |
4442 | + const gdb::byte_vector &tags) | |
4443 | +{ | |
4444 | + fprintf_unfiltered (gdb_stdlog, "-> %s->store_memtags (...)\n", this->beneath ()->shortname ()); | |
4445 | + int result = this->beneath ()->store_memtags (address, len, tags); | |
4446 | + fprintf_unfiltered (gdb_stdlog, "<- %s->store_memtags (", this->beneath ()->shortname ()); | |
4447 | + fputs_unfiltered (")\n", gdb_stdlog); | |
4448 | + return result; | |
4449 | +} |
@@ -1252,6 +1252,22 @@ struct target_ops | ||
1252 | 1252 | /* Cleanup after generating a core file. */ |
1253 | 1253 | virtual void done_generating_core () |
1254 | 1254 | TARGET_DEFAULT_IGNORE (); |
1255 | + | |
1256 | + /* Returns true if the target supports memory tagging. */ | |
1257 | + virtual bool supports_memory_tagging () | |
1258 | + TARGET_DEFAULT_RETURN (false); | |
1259 | + | |
1260 | + /* Return the allocated memory tags associated with | |
1261 | + [ADDRESS, ADDRESS + LEN) in TAGS. */ | |
1262 | + virtual int fetch_memtags (CORE_ADDR address, size_t len, | |
1263 | + gdb::byte_vector &tags) | |
1264 | + TARGET_DEFAULT_IGNORE (); | |
1265 | + | |
1266 | + /* Write the allocation tags contained in TAGS to the memory range | |
1267 | + [ADDRESS, ADDRESS + LEN). */ | |
1268 | + virtual int store_memtags (CORE_ADDR address, size_t len, | |
1269 | + const gdb::byte_vector &tags) | |
1270 | + TARGET_DEFAULT_IGNORE (); | |
1255 | 1271 | }; |
1256 | 1272 | |
1257 | 1273 | /* Deleter for std::unique_ptr. See comments in |
@@ -2308,6 +2324,15 @@ extern gdb::unique_xmalloc_ptr<char> target_fileio_read_stralloc | ||
2308 | 2324 | #define target_augmented_libraries_svr4_read() \ |
2309 | 2325 | (current_top_target ()->augmented_libraries_svr4_read) () |
2310 | 2326 | |
2327 | +#define target_supports_memory_tagging() \ | |
2328 | + ((current_top_target ()->supports_memory_tagging) ()) | |
2329 | + | |
2330 | +#define target_fetch_memtags(address, len, tags) \ | |
2331 | + (current_top_target ()->fetch_memtags) ((address), (len), (tags)) | |
2332 | + | |
2333 | +#define target_store_memtags(address, len, tags) \ | |
2334 | + (current_top_target ()->store_memtags) ((address), (len), (tags)) | |
2335 | + | |
2311 | 2336 | /* Command logging facility. */ |
2312 | 2337 | |
2313 | 2338 | #define target_log_command(p) \ |