1 /* Simulator memory option handling. 2 Copyright (C) 1996-2020 Free Software Foundation, Inc. 3 Contributed by Cygnus Support. 4 5 This file is part of GDB, the GNU debugger. 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 "config.h" 21 22 #include "sim-main.h" 23 #include "sim-assert.h" 24 #include "sim-options.h" 25 26 #ifdef HAVE_STRING_H 27 #include <string.h> 28 #else 29 #ifdef HAVE_STRINGS_H 30 #include <strings.h> 31 #endif 32 #endif 33 #ifdef HAVE_STDLIB_H 34 #include <stdlib.h> 35 #endif 36 #ifdef HAVE_ERRNO_H 37 #include <errno.h> 38 #endif 39 #ifdef HAVE_FCNTL_H 40 #include <fcntl.h> 41 #endif 42 #ifdef HAVE_SYS_MMAN_H 43 #include <sys/mman.h> 44 #endif 45 #ifdef HAVE_SYS_STAT_H 46 #include <sys/stat.h> 47 #endif 48 #ifdef HAVE_UNISTD_H 49 #include <unistd.h> 50 #endif 51 52 /* Memory fill byte. */ 53 static unsigned8 fill_byte_value; 54 static int fill_byte_flag = 0; 55 56 /* Memory mapping; see OPTION_MEMORY_MAPFILE. */ 57 static int mmap_next_fd = -1; 58 59 /* Memory command line options. */ 60 61 enum { 62 OPTION_MEMORY_DELETE = OPTION_START, 63 OPTION_MEMORY_REGION, 64 OPTION_MEMORY_SIZE, 65 OPTION_MEMORY_INFO, 66 OPTION_MEMORY_ALIAS, 67 OPTION_MEMORY_CLEAR, 68 OPTION_MEMORY_FILL, 69 OPTION_MEMORY_MAPFILE, 70 OPTION_MAP_INFO 71 }; 72 73 static DECLARE_OPTION_HANDLER (memory_option_handler); 74 75 static const OPTION memory_options[] = 76 { 77 { {"memory-delete", required_argument, NULL, OPTION_MEMORY_DELETE }, 78 '\0', "ADDRESS|all", "Delete memory at ADDRESS (all addresses)", 79 memory_option_handler }, 80 { {"delete-memory", required_argument, NULL, OPTION_MEMORY_DELETE }, 81 '\0', "ADDRESS", NULL, 82 memory_option_handler }, 83 84 { {"memory-region", required_argument, NULL, OPTION_MEMORY_REGION }, 85 '\0', "ADDRESS,SIZE[,MODULO]", "Add a memory region", 86 memory_option_handler }, 87 88 { {"memory-alias", required_argument, NULL, OPTION_MEMORY_ALIAS }, 89 '\0', "ADDRESS,SIZE{,ADDRESS}", "Add memory shadow", 90 memory_option_handler }, 91 92 { {"memory-size", required_argument, NULL, OPTION_MEMORY_SIZE }, 93 '\0', "<size>[in bytes, Kb (k suffix), Mb (m suffix) or Gb (g suffix)]", 94 "Add memory at address zero", memory_option_handler }, 95 96 { {"memory-fill", required_argument, NULL, OPTION_MEMORY_FILL }, 97 '\0', "VALUE", "Fill subsequently added memory regions", 98 memory_option_handler }, 99 100 { {"memory-clear", no_argument, NULL, OPTION_MEMORY_CLEAR }, 101 '\0', NULL, "Clear subsequently added memory regions", 102 memory_option_handler }, 103 104 #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) 105 { {"memory-mapfile", required_argument, NULL, OPTION_MEMORY_MAPFILE }, 106 '\0', "FILE", "Memory-map next memory region from file", 107 memory_option_handler }, 108 #endif 109 110 { {"memory-info", no_argument, NULL, OPTION_MEMORY_INFO }, 111 '\0', NULL, "List configurable memory regions", 112 memory_option_handler }, 113 { {"info-memory", no_argument, NULL, OPTION_MEMORY_INFO }, 114 '\0', NULL, NULL, 115 memory_option_handler }, 116 { {"map-info", no_argument, NULL, OPTION_MAP_INFO }, 117 '\0', NULL, "List mapped regions", 118 memory_option_handler }, 119 120 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL } 121 }; 122 123 124 static sim_memopt * 125 do_memopt_add (SIM_DESC sd, 126 int level, 127 int space, 128 address_word addr, 129 address_word nr_bytes, 130 unsigned modulo, 131 sim_memopt **entry, 132 void *buffer) 133 { 134 void *fill_buffer; 135 unsigned fill_length; 136 void *free_buffer; 137 unsigned long free_length; 138 139 if (buffer != NULL) 140 { 141 /* Buffer already given. sim_memory_uninstall will free it. */ 142 sim_core_attach (sd, NULL, 143 level, access_read_write_exec, space, 144 addr, nr_bytes, modulo, NULL, buffer); 145 146 free_buffer = buffer; 147 free_length = 0; 148 fill_buffer = buffer; 149 fill_length = (modulo == 0) ? nr_bytes : modulo; 150 } 151 else 152 { 153 /* Allocate new well-aligned buffer, just as sim_core_attach(). */ 154 void *aligned_buffer; 155 int padding = (addr % sizeof (unsigned64)); 156 unsigned long bytes; 157 158 #ifdef HAVE_MMAP 159 struct stat s; 160 161 if (mmap_next_fd >= 0) 162 { 163 /* Check that given file is big enough. */ 164 int rc = fstat (mmap_next_fd, &s); 165 166 if (rc < 0) 167 sim_io_error (sd, "Error, unable to stat file: %s\n", 168 strerror (errno)); 169 170 /* Autosize the mapping to the file length. */ 171 if (nr_bytes == 0) 172 nr_bytes = s.st_size; 173 } 174 #endif 175 176 bytes = (modulo == 0 ? nr_bytes : modulo) + padding; 177 178 free_buffer = NULL; 179 free_length = bytes; 180 181 #ifdef HAVE_MMAP 182 /* Memory map or malloc(). */ 183 if (mmap_next_fd >= 0) 184 { 185 /* Some kernels will SIGBUS the application if mmap'd file 186 is not large enough. */ 187 if (s.st_size < bytes) 188 { 189 sim_io_error (sd, 190 "Error, cannot confirm that mmap file is large enough " 191 "(>= %ld bytes)\n", bytes); 192 } 193 194 free_buffer = mmap (0, bytes, PROT_READ|PROT_WRITE, MAP_SHARED, mmap_next_fd, 0); 195 if (free_buffer == 0 || free_buffer == (char*)-1) /* MAP_FAILED */ 196 { 197 sim_io_error (sd, "Error, cannot mmap file (%s).\n", 198 strerror (errno)); 199 } 200 } 201 #endif 202 203 /* Need heap allocation? */ 204 if (free_buffer == NULL) 205 { 206 /* If filling with non-zero value, do not use clearing allocator. */ 207 if (fill_byte_flag && fill_byte_value != 0) 208 free_buffer = xmalloc (bytes); /* don't clear */ 209 else 210 free_buffer = zalloc (bytes); /* clear */ 211 } 212 213 aligned_buffer = (char*) free_buffer + padding; 214 215 sim_core_attach (sd, NULL, 216 level, access_read_write_exec, space, 217 addr, nr_bytes, modulo, NULL, aligned_buffer); 218 219 fill_buffer = aligned_buffer; 220 fill_length = (modulo == 0) ? nr_bytes : modulo; 221 222 /* If we just used a clearing allocator, and are about to fill with 223 zero, truncate the redundant fill operation. */ 224 225 if (fill_byte_flag && fill_byte_value == 0) 226 fill_length = 1; /* avoid boundary length=0 case */ 227 } 228 229 if (fill_byte_flag) 230 { 231 ASSERT (fill_buffer != 0); 232 memset ((char*) fill_buffer, fill_byte_value, fill_length); 233 } 234 235 while ((*entry) != NULL) 236 entry = &(*entry)->next; 237 (*entry) = ZALLOC (sim_memopt); 238 (*entry)->level = level; 239 (*entry)->space = space; 240 (*entry)->addr = addr; 241 (*entry)->nr_bytes = nr_bytes; 242 (*entry)->modulo = modulo; 243 (*entry)->buffer = free_buffer; 244 245 /* Record memory unmapping info. */ 246 if (mmap_next_fd >= 0) 247 { 248 (*entry)->munmap_length = free_length; 249 close (mmap_next_fd); 250 mmap_next_fd = -1; 251 } 252 else 253 (*entry)->munmap_length = 0; 254 255 return (*entry); 256 } 257 258 static SIM_RC 259 do_memopt_delete (SIM_DESC sd, 260 int level, 261 int space, 262 address_word addr) 263 { 264 sim_memopt **entry = &STATE_MEMOPT (sd); 265 sim_memopt *alias; 266 while ((*entry) != NULL 267 && ((*entry)->level != level 268 || (*entry)->space != space 269 || (*entry)->addr != addr)) 270 entry = &(*entry)->next; 271 if ((*entry) == NULL) 272 { 273 sim_io_eprintf (sd, "Memory at 0x%lx not found, not deleted\n", 274 (long) addr); 275 return SIM_RC_FAIL; 276 } 277 /* delete any buffer */ 278 if ((*entry)->buffer != NULL) 279 { 280 #ifdef HAVE_MUNMAP 281 if ((*entry)->munmap_length > 0) 282 munmap ((*entry)->buffer, (*entry)->munmap_length); 283 else 284 #endif 285 free ((*entry)->buffer); 286 } 287 288 /* delete it and its aliases */ 289 alias = *entry; 290 *entry = (*entry)->next; 291 while (alias != NULL) 292 { 293 sim_memopt *dead = alias; 294 alias = alias->alias; 295 sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr); 296 free (dead); 297 } 298 return SIM_RC_OK; 299 } 300 301 302 static char * 303 parse_size (char *chp, 304 address_word *nr_bytes, 305 unsigned *modulo) 306 { 307 /* <nr_bytes>[K|M|G] [ "%" <modulo> ] */ 308 *nr_bytes = strtoul (chp, &chp, 0); 309 switch (*chp) 310 { 311 case '%': 312 *modulo = strtoul (chp + 1, &chp, 0); 313 break; 314 case 'g': case 'G': /* Gigabyte suffix. */ 315 *nr_bytes <<= 10; 316 /* Fall through. */ 317 case 'm': case 'M': /* Megabyte suffix. */ 318 *nr_bytes <<= 10; 319 /* Fall through. */ 320 case 'k': case 'K': /* Kilobyte suffix. */ 321 *nr_bytes <<= 10; 322 /* Check for a modulo specifier after the suffix. */ 323 ++ chp; 324 if (* chp == 'b' || * chp == 'B') 325 ++ chp; 326 if (* chp == '%') 327 *modulo = strtoul (chp + 1, &chp, 0); 328 break; 329 } 330 return chp; 331 } 332 333 static char * 334 parse_ulong_value (char *chp, 335 unsigned long *value) 336 { 337 *value = strtoul (chp, &chp, 0); 338 return chp; 339 } 340 341 static char * 342 parse_addr (char *chp, 343 int *level, 344 int *space, 345 address_word *addr) 346 { 347 /* [ <space> ": " ] <addr> [ "@" <level> ] */ 348 *addr = (unsigned long) strtoul (chp, &chp, 0); 349 if (*chp == ':') 350 { 351 *space = *addr; 352 *addr = (unsigned long) strtoul (chp + 1, &chp, 0); 353 } 354 if (*chp == '@') 355 { 356 *level = strtoul (chp + 1, &chp, 0); 357 } 358 return chp; 359 } 360 361 362 static SIM_RC 363 memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, 364 char *arg, int is_command) 365 { 366 switch (opt) 367 { 368 369 case OPTION_MEMORY_DELETE: 370 if (strcasecmp (arg, "all") == 0) 371 { 372 while (STATE_MEMOPT (sd) != NULL) 373 do_memopt_delete (sd, 374 STATE_MEMOPT (sd)->level, 375 STATE_MEMOPT (sd)->space, 376 STATE_MEMOPT (sd)->addr); 377 return SIM_RC_OK; 378 } 379 else 380 { 381 int level = 0; 382 int space = 0; 383 address_word addr = 0; 384 parse_addr (arg, &level, &space, &addr); 385 return do_memopt_delete (sd, level, space, addr); 386 } 387 388 case OPTION_MEMORY_REGION: 389 { 390 char *chp = arg; 391 int level = 0; 392 int space = 0; 393 address_word addr = 0; 394 address_word nr_bytes = 0; 395 unsigned modulo = 0; 396 /* parse the arguments */ 397 chp = parse_addr (chp, &level, &space, &addr); 398 if (*chp != ',') 399 { 400 /* let the file autosize */ 401 if (mmap_next_fd == -1) 402 { 403 sim_io_eprintf (sd, "Missing size for memory-region\n"); 404 return SIM_RC_FAIL; 405 } 406 } 407 else 408 chp = parse_size (chp + 1, &nr_bytes, &modulo); 409 /* old style */ 410 if (*chp == ',') 411 modulo = strtoul (chp + 1, &chp, 0); 412 /* try to attach/insert it */ 413 do_memopt_add (sd, level, space, addr, nr_bytes, modulo, 414 &STATE_MEMOPT (sd), NULL); 415 return SIM_RC_OK; 416 } 417 418 case OPTION_MEMORY_ALIAS: 419 { 420 char *chp = arg; 421 int level = 0; 422 int space = 0; 423 address_word addr = 0; 424 address_word nr_bytes = 0; 425 unsigned modulo = 0; 426 sim_memopt *entry; 427 /* parse the arguments */ 428 chp = parse_addr (chp, &level, &space, &addr); 429 if (*chp != ',') 430 { 431 sim_io_eprintf (sd, "Missing size for memory-region\n"); 432 return SIM_RC_FAIL; 433 } 434 chp = parse_size (chp + 1, &nr_bytes, &modulo); 435 /* try to attach/insert the main record */ 436 entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo, 437 &STATE_MEMOPT (sd), 438 NULL); 439 /* now attach all the aliases */ 440 while (*chp == ',') 441 { 442 int a_level = level; 443 int a_space = space; 444 address_word a_addr = addr; 445 chp = parse_addr (chp + 1, &a_level, &a_space, &a_addr); 446 do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo, 447 &entry->alias, entry->buffer); 448 } 449 return SIM_RC_OK; 450 } 451 452 case OPTION_MEMORY_SIZE: 453 { 454 int level = 0; 455 int space = 0; 456 address_word addr = 0; 457 address_word nr_bytes = 0; 458 unsigned modulo = 0; 459 /* parse the arguments */ 460 parse_size (arg, &nr_bytes, &modulo); 461 /* try to attach/insert it */ 462 do_memopt_add (sd, level, space, addr, nr_bytes, modulo, 463 &STATE_MEMOPT (sd), NULL); 464 return SIM_RC_OK; 465 } 466 467 case OPTION_MEMORY_CLEAR: 468 { 469 fill_byte_value = (unsigned8) 0; 470 fill_byte_flag = 1; 471 return SIM_RC_OK; 472 break; 473 } 474 475 case OPTION_MEMORY_FILL: 476 { 477 unsigned long fill_value; 478 parse_ulong_value (arg, &fill_value); 479 if (fill_value > 255) 480 { 481 sim_io_eprintf (sd, "Missing fill value between 0 and 255\n"); 482 return SIM_RC_FAIL; 483 } 484 fill_byte_value = (unsigned8) fill_value; 485 fill_byte_flag = 1; 486 return SIM_RC_OK; 487 break; 488 } 489 490 case OPTION_MEMORY_MAPFILE: 491 { 492 if (mmap_next_fd >= 0) 493 { 494 sim_io_eprintf (sd, "Duplicate memory-mapfile option\n"); 495 return SIM_RC_FAIL; 496 } 497 498 mmap_next_fd = open (arg, O_RDWR); 499 if (mmap_next_fd < 0) 500 { 501 sim_io_eprintf (sd, "Cannot open file `%s': %s\n", 502 arg, strerror (errno)); 503 return SIM_RC_FAIL; 504 } 505 506 return SIM_RC_OK; 507 } 508 509 case OPTION_MEMORY_INFO: 510 { 511 sim_memopt *entry; 512 sim_io_printf (sd, "Memory maps:\n"); 513 for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) 514 { 515 sim_memopt *alias; 516 sim_io_printf (sd, " memory"); 517 if (entry->alias == NULL) 518 sim_io_printf (sd, " region "); 519 else 520 sim_io_printf (sd, " alias "); 521 if (entry->space != 0) 522 sim_io_printf (sd, "0x%lx:", (long) entry->space); 523 sim_io_printf (sd, "0x%08lx", (long) entry->addr); 524 if (entry->level != 0) 525 sim_io_printf (sd, "@0x%lx", (long) entry->level); 526 sim_io_printf (sd, ",0x%lx", 527 (long) entry->nr_bytes); 528 if (entry->modulo != 0) 529 sim_io_printf (sd, "%%0x%lx", (long) entry->modulo); 530 for (alias = entry->alias; 531 alias != NULL; 532 alias = alias->next) 533 { 534 if (alias->space != 0) 535 sim_io_printf (sd, "0x%lx:", (long) alias->space); 536 sim_io_printf (sd, ",0x%08lx", (long) alias->addr); 537 if (alias->level != 0) 538 sim_io_printf (sd, "@0x%lx", (long) alias->level); 539 } 540 sim_io_printf (sd, "\n"); 541 } 542 return SIM_RC_OK; 543 break; 544 } 545 546 case OPTION_MAP_INFO: 547 { 548 sim_core *memory = STATE_CORE (sd); 549 unsigned nr_map; 550 551 for (nr_map = 0; nr_map < nr_maps; ++nr_map) 552 { 553 sim_core_map *map = &memory->common.map[nr_map]; 554 sim_core_mapping *mapping = map->first; 555 556 if (!mapping) 557 continue; 558 559 sim_io_printf (sd, "%s maps:\n", map_to_str (nr_map)); 560 do 561 { 562 unsigned modulo; 563 564 sim_io_printf (sd, " map "); 565 if (mapping->space != 0) 566 sim_io_printf (sd, "0x%x:", mapping->space); 567 sim_io_printf (sd, "0x%08lx", (long) mapping->base); 568 if (mapping->level != 0) 569 sim_io_printf (sd, "@0x%x", mapping->level); 570 sim_io_printf (sd, ",0x%lx", (long) mapping->nr_bytes); 571 modulo = mapping->mask + 1; 572 if (modulo != 0) 573 sim_io_printf (sd, "%%0x%x", modulo); 574 sim_io_printf (sd, "\n"); 575 576 mapping = mapping->next; 577 } 578 while (mapping); 579 } 580 581 return SIM_RC_OK; 582 break; 583 } 584 585 default: 586 sim_io_eprintf (sd, "Unknown memory option %d\n", opt); 587 return SIM_RC_FAIL; 588 589 } 590 591 return SIM_RC_FAIL; 592 } 593 594 595 /* "memory" module install handler. 596 597 This is called via sim_module_install to install the "memory" subsystem 598 into the simulator. */ 599 600 static MODULE_INIT_FN sim_memory_init; 601 static MODULE_UNINSTALL_FN sim_memory_uninstall; 602 603 SIM_RC 604 sim_memopt_install (SIM_DESC sd) 605 { 606 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 607 sim_add_option_table (sd, NULL, memory_options); 608 sim_module_add_uninstall_fn (sd, sim_memory_uninstall); 609 sim_module_add_init_fn (sd, sim_memory_init); 610 return SIM_RC_OK; 611 } 612 613 614 /* Uninstall the "memory" subsystem from the simulator. */ 615 616 static void 617 sim_memory_uninstall (SIM_DESC sd) 618 { 619 sim_memopt **entry = &STATE_MEMOPT (sd); 620 sim_memopt *alias; 621 622 while ((*entry) != NULL) 623 { 624 /* delete any buffer */ 625 if ((*entry)->buffer != NULL) 626 { 627 #ifdef HAVE_MUNMAP 628 if ((*entry)->munmap_length > 0) 629 munmap ((*entry)->buffer, (*entry)->munmap_length); 630 else 631 #endif 632 free ((*entry)->buffer); 633 } 634 635 /* delete it and its aliases */ 636 alias = *entry; 637 638 /* next victim */ 639 *entry = (*entry)->next; 640 641 while (alias != NULL) 642 { 643 sim_memopt *dead = alias; 644 alias = alias->alias; 645 sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr); 646 free (dead); 647 } 648 } 649 } 650 651 652 static SIM_RC 653 sim_memory_init (SIM_DESC sd) 654 { 655 /* Reinitialize option modifier flags, in case they were left 656 over from a previous sim startup event. */ 657 fill_byte_flag = 0; 658 mmap_next_fd = -1; 659 660 return SIM_RC_OK; 661 } 662