]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/gdb/gdb/remote-sim.c
Import GDB in its full glory (all 25mb). We'll put it on a diet once it's
[FreeBSD/FreeBSD.git] / contrib / gdb / gdb / remote-sim.c
1 /* Generic remote debugging interface for simulators.
2    Copyright 1993, 1994 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4    Steve Chamberlain (sac@cygnus.com).
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "wait.h"
25 #include "value.h"
26 #include "gdb_string.h"
27 #include <ctype.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <setjmp.h>
31 #include <errno.h>
32 #include "terminal.h"
33 #include "target.h"
34 #include "gdbcore.h"
35 #include "remote-sim.h"
36 #include "remote-utils.h"
37 #include "callback.h"
38
39 /* Naming convention:
40
41    sim_* are the interface to the simulator (see remote-sim.h).
42    sim_callback_* are the stuff which the simulator can see inside GDB.
43    gdbsim_* are stuff which is internal to gdb.  */
44
45 /* Forward data declarations */
46 extern struct target_ops gdbsim_ops;
47
48 static int program_loaded = 0;
49
50 static void
51 dump_mem (buf, len)
52      char *buf;
53      int len;
54 {
55   if (len <= 8)
56     {
57       if (len == 8 || len == 4)
58         {
59           long l[2];
60           memcpy (l, buf, len);
61           printf_filtered ("\t0x%x", l[0]);
62           printf_filtered (len == 8 ? " 0x%x\n" : "\n", l[1]);
63         }
64       else
65         {
66           int i;
67           printf_filtered ("\t");
68           for (i = 0; i < len; i++)
69             printf_filtered ("0x%x ", buf[i]);
70           printf_filtered ("\n");
71         }
72     }
73 }
74
75 static void
76 gdbsim_fetch_register (regno)
77 int regno;
78 {
79   if (regno == -1) 
80     {
81       for (regno = 0; regno < NUM_REGS; regno++)
82         gdbsim_fetch_register (regno);
83     }
84   else
85     {
86       char buf[MAX_REGISTER_RAW_SIZE];
87
88       sim_fetch_register (regno, buf);
89       supply_register (regno, buf);
90       if (sr_get_debug ())
91         {
92           printf_filtered ("gdbsim_fetch_register: %d", regno);
93           /* FIXME: We could print something more intelligible.  */
94           dump_mem (buf, REGISTER_RAW_SIZE (regno));
95         }
96     }
97 }
98
99
100 static void
101 gdbsim_store_register (regno)
102 int regno;
103 {
104   if (regno  == -1) 
105     {
106       for (regno = 0; regno < NUM_REGS; regno++)
107         gdbsim_store_register (regno);
108     }
109   else
110     {
111       /* FIXME: Until read_register() returns LONGEST, we have this.  */
112       char tmp[MAX_REGISTER_RAW_SIZE];
113       read_register_gen (regno, tmp);
114       sim_store_register (regno, tmp);
115       if (sr_get_debug ())
116         {
117           printf_filtered ("gdbsim_store_register: %d", regno);
118           /* FIXME: We could print something more intelligible.  */
119           dump_mem (tmp, REGISTER_RAW_SIZE (regno));
120         }
121     }
122 }
123
124 /* Kill the running program.  This may involve closing any open files
125    and releasing other resources acquired by the simulated program.  */
126
127 static void
128 gdbsim_kill ()
129 {
130   if (sr_get_debug ())
131     printf_filtered ("gdbsim_kill\n");
132
133   sim_kill ();  /* close fd's, remove mappings */
134   inferior_pid = 0;
135 }
136
137 /* Load an executable file into the target process.  This is expected to
138    not only bring new code into the target process, but also to update
139    GDB's symbol tables to match.  */
140
141 static void
142 gdbsim_load (prog, fromtty)
143      char *prog;
144      int fromtty;
145 {
146   if (sr_get_debug ())
147     printf_filtered ("gdbsim_load: prog \"%s\"\n", prog);
148
149   inferior_pid = 0;
150
151   /* This must be done before calling gr_load_image.  */
152   program_loaded = 1;
153
154   if (sim_load (prog, fromtty) != 0)
155     generic_load (prog, fromtty);
156 }
157
158
159 /* Start an inferior process and set inferior_pid to its pid.
160    EXEC_FILE is the file to run.
161    ALLARGS is a string containing the arguments to the program.
162    ENV is the environment vector to pass.  Errors reported with error().
163    On VxWorks and various standalone systems, we ignore exec_file.  */
164 /* This is called not only when we first attach, but also when the
165    user types "run" after having attached.  */
166
167 static void
168 gdbsim_create_inferior (exec_file, args, env)
169      char *exec_file;
170      char *args;
171      char **env;
172 {
173   int len;
174   char *arg_buf,**argv;
175   CORE_ADDR entry_pt;
176
177   if (! program_loaded)
178     error ("No program loaded.");
179
180   if (sr_get_debug ())
181     printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n",
182       exec_file, args);
183
184   if (exec_file == 0 || exec_bfd == 0)
185    error ("No exec file specified.");
186
187   entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd);
188
189   gdbsim_kill (NULL, NULL);      
190   remove_breakpoints ();
191   init_wait_for_inferior ();
192
193   len = 5 + strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
194   arg_buf = (char *) alloca (len);
195   arg_buf[0] = '\0';
196   strcat (arg_buf, exec_file);
197   strcat (arg_buf, " ");
198   strcat (arg_buf, args);
199   argv = buildargv (arg_buf);
200   make_cleanup (freeargv, (char *) argv);
201   sim_create_inferior (entry_pt, argv, env);
202
203   inferior_pid = 42;
204   insert_breakpoints ();        /* Needed to get correct instruction in cache */
205   proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
206 }
207
208 /* The open routine takes the rest of the parameters from the command,
209    and (if successful) pushes a new target onto the stack.
210    Targets should supply this routine, if only to provide an error message.  */
211 /* Called when selecting the simulator. EG: (gdb) target sim name.  */
212
213 static void
214 gdbsim_open (args, from_tty)
215      char *args;
216      int from_tty;
217 {
218   if (sr_get_debug ())
219     printf_filtered ("gdbsim_open: args \"%s\"\n", args ? args : "(null)");
220
221   sim_set_callbacks (&default_callback);
222   default_callback.init (&default_callback);
223
224   sim_open (args);
225
226   push_target (&gdbsim_ops);
227   target_fetch_registers (-1);
228   printf_filtered ("Connected to the simulator.\n");
229 }
230
231 /* Does whatever cleanup is required for a target that we are no longer
232    going to be calling.  Argument says whether we are quitting gdb and
233    should not get hung in case of errors, or whether we want a clean
234    termination even if it takes a while.  This routine is automatically
235    always called just before a routine is popped off the target stack.
236    Closing file descriptors and freeing memory are typical things it should
237    do.  */
238 /* Close out all files and local state before this target loses control. */
239
240 static void
241 gdbsim_close (quitting)
242      int quitting;
243 {
244   if (sr_get_debug ())
245     printf_filtered ("gdbsim_close: quitting %d\n", quitting);
246
247   program_loaded = 0;
248
249   sim_close (quitting);
250 }
251
252 /* Takes a program previously attached to and detaches it.
253    The program may resume execution (some targets do, some don't) and will
254    no longer stop on signals, etc.  We better not have left any breakpoints
255    in the program or it'll die when it hits one.  ARGS is arguments
256    typed by the user (e.g. a signal to send the process).  FROM_TTY
257    says whether to be verbose or not.  */
258 /* Terminate the open connection to the remote debugger.
259    Use this when you want to detach and do something else with your gdb.  */
260
261 static void
262 gdbsim_detach (args,from_tty)
263      char *args;
264      int from_tty;
265 {
266   if (sr_get_debug ())
267     printf_filtered ("gdbsim_detach: args \"%s\"\n", args);
268
269   pop_target ();                /* calls gdbsim_close to do the real work */
270   if (from_tty)
271     printf_filtered ("Ending simulator %s debugging\n", target_shortname);
272 }
273  
274 /* Resume execution of the target process.  STEP says whether to single-step
275    or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
276    to the target, or zero for no signal.  */
277
278 static void
279 gdbsim_resume (pid, step, siggnal)
280      int pid, step;
281      enum target_signal siggnal;
282 {
283   if (sr_get_debug ())
284     printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal);
285
286   sim_resume (step, target_signal_to_host (siggnal));
287 }
288
289 /* Wait for inferior process to do something.  Return pid of child,
290    or -1 in case of error; store status through argument pointer STATUS,
291    just as `wait' would.  */
292
293 static int
294 gdbsim_wait (pid, status)
295      int pid;
296      struct target_waitstatus *status;
297 {
298   int sigrc;
299   enum sim_stop reason;
300
301   if (sr_get_debug ())
302     printf_filtered ("gdbsim_wait\n");
303
304   sim_stop_reason (&reason, &sigrc);
305   switch (reason)
306     {
307     case sim_exited:
308       status->kind = TARGET_WAITKIND_EXITED;
309       status->value.integer = sigrc;
310       break;
311     case sim_stopped:
312       status->kind = TARGET_WAITKIND_STOPPED;
313       /* The signal in sigrc is a host signal.  That probably
314          should be fixed.  */
315       status->value.sig = target_signal_from_host (sigrc);
316       break;
317     case sim_signalled:
318       status->kind = TARGET_WAITKIND_SIGNALLED;
319       /* The signal in sigrc is a host signal.  That probably
320          should be fixed.  */
321       status->value.sig = target_signal_from_host (sigrc);
322       break;
323     }
324
325   return inferior_pid;
326 }
327
328 /* Get ready to modify the registers array.  On machines which store
329    individual registers, this doesn't need to do anything.  On machines
330    which store all the registers in one fell swoop, this makes sure
331    that registers contains all the registers from the program being
332    debugged.  */
333
334 static void
335 gdbsim_prepare_to_store ()
336 {
337   /* Do nothing, since we can store individual regs */
338 }
339
340 static int
341 gdbsim_xfer_inferior_memory (memaddr, myaddr, len, write, target)
342      CORE_ADDR memaddr;
343      char *myaddr;
344      int len;
345      int write;
346      struct target_ops *target;                 /* ignored */
347 {
348   if (! program_loaded)
349     error ("No program loaded.");
350
351   if (sr_get_debug ())
352     {
353       printf_filtered ("gdbsim_xfer_inferior_memory: myaddr 0x%x, memaddr 0x%x, len %d, write %d\n",
354                        myaddr, memaddr, len, write);
355       if (sr_get_debug () && write)
356         dump_mem(myaddr, len);
357     }
358
359   if (write)
360     {
361       len = sim_write (memaddr, myaddr, len);
362     }
363   else 
364     {
365       len = sim_read (memaddr, myaddr, len);
366       if (sr_get_debug () && len > 0)
367         dump_mem(myaddr, len);
368     } 
369   return len;
370 }
371
372 static void
373 gdbsim_files_info (target)
374      struct target_ops *target;
375 {
376   char *file = "nothing";
377
378   if (exec_bfd)
379     file = bfd_get_filename (exec_bfd);
380
381   if (sr_get_debug ())
382     printf_filtered ("gdbsim_files_info: file \"%s\"\n", file);
383
384   if (exec_bfd)
385     {
386       printf_filtered ("\tAttached to %s running program %s\n",
387                        target_shortname, file);
388       sim_info (0);
389     }
390 }
391
392 /* Clear the simulator's notion of what the break points are.  */
393
394 static void
395 gdbsim_mourn_inferior () 
396
397   if (sr_get_debug ())
398     printf_filtered ("gdbsim_mourn_inferior:\n");
399
400   remove_breakpoints ();
401   generic_mourn_inferior ();
402 }
403
404 /* Put a command string, in args, out to MONITOR.  Output from MONITOR
405    is placed on the users terminal until the prompt is seen. FIXME: We
406    read the characters ourseleves here cause of a nasty echo.  */
407
408 static void
409 simulator_command (args, from_tty)
410      char *args;
411      int from_tty;
412 {
413   sim_do_command (args);
414 }
415
416 /* Define the target subroutine names */
417
418 struct target_ops gdbsim_ops = {
419   "sim",                        /* to_shortname */
420   "simulator",                  /* to_longname */
421   "Use the compiled-in simulator.",  /* to_doc */
422   gdbsim_open,                  /* to_open */
423   gdbsim_close,                 /* to_close */
424   NULL,                         /* to_attach */
425   gdbsim_detach,                /* to_detach */
426   gdbsim_resume,                /* to_resume */
427   gdbsim_wait,                  /* to_wait */
428   gdbsim_fetch_register,        /* to_fetch_registers */
429   gdbsim_store_register,        /* to_store_registers */
430   gdbsim_prepare_to_store,      /* to_prepare_to_store */
431   gdbsim_xfer_inferior_memory,  /* to_xfer_memory */
432   gdbsim_files_info,            /* to_files_info */
433   memory_insert_breakpoint,     /* to_insert_breakpoint */
434   memory_remove_breakpoint,     /* to_remove_breakpoint */
435   NULL,                         /* to_terminal_init */
436   NULL,                         /* to_terminal_inferior */
437   NULL,                         /* to_terminal_ours_for_output */
438   NULL,                         /* to_terminal_ours */
439   NULL,                         /* to_terminal_info */
440   gdbsim_kill,                  /* to_kill */
441   gdbsim_load,                  /* to_load */
442   NULL,                         /* to_lookup_symbol */
443   gdbsim_create_inferior,       /* to_create_inferior */ 
444   gdbsim_mourn_inferior,        /* to_mourn_inferior */
445   0,                            /* to_can_run */
446   0,                            /* to_notice_signals */
447   0,                            /* to_thread_alive */
448   0,                            /* to_stop */
449   process_stratum,              /* to_stratum */
450   NULL,                         /* to_next */
451   1,                            /* to_has_all_memory */
452   1,                            /* to_has_memory */
453   1,                            /* to_has_stack */
454   1,                            /* to_has_registers */
455   1,                            /* to_has_execution */
456   NULL,                         /* sections */
457   NULL,                         /* sections_end */
458   OPS_MAGIC,                    /* to_magic */
459 };
460
461 void
462 _initialize_remote_sim ()
463 {
464   add_target (&gdbsim_ops);
465
466   add_com ("sim <command>", class_obscure, simulator_command,
467            "Send a command to the simulator."); 
468 }