* sim_calls.c (sim_resume): Reset sim_should_run if single stepping.
[binutils-gdb.git] / sim / ppc / sim_calls.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
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 "../../gdb/defs.h"
44
45 #include "../../gdb/remote-sim.h"
46 #include "../../gdb/callback.h"
47
48
49 /* Structures used by the simulator, for gdb just have static structures */
50
51 static psim *simulator;
52 static device *root_device;
53 static const char *register_names[] = REGISTER_NAMES;
54
55 void
56 sim_open (char *args)
57 {
58 /* Note: The simulation is not created by sim_open() because
59 complete information is not yet available */
60 /* trace the call */
61 TRACE(trace_gdb, ("sim_open(args=%s) called\n", args ? args : "(null)"));
62
63 if (root_device != NULL)
64 sim_io_printf_filtered("Warning - re-open of simulator leaks memory\n");
65 root_device = psim_tree();
66 simulator = NULL;
67
68 if (args) {
69 char **argv = buildargv(args);
70 psim_options(root_device, argv);
71 freeargv(argv);
72 }
73
74 if (ppc_trace[trace_opts])
75 print_options ();
76 }
77
78
79 void
80 sim_close (int quitting)
81 {
82 TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting));
83 if (ppc_trace[trace_print_info] && simulator != NULL)
84 psim_print_info (simulator, ppc_trace[trace_print_info]);
85 }
86
87
88 int
89 sim_load (char *prog, int from_tty)
90 {
91 char **argv;
92 TRACE(trace_gdb, ("sim_load(prog=%s, from_tty=%d) called\n",
93 prog, from_tty));
94 ASSERT(prog != NULL);
95
96 /* parse the arguments, assume that the file is argument 0 */
97 argv = buildargv(prog);
98 ASSERT(argv != NULL && argv[0] != NULL);
99
100 /* create the simulator */
101 TRACE(trace_gdb, ("sim_load() - first time, create the simulator\n"));
102 simulator = psim_create(argv[0], root_device);
103
104 /* bring in all the data section */
105 psim_init(simulator);
106
107 /* release the arguments */
108 freeargv(argv);
109
110 /* `I did it my way' */
111 return 0;
112 }
113
114
115 void
116 sim_kill (void)
117 {
118 TRACE(trace_gdb, ("sim_kill(void) called\n"));
119 /* do nothing, nothing to do */
120 }
121
122
123 int
124 sim_read (SIM_ADDR mem, unsigned char *buf, int length)
125 {
126 int result = psim_read_memory(simulator, MAX_NR_PROCESSORS,
127 buf, mem, length);
128 TRACE(trace_gdb, ("sim_read(mem=0x%lx, buf=0x%lx, length=%d) = %d\n",
129 (long)mem, (long)buf, length, result));
130 return result;
131 }
132
133
134 int
135 sim_write (SIM_ADDR mem, unsigned char *buf, int length)
136 {
137 int result = psim_write_memory(simulator, MAX_NR_PROCESSORS,
138 buf, mem, length,
139 1/*violate_ro*/);
140 TRACE(trace_gdb, ("sim_write(mem=0x%lx, buf=0x%lx, length=%d) = %d\n",
141 (long)mem, (long)buf, length, result));
142 return result;
143 }
144
145
146 void
147 sim_fetch_register (int regno, unsigned char *buf)
148 {
149 if (simulator == NULL) {
150 return;
151 }
152 TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
153 regno, register_names[regno], (long)buf));
154 psim_read_register(simulator, MAX_NR_PROCESSORS,
155 buf, register_names[regno],
156 raw_transfer);
157 }
158
159
160 void
161 sim_store_register (int regno, unsigned char *buf)
162 {
163 if (simulator == NULL)
164 return;
165 TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",
166 regno, register_names[regno], (long)buf));
167 psim_write_register(simulator, MAX_NR_PROCESSORS,
168 buf, register_names[regno],
169 raw_transfer);
170 }
171
172
173 void
174 sim_info (int verbose)
175 {
176 TRACE(trace_gdb, ("sim_info(verbose=%d) called\n", verbose));
177 psim_print_info (simulator, verbose);
178 }
179
180
181 void
182 sim_create_inferior (SIM_ADDR start_address, char **argv, char **envp)
183 {
184 unsigned_word entry_point = start_address;
185
186 TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n",
187 start_address));
188
189 psim_init(simulator);
190 psim_stack(simulator, argv, envp);
191
192 psim_write_register(simulator, -1 /* all start at same PC */,
193 &entry_point, "pc", cooked_transfer);
194 }
195
196
197 static volatile int sim_should_run;
198
199 void
200 sim_stop_reason (enum sim_stop *reason, int *sigrc)
201 {
202 psim_status status = psim_get_status(simulator);
203
204 switch (CURRENT_ENVIRONMENT) {
205
206 case USER_ENVIRONMENT:
207 case VIRTUAL_ENVIRONMENT:
208 switch (status.reason) {
209 case was_continuing:
210 *reason = sim_stopped;
211 *sigrc = SIGTRAP;
212 if (sim_should_run) {
213 error("sim_stop_reason() unknown reason for halt\n");
214 }
215 break;
216 case was_trap:
217 *reason = sim_stopped;
218 *sigrc = SIGTRAP;
219 break;
220 case was_exited:
221 *reason = sim_exited;
222 *sigrc = 0;
223 break;
224 case was_signalled:
225 *reason = sim_signalled;
226 *sigrc = status.signal;
227 break;
228 }
229 break;
230
231 case OPERATING_ENVIRONMENT:
232 *reason = sim_stopped;
233 *sigrc = SIGTRAP;
234 break;
235
236 default:
237 error("sim_stop_reason() - unknown environment\n");
238
239 }
240
241 TRACE(trace_gdb, ("sim_stop_reason(reason=0x%lx(%ld), sigrc=0x%lx(%ld))\n",
242 (long)reason, (long)*reason, (long)sigrc, (long)*sigrc));
243 }
244
245
246
247 /* Run (or resume) the program. */
248 static void
249 sim_ctrl_c()
250 {
251 sim_should_run = 0;
252 }
253
254 void
255 sim_resume (int step, int siggnal)
256 {
257 TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n",
258 step, siggnal));
259
260 if (step)
261 {
262 psim_step(simulator);
263 /* sim_stop_reason has a sanity check for stopping while
264 was_continuing. We don't want that here so reset sim_should_run. */
265 sim_should_run = 0;
266 }
267 else
268 {
269 void (*prev) ();
270
271 prev = signal(SIGINT, sim_ctrl_c);
272 sim_should_run = 1;
273 psim_run_until_stop(simulator, &sim_should_run);
274 signal(SIGINT, prev);
275 }
276 }
277
278 void
279 sim_do_command (char *cmd)
280 {
281 TRACE(trace_gdb, ("sim_do_commands(cmd=%s) called\n",
282 cmd ? cmd : "(null)"));
283 if (cmd) {
284 char **argv = buildargv(cmd);
285 psim_options(root_device, argv);
286 freeargv(argv);
287 }
288 }
289
290
291 /* Map simulator IO operations onto the corresponding GDB I/O
292 functions.
293
294 NB: Only a limited subset of operations are mapped across. More
295 advanced operations (such as dup or write) must either be mapped to
296 one of the below calls or handled internally */
297
298 static host_callback *callbacks;
299
300 int
301 sim_io_read_stdin(char *buf,
302 int sizeof_buf)
303 {
304 switch (CURRENT_STDIO) {
305 case DO_USE_STDIO:
306 return callbacks->read_stdin(callbacks, buf, sizeof_buf);
307 break;
308 case DONT_USE_STDIO:
309 return callbacks->read(callbacks, 0, buf, sizeof_buf);
310 break;
311 default:
312 error("sim_io_read_stdin: unaccounted switch\n");
313 break;
314 }
315 }
316
317 int
318 sim_io_write_stdout(const char *buf,
319 int sizeof_buf)
320 {
321 switch (CURRENT_STDIO) {
322 case DO_USE_STDIO:
323 return callbacks->write_stdout(callbacks, buf, sizeof_buf);
324 break;
325 case DONT_USE_STDIO:
326 return callbacks->write(callbacks, 1, buf, sizeof_buf);
327 break;
328 default:
329 error("sim_io_write_stdout: unaccounted switch\n");
330 break;
331 }
332 }
333
334 int
335 sim_io_write_stderr(const char *buf,
336 int sizeof_buf)
337 {
338 switch (CURRENT_STDIO) {
339 case DO_USE_STDIO:
340 /* NB: I think there should be an explicit write_stderr callback */
341 return callbacks->write(callbacks, 3, buf, sizeof_buf);
342 break;
343 case DONT_USE_STDIO:
344 return callbacks->write(callbacks, 3, buf, sizeof_buf);
345 break;
346 default:
347 error("sim_io_write_stderr: unaccounted switch\n");
348 break;
349 }
350 }
351
352
353 void
354 sim_io_printf_filtered(const char *fmt,
355 ...)
356 {
357 char message[1024];
358 va_list ap;
359 /* format the message */
360 va_start(ap, fmt);
361 vsprintf(message, fmt, ap);
362 va_end(ap);
363 /* sanity check */
364 if (strlen(message) >= sizeof(message))
365 error("sim_io_printf_filtered: buffer overflow\n");
366 callbacks->printf_filtered(callbacks, "%s", message);
367 }
368
369 void
370 sim_io_flush_stdoutput(void)
371 {
372 switch (CURRENT_STDIO) {
373 case DO_USE_STDIO:
374 gdb_flush (gdb_stdout);
375 break;
376 case DONT_USE_STDIO:
377 break;
378 default:
379 error("sim_io_read_stdin: unaccounted switch\n");
380 break;
381 }
382 }
383
384 void
385 sim_set_callbacks (host_callback *callback)
386 {
387 callbacks = callback;
388 TRACE(trace_gdb, ("sim_set_callbacks called\n"));
389 }
390
391 /****/
392
393 void *
394 zalloc(long size)
395 {
396 void *memory = (void*)xmalloc(size);
397 if (memory == NULL)
398 error("xmalloc failed\n");
399 memset(memory, 0, size);
400 return memory;
401 }
402
403 void zfree(void *data)
404 {
405 mfree(NULL, data);
406 }