]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/ppc/sim_calls.c
2004-08-04 Andrew Cagney <cagney@gnu.org>
[thirdparty/binutils-gdb.git] / sim / ppc / sim_calls.c
1 /* This file is part of the program psim.
2
3 Copyright 1994, 1995, 1996, 1998, 2003 Andrew Cagney
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22 #include <signal.h> /* FIXME - should be machine dependant version */
23 #include <stdarg.h>
24 #include <ctype.h>
25
26 #include "psim.h"
27 #include "options.h"
28
29 #undef printf_filtered /* blow away the mapping */
30
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #else
38 #ifdef HAVE_STRINGS_H
39 #include <strings.h>
40 #endif
41 #endif
42
43 #include "defs.h"
44 #include "bfd.h"
45 #include "gdb/callback.h"
46 #include "gdb/remote-sim.h"
47
48 /* Define the rate at which the simulator should poll the host
49 for a quit. */
50 #ifndef POLL_QUIT_INTERVAL
51 #define POLL_QUIT_INTERVAL 0x20
52 #endif
53
54 static int poll_quit_count = POLL_QUIT_INTERVAL;
55
56 /* Structures used by the simulator, for gdb just have static structures */
57
58 static psim *simulator;
59 static device *root_device;
60 static host_callback *callbacks;
61
62 /* We use GDB's gdbarch_register_name function to map GDB register
63 numbers onto names, which we can then look up in the register
64 table. Since the `set architecture' command can select a new
65 processor variant at run-time, the meanings of the register numbers
66 can change, so we need to make sure the sim uses the same
67 name/number mapping that GDB uses.
68
69 (We don't use the REGISTER_NAME macro, which is a wrapper for
70 gdbarch_register_name. We #include GDB's "defs.h", which tries to
71 #include GDB's "config.h", but gets ours instead, and REGISTER_NAME
72 ends up not getting defined. Simpler to just use
73 gdbarch_register_name directly.)
74
75 We used to just use the REGISTER_NAMES macro from GDB's
76 target-dependent header files, which expanded into an initializer
77 for an array of strings. That was kind of nice, because it meant
78 that libsim.a had only a compile-time dependency on GDB; using
79 gdbarch_register_name directly means that there are now link-time
80 and run-time dependencies too.
81
82 Perhaps the host_callback structure could provide a function for
83 retrieving register names; that would be cleaner. */
84
85 SIM_DESC
86 sim_open (SIM_OPEN_KIND kind,
87 host_callback *callback,
88 struct bfd *abfd,
89 char **argv)
90 {
91 callbacks = callback;
92
93 /* Note: The simulation is not created by sim_open() because
94 complete information is not yet available */
95 /* trace the call */
96 TRACE(trace_gdb, ("sim_open called\n"));
97
98 if (root_device != NULL)
99 sim_io_printf_filtered("Warning - re-open of simulator leaks memory\n");
100 root_device = psim_tree();
101 simulator = NULL;
102
103 psim_options(root_device, argv + 1);
104
105 if (ppc_trace[trace_opts])
106 print_options ();
107
108 /* fudge our descriptor for now */
109 return (SIM_DESC) 1;
110 }
111
112
113 void
114 sim_close (SIM_DESC sd, int quitting)
115 {
116 TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting));
117 if (ppc_trace[trace_print_info] && simulator != NULL)
118 psim_print_info (simulator, ppc_trace[trace_print_info]);
119 }
120
121
122 SIM_RC
123 sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
124 {
125 TRACE(trace_gdb, ("sim_load(prog=%s, from_tty=%d) called\n",
126 prog, from_tty));
127 ASSERT(prog != NULL);
128
129 /* create the simulator */
130 TRACE(trace_gdb, ("sim_load() - first time, create the simulator\n"));
131 simulator = psim_create(prog, root_device);
132
133 /* bring in all the data section */
134 psim_init(simulator);
135
136 /* get the start address */
137 if (abfd == NULL)
138 {
139 abfd = bfd_openr (prog, 0);
140 if (abfd == NULL)
141 error ("psim: can't open \"%s\": %s\n",
142 prog, bfd_errmsg (bfd_get_error ()));
143 if (!bfd_check_format (abfd, bfd_object))
144 {
145 const char *errmsg = bfd_errmsg (bfd_get_error ());
146 bfd_close (abfd);
147 error ("psim: \"%s\" is not an object file: %s\n",
148 prog, errmsg);
149 }
150 bfd_close (abfd);
151 }
152
153 return SIM_RC_OK;
154 }
155
156
157 int
158 sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
159 {
160 int result = psim_read_memory(simulator, MAX_NR_PROCESSORS,
161 buf, mem, length);
162 TRACE(trace_gdb, ("sim_read(mem=0x%lx, buf=0x%lx, length=%d) = %d\n",
163 (long)mem, (long)buf, length, result));
164 return result;
165 }
166
167
168 int
169 sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
170 {
171 int result = psim_write_memory(simulator, MAX_NR_PROCESSORS,
172 buf, mem, length,
173 1/*violate_ro*/);
174 TRACE(trace_gdb, ("sim_write(mem=0x%lx, buf=0x%lx, length=%d) = %d\n",
175 (long)mem, (long)buf, length, result));
176 return result;
177 }
178
179
180 int
181 sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
182 {
183 const char *regname;
184
185 if (simulator == NULL) {
186 return 0;
187 }
188
189 /* GDB will sometimes ask for the contents of a register named "";
190 we ignore such requests, and leave garbage in *BUF. In GDB
191 terms, the empty string means "the register with this number is
192 not present in the currently selected architecture variant."
193 That's following the kludge we're using for the MIPS processors.
194 But there are loops that just walk through the entire list of
195 names and try to get everything. */
196 regname = gdbarch_register_name (current_gdbarch, regno);
197 if (! regname || regname[0] == '\0')
198 return -1;
199
200 TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
201 regno, regname, (long)buf));
202 return psim_read_register(simulator, MAX_NR_PROCESSORS,
203 buf, regname, raw_transfer);
204 }
205
206
207 int
208 sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
209 {
210 const char *regname;
211
212 if (simulator == NULL)
213 return 0;
214
215 /* See comments in sim_fetch_register, above. */
216 regname = gdbarch_register_name (current_gdbarch, regno);
217 if (! regname || regname[0] == '\0')
218 return -1;
219
220 TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",
221 regno, regname, (long)buf));
222 return psim_write_register(simulator, MAX_NR_PROCESSORS,
223 buf, regname, raw_transfer);
224 }
225
226
227 void
228 sim_info (SIM_DESC sd, int verbose)
229 {
230 TRACE(trace_gdb, ("sim_info(verbose=%d) called\n", verbose));
231 psim_print_info (simulator, verbose);
232 }
233
234
235 SIM_RC
236 sim_create_inferior (SIM_DESC sd,
237 struct bfd *abfd,
238 char **argv,
239 char **envp)
240 {
241 unsigned_word entry_point;
242 TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n",
243 entry_point));
244
245 if (simulator == NULL)
246 error ("No program loaded");
247
248 if (abfd != NULL)
249 entry_point = bfd_get_start_address (abfd);
250 else
251 entry_point = 0xfff00000; /* ??? */
252
253 psim_init(simulator);
254 psim_stack(simulator, argv, envp);
255
256 ASSERT (psim_write_register(simulator, -1 /* all start at same PC */,
257 &entry_point, "pc", cooked_transfer) > 0);
258 return SIM_RC_OK;
259 }
260
261
262 void
263 sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
264 {
265 psim_status status = psim_get_status(simulator);
266
267 switch (status.reason) {
268 case was_continuing:
269 *reason = sim_stopped;
270 if (status.signal == 0)
271 *sigrc = SIGTRAP;
272 else
273 *sigrc = status.signal;
274 break;
275 case was_trap:
276 *reason = sim_stopped;
277 *sigrc = SIGTRAP;
278 break;
279 case was_exited:
280 *reason = sim_exited;
281 *sigrc = status.signal;
282 break;
283 case was_signalled:
284 *reason = sim_signalled;
285 *sigrc = status.signal;
286 break;
287 }
288
289 TRACE(trace_gdb, ("sim_stop_reason(reason=0x%lx(%ld), sigrc=0x%lx(%ld))\n",
290 (long)reason, (long)*reason, (long)sigrc, (long)*sigrc));
291 }
292
293
294
295 /* Run (or resume) the program. */
296
297 int
298 sim_stop (SIM_DESC sd)
299 {
300 psim_stop (simulator);
301 return 1;
302 }
303
304 void
305 sim_resume (SIM_DESC sd, int step, int siggnal)
306 {
307 TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n",
308 step, siggnal));
309
310 if (step)
311 {
312 psim_step (simulator);
313 }
314 else
315 {
316 psim_run (simulator);
317 }
318 }
319
320 void
321 sim_do_command (SIM_DESC sd, char *cmd)
322 {
323 TRACE(trace_gdb, ("sim_do_commands(cmd=%s) called\n",
324 cmd ? cmd : "(null)"));
325 if (cmd != NULL) {
326 char **argv = buildargv(cmd);
327 psim_command(root_device, argv);
328 freeargv(argv);
329 }
330 }
331
332
333 /* Polling, if required */
334
335 void
336 sim_io_poll_quit (void)
337 {
338 if (callbacks->poll_quit != NULL && poll_quit_count-- < 0)
339 {
340 poll_quit_count = POLL_QUIT_INTERVAL;
341 if (callbacks->poll_quit (callbacks))
342 psim_stop (simulator);
343 }
344 }
345
346
347
348 /* Map simulator IO operations onto the corresponding GDB I/O
349 functions.
350
351 NB: Only a limited subset of operations are mapped across. More
352 advanced operations (such as dup or write) must either be mapped to
353 one of the below calls or handled internally */
354
355 int
356 sim_io_read_stdin(char *buf,
357 int sizeof_buf)
358 {
359 switch (CURRENT_STDIO) {
360 case DO_USE_STDIO:
361 return callbacks->read_stdin(callbacks, buf, sizeof_buf);
362 break;
363 case DONT_USE_STDIO:
364 return callbacks->read(callbacks, 0, buf, sizeof_buf);
365 break;
366 default:
367 error("sim_io_read_stdin: unaccounted switch\n");
368 break;
369 }
370 return 0;
371 }
372
373 int
374 sim_io_write_stdout(const char *buf,
375 int sizeof_buf)
376 {
377 switch (CURRENT_STDIO) {
378 case DO_USE_STDIO:
379 return callbacks->write_stdout(callbacks, buf, sizeof_buf);
380 break;
381 case DONT_USE_STDIO:
382 return callbacks->write(callbacks, 1, buf, sizeof_buf);
383 break;
384 default:
385 error("sim_io_write_stdout: unaccounted switch\n");
386 break;
387 }
388 return 0;
389 }
390
391 int
392 sim_io_write_stderr(const char *buf,
393 int sizeof_buf)
394 {
395 switch (CURRENT_STDIO) {
396 case DO_USE_STDIO:
397 /* NB: I think there should be an explicit write_stderr callback */
398 return callbacks->write(callbacks, 3, buf, sizeof_buf);
399 break;
400 case DONT_USE_STDIO:
401 return callbacks->write(callbacks, 3, buf, sizeof_buf);
402 break;
403 default:
404 error("sim_io_write_stderr: unaccounted switch\n");
405 break;
406 }
407 return 0;
408 }
409
410
411 void
412 sim_io_printf_filtered(const char *fmt,
413 ...)
414 {
415 char message[1024];
416 va_list ap;
417 /* format the message */
418 va_start(ap, fmt);
419 vsprintf(message, fmt, ap);
420 va_end(ap);
421 /* sanity check */
422 if (strlen(message) >= sizeof(message))
423 error("sim_io_printf_filtered: buffer overflow\n");
424 callbacks->printf_filtered(callbacks, "%s", message);
425 }
426
427 void
428 sim_io_flush_stdoutput(void)
429 {
430 switch (CURRENT_STDIO) {
431 case DO_USE_STDIO:
432 callbacks->flush_stdout (callbacks);
433 break;
434 case DONT_USE_STDIO:
435 break;
436 default:
437 error("sim_io_read_stdin: unaccounted switch\n");
438 break;
439 }
440 }
441
442 void
443 sim_io_error (SIM_DESC sd, const char *fmt, ...)
444 {
445 va_list ap;
446 va_start(ap, fmt);
447 callbacks->evprintf_filtered (callbacks, fmt, ap);
448 va_end(ap);
449 callbacks->error (callbacks, "");
450 }
451
452 /****/
453
454 void *
455 zalloc(long size)
456 {
457 void *memory = (void*)xmalloc(size);
458 if (memory == NULL)
459 error("xmalloc failed\n");
460 memset(memory, 0, size);
461 return memory;
462 }
463
464 void zfree(void *data)
465 {
466 free(data);
467 }