e975c745a8cfac06dce3d850b9fc7ba24afbd5c8
[deliverable/binutils-gdb.git] / gdb / remote-sp64sim.c
1 /* Generic remote debugging interface for simulators.
2 Copyright 1993 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4 Steve Chamberlain (sac@cygnus.com) and Doug Evans (dje@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., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "wait.h"
25 #include "value.h"
26 #include <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
37 /* Naming conventions:
38
39 simif_xxx are internal objects that describe top level interfaces to the
40 simulator (simif for SIMulator InterFace, duh...).
41
42 sim_xxx are external counterparts to the simif_xxx objects that must be
43 provided by the simulator.
44
45 See simif.h for a description. */
46
47 /* Forward data declarations */
48 extern struct target_ops simif_ops;
49
50 int sim_verbose = 0; /* available to the simulator to use */
51
52 static int program_loaded = 0;
53
54 static void dump_mem ();
55
56 static void
57 simif_fetch_register (regno)
58 int regno;
59 {
60 if (regno == -1)
61 {
62 for (regno = 0; regno < NUM_REGS; regno++)
63 simif_fetch_register (regno);
64 }
65 else
66 {
67 char buf[MAX_REGISTER_RAW_SIZE];
68
69 sim_fetch_register (regno, buf);
70 supply_register (regno, buf);
71 if (sim_verbose)
72 {
73 printf_filtered ("simif_fetch_register: %d", regno);
74 /* FIXME: We could print something more intelligible. */
75 dump_mem (buf, REGISTER_RAW_SIZE (regno));
76 }
77 }
78 }
79
80 static void
81 simif_store_register (regno)
82 int regno;
83 {
84 if (regno == -1)
85 {
86 for (regno = 0; regno < NUM_REGS; regno++)
87 simif_store_register (regno);
88 }
89 else
90 {
91 /* FIXME: Until read_register() returns LONGEST, we have this. */
92 char value[MAX_REGISTER_RAW_SIZE];
93
94 read_register_gen (regno, value);
95 SWAP_TARGET_AND_HOST (value, REGISTER_RAW_SIZE (regno));
96 sim_store_register (regno, value);
97 if (sim_verbose)
98 {
99 printf_filtered ("simif_store_register: %d", regno);
100 /* FIXME: We could print something more intelligible. */
101 dump_mem (value, REGISTER_RAW_SIZE (regno));
102 }
103 }
104 }
105
106 static void
107 simif_kill ()
108 {
109 if (sim_verbose)
110 printf_filtered ("simif_kill\n");
111
112 sim_kill (); /* close fd's, remove mappings */
113 inferior_pid = 0;
114 }
115
116 /* Load an executable file into the target process. This is expected to
117 not only bring new code into the target process, but also to update
118 GDB's symbol tables to match. */
119
120 static void
121 simif_load (prog, fromtty)
122 char *prog;
123 int fromtty;
124 {
125 bfd *abfd;
126
127 if (sim_verbose)
128 printf_filtered ("simif_load: prog \"%s\"\n", prog);
129
130 inferior_pid = 0;
131 program_loaded = 0;
132 abfd = bfd_openr (prog, (char *) 0);
133
134 if (!abfd)
135 error ("Unable to open file %s.", prog);
136
137 if (bfd_check_format (abfd, bfd_object) == 0)
138 error ("File is not an object file.");
139
140 if (sim_load (abfd, prog) != 0)
141 return;
142
143 program_loaded = 1;
144
145 sim_set_pc (abfd->start_address);
146 }
147
148 /*
149 * This is a utility routine that sim_load() can call to do the work.
150 * The result is 0 for success, non-zero for failure.
151 *
152 * Eg: int sim_load (bfd *bfd, char *prog) { return sim_load_standard (bfd); }
153 */
154
155 sim_load_standard (abfd)
156 bfd *abfd;
157 {
158 asection *s;
159
160 s = abfd->sections;
161 while (s != (asection *)NULL)
162 {
163 if (s->flags & SEC_LOAD)
164 {
165 int i;
166 int delta = 4096;
167 char *buffer = xmalloc (delta);
168 printf_filtered ("%s\t: 0x%4x .. 0x%4x ",
169 s->name, s->vma, s->vma + s->_raw_size);
170 for (i = 0; i < s->_raw_size; i+= delta)
171 {
172 int sub_delta = delta;
173 if (sub_delta > s->_raw_size - i)
174 sub_delta = s->_raw_size - i ;
175
176 bfd_get_section_contents (abfd, s, buffer, i, sub_delta);
177 sim_write (s->vma + i, buffer, sub_delta);
178 printf_filtered ("*");
179 fflush (stdout);
180 }
181 printf_filtered ("\n");
182 free (buffer);
183 }
184 s = s->next;
185 }
186
187 return 0;
188 }
189
190 /* Start an inferior process and set inferior_pid to its pid.
191 EXEC_FILE is the file to run.
192 ALLARGS is a string containing the arguments to the program.
193 ENV is the environment vector to pass. Errors reported with error().
194 On VxWorks and various standalone systems, we ignore exec_file. */
195 /* This is called not only when we first attach, but also when the
196 user types "run" after having attached. */
197
198 static void
199 simif_create_inferior (exec_file, args, env)
200 char *exec_file;
201 char *args;
202 char **env;
203 {
204 int len,entry_pt;
205 char *arg_buf,**argv;
206
207 if (! program_loaded)
208 error ("No program loaded.");
209
210 if (sim_verbose)
211 printf_filtered ("simif_create_inferior: exec_file \"%s\", args \"%s\"\n",
212 exec_file, args);
213
214 if (exec_file == 0 || exec_bfd == 0)
215 error ("No exec file specified.");
216
217 entry_pt = (int) bfd_get_start_address (exec_bfd);
218
219 simif_kill (NULL, NULL);
220 remove_breakpoints ();
221 init_wait_for_inferior ();
222
223 len = 5 + strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
224 arg_buf = (char *) alloca (len);
225 arg_buf[0] = '\0';
226 strcat (arg_buf, exec_file);
227 strcat (arg_buf, " ");
228 strcat (arg_buf, args);
229 argv = buildargv (arg_buf);
230 make_cleanup (freeargv, (char *) argv);
231 if (sim_set_args (argv, env) != 0)
232 return;
233
234 inferior_pid = 42;
235 insert_breakpoints (); /* Needed to get correct instruction in cache */
236 proceed (entry_pt, -1, 0);
237 }
238
239 /* The open routine takes the rest of the parameters from the command,
240 and (if successful) pushes a new target onto the stack.
241 Targets should supply this routine, if only to provide an error message. */
242 /* Called when selecting the simulator. EG: (gdb) target sim name. */
243
244 static void
245 simif_open (args, from_tty)
246 char *args;
247 int from_tty;
248 {
249 if (sim_verbose)
250 printf_filtered ("simif_open: args \"%s\"\n", args);
251
252 if (sim_open (args) != 0)
253 {
254 error ("Unable to initialize simulator (insufficient memory?).");
255 return;
256 }
257
258 push_target (&simif_ops);
259 target_fetch_registers (-1);
260
261 /* FIXME: check from_tty here? */
262 printf_filtered ("Connected to the simulator.\n");
263 }
264
265 /* Does whatever cleanup is required for a target that we are no longer
266 going to be calling. Argument says whether we are quitting gdb and
267 should not get hung in case of errors, or whether we want a clean
268 termination even if it takes a while. This routine is automatically
269 always called just before a routine is popped off the target stack.
270 Closing file descriptors and freeing memory are typical things it should
271 do. */
272 /* Close out all files and local state before this target loses control. */
273
274 static void
275 simif_close (quitting)
276 int quitting;
277 {
278 if (sim_verbose)
279 printf_filtered ("simif_close: quitting %d\n", quitting);
280
281 program_loaded = 0;
282
283 /* FIXME: Need to call sim_close() to close all files and
284 delete all mappings. */
285 }
286
287 /* Takes a program previously attached to and detaches it.
288 The program may resume execution (some targets do, some don't) and will
289 no longer stop on signals, etc. We better not have left any breakpoints
290 in the program or it'll die when it hits one. ARGS is arguments
291 typed by the user (e.g. a signal to send the process). FROM_TTY
292 says whether to be verbose or not. */
293 /* Terminate the open connection to the remote debugger.
294 Use this when you want to detach and do something else with your gdb. */
295
296 static void
297 simif_detach (args,from_tty)
298 char *args;
299 int from_tty;
300 {
301 if (sim_verbose)
302 printf_filtered ("simif_detach: args \"%s\"\n", args);
303
304 pop_target (); /* calls simif_close to do the real work */
305 if (from_tty)
306 printf_filtered ("Ending simulator %s debugging\n", target_shortname);
307 }
308
309 /* Resume execution of the target process. STEP says whether to single-step
310 or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
311 to the target, or zero for no signal. */
312
313 static void
314 simif_resume (step, siggnal)
315 int step, siggnal;
316 {
317 if (sim_verbose)
318 printf_filtered ("simif_resume: step %d, signal %d\n", step, siggnal);
319
320 sim_resume (step, siggnal);
321 }
322
323 /* Wait for inferior process to do something. Return pid of child,
324 or -1 in case of error; store status through argument pointer STATUS,
325 just as `wait' would. */
326
327 static int
328 simif_wait (status)
329 WAITTYPE *status;
330 {
331 if (sim_verbose)
332 printf_filtered ("simif_wait: ");
333 #if 1
334 *status = sim_stop_signal ();
335 #else
336 WSETSTOP (*status, sim_stop_signal ());
337 #endif
338 if (sim_verbose)
339 printf_filtered ("status %d\n", *status);
340 return 0;
341 }
342
343 /* Get ready to modify the registers array. On machines which store
344 individual registers, this doesn't need to do anything. On machines
345 which store all the registers in one fell swoop, this makes sure
346 that registers contains all the registers from the program being
347 debugged. */
348
349 static void
350 simif_prepare_to_store ()
351 {
352 /* Do nothing, since we can store individual regs */
353 }
354
355 static int
356 simif_xfer_inferior_memory (memaddr, myaddr, len, write, target)
357 CORE_ADDR memaddr;
358 char *myaddr;
359 int len;
360 int write;
361 struct target_ops *target; /* ignored */
362 {
363 if (! program_loaded)
364 error ("No program loaded.");
365
366 if (sim_verbose)
367 {
368 printf_filtered ("simif_xfer_inferior_memory: myaddr 0x%x, memaddr 0x%x, len %d, write %d\n",
369 myaddr, memaddr, len, write);
370 if (sim_verbose && write)
371 dump_mem(myaddr, len);
372 }
373
374 if (write)
375 {
376 len = sim_write (memaddr, myaddr, len);
377 }
378 else
379 {
380 len = sim_read (memaddr, myaddr, len);
381 if (sim_verbose && len > 0)
382 dump_mem(myaddr, len);
383 }
384 return len;
385 }
386
387 static void
388 simif_files_info (target)
389 struct target_ops *target;
390 {
391 char *file = "nothing";
392
393 if (exec_bfd)
394 file = bfd_get_filename (exec_bfd);
395
396 if (sim_verbose)
397 printf_filtered ("simif_files_info: file \"%s\"\n", file);
398
399 if (exec_bfd)
400 {
401 printf_filtered ("\tAttached to %s running program %s\n",
402 target_shortname, file);
403 sim_info ();
404 }
405 }
406
407 /* Clear the sims notion of what the break points are. */
408
409 static void
410 simif_mourn_inferior ()
411 {
412 if (sim_verbose)
413 printf_filtered ("simif_mourn_inferior:\n");
414
415 remove_breakpoints ();
416 generic_mourn_inferior ();
417 }
418
419 /* Define the target subroutine names */
420
421 struct target_ops simif_ops =
422 {
423 "sim", "simulator",
424 "Use the simulator",
425 simif_open, simif_close,
426 0, simif_detach, simif_resume, simif_wait, /* attach */
427 simif_fetch_register, simif_store_register,
428 simif_prepare_to_store,
429 simif_xfer_inferior_memory,
430 simif_files_info,
431 0, 0, /* Breakpoints */
432 0, 0, 0, 0, 0, /* Terminal handling */
433 simif_kill, /* FIXME, kill */
434 simif_load,
435 0, /* lookup_symbol */
436 simif_create_inferior, /* create_inferior */
437 simif_mourn_inferior, /* mourn_inferior FIXME */
438 0, /* can_run */
439 0, /* notice_signals */
440 process_stratum, 0, /* next */
441 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
442 0, 0, /* Section pointers */
443 OPS_MAGIC, /* Always the last thing */
444 };
445
446 static void
447 simif_snoop ()
448 {
449 sim_verbose = ! sim_verbose;
450 if (sim_verbose)
451 printf_filtered ("Snoop enabled\n");
452 else
453 printf_filtered ("Snoop disabled\n");
454
455 }
456
457 /***********************************************************************/
458
459 void
460 _initialize_remote_sim ()
461 {
462 add_target (&simif_ops);
463 add_com ("snoop", class_obscure, simif_snoop,
464 "Show what commands are going to the simulator");
465 }
466
467 static void
468 dump_mem (buf, len)
469 char *buf;
470 int len;
471 {
472 if (len <= 8)
473 {
474 if (len == 8 || len == 4)
475 {
476 long l[2];
477 memcpy (l, buf, len);
478 printf_filtered ("\t0x%x", l[0]);
479 printf_filtered (len == 8 ? " 0x%x\n" : "\n", l[1]);
480 }
481 else
482 {
483 int i;
484 printf_filtered ("\t");
485 for (i = 0; i < len; i++)
486 printf_filtered ("0x%x ", buf[i]);
487 printf_filtered ("\n");
488 }
489 }
490 }
This page took 0.039145 seconds and 3 git commands to generate.