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