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