diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/remote-sim.h | 87 | ||||
-rw-r--r-- | gdb/remote-sp64sim.c | 317 | ||||
-rw-r--r-- | gdb/sp64-tdep.c | 93 |
3 files changed, 295 insertions, 202 deletions
diff --git a/gdb/remote-sim.h b/gdb/remote-sim.h new file mode 100644 index 0000000..840457c --- /dev/null +++ b/gdb/remote-sim.h @@ -0,0 +1,87 @@ +/* This file defines the interface between the simulator and gdb. + Copyright (C) 1993 Free Software Foundation, Inc. + +This file is part of GDB. + +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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if !defined (REMOTE_SIM_H) +#define REMOTE_SIM_H 1 + +/* Main simulator globals ... */ + +extern int sim_verbose; + +/* Main simulator entry points ... + + All functions return 0 for success and non-zero for failure. */ + +/* Initialize the simulator. This function is called when the simulator + is selected from the command line. ARGS is passed from the command line + and can be used to select whatever run time options the simulator provides. + ARGS is the raw character string and must be parsed by the simulator. */ + +int sim_open PARAMS ((char *name)); + +/* Load program PROG into the simulator. + We use "void *" instead of "bfd *" to isolate this file from BFD. */ + +int sim_load PARAMS ((void *bfd_handle, char *args)); + +/* Set the arguments and environment for the program loaded into the + simulator. ARGV and ENV are NULL terminated lists of pointers. + If the simulator doesn't support setting arguments, print an error message + and return non-zero. */ + +int sim_set_args PARAMS ((char **argv, char **env)); + +/* Fetch register REGNO and store the raw value in BUF. */ + +int sim_fetch_register PARAMS ((int regno, char *buf)); + +/* Store register REGNO from BUF (in raw format). */ + +int sim_store_register PARAMS ((int regno, char *buf)); + +/* Kill the running program. + This may involve closing any open files and deleting any mmap'd areas. */ + +int sim_kill PARAMS ((void)); + +/* Read LENGTH bytes of the simulated program's memory and store in BUF. */ + +int sim_read PARAMS ((CORE_ADDR mem, char *buf, int length)); + +/* Store LENGTH bytes from BUF in the simulated program's memory. */ + +int sim_write PARAMS ((CORE_ADDR mem, char *buf, int length)); + +/* Print some interesting information about the simulator. */ + +int sim_info PARAMS ((void)); + +/* Set the simulated cpu's program counter to PC. */ + +int sim_set_pc PARAMS ((CORE_ADDR pc)); + +/* Fetch why the program stopped. */ + +int sim_stop_signal PARAMS ((void)); + +/* Run (or resume) the program. */ + +int sim_resume PARAMS ((int step, int siggnal)); + +#endif /* !defined (REMOTE_SIM_H) */ diff --git a/gdb/remote-sp64sim.c b/gdb/remote-sp64sim.c index 7c222d7..e975c74 100644 --- a/gdb/remote-sp64sim.c +++ b/gdb/remote-sp64sim.c @@ -1,7 +1,7 @@ /* Generic remote debugging interface for simulators. Copyright 1993 Free Software Foundation, Inc. - Contributed by Cygnus Support. Hacked from Steve Chamberlain's Z8000 work - by Doug Evans. (dje@cygnus.com). + Contributed by Cygnus Support. + Steve Chamberlain (sac@cygnus.com) and Doug Evans (dje@cygnus.com). This file is part of GDB. @@ -32,70 +32,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "terminal.h" #include "target.h" #include "gdbcore.h" -#include "simif.h" +#include "remote-sim.h" /* Naming conventions: - sim_xxx are internal objects that describe top level interfaces to the - simulator. + simif_xxx are internal objects that describe top level interfaces to the + simulator (simif for SIMulator InterFace, duh...). - simif_xxx are external counterparts to the sim_xxx objects that must be - provided by the simulator (simif for SIMulator InterFace, duh...). + sim_xxx are external counterparts to the simif_xxx objects that must be + provided by the simulator. - A complete list of them is: - - --- Fetch one register and store the raw value in BUF. - -int simif_fetch_register (int regno, char *buf); - - --- Store VAL in one register. - -int simif_store_register (int regno, char *val); - - --- Complete terminate the simulator. This includes freeing all memory, - closing all open files, and releasing all mmap'd memory. - -int simif_kill (void); - - --- Load program PROG into the simulator. - -int simif_load (bfd *abfd, char *prog); - - --- Set the arguments and environment for the program loaded into the - simulator. ARGV and ENV are NULL terminated lists of pointers. - -int simif_set_args (char **argv, char **env); - - --- Initialize the simulator. This function is called when the simulator - is selected from the command line. ARGS is passed from the command line - and can be used to select whatever run time options the simulator provides. - ARGS is the raw character string and must be parsed by the simulator. - -int simif_open (char *args); - - --- Start running the program, or resume it after a breakpoint. - FIXME: What are A and B? - -int simif_resume (int a, int b); - - --- Fetch the reason why the program stopped running (breakpoint, signal, - etc.) - -WAITTYPE simif_stop_signal (void); - - --- Write some data into the program's memory. - Result is 0 for success, nonzero for failure. - -int simif_write (CORE_ADDR memaddr, char *myaddr, int len); - - --- Read some data from the program's memory. - Result is 0 for success, nonzero for failure. - -int simif_read (CORE_ADDR memaddr, char *myaddr, int len); -*/ + See simif.h for a description. */ /* Forward data declarations */ -extern struct target_ops sim_ops; +extern struct target_ops simif_ops; int sim_verbose = 0; /* available to the simulator to use */ @@ -104,81 +54,78 @@ static int program_loaded = 0; static void dump_mem (); static void -sim_fetch_register (regno) +simif_fetch_register (regno) int regno; { if (regno == -1) { - if (sim_verbose) - printf_filtered ("sim_fetch_register: %d\n", regno); - /* FIXME: Where did the 16 come from and what does it need to be? */ - for (regno = 0; regno < 16; regno++) - sim_fetch_register (regno); + for (regno = 0; regno < NUM_REGS; regno++) + simif_fetch_register (regno); } else { char buf[MAX_REGISTER_RAW_SIZE]; - simif_fetch_register (regno, buf); + sim_fetch_register (regno, buf); supply_register (regno, buf); if (sim_verbose) { - printf_filtered ("sim_fetch_register: %d", regno); - dump_mem (buf, sizeof (REGISTER_TYPE)); + printf_filtered ("simif_fetch_register: %d", regno); + /* FIXME: We could print something more intelligible. */ + dump_mem (buf, REGISTER_RAW_SIZE (regno)); } } } static void -sim_store_register (regno) +simif_store_register (regno) int regno; { if (regno == -1) { - if (sim_verbose) - printf_filtered ("sim_store_register: %d\n", regno); - /* FIXME: 16? */ - for (regno = 0; regno < 16; regno++) - sim_store_register (regno); + for (regno = 0; regno < NUM_REGS; regno++) + simif_store_register (regno); } else { - char value[sizeof (REGISTER_TYPE)]; + /* FIXME: Until read_register() returns LONGEST, we have this. */ + char value[MAX_REGISTER_RAW_SIZE]; read_register_gen (regno, value); - SWAP_TARGET_AND_HOST (value, sizeof (REGISTER_TYPE)); - simif_store_register (regno, value); + SWAP_TARGET_AND_HOST (value, REGISTER_RAW_SIZE (regno)); + sim_store_register (regno, value); if (sim_verbose) { - printf_filtered ("sim_store_register: %d", regno); - dump_mem (value, sizeof (REGISTER_TYPE)); + printf_filtered ("simif_store_register: %d", regno); + /* FIXME: We could print something more intelligible. */ + dump_mem (value, REGISTER_RAW_SIZE (regno)); } } } static void -sim_kill (arg,from_tty) -char *arg; -int from_tty; +simif_kill () { if (sim_verbose) - printf_filtered ("sim_kill: arg \"%s\"\n", arg); + printf_filtered ("simif_kill\n"); - simif_kill (); /* close fd's, remove mappings */ + sim_kill (); /* close fd's, remove mappings */ inferior_pid = 0; } -/* Load program PROG into the sim. */ +/* Load an executable file into the target process. This is expected to + not only bring new code into the target process, but also to update + GDB's symbol tables to match. */ static void -sim_load (prog, fromtty) +simif_load (prog, fromtty) char *prog; int fromtty; { bfd *abfd; if (sim_verbose) - printf_filtered ("sim_load: prog \"%s\"\n", prog); + printf_filtered ("simif_load: prog \"%s\"\n", prog); inferior_pid = 0; program_loaded = 0; @@ -187,22 +134,69 @@ sim_load (prog, fromtty) if (!abfd) error ("Unable to open file %s.", prog); - if (bfd_check_format (abfd, bfd_object) ==0) + if (bfd_check_format (abfd, bfd_object) == 0) error ("File is not an object file."); - if (simif_load (abfd, prog) != 0) + if (sim_load (abfd, prog) != 0) return; program_loaded = 1; - simif_set_pc (abfd->start_address); + sim_set_pc (abfd->start_address); +} + +/* + * This is a utility routine that sim_load() can call to do the work. + * The result is 0 for success, non-zero for failure. + * + * Eg: int sim_load (bfd *bfd, char *prog) { return sim_load_standard (bfd); } + */ + +sim_load_standard (abfd) + bfd *abfd; +{ + asection *s; + + s = abfd->sections; + while (s != (asection *)NULL) + { + if (s->flags & SEC_LOAD) + { + int i; + int delta = 4096; + char *buffer = xmalloc (delta); + printf_filtered ("%s\t: 0x%4x .. 0x%4x ", + s->name, s->vma, s->vma + s->_raw_size); + for (i = 0; i < s->_raw_size; i+= delta) + { + int sub_delta = delta; + if (sub_delta > s->_raw_size - i) + sub_delta = s->_raw_size - i ; + + bfd_get_section_contents (abfd, s, buffer, i, sub_delta); + sim_write (s->vma + i, buffer, sub_delta); + printf_filtered ("*"); + fflush (stdout); + } + printf_filtered ("\n"); + free (buffer); + } + s = s->next; + } + + return 0; } +/* Start an inferior process and set inferior_pid to its pid. + EXEC_FILE is the file to run. + ALLARGS is a string containing the arguments to the program. + ENV is the environment vector to pass. Errors reported with error(). + On VxWorks and various standalone systems, we ignore exec_file. */ /* This is called not only when we first attach, but also when the user types "run" after having attached. */ static void -sim_create_inferior (exec_file, args, env) +simif_create_inferior (exec_file, args, env) char *exec_file; char *args; char **env; @@ -214,7 +208,7 @@ sim_create_inferior (exec_file, args, env) error ("No program loaded."); if (sim_verbose) - printf_filtered ("sim_create_inferior: exec_file \"%s\", args \"%s\"\n", + printf_filtered ("simif_create_inferior: exec_file \"%s\", args \"%s\"\n", exec_file, args); if (exec_file == 0 || exec_bfd == 0) @@ -222,7 +216,7 @@ sim_create_inferior (exec_file, args, env) entry_pt = (int) bfd_get_start_address (exec_bfd); - sim_kill (NULL, NULL); + simif_kill (NULL, NULL); remove_breakpoints (); init_wait_for_inferior (); @@ -234,92 +228,112 @@ sim_create_inferior (exec_file, args, env) strcat (arg_buf, args); argv = buildargv (arg_buf); make_cleanup (freeargv, (char *) argv); - simif_set_args (argv, env); + if (sim_set_args (argv, env) != 0) + return; inferior_pid = 42; insert_breakpoints (); /* Needed to get correct instruction in cache */ proceed (entry_pt, -1, 0); } +/* The open routine takes the rest of the parameters from the command, + and (if successful) pushes a new target onto the stack. + Targets should supply this routine, if only to provide an error message. */ /* Called when selecting the simulator. EG: (gdb) target sim name. */ static void -sim_open (args, from_tty) +simif_open (args, from_tty) char *args; int from_tty; { if (sim_verbose) - printf_filtered ("sim_open: args \"%s\"\n", args); + printf_filtered ("simif_open: args \"%s\"\n", args); - if (simif_open (args) != 0) + if (sim_open (args) != 0) { error ("Unable to initialize simulator (insufficient memory?)."); return; } - push_target (&sim_ops); + push_target (&simif_ops); target_fetch_registers (-1); + /* FIXME: check from_tty here? */ printf_filtered ("Connected to the simulator.\n"); } +/* Does whatever cleanup is required for a target that we are no longer + going to be calling. Argument says whether we are quitting gdb and + should not get hung in case of errors, or whether we want a clean + termination even if it takes a while. This routine is automatically + always called just before a routine is popped off the target stack. + Closing file descriptors and freeing memory are typical things it should + do. */ /* Close out all files and local state before this target loses control. */ static void -sim_close (quitting) +simif_close (quitting) int quitting; { if (sim_verbose) - printf_filtered ("sim_close: quitting %d\n", quitting); + printf_filtered ("simif_close: quitting %d\n", quitting); program_loaded = 0; - /* FIXME: Need to call simif_close() to close all files and + /* FIXME: Need to call sim_close() to close all files and delete all mappings. */ } +/* Takes a program previously attached to and detaches it. + The program may resume execution (some targets do, some don't) and will + no longer stop on signals, etc. We better not have left any breakpoints + in the program or it'll die when it hits one. ARGS is arguments + typed by the user (e.g. a signal to send the process). FROM_TTY + says whether to be verbose or not. */ /* Terminate the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ + Use this when you want to detach and do something else with your gdb. */ static void -sim_detach (args,from_tty) +simif_detach (args,from_tty) char *args; int from_tty; { if (sim_verbose) - printf_filtered ("sim_detach: args \"%s\"\n", args); + printf_filtered ("simif_detach: args \"%s\"\n", args); - pop_target (); /* calls sim_close to do the real work */ + pop_target (); /* calls simif_close to do the real work */ if (from_tty) printf_filtered ("Ending simulator %s debugging\n", target_shortname); } -/* Tell the remote machine to resume. */ -/* FIXME: What are A and B? */ +/* Resume execution of the target process. STEP says whether to single-step + or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given + to the target, or zero for no signal. */ static void -sim_resume (a,b) +simif_resume (step, siggnal) + int step, siggnal; { if (sim_verbose) - printf_filtered ("sim_resume: %d/%d\n", a, b); + printf_filtered ("simif_resume: step %d, signal %d\n", step, siggnal); - simif_resume (a, b); + sim_resume (step, siggnal); } -/* Wait until the remote machine stops, then return, - storing status in STATUS just as `wait' would. */ +/* Wait for inferior process to do something. Return pid of child, + or -1 in case of error; store status through argument pointer STATUS, + just as `wait' would. */ static int -sim_wait (status) +simif_wait (status) WAITTYPE *status; { if (sim_verbose) - printf_filtered ("sim_wait: "); + printf_filtered ("simif_wait: "); #if 1 - *status = simif_stop_signal (); + *status = sim_stop_signal (); #else - WSETSTOP (*status, simif_stop_signal ()); + WSETSTOP (*status, sim_stop_signal ()); #endif if (sim_verbose) printf_filtered ("status %d\n", *status); @@ -333,45 +347,46 @@ sim_wait (status) debugged. */ static void -sim_prepare_to_store () +simif_prepare_to_store () { /* Do nothing, since we can store individual regs */ } static int -sim_xfer_inferior_memory (memaddr, myaddr, len, write, target) +simif_xfer_inferior_memory (memaddr, myaddr, len, write, target) CORE_ADDR memaddr; char *myaddr; int len; int write; struct target_ops *target; /* ignored */ { + if (! program_loaded) + error ("No program loaded."); + if (sim_verbose) { - printf_filtered ("sim_xfer_inferior_memory: myaddr 0x%x, memaddr 0x%x, len %d, write %d\n", + printf_filtered ("simif_xfer_inferior_memory: myaddr 0x%x, memaddr 0x%x, len %d, write %d\n", myaddr, memaddr, len, write); if (sim_verbose && write) dump_mem(myaddr, len); } - if (! program_loaded) - error ("No program loaded."); - if (write) { - len = simif_write (memaddr, myaddr, len); + len = sim_write (memaddr, myaddr, len); } else { - len = simif_read (memaddr, myaddr, len); - if (sim_verbose && len > 0) + len = sim_read (memaddr, myaddr, len); + if (sim_verbose && len > 0) dump_mem(myaddr, len); } return len; } static void -sim_files_info () +simif_files_info (target) + struct target_ops *target; { char *file = "nothing"; @@ -379,19 +394,23 @@ sim_files_info () file = bfd_get_filename (exec_bfd); if (sim_verbose) - printf_filtered ("sim_files_info: file \"%s\"\n", file); + printf_filtered ("simif_files_info: file \"%s\"\n", file); if (exec_bfd) - printf_filtered ("\tAttached to %s running program %s\n", - target_shortname, file); + { + printf_filtered ("\tAttached to %s running program %s\n", + target_shortname, file); + sim_info (); + } } -/* Clear the sims notion of what the break points are */ +/* Clear the sims notion of what the break points are. */ + static void -sim_mourn () +simif_mourn_inferior () { if (sim_verbose) - printf_filtered ("sim_mourn:\n"); + printf_filtered ("simif_mourn_inferior:\n"); remove_breakpoints (); generic_mourn_inferior (); @@ -399,23 +418,23 @@ sim_mourn () /* Define the target subroutine names */ -struct target_ops sim_ops = +struct target_ops simif_ops = { - "sim", "Simulator", - "Use the Simulator", - sim_open, sim_close, - 0, sim_detach, sim_resume, sim_wait, /* attach */ - sim_fetch_register, sim_store_register, - sim_prepare_to_store, - sim_xfer_inferior_memory, - sim_files_info, + "sim", "simulator", + "Use the simulator", + simif_open, simif_close, + 0, simif_detach, simif_resume, simif_wait, /* attach */ + simif_fetch_register, simif_store_register, + simif_prepare_to_store, + simif_xfer_inferior_memory, + simif_files_info, 0, 0, /* Breakpoints */ 0, 0, 0, 0, 0, /* Terminal handling */ - sim_kill, /* FIXME, kill */ - sim_load, + simif_kill, /* FIXME, kill */ + simif_load, 0, /* lookup_symbol */ - sim_create_inferior, /* create_inferior */ - sim_mourn, /* mourn_inferior FIXME */ + simif_create_inferior, /* create_inferior */ + simif_mourn_inferior, /* mourn_inferior FIXME */ 0, /* can_run */ 0, /* notice_signals */ process_stratum, 0, /* next */ @@ -425,7 +444,7 @@ struct target_ops sim_ops = }; static void -sim_snoop () +simif_snoop () { sim_verbose = ! sim_verbose; if (sim_verbose) @@ -440,8 +459,8 @@ sim_snoop () void _initialize_remote_sim () { - add_target (&sim_ops); - add_com ("snoop", class_obscure, sim_snoop, + add_target (&simif_ops); + add_com ("snoop", class_obscure, simif_snoop, "Show what commands are going to the simulator"); } diff --git a/gdb/sp64-tdep.c b/gdb/sp64-tdep.c index d202e25..c6c4a8e 100644 --- a/gdb/sp64-tdep.c +++ b/gdb/sp64-tdep.c @@ -132,29 +132,6 @@ sparc64_single_step (ignore) } } -/* FIXME: sparc64_frame_chain() is temporary. sparc_frame_chain() can - be fixed to support both of us. */ - -#define FRAME_SAVED_L0 0 /* Byte offset from SP */ -#define FRAME_SAVED_I0 (8*REGISTER_RAW_SIZE (0)) /* Byte offset from SP */ - -CORE_ADDR -sparc64_frame_chain (thisframe) - FRAME thisframe; -{ - REGISTER_TYPE retval; - int err; - CORE_ADDR addr; - - addr = thisframe->frame + FRAME_SAVED_I0 + - REGISTER_RAW_SIZE (0) * (FP_REGNUM - I0_REGNUM); - err = target_read_memory (addr, (char *) &retval, sizeof (REGISTER_TYPE)); - if (err) - return 0; - SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); - return retval; -} - CORE_ADDR sparc64_extract_struct_value_address (regbuf) char regbuf[REGISTER_BYTES]; @@ -166,36 +143,6 @@ sparc64_extract_struct_value_address (regbuf) return addr; } -/* Find the pc saved in frame FRAME. */ -/* FIXME: This function can be removed when sparc_frame_saved_pc - handles us too. */ - -CORE_ADDR -sparc64_frame_saved_pc (frame) - FRAME frame; -{ - int err; - REGISTER_TYPE retval; - CORE_ADDR addr,prev_pc; - - if (get_current_frame () == frame) /* FIXME, debug check. Remove >=gdb-4.6 */ - { - if (read_register (SP_REGNUM) != frame->bottom) abort(); - } - - addr = frame->bottom + FRAME_SAVED_I0 + - REGISTER_RAW_SIZE (0) * (I7_REGNUM - I0_REGNUM); - err = target_read_memory (addr, (char *) &retval, sizeof (REGISTER_TYPE)); - if (err) - return 0; - SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); - - /* CORE_ADDR isn't always the same size as REGISTER_TYPE, so convert. */ - - prev_pc = (CORE_ADDR) retval; - return PC_ADJUST (prev_pc); -} - /* Check instruction at ADDR to see if it is an annulled branch or other instruction whose npc isn't pc+4 (eg: trap, done, retry). All other instructions will go to NPC or will trap. @@ -301,6 +248,46 @@ isbranch (instruction, addr, target) return val; } +/* PRINT_REGISTER_HOOK routine. + Pretty print various registers. */ + +static void +dump_ccreg (reg, val) + char *reg; + int val; +{ + printf ("%s:%s,%s,%s,%s", reg, + val & 8 ? "N" : "NN", + val & 4 ? "Z" : "NZ", + val & 2 ? "O" : "NO", + val & 1 ? "C" : "NC" + ); +} + +void +sparc_print_register_hook (regno) + int regno; +{ + if (((unsigned) (regno) - FP0_REGNUM < FP_MAX_REGNUM - FP0_REGNUM) + && ((regno) & 1) == 0) + { + char doublereg[8]; /* two float regs */ + if (!read_relative_register_raw_bytes ((regno), doublereg)) + { + printf("\t"); + print_floating (doublereg, builtin_type_double, stdout); + } + } + else if ((regno) == CCR_REGNUM) + { + int ccr = read_register (CCR_REGNUM); + printf("\t"); + dump_ccreg ("xcc", ccr >> 4); + printf(", "); + dump_ccreg ("icc", ccr & 15); + } +} + /* We try to support 32 bit and 64 bit pointers. We are called when the Shade target is selected by shadeif.c. */ |