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