summaryrefslogtreecommitdiff
path: root/sim/common/sim-memopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/common/sim-memopt.c')
-rw-r--r--sim/common/sim-memopt.c579
1 files changed, 0 insertions, 579 deletions
diff --git a/sim/common/sim-memopt.c b/sim/common/sim-memopt.c
deleted file mode 100644
index a8e9df65332..00000000000
--- a/sim/common/sim-memopt.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/* Simulator memory option handling.
- Copyright (C) 1996-1999 Free Software Foundation, Inc.
- Contributed by Cygnus Support.
-
-This file is part of GDB, the GNU debugger.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "cconfig.h"
-
-#include "sim-main.h"
-#include "sim-assert.h"
-#include "sim-options.h"
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-/* Memory fill byte. */
-static unsigned8 fill_byte_value;
-static int fill_byte_flag = 0;
-
-/* Memory mapping; see OPTION_MEMORY_MAPFILE. */
-static int mmap_next_fd = -1;
-
-/* Memory command line options. */
-
-enum {
- OPTION_MEMORY_DELETE = OPTION_START,
- OPTION_MEMORY_REGION,
- OPTION_MEMORY_SIZE,
- OPTION_MEMORY_INFO,
- OPTION_MEMORY_ALIAS,
- OPTION_MEMORY_CLEAR,
- OPTION_MEMORY_FILL,
- OPTION_MEMORY_MAPFILE
-};
-
-static DECLARE_OPTION_HANDLER (memory_option_handler);
-
-static const OPTION memory_options[] =
-{
- { {"memory-delete", required_argument, NULL, OPTION_MEMORY_DELETE },
- '\0', "ADDRESS|all", "Delete memory at ADDRESS (all addresses)",
- memory_option_handler },
- { {"delete-memory", required_argument, NULL, OPTION_MEMORY_DELETE },
- '\0', "ADDRESS", NULL,
- memory_option_handler },
-
- { {"memory-region", required_argument, NULL, OPTION_MEMORY_REGION },
- '\0', "ADDRESS,SIZE[,MODULO]", "Add a memory region",
- memory_option_handler },
-
- { {"memory-alias", required_argument, NULL, OPTION_MEMORY_ALIAS },
- '\0', "ADDRESS,SIZE{,ADDRESS}", "Add memory shadow",
- memory_option_handler },
-
- { {"memory-size", required_argument, NULL, OPTION_MEMORY_SIZE },
- '\0', "SIZE", "Add memory at address zero",
- memory_option_handler },
-
- { {"memory-fill", required_argument, NULL, OPTION_MEMORY_FILL },
- '\0', "VALUE", "Fill subsequently added memory regions",
- memory_option_handler },
-
- { {"memory-clear", no_argument, NULL, OPTION_MEMORY_CLEAR },
- '\0', NULL, "Clear subsequently added memory regions",
- memory_option_handler },
-
-#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
- { {"memory-mapfile", required_argument, NULL, OPTION_MEMORY_MAPFILE },
- '\0', "FILE", "Memory-map next memory region from file",
- memory_option_handler },
-#endif
-
- { {"memory-info", no_argument, NULL, OPTION_MEMORY_INFO },
- '\0', NULL, "List configurable memory regions",
- memory_option_handler },
- { {"info-memory", no_argument, NULL, OPTION_MEMORY_INFO },
- '\0', NULL, NULL,
- memory_option_handler },
-
- { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
-};
-
-
-static sim_memopt *
-do_memopt_add (SIM_DESC sd,
- int level,
- int space,
- address_word addr,
- address_word nr_bytes,
- unsigned modulo,
- sim_memopt **entry,
- void *buffer)
-{
- void *fill_buffer;
- unsigned fill_length;
- void *free_buffer;
- unsigned long free_length;
-
- if (buffer != NULL)
- {
- /* Buffer already given. sim_memory_uninstall will free it. */
- sim_core_attach (sd, NULL,
- level, access_read_write_exec, space,
- addr, nr_bytes, modulo, NULL, buffer);
-
- free_buffer = buffer;
- free_length = 0;
- fill_buffer = buffer;
- fill_length = (modulo == 0) ? nr_bytes : modulo;
- }
- else
- {
- /* Allocate new well-aligned buffer, just as sim_core_attach(). */
- void *aligned_buffer;
- int padding = (addr % sizeof (unsigned64));
- unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding;
-
- free_buffer = NULL;
- free_length = bytes;
-
-#ifdef HAVE_MMAP
- /* Memory map or malloc(). */
- if (mmap_next_fd >= 0)
- {
- /* Check that given file is big enough. */
- struct stat s;
- int rc;
-
- /* Some kernels will SIGBUS the application if mmap'd file
- is not large enough. */
- rc = fstat (mmap_next_fd, &s);
- if (rc < 0 || s.st_size < bytes)
- {
- sim_io_error (sd,
- "Error, cannot confirm that mmap file is large enough "
- "(>= %d bytes)\n", bytes);
- }
-
- free_buffer = mmap (0, bytes, PROT_READ|PROT_WRITE, MAP_SHARED, mmap_next_fd, 0);
- if (free_buffer == 0 || free_buffer == (char*)-1) /* MAP_FAILED */
- {
- sim_io_error (sd, "Error, cannot mmap file (%s).\n",
- strerror(errno));
- }
- }
-#endif
-
- /* Need heap allocation? */
- if (free_buffer == NULL)
- {
- /* If filling with non-zero value, do not use clearing allocator. */
- if (fill_byte_flag && fill_byte_value != 0)
- free_buffer = xmalloc (bytes); /* don't clear */
- else
- free_buffer = zalloc (bytes); /* clear */
- }
-
- aligned_buffer = (char*) free_buffer + padding;
-
- sim_core_attach (sd, NULL,
- level, access_read_write_exec, space,
- addr, nr_bytes, modulo, NULL, aligned_buffer);
-
- fill_buffer = aligned_buffer;
- fill_length = (modulo == 0) ? nr_bytes : modulo;
-
- /* If we just used a clearing allocator, and are about to fill with
- zero, truncate the redundant fill operation. */
-
- if (fill_byte_flag && fill_byte_value == 0)
- fill_length = 1; /* avoid boundary length=0 case */
- }
-
- if (fill_byte_flag)
- {
- ASSERT (fill_buffer != 0);
- memset ((char*) fill_buffer, fill_byte_value, fill_length);
- }
-
- while ((*entry) != NULL)
- entry = &(*entry)->next;
- (*entry) = ZALLOC (sim_memopt);
- (*entry)->level = level;
- (*entry)->space = space;
- (*entry)->addr = addr;
- (*entry)->nr_bytes = nr_bytes;
- (*entry)->modulo = modulo;
- (*entry)->buffer = free_buffer;
-
- /* Record memory unmapping info. */
- if (mmap_next_fd >= 0)
- {
- (*entry)->munmap_length = free_length;
- close (mmap_next_fd);
- mmap_next_fd = -1;
- }
- else
- (*entry)->munmap_length = 0;
-
- return (*entry);
-}
-
-static SIM_RC
-do_memopt_delete (SIM_DESC sd,
- int level,
- int space,
- address_word addr)
-{
- sim_memopt **entry = &STATE_MEMOPT (sd);
- sim_memopt *alias;
- while ((*entry) != NULL
- && ((*entry)->level != level
- || (*entry)->space != space
- || (*entry)->addr != addr))
- entry = &(*entry)->next;
- if ((*entry) == NULL)
- {
- sim_io_eprintf (sd, "Memory at 0x%lx not found, not deleted\n",
- (long) addr);
- return SIM_RC_FAIL;
- }
- /* delete any buffer */
- if ((*entry)->buffer != NULL)
- {
-#ifdef HAVE_MUNMAP
- if ((*entry)->munmap_length > 0)
- munmap ((*entry)->buffer, (*entry)->munmap_length);
- else
-#endif
- zfree ((*entry)->buffer);
- }
-
- /* delete it and its aliases */
- alias = *entry;
- *entry = (*entry)->next;
- while (alias != NULL)
- {
- sim_memopt *dead = alias;
- alias = alias->alias;
- sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr);
- zfree (dead);
- }
- return SIM_RC_OK;
-}
-
-
-static char *
-parse_size (char *chp,
- address_word *nr_bytes,
- unsigned *modulo)
-{
- /* <nr_bytes> [ "%" <modulo> ] */
- *nr_bytes = strtoul (chp, &chp, 0);
- if (*chp == '%')
- {
- *modulo = strtoul (chp + 1, &chp, 0);
- }
- return chp;
-}
-
-static char *
-parse_ulong_value (char *chp,
- unsigned long *value)
-{
- *value = strtoul (chp, &chp, 0);
- return chp;
-}
-
-static char *
-parse_addr (char *chp,
- int *level,
- int *space,
- address_word *addr)
-{
- /* [ <space> ": " ] <addr> [ "@" <level> ] */
- *addr = (unsigned long) strtoul (chp, &chp, 0);
- if (*chp == ':')
- {
- *space = *addr;
- *addr = (unsigned long) strtoul (chp + 1, &chp, 0);
- }
- if (*chp == '@')
- {
- *level = strtoul (chp + 1, &chp, 0);
- }
- return chp;
-}
-
-
-static SIM_RC
-memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
- char *arg, int is_command)
-{
- switch (opt)
- {
-
- case OPTION_MEMORY_DELETE:
- if (strcasecmp (arg, "all") == 0)
- {
- while (STATE_MEMOPT (sd) != NULL)
- do_memopt_delete (sd,
- STATE_MEMOPT (sd)->level,
- STATE_MEMOPT (sd)->space,
- STATE_MEMOPT (sd)->addr);
- return SIM_RC_OK;
- }
- else
- {
- int level = 0;
- int space = 0;
- address_word addr = 0;
- parse_addr (arg, &level, &space, &addr);
- return do_memopt_delete (sd, level, space, addr);
- }
-
- case OPTION_MEMORY_REGION:
- {
- char *chp = arg;
- int level = 0;
- int space = 0;
- address_word addr = 0;
- address_word nr_bytes = 0;
- unsigned modulo = 0;
- /* parse the arguments */
- chp = parse_addr (chp, &level, &space, &addr);
- if (*chp != ',')
- {
- sim_io_eprintf (sd, "Missing size for memory-region\n");
- return SIM_RC_FAIL;
- }
- chp = parse_size (chp + 1, &nr_bytes, &modulo);
- /* old style */
- if (*chp == ',')
- modulo = strtoul (chp + 1, &chp, 0);
- /* try to attach/insert it */
- do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
- &STATE_MEMOPT (sd), NULL);
- return SIM_RC_OK;
- }
-
- case OPTION_MEMORY_ALIAS:
- {
- char *chp = arg;
- int level = 0;
- int space = 0;
- address_word addr = 0;
- address_word nr_bytes = 0;
- unsigned modulo = 0;
- sim_memopt *entry;
- /* parse the arguments */
- chp = parse_addr (chp, &level, &space, &addr);
- if (*chp != ',')
- {
- sim_io_eprintf (sd, "Missing size for memory-region\n");
- return SIM_RC_FAIL;
- }
- chp = parse_size (chp + 1, &nr_bytes, &modulo);
- /* try to attach/insert the main record */
- entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
- &STATE_MEMOPT (sd),
- NULL);
- /* now attach all the aliases */
- while (*chp == ',')
- {
- int a_level = level;
- int a_space = space;
- address_word a_addr = addr;
- chp = parse_addr (chp + 1, &a_level, &a_space, &a_addr);
- do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo,
- &entry->alias, entry->buffer);
- }
- return SIM_RC_OK;
- }
-
- case OPTION_MEMORY_SIZE:
- {
- int level = 0;
- int space = 0;
- address_word addr = 0;
- address_word nr_bytes = 0;
- unsigned modulo = 0;
- /* parse the arguments */
- parse_size (arg, &nr_bytes, &modulo);
- /* try to attach/insert it */
- do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
- &STATE_MEMOPT (sd), NULL);
- return SIM_RC_OK;
- }
-
- case OPTION_MEMORY_CLEAR:
- {
- fill_byte_value = (unsigned8) 0;
- fill_byte_flag = 1;
- return SIM_RC_OK;
- break;
- }
-
- case OPTION_MEMORY_FILL:
- {
- unsigned long fill_value;
- parse_ulong_value (arg, &fill_value);
- if (fill_value > 255)
- {
- sim_io_eprintf (sd, "Missing fill value between 0 and 255\n");
- return SIM_RC_FAIL;
- }
- fill_byte_value = (unsigned8) fill_value;
- fill_byte_flag = 1;
- return SIM_RC_OK;
- break;
- }
-
- case OPTION_MEMORY_MAPFILE:
- {
- if (mmap_next_fd >= 0)
- {
- sim_io_eprintf (sd, "Duplicate memory-mapfile option\n");
- return SIM_RC_FAIL;
- }
-
- mmap_next_fd = open (arg, O_RDWR);
- if (mmap_next_fd < 0)
- {
- sim_io_eprintf (sd, "Cannot open file `%s': %s\n",
- arg, strerror(errno));
- return SIM_RC_FAIL;
- }
-
- return SIM_RC_OK;
- }
-
- case OPTION_MEMORY_INFO:
- {
- sim_memopt *entry;
- sim_io_printf (sd, "Memory maps:\n");
- for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
- {
- sim_memopt *alias;
- sim_io_printf (sd, " memory");
- if (entry->alias == NULL)
- sim_io_printf (sd, " region ");
- else
- sim_io_printf (sd, " alias ");
- if (entry->space != 0)
- sim_io_printf (sd, "0x%lx:", (long) entry->space);
- sim_io_printf (sd, "0x%08lx", (long) entry->addr);
- if (entry->level != 0)
- sim_io_printf (sd, "@0x%lx", (long) entry->level);
- sim_io_printf (sd, ",0x%lx",
- (long) entry->nr_bytes);
- if (entry->modulo != 0)
- sim_io_printf (sd, "%%0x%lx", (long) entry->modulo);
- for (alias = entry->alias;
- alias != NULL;
- alias = alias->next)
- {
- if (alias->space != 0)
- sim_io_printf (sd, "0x%lx:", (long) alias->space);
- sim_io_printf (sd, ",0x%08lx", (long) alias->addr);
- if (alias->level != 0)
- sim_io_printf (sd, "@0x%lx", (long) alias->level);
- }
- sim_io_printf (sd, "\n");
- }
- return SIM_RC_OK;
- break;
- }
-
- default:
- sim_io_eprintf (sd, "Unknown memory option %d\n", opt);
- return SIM_RC_FAIL;
-
- }
-
- return SIM_RC_FAIL;
-}
-
-
-/* "memory" module install handler.
-
- This is called via sim_module_install to install the "memory" subsystem
- into the simulator. */
-
-static MODULE_INIT_FN sim_memory_init;
-static MODULE_UNINSTALL_FN sim_memory_uninstall;
-
-SIM_RC
-sim_memopt_install (SIM_DESC sd)
-{
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- sim_add_option_table (sd, NULL, memory_options);
- sim_module_add_uninstall_fn (sd, sim_memory_uninstall);
- sim_module_add_init_fn (sd, sim_memory_init);
- return SIM_RC_OK;
-}
-
-
-/* Uninstall the "memory" subsystem from the simulator. */
-
-static void
-sim_memory_uninstall (SIM_DESC sd)
-{
- sim_memopt **entry = &STATE_MEMOPT (sd);
- sim_memopt *alias;
-
- while ((*entry) != NULL)
- {
- /* delete any buffer */
- if ((*entry)->buffer != NULL)
- {
-#ifdef HAVE_MUNMAP
- if ((*entry)->munmap_length > 0)
- munmap ((*entry)->buffer, (*entry)->munmap_length);
- else
-#endif
- zfree ((*entry)->buffer);
- }
-
- /* delete it and its aliases */
- alias = *entry;
-
- /* next victim */
- *entry = (*entry)->next;
-
- while (alias != NULL)
- {
- sim_memopt *dead = alias;
- alias = alias->alias;
- sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr);
- zfree (dead);
- }
- }
-}
-
-
-static SIM_RC
-sim_memory_init (SIM_DESC sd)
-{
- /* Reinitialize option modifier flags, in case they were left
- over from a previous sim startup event. */
- fill_byte_flag = 0;
- mmap_next_fd = -1;
-
- return SIM_RC_OK;
-}