Use host_makefile_frag.
[deliverable/binutils-gdb.git] / gdb / remote-sp64sim.c
CommitLineData
cb747ec5
DE
1/* Remote debugging interface for SPARC64 Simulator.
2 Copyright 1992 Free Software Foundation, Inc.
3 Contributed by Cygnus Support. Hacked from Steve Chamberlain's Z8000 work
4 by Doug Evans. (dje@cygnus.com).
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"
35#include "sp64sim.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).
41
42 sim_xxx are external counterparts to the simif_xxx objects that must be
43 provided by the simulator. */
44
45/* Forward data declarations */
46extern struct target_ops simif_ops;
47
48int simif_verbose = 0; /* available to the simulator to use */
49
50static int program_loaded = 0;
51
52static void dump_mem ();
53
54static void
55simif_fetch_register (regno)
56int regno;
57{
58 if (regno == -1)
59 {
60 if (simif_verbose)
61 printf_filtered ("simif_fetch_register: %d\n", regno);
62 for (regno = 0; regno < 16; 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 (simif_verbose)
72 {
73 printf_filtered ("simif_fetch_register: %d", regno);
74 dump_mem (buf, sizeof (REGISTER_TYPE));
75 }
76 }
77}
78
79static void
80simif_store_register (regno)
81int regno;
82{
83 if (regno == -1)
84 {
85 if (simif_verbose)
86 printf_filtered ("simif_store_register: %d\n", regno);
87 for (regno = 0; regno < 16; regno++)
88 simif_store_register (regno);
89 }
90 else
91 {
92 char value[sizeof (REGISTER_TYPE)];
93
94 read_register_gen (regno, value);
95 SWAP_TARGET_AND_HOST (value, sizeof (REGISTER_TYPE));
96 sim_store_register (regno, value);
97 if (simif_verbose)
98 {
99 printf_filtered ("simif_store_register: %d", regno);
100 dump_mem (value, sizeof (REGISTER_TYPE));
101 }
102 }
103}
104
105static void
106simif_kill (arg,from_tty)
107char *arg;
108int from_tty;
109{
110 if (simif_verbose)
111 printf_filtered ("simif_kill: arg \"%s\"\n", arg);
112
113 sim_kill (); /* close fd's, remove mappings */
114 inferior_pid = 0;
115}
116
117/* Download a file specified in 'args', to the sim. */
118
119static void
120simif_load (args, fromtty)
121 char *args;
122 int fromtty;
123{
124 bfd *abfd;
125
126 if (simif_verbose)
127 printf_filtered ("simif_load: args \"%s\"\n", args);
128
129 inferior_pid = 0;
130 program_loaded = 0;
131 /* FIXME: a.out should be a config parm and/or an arg. */
132 abfd = bfd_openr (args,"a.out-sunos-big");
133
134 if (!abfd)
135 error ("Unable to open file %s.", args);
136
137 if (bfd_check_format (abfd, bfd_object) ==0)
138 error ("File is not an object file.");
139
140 if (sim_load (abfd, args) != 0)
141 return;
142
143 program_loaded = 1;
144
145 /* It is sim_load()'s job to set this. */
146 /*sim_set_pc (abfd->start_address); - can't do 'cus we use RMTVaddr */
147}
148
149/* This is called not only when we first attach, but also when the
150 user types "run" after having attached. */
151
152static void
153simif_create_inferior (exec_file, args, env)
154 char *exec_file;
155 char *args;
156 char **env;
157{
158 int len,entry_pt;
159 char *arg_buf,**argv;
160
161 if (! program_loaded)
162 error ("No program loaded.");
163
164 if (simif_verbose)
165 printf_filtered ("simif_create_inferior: exec_file \"%s\", args \"%s\"\n",
166 exec_file, args);
167
168 if (exec_file == 0 || exec_bfd == 0)
169 error ("No exec file specified.");
170
171 entry_pt = (int) bfd_get_start_address (exec_bfd);
172
173 simif_kill (NULL, NULL);
174 remove_breakpoints ();
175 init_wait_for_inferior ();
176
177 len = 5 + strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
178 arg_buf = (char *) alloca (len);
179 arg_buf[0] = '\0';
180 strcat (arg_buf, exec_file);
181 strcat (arg_buf, " ");
182 strcat (arg_buf, args);
183 argv = buildargv (arg_buf);
184 make_cleanup (freeargv, (char *) argv);
185 sim_set_args (argv, env);
186
187 inferior_pid = 42;
188 insert_breakpoints (); /* Needed to get correct instruction in cache */
189 proceed (entry_pt, -1, 0);
190}
191
192/* Called when selecting the simulator. EG: (gdb) target sim name.
193 NAME unused at present. */
194
195static void
196simif_open (name, from_tty)
197 char *name;
198 int from_tty;
199{
200 if (simif_verbose)
201 printf_filtered ("simif_open: name \"%s\"\n", name);
202
203 if (sim_init (name) != 0)
204 {
205 error ("Unable to initialize simulator (insufficient memory?).");
206 return;
207 }
208
209 push_target (&simif_ops);
210 target_fetch_registers (-1);
211
212 printf_filtered ("Connected to the simulator.\n");
213}
214
215/* Close out all files and local state before this target loses control. */
216
217static void
218simif_close (quitting)
219 int quitting;
220{
221 if (simif_verbose)
222 printf_filtered ("simif_close: quitting %d\n", quitting);
223
224 program_loaded = 0;
225
226 /* FIXME: Need to call sim_close() to close all files and
227 delete all mappings. */
228}
229
230/* Terminate the open connection to the remote debugger.
231 Use this when you want to detach and do something else
232 with your gdb. */
233
234static void
235simif_detach (args,from_tty)
236 char *args;
237 int from_tty;
238{
239 if (simif_verbose)
240 printf_filtered ("simif_detach: args \"%s\"\n", args);
241
242 pop_target (); /* calls simif_close to do the real work */
243 if (from_tty)
244 printf_filtered ("Ending simulator %s debugging\n", target_shortname);
245}
246
247/* Tell the remote machine to resume. */
248/* FIXME: What are A and B? */
249
250static void
251simif_resume (a,b)
252{
253 if (simif_verbose)
254 printf_filtered ("simif_resume: %d/%d\n", a, b);
255
256 sim_resume (a, b);
257}
258
259/* Wait until the remote machine stops, then return,
260 storing status in STATUS just as `wait' would. */
261
262static int
263simif_wait (status)
264 WAITTYPE *status;
265{
266 if (simif_verbose)
267 printf_filtered ("simif_wait: ");
268#if 1
269 *status = sim_stop_signal ();
270#else
271 WSETSTOP (*status, sim_stop_signal ());
272#endif
273 if (simif_verbose)
274 printf_filtered ("status %d\n", *status);
275 return 0;
276}
277
278/* Get ready to modify the registers array. On machines which store
279 individual registers, this doesn't need to do anything. On machines
280 which store all the registers in one fell swoop, this makes sure
281 that registers contains all the registers from the program being
282 debugged. */
283
284static void
285simif_prepare_to_store ()
286{
287 /* Do nothing, since we can store individual regs */
288}
289
290static int
291simif_xfer_inferior_memory (memaddr, myaddr, len, write, target)
292 CORE_ADDR memaddr;
293 char *myaddr;
294 int len;
295 int write;
296 struct target_ops *target; /* ignored */
297{
298 if (simif_verbose)
299 {
300 printf_filtered ("simif_xfer_inferior_memory: myaddr 0x%x, memaddr 0x%x, len %d, write %d\n",
301 myaddr, memaddr, len, write);
302 if (simif_verbose && write)
303 dump_mem(myaddr, len);
304 }
305
306 if (! program_loaded)
307 error ("No program loaded.");
308
309 if (write)
310 {
311 len = sim_write (memaddr, myaddr, len);
312 }
313 else
314 {
315 len = sim_read (memaddr, myaddr, len);
316 if (simif_verbose && len > 0)
317 dump_mem(myaddr, len);
318 }
319 return len;
320}
321
322static void
323simif_files_info ()
324{
325 char *file = "nothing";
326
327 if (exec_bfd)
328 file = bfd_get_filename (exec_bfd);
329
330 if (simif_verbose)
331 printf_filtered ("simif_files_info: file \"%s\"\n", file);
332
333 if (exec_bfd)
334 printf_filtered ("\tAttached to %s running program %s\n",
335 target_shortname, file);
336}
337
338/* Clear the sims notion of what the break points are */
339static void
340simif_mourn ()
341{
342 if (simif_verbose)
343 printf_filtered ("simif_mourn:\n");
344
345 remove_breakpoints ();
346 generic_mourn_inferior ();
347}
348
349/* Define the target subroutine names */
350
351struct target_ops simif_ops =
352{
353 "sim", "SPARC64 Simulator",
354 "Use the SPARC64 Simulator",
355 simif_open, simif_close,
356 0, simif_detach, simif_resume, simif_wait, /* attach */
357 simif_fetch_register, simif_store_register,
358 simif_prepare_to_store,
359 simif_xfer_inferior_memory,
360 simif_files_info,
361 0, 0, /* Breakpoints */
362 0, 0, 0, 0, 0, /* Terminal handling */
363 simif_kill, /* FIXME, kill */
364 simif_load,
365 0, /* lookup_symbol */
366 simif_create_inferior, /* create_inferior */
367 simif_mourn, /* mourn_inferior FIXME */
368 0, /* can_run */
369 0, /* notice_signals */
370 process_stratum, 0, /* next */
371 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
372 0, 0, /* Section pointers */
373 OPS_MAGIC, /* Always the last thing */
374};
375
376static void
377simif_snoop ()
378{
379 simif_verbose = ! simif_verbose;
380 if (simif_verbose)
381 printf_filtered ("Snoop enabled\n");
382 else
383 printf_filtered ("Snoop disabled\n");
384
385}
386
387/***********************************************************************/
388
389void
390_initialize_remote_sim ()
391{
392 add_target (&simif_ops);
393 add_com ("snoop", class_obscure, simif_snoop,
394 "Show what commands are going to the simulator");
395}
396
397static void
398dump_mem (buf, len)
399 char *buf;
400 int len;
401{
402 if (len <= 8)
403 {
404 if (len == 8 || len == 4)
405 {
406 long l[2];
407 memcpy (l, buf, len);
408 printf_filtered ("\t0x%x", l[0]);
409 printf_filtered (len == 8 ? " 0x%x\n" : "\n", l[1]);
410 }
411 else
412 {
413 int i;
414 printf_filtered ("\t");
415 for (i = 0; i < len; i++)
416 printf_filtered ("0x%x ", buf[i]);
417 printf_filtered ("\n");
418 }
419 }
420}
This page took 0.039037 seconds and 4 git commands to generate.