Constify add_com
[deliverable/binutils-gdb.git] / gdb / memattr.c
1 /* Memory attributes support, for GDB.
2
3 Copyright (C) 2001-2017 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20 #include "defs.h"
21 #include "command.h"
22 #include "gdbcmd.h"
23 #include "memattr.h"
24 #include "target.h"
25 #include "target-dcache.h"
26 #include "value.h"
27 #include "language.h"
28 #include "vec.h"
29 #include "breakpoint.h"
30 #include "cli/cli-utils.h"
31 #include <algorithm>
32
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;
36
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. */
40
41 static bool
42 mem_use_target ()
43 {
44 return mem_region_list == &target_mem_region_list;
45 }
46
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;
51
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;
56
57 static void
58 show_inaccessible_by_default (struct ui_file *file, int from_tty,
59 struct cmd_list_element *c,
60 const char *value)
61 {
62 if (inaccessible_by_default)
63 fprintf_filtered (file, _("Unknown memory addresses will "
64 "be treated as inaccessible.\n"));
65 else
66 fprintf_filtered (file, _("Unknown memory addresses "
67 "will be treated as RAM.\n"));
68 }
69
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. */
73
74 static void
75 require_user_regions (int from_tty)
76 {
77 struct mem_region *m;
78 int ix, length;
79
80 /* If we're already using a user-provided list, nothing to do. */
81 if (!mem_use_target ())
82 return;
83
84 /* Switch to a user-provided list (possibly a copy of the current
85 one). */
86 mem_region_list = &user_mem_region_list;
87
88 /* If we don't have a target-provided region list yet, then
89 no need to warn. */
90 if (target_mem_region_list.empty ())
91 return;
92
93 /* Otherwise, let the user know how to get back. */
94 if (from_tty)
95 warning (_("Switching to manual control of memory regions; use "
96 "\"mem auto\" to fetch regions from the target again."));
97
98 /* And create a new list (copy of the target-supplied regions) for the user
99 to modify. */
100 user_mem_region_list = target_mem_region_list;
101 }
102
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. */
107
108 static void
109 require_target_regions (void)
110 {
111 if (mem_use_target () && !target_mem_regions_valid)
112 {
113 target_mem_regions_valid = true;
114 target_mem_region_list = target_memory_map ();
115 }
116 }
117
118 /* Create a new user-defined memory region. */
119
120 static void
121 create_user_mem_region (CORE_ADDR lo, CORE_ADDR hi,
122 const mem_attrib &attrib)
123 {
124 /* lo == hi is a useless empty region. */
125 if (lo >= hi && hi != 0)
126 {
127 printf_unfiltered (_("invalid memory region: low >= high\n"));
128 return;
129 }
130
131 mem_region newobj (lo, hi, attrib);
132
133 auto it = std::lower_bound (user_mem_region_list.begin (),
134 user_mem_region_list.end (),
135 newobj);
136 int ix = std::distance (user_mem_region_list.begin (), it);
137
138 /* Check for an overlapping memory region. We only need to check
139 in the vicinity - at most one before and one after the
140 insertion point. */
141 for (int i = ix - 1; i < ix + 1; i++)
142 {
143 if (i < 0)
144 continue;
145 if (i >= user_mem_region_list.size ())
146 continue;
147
148 mem_region &n = user_mem_region_list[i];
149
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)))
153 {
154 printf_unfiltered (_("overlapping memory region\n"));
155 return;
156 }
157 }
158
159 newobj.number = ++mem_number;
160 user_mem_region_list.insert (it, newobj);
161 }
162
163 /* Look up the memory region corresponding to ADDR. */
164
165 struct mem_region *
166 lookup_mem_region (CORE_ADDR addr)
167 {
168 static struct mem_region region (0, 0);
169 struct mem_region *m;
170 CORE_ADDR lo;
171 CORE_ADDR hi;
172 int ix;
173
174 require_target_regions ();
175
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. */
183
184 lo = 0;
185 hi = 0;
186
187 /* Either find memory range containing ADDR, or set LO and HI
188 to the nearest boundaries of an existing memory range.
189
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
192 VEC_lower_bound). */
193 for (mem_region &m : *mem_region_list)
194 {
195 if (m.enabled_p == 1)
196 {
197 /* If the address is in the memory region, return that
198 memory range. */
199 if (addr >= m.lo && (addr < m.hi || m.hi == 0))
200 return &m;
201
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)
206 lo = m.hi;
207
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))
212 hi = m.lo;
213 }
214 }
215
216 /* Because no region was found, we must cons up one based on what
217 was learned above. */
218 region.lo = lo;
219 region.hi = hi;
220
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 ();
226 else
227 region.attrib = mem_attrib ();
228
229 return &region;
230 }
231
232 /* Invalidate any memory regions fetched from the target. */
233
234 void
235 invalidate_target_mem_regions (void)
236 {
237 if (!target_mem_regions_valid)
238 return;
239
240 target_mem_regions_valid = false;
241 target_mem_region_list.clear ();
242 }
243
244 /* Clear user-defined memory region list. */
245
246 static void
247 user_mem_clear (void)
248 {
249 user_mem_region_list.clear ();
250 }
251 \f
252
253 static void
254 mem_command (const char *args, int from_tty)
255 {
256 CORE_ADDR lo, hi;
257
258 if (!args)
259 error_no_arg (_("No mem"));
260
261 /* For "mem auto", switch back to using a target provided list. */
262 if (strcmp (args, "auto") == 0)
263 {
264 if (mem_use_target ())
265 return;
266
267 user_mem_clear ();
268 mem_region_list = &target_mem_region_list;
269
270 return;
271 }
272
273 require_user_regions (from_tty);
274
275 std::string tok = extract_arg (&args);
276 if (tok == "")
277 error (_("no lo address"));
278 lo = parse_and_eval_address (tok.c_str ());
279
280 tok = extract_arg (&args);
281 if (tok == "")
282 error (_("no hi address"));
283 hi = parse_and_eval_address (tok.c_str ());
284
285 mem_attrib attrib;
286 while ((tok = extract_arg (&args)) != "")
287 {
288 if (tok == "rw")
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;
294
295 else if (tok == "8")
296 attrib.width = MEM_WIDTH_8;
297 else if (tok == "16")
298 {
299 if ((lo % 2 != 0) || (hi % 2 != 0))
300 error (_("region bounds not 16 bit aligned"));
301 attrib.width = MEM_WIDTH_16;
302 }
303 else if (tok == "32")
304 {
305 if ((lo % 4 != 0) || (hi % 4 != 0))
306 error (_("region bounds not 32 bit aligned"));
307 attrib.width = MEM_WIDTH_32;
308 }
309 else if (tok == "64")
310 {
311 if ((lo % 8 != 0) || (hi % 8 != 0))
312 error (_("region bounds not 64 bit aligned"));
313 attrib.width = MEM_WIDTH_64;
314 }
315
316 #if 0
317 else if (tok == "hwbreak")
318 attrib.hwbreak = 1;
319 else if (tok == "swbreak")
320 attrib.hwbreak = 0;
321 #endif
322
323 else if (tok == "cache")
324 attrib.cache = 1;
325 else if (tok == "nocache")
326 attrib.cache = 0;
327
328 #if 0
329 else if (tok == "verify")
330 attrib.verify = 1;
331 else if (tok == "noverify")
332 attrib.verify = 0;
333 #endif
334
335 else
336 error (_("unknown attribute: %s"), tok.c_str ());
337 }
338
339 create_user_mem_region (lo, hi, attrib);
340 }
341 \f
342
343 static void
344 info_mem_command (char *args, int from_tty)
345 {
346 if (mem_use_target ())
347 printf_filtered (_("Using memory regions provided by the target.\n"));
348 else
349 printf_filtered (_("Using user-defined memory regions.\n"));
350
351 require_target_regions ();
352
353 if (mem_region_list->empty ())
354 {
355 printf_unfiltered (_("There are no memory regions defined.\n"));
356 return;
357 }
358
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");
369
370 for (const mem_region &m : *mem_region_list)
371 {
372 const char *tmp;
373
374 printf_filtered ("%-3d %-3c\t",
375 m.number,
376 m.enabled_p ? 'y' : 'n');
377 if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
378 tmp = hex_string_custom (m.lo, 8);
379 else
380 tmp = hex_string_custom (m.lo, 16);
381
382 printf_filtered ("%s ", tmp);
383
384 if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
385 {
386 if (m.hi == 0)
387 tmp = "0x100000000";
388 else
389 tmp = hex_string_custom (m.hi, 8);
390 }
391 else
392 {
393 if (m.hi == 0)
394 tmp = "0x10000000000000000";
395 else
396 tmp = hex_string_custom (m.hi, 16);
397 }
398
399 printf_filtered ("%s ", tmp);
400
401 /* Print a token for each attribute.
402
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.
407 *
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. */
412
413 switch (m.attrib.mode)
414 {
415 case MEM_RW:
416 printf_filtered ("rw ");
417 break;
418 case MEM_RO:
419 printf_filtered ("ro ");
420 break;
421 case MEM_WO:
422 printf_filtered ("wo ");
423 break;
424 case MEM_FLASH:
425 printf_filtered ("flash blocksize 0x%x ", m.attrib.blocksize);
426 break;
427 }
428
429 switch (m.attrib.width)
430 {
431 case MEM_WIDTH_8:
432 printf_filtered ("8 ");
433 break;
434 case MEM_WIDTH_16:
435 printf_filtered ("16 ");
436 break;
437 case MEM_WIDTH_32:
438 printf_filtered ("32 ");
439 break;
440 case MEM_WIDTH_64:
441 printf_filtered ("64 ");
442 break;
443 case MEM_WIDTH_UNSPECIFIED:
444 break;
445 }
446
447 #if 0
448 if (attrib->hwbreak)
449 printf_filtered ("hwbreak");
450 else
451 printf_filtered ("swbreak");
452 #endif
453
454 if (m.attrib.cache)
455 printf_filtered ("cache ");
456 else
457 printf_filtered ("nocache ");
458
459 #if 0
460 if (attrib->verify)
461 printf_filtered ("verify ");
462 else
463 printf_filtered ("noverify ");
464 #endif
465
466 printf_filtered ("\n");
467
468 gdb_flush (gdb_stdout);
469 }
470 }
471 \f
472
473 /* Enable the memory region number NUM. */
474
475 static void
476 mem_enable (int num)
477 {
478 for (mem_region &m : *mem_region_list)
479 if (m.number == num)
480 {
481 m.enabled_p = 1;
482 return;
483 }
484 printf_unfiltered (_("No memory region number %d.\n"), num);
485 }
486
487 static void
488 enable_mem_command (const char *args, int from_tty)
489 {
490 require_user_regions (from_tty);
491
492 target_dcache_invalidate ();
493
494 if (args == NULL || *args == '\0')
495 { /* Enable all mem regions. */
496 for (mem_region &m : *mem_region_list)
497 m.enabled_p = 1;
498 }
499 else
500 {
501 number_or_range_parser parser (args);
502 while (!parser.finished ())
503 {
504 int num = parser.get_number ();
505 mem_enable (num);
506 }
507 }
508 }
509 \f
510
511 /* Disable the memory region number NUM. */
512
513 static void
514 mem_disable (int num)
515 {
516 for (mem_region &m : *mem_region_list)
517 if (m.number == num)
518 {
519 m.enabled_p = 0;
520 return;
521 }
522 printf_unfiltered (_("No memory region number %d.\n"), num);
523 }
524
525 static void
526 disable_mem_command (const char *args, int from_tty)
527 {
528 require_user_regions (from_tty);
529
530 target_dcache_invalidate ();
531
532 if (args == NULL || *args == '\0')
533 {
534 struct mem_region *m;
535 int ix;
536
537 for (mem_region &m : *mem_region_list)
538 m.enabled_p = false;
539 }
540 else
541 {
542 number_or_range_parser parser (args);
543 while (!parser.finished ())
544 {
545 int num = parser.get_number ();
546 mem_disable (num);
547 }
548 }
549 }
550
551 /* Delete the memory region number NUM. */
552
553 static void
554 mem_delete (int num)
555 {
556 struct mem_region *m;
557 int ix;
558
559 if (!mem_region_list)
560 {
561 printf_unfiltered (_("No memory region number %d.\n"), num);
562 return;
563 }
564
565 auto it = std::remove_if (mem_region_list->begin (), mem_region_list->end (),
566 [num] (const mem_region &m)
567 {
568 return m.number == num;
569 });
570
571 if (it != mem_region_list->end ())
572 mem_region_list->erase (it);
573 else
574 printf_unfiltered (_("No memory region number %d.\n"), num);
575 }
576
577 static void
578 delete_mem_command (const char *args, int from_tty)
579 {
580 require_user_regions (from_tty);
581
582 target_dcache_invalidate ();
583
584 if (args == NULL || *args == '\0')
585 {
586 if (query (_("Delete all memory regions? ")))
587 user_mem_clear ();
588 dont_repeat ();
589 return;
590 }
591
592 number_or_range_parser parser (args);
593 while (!parser.finished ())
594 {
595 int num = parser.get_number ();
596 mem_delete (num);
597 }
598
599 dont_repeat ();
600 }
601
602 static void
603 dummy_cmd (const char *args, int from_tty)
604 {
605 }
606
607 static struct cmd_list_element *mem_set_cmdlist;
608 static struct cmd_list_element *mem_show_cmdlist;
609
610 void
611 _initialize_mem (void)
612 {
613 add_com ("mem", class_vars, mem_command, _("\
614 Define attributes for memory region or reset memory region handling to\n\
615 target-based.\n\
616 Usage: mem auto\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"));
621
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);
627
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);
633
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);
639
640 add_info ("mem", info_mem_command,
641 _("Memory region attributes"));
642
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);
651
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."),
659 NULL,
660 show_inaccessible_by_default,
661 &mem_set_cmdlist,
662 &mem_show_cmdlist);
663 }
This page took 0.07565 seconds and 5 git commands to generate.