]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/memattr.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / memattr.c
CommitLineData
80629b1b 1/* Memory attributes support, for GDB.
14a5e767 2
6aba47ca 3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
c96fc75e 4 Free Software Foundation, Inc.
80629b1b
EZ
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
80629b1b 22
29e57380
C
23#include "defs.h"
24#include "command.h"
25#include "gdbcmd.h"
26#include "memattr.h"
27#include "target.h"
28#include "value.h"
29#include "language.h"
c96fc75e 30#include "vec.h"
29e57380
C
31#include "gdb_string.h"
32
29e57380
C
33const struct mem_attrib default_mem_attrib =
34{
35 MEM_RW, /* mode */
36 MEM_WIDTH_UNSPECIFIED,
81a9a963
AC
37 0, /* hwbreak */
38 0, /* cache */
fd79ecee
DJ
39 0, /* verify */
40 -1 /* Flash blocksize not specified. */
29e57380
C
41};
42
4b5752d0
VP
43const struct mem_attrib unknown_mem_attrib =
44{
45 MEM_NONE, /* mode */
46 MEM_WIDTH_UNSPECIFIED,
47 0, /* hwbreak */
48 0, /* cache */
49 0, /* verify */
50 -1 /* Flash blocksize not specified. */
51};
52
53
fd79ecee 54VEC(mem_region_s) *mem_region_list, *target_mem_region_list;
f4d650ec 55static int mem_number = 0;
29e57380 56
fd79ecee
DJ
57/* If this flag is set, the memory region list should be automatically
58 updated from the target. If it is clear, the list is user-controlled
59 and should be left alone. */
60static int mem_use_target = 1;
61
62/* If this flag is set, we have tried to fetch the target memory regions
63 since the last time it was invalidated. If that list is still
64 empty, then the target can't supply memory regions. */
65static int target_mem_regions_valid;
66
4b5752d0
VP
67/* If this flag is set, gdb will assume that memory ranges not
68 specified by the memory map have type MEM_NONE, and will
69 emit errors on all accesses to that memory. */
70static int inaccessible_by_default = 0;
71
72static void
73show_inaccessible_by_default (struct ui_file *file, int from_tty,
74 struct cmd_list_element *c,
75 const char *value)
76{
77 if (inaccessible_by_default)
78 fprintf_filtered (file, _("\
79Unknown memory addresses will be treated as inaccessible.\n"));
80 else
81 fprintf_filtered (file, _("\
82Unknown memory addresses will be treated as RAM.\n"));
83}
84
85
c96fc75e
DJ
86/* Predicate function which returns true if LHS should sort before RHS
87 in a list of memory regions, useful for VEC_lower_bound. */
88
89static int
90mem_region_lessthan (const struct mem_region *lhs,
91 const struct mem_region *rhs)
92{
93 return lhs->lo < rhs->lo;
94}
95
fd79ecee
DJ
96/* A helper function suitable for qsort, used to sort a
97 VEC(mem_region_s) by starting address. */
98
99int
100mem_region_cmp (const void *untyped_lhs, const void *untyped_rhs)
101{
102 const struct mem_region *lhs = untyped_lhs;
103 const struct mem_region *rhs = untyped_rhs;
104
105 if (lhs->lo < rhs->lo)
106 return -1;
107 else if (lhs->lo == rhs->lo)
108 return 0;
109 else
110 return 1;
111}
112
113/* Allocate a new memory region, with default settings. */
114
115void
116mem_region_init (struct mem_region *new)
117{
118 memset (new, 0, sizeof (struct mem_region));
119 new->enabled_p = 1;
120 new->attrib = default_mem_attrib;
121}
122
123/* This function should be called before any command which would
124 modify the memory region list. It will handle switching from
125 a target-provided list to a local list, if necessary. */
126
127static void
128require_user_regions (int from_tty)
129{
130 struct mem_region *m;
131 int ix, length;
132
133 /* If we're already using a user-provided list, nothing to do. */
134 if (!mem_use_target)
135 return;
136
137 /* Switch to a user-provided list (possibly a copy of the current
138 one). */
139 mem_use_target = 0;
140
141 /* If we don't have a target-provided region list yet, then
142 no need to warn. */
143 if (mem_region_list == NULL)
144 return;
145
146 /* Otherwise, let the user know how to get back. */
147 if (from_tty)
148 warning (_("Switching to manual control of memory regions; use "
149 "\"mem auto\" to fetch regions from the target again."));
150
151 /* And create a new list for the user to modify. */
152 length = VEC_length (mem_region_s, target_mem_region_list);
153 mem_region_list = VEC_alloc (mem_region_s, length);
154 for (ix = 0; VEC_iterate (mem_region_s, target_mem_region_list, ix, m); ix++)
155 VEC_quick_push (mem_region_s, mem_region_list, m);
156}
157
158/* This function should be called before any command which would
159 read the memory region list, other than those which call
160 require_user_regions. It will handle fetching the
161 target-provided list, if necessary. */
162
163static void
164require_target_regions (void)
165{
166 if (mem_use_target && !target_mem_regions_valid)
167 {
168 target_mem_regions_valid = 1;
169 target_mem_region_list = target_memory_map ();
170 mem_region_list = target_mem_region_list;
171 }
172}
173
c96fc75e 174static void
29e57380
C
175create_mem_region (CORE_ADDR lo, CORE_ADDR hi,
176 const struct mem_attrib *attrib)
177{
c96fc75e
DJ
178 struct mem_region new;
179 int i, ix;
29e57380 180
b6d1a1d5 181 /* lo == hi is a useless empty region */
2b236d82 182 if (lo >= hi && hi != 0)
29e57380 183 {
a3f17187 184 printf_unfiltered (_("invalid memory region: low >= high\n"));
c96fc75e 185 return;
29e57380
C
186 }
187
fd79ecee 188 mem_region_init (&new);
c96fc75e
DJ
189 new.lo = lo;
190 new.hi = hi;
191
192 ix = VEC_lower_bound (mem_region_s, mem_region_list, &new,
193 mem_region_lessthan);
194
195 /* Check for an overlapping memory region. We only need to check
196 in the vicinity - at most one before and one after the
197 insertion point. */
198 for (i = ix - 1; i < ix + 1; i++)
29e57380 199 {
c96fc75e
DJ
200 struct mem_region *n;
201
202 if (i < 0)
203 continue;
204 if (i >= VEC_length (mem_region_s, mem_region_list))
205 continue;
206
207 n = VEC_index (mem_region_s, mem_region_list, i);
208
2b236d82
DH
209 if ((lo >= n->lo && (lo < n->hi || n->hi == 0))
210 || (hi > n->lo && (hi <= n->hi || n->hi == 0))
211 || (lo <= n->lo && (hi >= n->hi || hi == 0)))
29e57380 212 {
a3f17187 213 printf_unfiltered (_("overlapping memory region\n"));
c96fc75e 214 return;
29e57380
C
215 }
216 }
217
c96fc75e 218 new.number = ++mem_number;
c96fc75e
DJ
219 new.attrib = *attrib;
220 VEC_safe_insert (mem_region_s, mem_region_list, ix, &new);
29e57380
C
221}
222
223/*
224 * Look up the memory region cooresponding to ADDR.
225 */
226struct mem_region *
227lookup_mem_region (CORE_ADDR addr)
228{
229 static struct mem_region region;
230 struct mem_region *m;
231 CORE_ADDR lo;
232 CORE_ADDR hi;
c96fc75e 233 int ix;
29e57380 234
fd79ecee
DJ
235 require_target_regions ();
236
29e57380
C
237 /* First we initialize LO and HI so that they describe the entire
238 memory space. As we process the memory region chain, they are
239 redefined to describe the minimal region containing ADDR. LO
240 and HI are used in the case where no memory region is defined
241 that contains ADDR. If a memory region is disabled, it is
a76d924d
DJ
242 treated as if it does not exist. The initial values for LO
243 and HI represent the bottom and top of memory. */
29e57380 244
a76d924d
DJ
245 lo = 0;
246 hi = 0;
29e57380 247
4b5752d0
VP
248 /* Either find memory range containing ADDRESS, or set LO and HI
249 to the nearest boundaries of an existing memory range.
250
251 If we ever want to support a huge list of memory regions, this
c96fc75e
DJ
252 check should be replaced with a binary search (probably using
253 VEC_lower_bound). */
254 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
29e57380 255 {
b5de0fa7 256 if (m->enabled_p == 1)
29e57380 257 {
4b5752d0 258 /* If the address is in the memory region, return that memory range. */
2b236d82 259 if (addr >= m->lo && (addr < m->hi || m->hi == 0))
29e57380
C
260 return m;
261
a76d924d
DJ
262 /* This (correctly) won't match if m->hi == 0, representing
263 the top of the address space, because CORE_ADDR is unsigned;
264 no value of LO is less than zero. */
29e57380
C
265 if (addr >= m->hi && lo < m->hi)
266 lo = m->hi;
267
a76d924d
DJ
268 /* This will never set HI to zero; if we're here and ADDR
269 is at or below M, and the region starts at zero, then ADDR
270 would have been in the region. */
271 if (addr <= m->lo && (hi == 0 || hi > m->lo))
29e57380
C
272 hi = m->lo;
273 }
274 }
275
276 /* Because no region was found, we must cons up one based on what
277 was learned above. */
278 region.lo = lo;
279 region.hi = hi;
4b5752d0
VP
280
281 /* When no memory map is defined at all, we always return
282 'default_mem_attrib', so that we do not make all memory
283 inaccessible for targets that don't provide a memory map. */
284 if (inaccessible_by_default && !VEC_empty (mem_region_s, mem_region_list))
285 region.attrib = unknown_mem_attrib;
286 else
287 region.attrib = default_mem_attrib;
288
29e57380
C
289 return &region;
290}
fd79ecee
DJ
291
292/* Invalidate any memory regions fetched from the target. */
293
294void
295invalidate_target_mem_regions (void)
296{
297 struct mem_region *m;
298 int ix;
299
300 if (!target_mem_regions_valid)
301 return;
302
303 target_mem_regions_valid = 0;
304 VEC_free (mem_region_s, target_mem_region_list);
305 if (mem_use_target)
306 mem_region_list = NULL;
307}
308
309/* Clear memory region list */
310
311static void
312mem_clear (void)
313{
314 VEC_free (mem_region_s, mem_region_list);
315}
29e57380
C
316\f
317
318static void
319mem_command (char *args, int from_tty)
320{
321 CORE_ADDR lo, hi;
322 char *tok;
323 struct mem_attrib attrib;
324
325 if (!args)
e2e0b3e5 326 error_no_arg (_("No mem"));
29e57380 327
fd79ecee
DJ
328 /* For "mem auto", switch back to using a target provided list. */
329 if (strcmp (args, "auto") == 0)
330 {
331 if (mem_use_target)
332 return;
333
334 if (mem_region_list != target_mem_region_list)
335 {
336 mem_clear ();
337 mem_region_list = target_mem_region_list;
338 }
339
340 mem_use_target = 1;
341 return;
342 }
343
344 require_user_regions (from_tty);
345
29e57380
C
346 tok = strtok (args, " \t");
347 if (!tok)
8a3fe4f8 348 error (_("no lo address"));
29e57380
C
349 lo = parse_and_eval_address (tok);
350
351 tok = strtok (NULL, " \t");
352 if (!tok)
8a3fe4f8 353 error (_("no hi address"));
29e57380
C
354 hi = parse_and_eval_address (tok);
355
356 attrib = default_mem_attrib;
357 while ((tok = strtok (NULL, " \t")) != NULL)
358 {
359 if (strcmp (tok, "rw") == 0)
360 attrib.mode = MEM_RW;
361 else if (strcmp (tok, "ro") == 0)
362 attrib.mode = MEM_RO;
363 else if (strcmp (tok, "wo") == 0)
364 attrib.mode = MEM_WO;
365
366 else if (strcmp (tok, "8") == 0)
367 attrib.width = MEM_WIDTH_8;
368 else if (strcmp (tok, "16") == 0)
369 {
370 if ((lo % 2 != 0) || (hi % 2 != 0))
8a3fe4f8 371 error (_("region bounds not 16 bit aligned"));
29e57380
C
372 attrib.width = MEM_WIDTH_16;
373 }
374 else if (strcmp (tok, "32") == 0)
375 {
376 if ((lo % 4 != 0) || (hi % 4 != 0))
8a3fe4f8 377 error (_("region bounds not 32 bit aligned"));
29e57380
C
378 attrib.width = MEM_WIDTH_32;
379 }
380 else if (strcmp (tok, "64") == 0)
381 {
382 if ((lo % 8 != 0) || (hi % 8 != 0))
8a3fe4f8 383 error (_("region bounds not 64 bit aligned"));
29e57380
C
384 attrib.width = MEM_WIDTH_64;
385 }
386
387#if 0
388 else if (strcmp (tok, "hwbreak") == 0)
81a9a963 389 attrib.hwbreak = 1;
29e57380 390 else if (strcmp (tok, "swbreak") == 0)
81a9a963 391 attrib.hwbreak = 0;
29e57380
C
392#endif
393
394 else if (strcmp (tok, "cache") == 0)
81a9a963 395 attrib.cache = 1;
29e57380 396 else if (strcmp (tok, "nocache") == 0)
81a9a963 397 attrib.cache = 0;
29e57380
C
398
399#if 0
400 else if (strcmp (tok, "verify") == 0)
81a9a963 401 attrib.verify = 1;
29e57380 402 else if (strcmp (tok, "noverify") == 0)
81a9a963 403 attrib.verify = 0;
29e57380
C
404#endif
405
406 else
8a3fe4f8 407 error (_("unknown attribute: %s"), tok);
29e57380
C
408 }
409
410 create_mem_region (lo, hi, &attrib);
411}
412\f
413
414static void
415mem_info_command (char *args, int from_tty)
416{
417 struct mem_region *m;
418 struct mem_attrib *attrib;
c96fc75e 419 int ix;
29e57380 420
fd79ecee
DJ
421 if (mem_use_target)
422 printf_filtered (_("Using memory regions provided by the target.\n"));
423 else
424 printf_filtered (_("Using user-defined memory regions.\n"));
425
426 require_target_regions ();
427
c96fc75e 428 if (!mem_region_list)
29e57380 429 {
a3f17187 430 printf_unfiltered (_("There are no memory regions defined.\n"));
29e57380
C
431 return;
432 }
433
ab35b611
EZ
434 printf_filtered ("Num ");
435 printf_filtered ("Enb ");
436 printf_filtered ("Low Addr ");
437 if (TARGET_ADDR_BIT > 32)
438 printf_filtered (" ");
439 printf_filtered ("High Addr ");
440 if (TARGET_ADDR_BIT > 32)
441 printf_filtered (" ");
442 printf_filtered ("Attrs ");
443 printf_filtered ("\n");
444
c96fc75e 445 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
29e57380 446 {
ab35b611
EZ
447 char *tmp;
448 printf_filtered ("%-3d %-3c\t",
29e57380 449 m->number,
b5de0fa7 450 m->enabled_p ? 'y' : 'n');
ab35b611 451 if (TARGET_ADDR_BIT <= 32)
bb599908 452 tmp = hex_string_custom ((unsigned long) m->lo, 8);
ab35b611 453 else
bb599908 454 tmp = hex_string_custom ((unsigned long) m->lo, 16);
ab35b611
EZ
455
456 printf_filtered ("%s ", tmp);
2b236d82 457
ab35b611 458 if (TARGET_ADDR_BIT <= 32)
2163ab9d
DH
459 {
460 if (m->hi == 0)
461 tmp = "0x100000000";
462 else
bb599908 463 tmp = hex_string_custom ((unsigned long) m->hi, 8);
2163ab9d 464 }
ab35b611 465 else
2163ab9d
DH
466 {
467 if (m->hi == 0)
468 tmp = "0x10000000000000000";
469 else
bb599908 470 tmp = hex_string_custom ((unsigned long) m->hi, 16);
2163ab9d
DH
471 }
472
ab35b611 473 printf_filtered ("%s ", tmp);
29e57380
C
474
475 /* Print a token for each attribute.
476
477 * FIXME: Should we output a comma after each token? It may
478 * make it easier for users to read, but we'd lose the ability
479 * to cut-and-paste the list of attributes when defining a new
480 * region. Perhaps that is not important.
481 *
482 * FIXME: If more attributes are added to GDB, the output may
483 * become cluttered and difficult for users to read. At that
484 * time, we may want to consider printing tokens only if they
485 * are different from the default attribute. */
486
487 attrib = &m->attrib;
488 switch (attrib->mode)
489 {
490 case MEM_RW:
491 printf_filtered ("rw ");
492 break;
493 case MEM_RO:
494 printf_filtered ("ro ");
495 break;
496 case MEM_WO:
497 printf_filtered ("wo ");
498 break;
fd79ecee
DJ
499 case MEM_FLASH:
500 printf_filtered ("flash blocksize 0x%x ", attrib->blocksize);
501 break;
29e57380
C
502 }
503
504 switch (attrib->width)
505 {
506 case MEM_WIDTH_8:
507 printf_filtered ("8 ");
508 break;
509 case MEM_WIDTH_16:
510 printf_filtered ("16 ");
511 break;
512 case MEM_WIDTH_32:
513 printf_filtered ("32 ");
514 break;
515 case MEM_WIDTH_64:
516 printf_filtered ("64 ");
517 break;
518 case MEM_WIDTH_UNSPECIFIED:
519 break;
520 }
521
522#if 0
523 if (attrib->hwbreak)
524 printf_filtered ("hwbreak");
525 else
526 printf_filtered ("swbreak");
527#endif
528
529 if (attrib->cache)
530 printf_filtered ("cache ");
531 else
532 printf_filtered ("nocache ");
533
534#if 0
535 if (attrib->verify)
536 printf_filtered ("verify ");
537 else
538 printf_filtered ("noverify ");
539#endif
540
541 printf_filtered ("\n");
542
543 gdb_flush (gdb_stdout);
544 }
545}
546\f
547
548/* Enable the memory region number NUM. */
549
550static void
551mem_enable (int num)
552{
553 struct mem_region *m;
c96fc75e 554 int ix;
29e57380 555
c96fc75e 556 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
29e57380
C
557 if (m->number == num)
558 {
b5de0fa7 559 m->enabled_p = 1;
29e57380
C
560 return;
561 }
a3f17187 562 printf_unfiltered (_("No memory region number %d.\n"), num);
29e57380
C
563}
564
565static void
566mem_enable_command (char *args, int from_tty)
567{
568 char *p = args;
569 char *p1;
570 int num;
571 struct mem_region *m;
c96fc75e 572 int ix;
29e57380 573
fd79ecee
DJ
574 require_user_regions (from_tty);
575
29e57380
C
576 dcache_invalidate (target_dcache);
577
578 if (p == 0)
579 {
c96fc75e 580 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
b5de0fa7 581 m->enabled_p = 1;
29e57380
C
582 }
583 else
584 while (*p)
585 {
586 p1 = p;
587 while (*p1 >= '0' && *p1 <= '9')
588 p1++;
589 if (*p1 && *p1 != ' ' && *p1 != '\t')
8a3fe4f8 590 error (_("Arguments must be memory region numbers."));
29e57380
C
591
592 num = atoi (p);
593 mem_enable (num);
594
595 p = p1;
596 while (*p == ' ' || *p == '\t')
597 p++;
598 }
599}
600\f
601
602/* Disable the memory region number NUM. */
603
604static void
605mem_disable (int num)
606{
607 struct mem_region *m;
c96fc75e 608 int ix;
29e57380 609
c96fc75e 610 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
29e57380
C
611 if (m->number == num)
612 {
b5de0fa7 613 m->enabled_p = 0;
29e57380
C
614 return;
615 }
a3f17187 616 printf_unfiltered (_("No memory region number %d.\n"), num);
29e57380
C
617}
618
619static void
620mem_disable_command (char *args, int from_tty)
621{
622 char *p = args;
623 char *p1;
624 int num;
625 struct mem_region *m;
c96fc75e 626 int ix;
29e57380 627
fd79ecee
DJ
628 require_user_regions (from_tty);
629
29e57380
C
630 dcache_invalidate (target_dcache);
631
632 if (p == 0)
633 {
c96fc75e 634 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
b5de0fa7 635 m->enabled_p = 0;
29e57380
C
636 }
637 else
638 while (*p)
639 {
640 p1 = p;
641 while (*p1 >= '0' && *p1 <= '9')
642 p1++;
643 if (*p1 && *p1 != ' ' && *p1 != '\t')
8a3fe4f8 644 error (_("Arguments must be memory region numbers."));
29e57380
C
645
646 num = atoi (p);
647 mem_disable (num);
648
649 p = p1;
650 while (*p == ' ' || *p == '\t')
651 p++;
652 }
653}
654
29e57380
C
655/* Delete the memory region number NUM. */
656
657static void
658mem_delete (int num)
659{
660 struct mem_region *m1, *m;
c96fc75e 661 int ix;
29e57380 662
c96fc75e 663 if (!mem_region_list)
29e57380 664 {
a3f17187 665 printf_unfiltered (_("No memory region number %d.\n"), num);
29e57380
C
666 return;
667 }
668
c96fc75e
DJ
669 for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++)
670 if (m->number == num)
671 break;
672
673 if (m == NULL)
29e57380 674 {
c96fc75e
DJ
675 printf_unfiltered (_("No memory region number %d.\n"), num);
676 return;
29e57380 677 }
c96fc75e
DJ
678
679 VEC_ordered_remove (mem_region_s, mem_region_list, ix);
29e57380
C
680}
681
682static void
683mem_delete_command (char *args, int from_tty)
684{
685 char *p = args;
686 char *p1;
687 int num;
688
fd79ecee
DJ
689 require_user_regions (from_tty);
690
29e57380
C
691 dcache_invalidate (target_dcache);
692
693 if (p == 0)
694 {
695 if (query ("Delete all memory regions? "))
696 mem_clear ();
697 dont_repeat ();
698 return;
699 }
700
701 while (*p)
702 {
703 p1 = p;
704 while (*p1 >= '0' && *p1 <= '9')
705 p1++;
706 if (*p1 && *p1 != ' ' && *p1 != '\t')
8a3fe4f8 707 error (_("Arguments must be memory region numbers."));
29e57380
C
708
709 num = atoi (p);
710 mem_delete (num);
711
712 p = p1;
713 while (*p == ' ' || *p == '\t')
714 p++;
715 }
716
717 dont_repeat ();
718}
4b5752d0
VP
719
720static void
721dummy_cmd (char *args, int from_tty)
722{
723}
29e57380 724\f
b9362cc7
AC
725extern initialize_file_ftype _initialize_mem; /* -Wmissing-prototype */
726
4b5752d0
VP
727static struct cmd_list_element *mem_set_cmdlist;
728static struct cmd_list_element *mem_show_cmdlist;
729
29e57380 730void
5ae5f592 731_initialize_mem (void)
29e57380 732{
1bedd215 733 add_com ("mem", class_vars, mem_command, _("\
fd79ecee
DJ
734Define attributes for memory region or reset memory region handling to\n\
735target-based.\n\
736Usage: mem auto\n\
737 mem <lo addr> <hi addr> [<mode> <width> <cache>], \n\
f9ba0717
MS
738where <mode> may be rw (read/write), ro (read-only) or wo (write-only), \n\
739 <width> may be 8, 16, 32, or 64, and \n\
1bedd215 740 <cache> may be cache or nocache"));
29e57380 741
1a966eab
AC
742 add_cmd ("mem", class_vars, mem_enable_command, _("\
743Enable memory region.\n\
29e57380 744Arguments are the code numbers of the memory regions to enable.\n\
ab35b611 745Usage: enable mem <code number>\n\
1a966eab 746Do \"info mem\" to see current list of code numbers."), &enablelist);
29e57380 747
1a966eab
AC
748 add_cmd ("mem", class_vars, mem_disable_command, _("\
749Disable memory region.\n\
29e57380 750Arguments are the code numbers of the memory regions to disable.\n\
ab35b611 751Usage: disable mem <code number>\n\
1a966eab 752Do \"info mem\" to see current list of code numbers."), &disablelist);
29e57380 753
1a966eab
AC
754 add_cmd ("mem", class_vars, mem_delete_command, _("\
755Delete memory region.\n\
29e57380 756Arguments are the code numbers of the memory regions to delete.\n\
ab35b611 757Usage: delete mem <code number>\n\
1a966eab 758Do \"info mem\" to see current list of code numbers."), &deletelist);
29e57380
C
759
760 add_info ("mem", mem_info_command,
1bedd215 761 _("Memory region attributes"));
4b5752d0
VP
762
763 add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\
764Memory regions settings"),
765 &mem_set_cmdlist, "set mem ",
766 0/* allow-unknown */, &setlist);
767 add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\
768Memory regions settings"),
769 &mem_show_cmdlist, "show mem ",
770 0/* allow-unknown */, &showlist);
771
772 add_setshow_boolean_cmd ("inaccessible-by-default", no_class,
773 &inaccessible_by_default, _("\
774Set handling of unknown memory regions."), _("\
775Show handling of unknown memory regions."), _("\
776If on, and some memory map is defined, debugger will emit errors on\n\
777accesses to memory not defined in the memory map. If off, accesses to all\n\
778memory addresses will be allowed."),
779 NULL,
780 show_inaccessible_by_default,
781 &mem_set_cmdlist,
782 &mem_show_cmdlist);
29e57380 783}