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