1 /* Memory attributes support, for GDB.
3 Copyright (C) 2001-2017 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #include "target-dcache.h"
29 #include "breakpoint.h"
30 #include "cli/cli-utils.h"
33 static std::vector<mem_region> user_mem_region_list, target_mem_region_list;
34 static std::vector<mem_region> *mem_region_list = &target_mem_region_list;
35 static int mem_number = 0;
37 /* If this flag is set, the memory region list should be automatically
38 updated from the target. If it is clear, the list is user-controlled
39 and should be left alone. */
44 return mem_region_list == &target_mem_region_list;
47 /* If this flag is set, we have tried to fetch the target memory regions
48 since the last time it was invalidated. If that list is still
49 empty, then the target can't supply memory regions. */
50 static bool target_mem_regions_valid;
52 /* If this flag is set, gdb will assume that memory ranges not
53 specified by the memory map have type MEM_NONE, and will
54 emit errors on all accesses to that memory. */
55 static int inaccessible_by_default = 1;
58 show_inaccessible_by_default (struct ui_file *file, int from_tty,
59 struct cmd_list_element *c,
62 if (inaccessible_by_default)
63 fprintf_filtered (file, _("Unknown memory addresses will "
64 "be treated as inaccessible.\n"));
66 fprintf_filtered (file, _("Unknown memory addresses "
67 "will be treated as RAM.\n"));
70 /* This function should be called before any command which would
71 modify the memory region list. It will handle switching from
72 a target-provided list to a local list, if necessary. */
75 require_user_regions (int from_tty)
80 /* If we're already using a user-provided list, nothing to do. */
81 if (!mem_use_target ())
84 /* Switch to a user-provided list (possibly a copy of the current
86 mem_region_list = &user_mem_region_list;
88 /* If we don't have a target-provided region list yet, then
90 if (target_mem_region_list.empty ())
93 /* Otherwise, let the user know how to get back. */
95 warning (_("Switching to manual control of memory regions; use "
96 "\"mem auto\" to fetch regions from the target again."));
98 /* And create a new list (copy of the target-supplied regions) for the user
100 user_mem_region_list = target_mem_region_list;
103 /* This function should be called before any command which would
104 read the memory region list, other than those which call
105 require_user_regions. It will handle fetching the
106 target-provided list, if necessary. */
109 require_target_regions (void)
111 if (mem_use_target () && !target_mem_regions_valid)
113 target_mem_regions_valid = true;
114 target_mem_region_list = target_memory_map ();
118 /* Create a new user-defined memory region. */
121 create_user_mem_region (CORE_ADDR lo, CORE_ADDR hi,
122 const mem_attrib &attrib)
124 /* lo == hi is a useless empty region. */
125 if (lo >= hi && hi != 0)
127 printf_unfiltered (_("invalid memory region: low >= high\n"));
131 mem_region newobj (lo, hi, attrib);
133 auto it = std::lower_bound (user_mem_region_list.begin (),
134 user_mem_region_list.end (),
136 int ix = std::distance (user_mem_region_list.begin (), it);
138 /* Check for an overlapping memory region. We only need to check
139 in the vicinity - at most one before and one after the
141 for (int i = ix - 1; i < ix + 1; i++)
145 if (i >= user_mem_region_list.size ())
148 mem_region &n = user_mem_region_list[i];
150 if ((lo >= n.lo && (lo < n.hi || n.hi == 0))
151 || (hi > n.lo && (hi <= n.hi || n.hi == 0))
152 || (lo <= n.lo && ((hi >= n.hi && n.hi != 0) || hi == 0)))
154 printf_unfiltered (_("overlapping memory region\n"));
159 newobj.number = ++mem_number;
160 user_mem_region_list.insert (it, newobj);
163 /* Look up the memory region corresponding to ADDR. */
166 lookup_mem_region (CORE_ADDR addr)
168 static struct mem_region region (0, 0);
169 struct mem_region *m;
174 require_target_regions ();
176 /* First we initialize LO and HI so that they describe the entire
177 memory space. As we process the memory region chain, they are
178 redefined to describe the minimal region containing ADDR. LO
179 and HI are used in the case where no memory region is defined
180 that contains ADDR. If a memory region is disabled, it is
181 treated as if it does not exist. The initial values for LO
182 and HI represent the bottom and top of memory. */
187 /* Either find memory range containing ADDR, or set LO and HI
188 to the nearest boundaries of an existing memory range.
190 If we ever want to support a huge list of memory regions, this
191 check should be replaced with a binary search (probably using
193 for (mem_region &m : *mem_region_list)
195 if (m.enabled_p == 1)
197 /* If the address is in the memory region, return that
199 if (addr >= m.lo && (addr < m.hi || m.hi == 0))
202 /* This (correctly) won't match if m->hi == 0, representing
203 the top of the address space, because CORE_ADDR is unsigned;
204 no value of LO is less than zero. */
205 if (addr >= m.hi && lo < m.hi)
208 /* This will never set HI to zero; if we're here and ADDR
209 is at or below M, and the region starts at zero, then ADDR
210 would have been in the region. */
211 if (addr <= m.lo && (hi == 0 || hi > m.lo))
216 /* Because no region was found, we must cons up one based on what
217 was learned above. */
221 /* When no memory map is defined at all, we always return
222 'default_mem_attrib', so that we do not make all memory
223 inaccessible for targets that don't provide a memory map. */
224 if (inaccessible_by_default && !mem_region_list->empty ())
225 region.attrib = mem_attrib::unknown ();
227 region.attrib = mem_attrib ();
232 /* Invalidate any memory regions fetched from the target. */
235 invalidate_target_mem_regions (void)
237 if (!target_mem_regions_valid)
240 target_mem_regions_valid = false;
241 target_mem_region_list.clear ();
244 /* Clear user-defined memory region list. */
247 user_mem_clear (void)
249 user_mem_region_list.clear ();
254 mem_command (const char *args, int from_tty)
259 error_no_arg (_("No mem"));
261 /* For "mem auto", switch back to using a target provided list. */
262 if (strcmp (args, "auto") == 0)
264 if (mem_use_target ())
268 mem_region_list = &target_mem_region_list;
273 require_user_regions (from_tty);
275 std::string tok = extract_arg (&args);
277 error (_("no lo address"));
278 lo = parse_and_eval_address (tok.c_str ());
280 tok = extract_arg (&args);
282 error (_("no hi address"));
283 hi = parse_and_eval_address (tok.c_str ());
286 while ((tok = extract_arg (&args)) != "")
289 attrib.mode = MEM_RW;
290 else if (tok == "ro")
291 attrib.mode = MEM_RO;
292 else if (tok == "wo")
293 attrib.mode = MEM_WO;
296 attrib.width = MEM_WIDTH_8;
297 else if (tok == "16")
299 if ((lo % 2 != 0) || (hi % 2 != 0))
300 error (_("region bounds not 16 bit aligned"));
301 attrib.width = MEM_WIDTH_16;
303 else if (tok == "32")
305 if ((lo % 4 != 0) || (hi % 4 != 0))
306 error (_("region bounds not 32 bit aligned"));
307 attrib.width = MEM_WIDTH_32;
309 else if (tok == "64")
311 if ((lo % 8 != 0) || (hi % 8 != 0))
312 error (_("region bounds not 64 bit aligned"));
313 attrib.width = MEM_WIDTH_64;
317 else if (tok == "hwbreak")
319 else if (tok == "swbreak")
323 else if (tok == "cache")
325 else if (tok == "nocache")
329 else if (tok == "verify")
331 else if (tok == "noverify")
336 error (_("unknown attribute: %s"), tok.c_str ());
339 create_user_mem_region (lo, hi, attrib);
344 info_mem_command (const char *args, int from_tty)
346 if (mem_use_target ())
347 printf_filtered (_("Using memory regions provided by the target.\n"));
349 printf_filtered (_("Using user-defined memory regions.\n"));
351 require_target_regions ();
353 if (mem_region_list->empty ())
355 printf_unfiltered (_("There are no memory regions defined.\n"));
359 printf_filtered ("Num ");
360 printf_filtered ("Enb ");
361 printf_filtered ("Low Addr ");
362 if (gdbarch_addr_bit (target_gdbarch ()) > 32)
363 printf_filtered (" ");
364 printf_filtered ("High Addr ");
365 if (gdbarch_addr_bit (target_gdbarch ()) > 32)
366 printf_filtered (" ");
367 printf_filtered ("Attrs ");
368 printf_filtered ("\n");
370 for (const mem_region &m : *mem_region_list)
374 printf_filtered ("%-3d %-3c\t",
376 m.enabled_p ? 'y' : 'n');
377 if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
378 tmp = hex_string_custom (m.lo, 8);
380 tmp = hex_string_custom (m.lo, 16);
382 printf_filtered ("%s ", tmp);
384 if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
389 tmp = hex_string_custom (m.hi, 8);
394 tmp = "0x10000000000000000";
396 tmp = hex_string_custom (m.hi, 16);
399 printf_filtered ("%s ", tmp);
401 /* Print a token for each attribute.
403 * FIXME: Should we output a comma after each token? It may
404 * make it easier for users to read, but we'd lose the ability
405 * to cut-and-paste the list of attributes when defining a new
406 * region. Perhaps that is not important.
408 * FIXME: If more attributes are added to GDB, the output may
409 * become cluttered and difficult for users to read. At that
410 * time, we may want to consider printing tokens only if they
411 * are different from the default attribute. */
413 switch (m.attrib.mode)
416 printf_filtered ("rw ");
419 printf_filtered ("ro ");
422 printf_filtered ("wo ");
425 printf_filtered ("flash blocksize 0x%x ", m.attrib.blocksize);
429 switch (m.attrib.width)
432 printf_filtered ("8 ");
435 printf_filtered ("16 ");
438 printf_filtered ("32 ");
441 printf_filtered ("64 ");
443 case MEM_WIDTH_UNSPECIFIED:
449 printf_filtered ("hwbreak");
451 printf_filtered ("swbreak");
455 printf_filtered ("cache ");
457 printf_filtered ("nocache ");
461 printf_filtered ("verify ");
463 printf_filtered ("noverify ");
466 printf_filtered ("\n");
468 gdb_flush (gdb_stdout);
473 /* Enable the memory region number NUM. */
478 for (mem_region &m : *mem_region_list)
484 printf_unfiltered (_("No memory region number %d.\n"), num);
488 enable_mem_command (const char *args, int from_tty)
490 require_user_regions (from_tty);
492 target_dcache_invalidate ();
494 if (args == NULL || *args == '\0')
495 { /* Enable all mem regions. */
496 for (mem_region &m : *mem_region_list)
501 number_or_range_parser parser (args);
502 while (!parser.finished ())
504 int num = parser.get_number ();
511 /* Disable the memory region number NUM. */
514 mem_disable (int num)
516 for (mem_region &m : *mem_region_list)
522 printf_unfiltered (_("No memory region number %d.\n"), num);
526 disable_mem_command (const char *args, int from_tty)
528 require_user_regions (from_tty);
530 target_dcache_invalidate ();
532 if (args == NULL || *args == '\0')
534 struct mem_region *m;
537 for (mem_region &m : *mem_region_list)
542 number_or_range_parser parser (args);
543 while (!parser.finished ())
545 int num = parser.get_number ();
551 /* Delete the memory region number NUM. */
556 struct mem_region *m;
559 if (!mem_region_list)
561 printf_unfiltered (_("No memory region number %d.\n"), num);
565 auto it = std::remove_if (mem_region_list->begin (), mem_region_list->end (),
566 [num] (const mem_region &m)
568 return m.number == num;
571 if (it != mem_region_list->end ())
572 mem_region_list->erase (it);
574 printf_unfiltered (_("No memory region number %d.\n"), num);
578 delete_mem_command (const char *args, int from_tty)
580 require_user_regions (from_tty);
582 target_dcache_invalidate ();
584 if (args == NULL || *args == '\0')
586 if (query (_("Delete all memory regions? ")))
592 number_or_range_parser parser (args);
593 while (!parser.finished ())
595 int num = parser.get_number ();
603 dummy_cmd (const char *args, int from_tty)
607 static struct cmd_list_element *mem_set_cmdlist;
608 static struct cmd_list_element *mem_show_cmdlist;
611 _initialize_mem (void)
613 add_com ("mem", class_vars, mem_command, _("\
614 Define attributes for memory region or reset memory region handling to\n\
617 mem <lo addr> <hi addr> [<mode> <width> <cache>],\n\
618 where <mode> may be rw (read/write), ro (read-only) or wo (write-only),\n\
619 <width> may be 8, 16, 32, or 64, and\n\
620 <cache> may be cache or nocache"));
622 add_cmd ("mem", class_vars, enable_mem_command, _("\
623 Enable memory region.\n\
624 Arguments are the code numbers of the memory regions to enable.\n\
625 Usage: enable mem <code number>...\n\
626 Do \"info mem\" to see current list of code numbers."), &enablelist);
628 add_cmd ("mem", class_vars, disable_mem_command, _("\
629 Disable memory region.\n\
630 Arguments are the code numbers of the memory regions to disable.\n\
631 Usage: disable mem <code number>...\n\
632 Do \"info mem\" to see current list of code numbers."), &disablelist);
634 add_cmd ("mem", class_vars, delete_mem_command, _("\
635 Delete memory region.\n\
636 Arguments are the code numbers of the memory regions to delete.\n\
637 Usage: delete mem <code number>...\n\
638 Do \"info mem\" to see current list of code numbers."), &deletelist);
640 add_info ("mem", info_mem_command,
641 _("Memory region attributes"));
643 add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\
644 Memory regions settings"),
645 &mem_set_cmdlist, "set mem ",
646 0/* allow-unknown */, &setlist);
647 add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\
648 Memory regions settings"),
649 &mem_show_cmdlist, "show mem ",
650 0/* allow-unknown */, &showlist);
652 add_setshow_boolean_cmd ("inaccessible-by-default", no_class,
653 &inaccessible_by_default, _("\
654 Set handling of unknown memory regions."), _("\
655 Show handling of unknown memory regions."), _("\
656 If on, and some memory map is defined, debugger will emit errors on\n\
657 accesses to memory not defined in the memory map. If off, accesses to all\n\
658 memory addresses will be allowed."),
660 show_inaccessible_by_default,