]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/memattr.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / memattr.c
CommitLineData
80629b1b 1/* Memory attributes support, for GDB.
14a5e767 2
d01e8234 3 Copyright (C) 2001-2025 Free Software Foundation, Inc.
80629b1b
EZ
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
80629b1b
EZ
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
80629b1b 19
29e57380 20#include "command.h"
5b9707eb 21#include "cli/cli-cmds.h"
9e69a2e1 22#include "cli/cli-style.h"
29e57380
C
23#include "memattr.h"
24#include "target.h"
68c765e2 25#include "target-dcache.h"
29e57380
C
26#include "value.h"
27#include "language.h"
fbcb778d 28#include "breakpoint.h"
197f0a60 29#include "cli/cli-utils.h"
a664f67e 30#include <algorithm>
0d12e84c 31#include "gdbarch.h"
99d9c3b9 32#include "inferior.h"
41336620 33#include "progspace.h"
29e57380 34
a664f67e
SM
35static std::vector<mem_region> user_mem_region_list, target_mem_region_list;
36static std::vector<mem_region> *mem_region_list = &target_mem_region_list;
f4d650ec 37static int mem_number = 0;
29e57380 38
fd79ecee
DJ
39/* If this flag is set, the memory region list should be automatically
40 updated from the target. If it is clear, the list is user-controlled
41 and should be left alone. */
a664f67e
SM
42
43static bool
44mem_use_target ()
45{
46 return mem_region_list == &target_mem_region_list;
47}
fd79ecee
DJ
48
49/* If this flag is set, we have tried to fetch the target memory regions
50 since the last time it was invalidated. If that list is still
51 empty, then the target can't supply memory regions. */
a664f67e 52static bool target_mem_regions_valid;
fd79ecee 53
4b5752d0
VP
54/* If this flag is set, gdb will assume that memory ranges not
55 specified by the memory map have type MEM_NONE, and will
56 emit errors on all accesses to that memory. */
491144b5 57static bool inaccessible_by_default = true;
4b5752d0
VP
58
59static void
60show_inaccessible_by_default (struct ui_file *file, int from_tty,
61 struct cmd_list_element *c,
62 const char *value)
63{
64 if (inaccessible_by_default)
6cb06a8c
TT
65 gdb_printf (file, _("Unknown memory addresses will "
66 "be treated as inaccessible.\n"));
4b5752d0 67 else
6cb06a8c
TT
68 gdb_printf (file, _("Unknown memory addresses "
69 "will be treated as RAM.\n"));
4b5752d0
VP
70}
71
fd79ecee
DJ
72/* This function should be called before any command which would
73 modify the memory region list. It will handle switching from
74 a target-provided list to a local list, if necessary. */
75
76static void
77require_user_regions (int from_tty)
78{
fd79ecee 79 /* If we're already using a user-provided list, nothing to do. */
a664f67e 80 if (!mem_use_target ())
fd79ecee
DJ
81 return;
82
83 /* Switch to a user-provided list (possibly a copy of the current
84 one). */
a664f67e 85 mem_region_list = &user_mem_region_list;
fd79ecee
DJ
86
87 /* If we don't have a target-provided region list yet, then
88 no need to warn. */
a664f67e 89 if (target_mem_region_list.empty ())
fd79ecee
DJ
90 return;
91
92 /* Otherwise, let the user know how to get back. */
93 if (from_tty)
94 warning (_("Switching to manual control of memory regions; use "
9e69a2e1
TT
95 "\"%ps\" to fetch regions from the target again."),
96 styled_string (command_style.style (), "mem auto"));
fd79ecee 97
a664f67e
SM
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;
fd79ecee
DJ
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
108static void
109require_target_regions (void)
110{
a664f67e 111 if (mem_use_target () && !target_mem_regions_valid)
fd79ecee 112 {
a664f67e 113 target_mem_regions_valid = true;
fd79ecee 114 target_mem_region_list = target_memory_map ();
fd79ecee
DJ
115 }
116}
117
a664f67e
SM
118/* Create a new user-defined memory region. */
119
c96fc75e 120static void
a664f67e
SM
121create_user_mem_region (CORE_ADDR lo, CORE_ADDR hi,
122 const mem_attrib &attrib)
29e57380 123{
025bb325 124 /* lo == hi is a useless empty region. */
2b236d82 125 if (lo >= hi && hi != 0)
29e57380 126 {
6cb06a8c 127 gdb_printf (_("invalid memory region: low >= high\n"));
c96fc75e 128 return;
29e57380
C
129 }
130
a664f67e 131 mem_region newobj (lo, hi, attrib);
c96fc75e 132
a664f67e
SM
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);
c96fc75e
DJ
137
138 /* Check for an overlapping memory region. We only need to check
8f6606b6 139 in the vicinity - at most one before and one after the
c96fc75e 140 insertion point. */
a664f67e 141 for (int i = ix - 1; i < ix + 1; i++)
29e57380 142 {
c96fc75e
DJ
143 if (i < 0)
144 continue;
a664f67e 145 if (i >= user_mem_region_list.size ())
c96fc75e
DJ
146 continue;
147
a664f67e 148 mem_region &n = user_mem_region_list[i];
c96fc75e 149
a664f67e
SM
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)))
29e57380 153 {
6cb06a8c 154 gdb_printf (_("overlapping memory region\n"));
c96fc75e 155 return;
29e57380
C
156 }
157 }
158
fe978cb0 159 newobj.number = ++mem_number;
a664f67e 160 user_mem_region_list.insert (it, newobj);
29e57380
C
161}
162
a664f67e
SM
163/* Look up the memory region corresponding to ADDR. */
164
29e57380
C
165struct mem_region *
166lookup_mem_region (CORE_ADDR addr)
167{
a664f67e 168 static struct mem_region region (0, 0);
29e57380
C
169 CORE_ADDR lo;
170 CORE_ADDR hi;
171
fd79ecee
DJ
172 require_target_regions ();
173
29e57380
C
174 /* First we initialize LO and HI so that they describe the entire
175 memory space. As we process the memory region chain, they are
176 redefined to describe the minimal region containing ADDR. LO
177 and HI are used in the case where no memory region is defined
178 that contains ADDR. If a memory region is disabled, it is
a76d924d
DJ
179 treated as if it does not exist. The initial values for LO
180 and HI represent the bottom and top of memory. */
29e57380 181
a76d924d
DJ
182 lo = 0;
183 hi = 0;
29e57380 184
a664f67e 185 /* Either find memory range containing ADDR, or set LO and HI
4b5752d0
VP
186 to the nearest boundaries of an existing memory range.
187
188 If we ever want to support a huge list of memory regions, this
c96fc75e
DJ
189 check should be replaced with a binary search (probably using
190 VEC_lower_bound). */
a664f67e 191 for (mem_region &m : *mem_region_list)
29e57380 192 {
a664f67e 193 if (m.enabled_p == 1)
29e57380 194 {
3e43a32a
MS
195 /* If the address is in the memory region, return that
196 memory range. */
a664f67e
SM
197 if (addr >= m.lo && (addr < m.hi || m.hi == 0))
198 return &m;
29e57380 199
a76d924d
DJ
200 /* This (correctly) won't match if m->hi == 0, representing
201 the top of the address space, because CORE_ADDR is unsigned;
202 no value of LO is less than zero. */
a664f67e
SM
203 if (addr >= m.hi && lo < m.hi)
204 lo = m.hi;
29e57380 205
a76d924d
DJ
206 /* This will never set HI to zero; if we're here and ADDR
207 is at or below M, and the region starts at zero, then ADDR
208 would have been in the region. */
a664f67e
SM
209 if (addr <= m.lo && (hi == 0 || hi > m.lo))
210 hi = m.lo;
29e57380
C
211 }
212 }
213
214 /* Because no region was found, we must cons up one based on what
215 was learned above. */
216 region.lo = lo;
217 region.hi = hi;
4b5752d0
VP
218
219 /* When no memory map is defined at all, we always return
220 'default_mem_attrib', so that we do not make all memory
221 inaccessible for targets that don't provide a memory map. */
a664f67e
SM
222 if (inaccessible_by_default && !mem_region_list->empty ())
223 region.attrib = mem_attrib::unknown ();
4b5752d0 224 else
a664f67e 225 region.attrib = mem_attrib ();
4b5752d0 226
29e57380
C
227 return &region;
228}
fd79ecee
DJ
229
230/* Invalidate any memory regions fetched from the target. */
231
232void
233invalidate_target_mem_regions (void)
234{
fd79ecee
DJ
235 if (!target_mem_regions_valid)
236 return;
237
a664f67e
SM
238 target_mem_regions_valid = false;
239 target_mem_region_list.clear ();
fd79ecee
DJ
240}
241
a664f67e 242/* Clear user-defined memory region list. */
fd79ecee
DJ
243
244static void
a664f67e 245user_mem_clear (void)
fd79ecee 246{
a664f67e 247 user_mem_region_list.clear ();
fd79ecee 248}
29e57380
C
249\f
250
251static void
0b39b52e 252mem_command (const char *args, int from_tty)
29e57380
C
253{
254 CORE_ADDR lo, hi;
29e57380
C
255
256 if (!args)
e2e0b3e5 257 error_no_arg (_("No mem"));
29e57380 258
fd79ecee
DJ
259 /* For "mem auto", switch back to using a target provided list. */
260 if (strcmp (args, "auto") == 0)
261 {
a664f67e 262 if (mem_use_target ())
fd79ecee
DJ
263 return;
264
a664f67e
SM
265 user_mem_clear ();
266 mem_region_list = &target_mem_region_list;
fd79ecee 267
fd79ecee
DJ
268 return;
269 }
270
271 require_user_regions (from_tty);
272
0b39b52e
TT
273 std::string tok = extract_arg (&args);
274 if (tok == "")
8a3fe4f8 275 error (_("no lo address"));
0b39b52e 276 lo = parse_and_eval_address (tok.c_str ());
29e57380 277
0b39b52e
TT
278 tok = extract_arg (&args);
279 if (tok == "")
8a3fe4f8 280 error (_("no hi address"));
0b39b52e 281 hi = parse_and_eval_address (tok.c_str ());
29e57380 282
a664f67e 283 mem_attrib attrib;
0b39b52e 284 while ((tok = extract_arg (&args)) != "")
29e57380 285 {
0b39b52e 286 if (tok == "rw")
29e57380 287 attrib.mode = MEM_RW;
0b39b52e 288 else if (tok == "ro")
29e57380 289 attrib.mode = MEM_RO;
0b39b52e 290 else if (tok == "wo")
29e57380
C
291 attrib.mode = MEM_WO;
292
0b39b52e 293 else if (tok == "8")
29e57380 294 attrib.width = MEM_WIDTH_8;
0b39b52e 295 else if (tok == "16")
29e57380
C
296 {
297 if ((lo % 2 != 0) || (hi % 2 != 0))
8a3fe4f8 298 error (_("region bounds not 16 bit aligned"));
29e57380
C
299 attrib.width = MEM_WIDTH_16;
300 }
0b39b52e 301 else if (tok == "32")
29e57380
C
302 {
303 if ((lo % 4 != 0) || (hi % 4 != 0))
8a3fe4f8 304 error (_("region bounds not 32 bit aligned"));
29e57380
C
305 attrib.width = MEM_WIDTH_32;
306 }
0b39b52e 307 else if (tok == "64")
29e57380
C
308 {
309 if ((lo % 8 != 0) || (hi % 8 != 0))
8a3fe4f8 310 error (_("region bounds not 64 bit aligned"));
29e57380
C
311 attrib.width = MEM_WIDTH_64;
312 }
313
314#if 0
0b39b52e 315 else if (tok == "hwbreak")
81a9a963 316 attrib.hwbreak = 1;
0b39b52e 317 else if (tok == "swbreak")
81a9a963 318 attrib.hwbreak = 0;
29e57380
C
319#endif
320
0b39b52e 321 else if (tok == "cache")
81a9a963 322 attrib.cache = 1;
0b39b52e 323 else if (tok == "nocache")
81a9a963 324 attrib.cache = 0;
29e57380
C
325
326#if 0
0b39b52e 327 else if (tok == "verify")
81a9a963 328 attrib.verify = 1;
0b39b52e 329 else if (tok == "noverify")
81a9a963 330 attrib.verify = 0;
29e57380
C
331#endif
332
333 else
0b39b52e 334 error (_("unknown attribute: %s"), tok.c_str ());
29e57380
C
335 }
336
a664f67e 337 create_user_mem_region (lo, hi, attrib);
29e57380
C
338}
339\f
340
341static void
1d12d88f 342info_mem_command (const char *args, int from_tty)
29e57380 343{
a664f67e 344 if (mem_use_target ())
6cb06a8c 345 gdb_printf (_("Using memory regions provided by the target.\n"));
fd79ecee 346 else
6cb06a8c 347 gdb_printf (_("Using user-defined memory regions.\n"));
fd79ecee
DJ
348
349 require_target_regions ();
350
a664f67e 351 if (mem_region_list->empty ())
29e57380 352 {
6cb06a8c 353 gdb_printf (_("There are no memory regions defined.\n"));
29e57380
C
354 return;
355 }
356
6cb06a8c
TT
357 gdb_printf ("Num ");
358 gdb_printf ("Enb ");
359 gdb_printf ("Low Addr ");
99d9c3b9 360 if (gdbarch_addr_bit (current_inferior ()->arch ()) > 32)
6cb06a8c
TT
361 gdb_printf (" ");
362 gdb_printf ("High Addr ");
99d9c3b9 363 if (gdbarch_addr_bit (current_inferior ()->arch ()) > 32)
6cb06a8c
TT
364 gdb_printf (" ");
365 gdb_printf ("Attrs ");
366 gdb_printf ("\n");
ab35b611 367
a664f67e 368 for (const mem_region &m : *mem_region_list)
29e57380 369 {
a121b7c1 370 const char *tmp;
b8d56208 371
6cb06a8c
TT
372 gdb_printf ("%-3d %-3c\t",
373 m.number,
374 m.enabled_p ? 'y' : 'n');
99d9c3b9 375 if (gdbarch_addr_bit (current_inferior ()->arch ()) <= 32)
a664f67e 376 tmp = hex_string_custom (m.lo, 8);
ab35b611 377 else
a664f67e 378 tmp = hex_string_custom (m.lo, 16);
ab35b611 379
6cb06a8c 380 gdb_printf ("%s ", tmp);
2b236d82 381
99d9c3b9 382 if (gdbarch_addr_bit (current_inferior ()->arch ()) <= 32)
2163ab9d 383 {
a664f67e 384 if (m.hi == 0)
b8d56208
MS
385 tmp = "0x100000000";
386 else
a664f67e 387 tmp = hex_string_custom (m.hi, 8);
2163ab9d 388 }
ab35b611 389 else
2163ab9d 390 {
a664f67e 391 if (m.hi == 0)
b8d56208
MS
392 tmp = "0x10000000000000000";
393 else
a664f67e 394 tmp = hex_string_custom (m.hi, 16);
2163ab9d
DH
395 }
396
6cb06a8c 397 gdb_printf ("%s ", tmp);
29e57380
C
398
399 /* Print a token for each attribute.
400
401 * FIXME: Should we output a comma after each token? It may
402 * make it easier for users to read, but we'd lose the ability
403 * to cut-and-paste the list of attributes when defining a new
404 * region. Perhaps that is not important.
405 *
406 * FIXME: If more attributes are added to GDB, the output may
407 * become cluttered and difficult for users to read. At that
408 * time, we may want to consider printing tokens only if they
409 * are different from the default attribute. */
410
a664f67e 411 switch (m.attrib.mode)
29e57380
C
412 {
413 case MEM_RW:
6cb06a8c 414 gdb_printf ("rw ");
29e57380
C
415 break;
416 case MEM_RO:
6cb06a8c 417 gdb_printf ("ro ");
29e57380
C
418 break;
419 case MEM_WO:
6cb06a8c 420 gdb_printf ("wo ");
29e57380 421 break;
fd79ecee 422 case MEM_FLASH:
6cb06a8c 423 gdb_printf ("flash blocksize 0x%x ", m.attrib.blocksize);
fd79ecee 424 break;
29e57380
C
425 }
426
a664f67e 427 switch (m.attrib.width)
29e57380
C
428 {
429 case MEM_WIDTH_8:
6cb06a8c 430 gdb_printf ("8 ");
29e57380
C
431 break;
432 case MEM_WIDTH_16:
6cb06a8c 433 gdb_printf ("16 ");
29e57380
C
434 break;
435 case MEM_WIDTH_32:
6cb06a8c 436 gdb_printf ("32 ");
29e57380
C
437 break;
438 case MEM_WIDTH_64:
6cb06a8c 439 gdb_printf ("64 ");
29e57380
C
440 break;
441 case MEM_WIDTH_UNSPECIFIED:
442 break;
443 }
444
445#if 0
446 if (attrib->hwbreak)
6cb06a8c 447 gdb_printf ("hwbreak");
29e57380 448 else
6cb06a8c 449 gdb_printf ("swbreak");
29e57380
C
450#endif
451
a664f67e 452 if (m.attrib.cache)
6cb06a8c 453 gdb_printf ("cache ");
29e57380 454 else
6cb06a8c 455 gdb_printf ("nocache ");
29e57380
C
456
457#if 0
458 if (attrib->verify)
6cb06a8c 459 gdb_printf ("verify ");
29e57380 460 else
6cb06a8c 461 gdb_printf ("noverify ");
29e57380
C
462#endif
463
6cb06a8c 464 gdb_printf ("\n");
29e57380
C
465 }
466}
467\f
468
025bb325 469/* Enable the memory region number NUM. */
29e57380
C
470
471static void
472mem_enable (int num)
473{
a664f67e
SM
474 for (mem_region &m : *mem_region_list)
475 if (m.number == num)
29e57380 476 {
a664f67e 477 m.enabled_p = 1;
29e57380
C
478 return;
479 }
6cb06a8c 480 gdb_printf (_("No memory region number %d.\n"), num);
29e57380
C
481}
482
483static void
4465d9db 484enable_mem_command (const char *args, int from_tty)
29e57380 485{
fd79ecee
DJ
486 require_user_regions (from_tty);
487
41336620 488 target_dcache_invalidate (current_program_space->aspace);
29e57380 489
fbcb778d
MS
490 if (args == NULL || *args == '\0')
491 { /* Enable all mem regions. */
a664f67e
SM
492 for (mem_region &m : *mem_region_list)
493 m.enabled_p = 1;
29e57380
C
494 }
495 else
197f0a60 496 {
bfd28288
PA
497 number_or_range_parser parser (args);
498 while (!parser.finished ())
197f0a60 499 {
a664f67e 500 int num = parser.get_number ();
197f0a60
TT
501 mem_enable (num);
502 }
503 }
29e57380
C
504}
505\f
506
025bb325 507/* Disable the memory region number NUM. */
29e57380
C
508
509static void
510mem_disable (int num)
511{
a664f67e
SM
512 for (mem_region &m : *mem_region_list)
513 if (m.number == num)
29e57380 514 {
a664f67e 515 m.enabled_p = 0;
29e57380
C
516 return;
517 }
6cb06a8c 518 gdb_printf (_("No memory region number %d.\n"), num);
29e57380
C
519}
520
521static void
4465d9db 522disable_mem_command (const char *args, int from_tty)
29e57380 523{
fd79ecee
DJ
524 require_user_regions (from_tty);
525
41336620 526 target_dcache_invalidate (current_program_space->aspace);
29e57380 527
fbcb778d 528 if (args == NULL || *args == '\0')
29e57380 529 {
a664f67e
SM
530 for (mem_region &m : *mem_region_list)
531 m.enabled_p = false;
29e57380
C
532 }
533 else
197f0a60 534 {
bfd28288
PA
535 number_or_range_parser parser (args);
536 while (!parser.finished ())
197f0a60 537 {
bfd28288 538 int num = parser.get_number ();
197f0a60
TT
539 mem_disable (num);
540 }
541 }
29e57380
C
542}
543
025bb325 544/* Delete the memory region number NUM. */
29e57380
C
545
546static void
547mem_delete (int num)
548{
c96fc75e 549 if (!mem_region_list)
29e57380 550 {
6cb06a8c 551 gdb_printf (_("No memory region number %d.\n"), num);
29e57380
C
552 return;
553 }
554
a664f67e
SM
555 auto it = std::remove_if (mem_region_list->begin (), mem_region_list->end (),
556 [num] (const mem_region &m)
29e57380 557 {
a664f67e
SM
558 return m.number == num;
559 });
c96fc75e 560
a664f67e
SM
561 if (it != mem_region_list->end ())
562 mem_region_list->erase (it);
563 else
6cb06a8c 564 gdb_printf (_("No memory region number %d.\n"), num);
29e57380
C
565}
566
567static void
4465d9db 568delete_mem_command (const char *args, int from_tty)
29e57380 569{
fd79ecee
DJ
570 require_user_regions (from_tty);
571
41336620 572 target_dcache_invalidate (current_program_space->aspace);
29e57380 573
fbcb778d 574 if (args == NULL || *args == '\0')
29e57380 575 {
9e2f0ad4 576 if (query (_("Delete all memory regions? ")))
a664f67e 577 user_mem_clear ();
29e57380
C
578 dont_repeat ();
579 return;
580 }
581
bfd28288
PA
582 number_or_range_parser parser (args);
583 while (!parser.finished ())
29e57380 584 {
bfd28288 585 int num = parser.get_number ();
29e57380 586 mem_delete (num);
29e57380
C
587 }
588
589 dont_repeat ();
590}
4b5752d0 591
4b5752d0
VP
592static struct cmd_list_element *mem_set_cmdlist;
593static struct cmd_list_element *mem_show_cmdlist;
594
5fe70629 595INIT_GDB_FILE (mem)
29e57380 596{
1bedd215 597 add_com ("mem", class_vars, mem_command, _("\
fc55e99a 598Define or reset attributes for memory regions.\n\
fd79ecee 599Usage: mem auto\n\
99806209
TT
600 mem LOW HIGH [MODE WIDTH CACHE],\n\
601where MODE may be rw (read/write), ro (read-only) or wo (write-only),\n\
602 WIDTH may be 8, 16, 32, or 64, and\n\
603 CACHE may be cache or nocache"));
29e57380 604
ae3b3f34 605 add_cmd ("mem", class_vars, enable_mem_command, _("\
1a966eab 606Enable memory region.\n\
99806209
TT
607Arguments are the IDs of the memory regions to enable.\n\
608Usage: enable mem [ID]...\n\
609Do \"info mem\" to see current list of IDs."), &enablelist);
29e57380 610
ae3b3f34 611 add_cmd ("mem", class_vars, disable_mem_command, _("\
1a966eab 612Disable memory region.\n\
99806209
TT
613Arguments are the IDs of the memory regions to disable.\n\
614Usage: disable mem [ID]...\n\
615Do \"info mem\" to see current list of IDs."), &disablelist);
29e57380 616
ae3b3f34 617 add_cmd ("mem", class_vars, delete_mem_command, _("\
1a966eab 618Delete memory region.\n\
99806209
TT
619Arguments are the IDs of the memory regions to delete.\n\
620Usage: delete mem [ID]...\n\
621Do \"info mem\" to see current list of IDs."), &deletelist);
29e57380 622
ae3b3f34 623 add_info ("mem", info_mem_command,
590042fc 624 _("Memory region attributes."));
4b5752d0 625
f54bdb6d
SM
626 add_setshow_prefix_cmd ("mem", class_vars,
627 _("Memory regions settings."),
628 _("Memory regions settings."),
629 &mem_set_cmdlist, &mem_show_cmdlist,
630 &setlist, &showlist);
4b5752d0
VP
631
632 add_setshow_boolean_cmd ("inaccessible-by-default", no_class,
633 &inaccessible_by_default, _("\
634Set handling of unknown memory regions."), _("\
635Show handling of unknown memory regions."), _("\
636If on, and some memory map is defined, debugger will emit errors on\n\
637accesses to memory not defined in the memory map. If off, accesses to all\n\
638memory addresses will be allowed."),
639 NULL,
640 show_inaccessible_by_default,
641 &mem_set_cmdlist,
642 &mem_show_cmdlist);
29e57380 643}