Change inferior thread list to be a thread map
[deliverable/binutils-gdb.git] / sim / ppc / main.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, 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 3 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, see <http://www.gnu.org/licenses/>.
17
18 */
19
20
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <fcntl.h>
24
25 #include <signal.h>
26
27 #include "psim.h"
28 #include "options.h"
29 #include "device.h" /* FIXME: psim should provide the interface */
30 #include "events.h" /* FIXME: psim should provide the interface */
31
32 #include "bfd.h"
33 #include "gdb/callback.h"
34 #include "gdb/remote-sim.h"
35
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43
44 #ifdef HAVE_STRING_H
45 #include <string.h>
46 #else
47 #ifdef HAVE_STRINGS_H
48 #include <strings.h>
49 #endif
50 #endif
51
52 #include <errno.h>
53
54 #if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
55 #undef WITH_STDIO
56 #define WITH_STDIO DO_USE_STDIO
57 #endif
58
59
60 extern char **environ;
61
62 static psim *simulation = NULL;
63
64
65 void
66 sim_io_poll_quit (void)
67 {
68 /* nothing to do */
69 }
70
71 void
72 sim_io_printf_filtered(const char *msg, ...)
73 {
74 va_list ap;
75 va_start(ap, msg);
76 vprintf(msg, ap);
77 va_end(ap);
78 }
79
80 void
81 error (const char *msg, ...)
82 {
83 va_list ap;
84 va_start(ap, msg);
85 vprintf(msg, ap);
86 printf("\n");
87 va_end(ap);
88
89 /* any final clean up */
90 if (ppc_trace[trace_print_info] && simulation != NULL)
91 psim_print_info (simulation, ppc_trace[trace_print_info]);
92
93 exit (1);
94 }
95
96 int
97 sim_io_write_stdout(const char *buf,
98 int sizeof_buf)
99 {
100 switch (CURRENT_STDIO) {
101 case DO_USE_STDIO:
102 {
103 int i;
104 for (i = 0; i < sizeof_buf; i++) {
105 putchar(buf[i]);
106 }
107 return i;
108 }
109 break;
110 case DONT_USE_STDIO:
111 return write(1, buf, sizeof_buf);
112 break;
113 default:
114 error("sim_io_write_stdout: invalid switch\n");
115 }
116 return 0;
117 }
118
119 int
120 sim_io_write_stderr(const char *buf,
121 int sizeof_buf)
122 {
123 switch (CURRENT_STDIO) {
124 case DO_USE_STDIO:
125 {
126 int i;
127 for (i = 0; i < sizeof_buf; i++) {
128 fputc(buf[i], stderr);
129 }
130 return i;
131 }
132 break;
133 case DONT_USE_STDIO:
134 return write(2, buf, sizeof_buf);
135 break;
136 default:
137 error("sim_io_write_stdout: invalid switch\n");
138 }
139 return 0;
140 }
141
142 int
143 sim_io_read_stdin(char *buf,
144 int sizeof_buf)
145 {
146 switch (CURRENT_STDIO) {
147 case DO_USE_STDIO:
148 if (sizeof_buf > 1) {
149 if (fgets(buf, sizeof_buf, stdin) != NULL)
150 return strlen(buf);
151 }
152 else if (sizeof_buf == 1) {
153 char b[2];
154 if (fgets(b, sizeof(b), stdin) != NULL) {
155 memcpy(buf, b, strlen(b));
156 return strlen(b);
157 }
158 }
159 else if (sizeof_buf == 0)
160 return 0;
161 return sim_io_eof;
162 break;
163 case DONT_USE_STDIO:
164 #if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL)
165 {
166 /* check for input */
167 int flags;
168 int status;
169 int nr_read;
170 int result;
171 /* get the old status */
172 flags = fcntl(0, F_GETFL, 0);
173 if (flags == -1) {
174 perror("sim_io_read_stdin");
175 return sim_io_eof;
176 }
177 /* temp, disable blocking IO */
178 status = fcntl(0, F_SETFL, flags | O_NDELAY);
179 if (status == -1) {
180 perror("sim_io_read_stdin");
181 return sim_io_eof;
182 }
183 /* try for input */
184 nr_read = read(0, buf, sizeof_buf);
185 if (nr_read > 0
186 || (nr_read == 0 && sizeof_buf == 0))
187 result = nr_read;
188 else if (nr_read == 0)
189 result = sim_io_eof;
190 else { /* nr_read < 0 */
191 if (errno == EAGAIN)
192 result = sim_io_not_ready;
193 else
194 result = sim_io_eof;
195 }
196 /* return to regular vewing */
197 status = fcntl(0, F_SETFL, flags);
198 if (status == -1) {
199 perror("sim_io_read_stdin");
200 return sim_io_eof;
201 }
202 return result;
203 }
204 break;
205 #endif
206 default:
207 error("sim_io_read_stdin: invalid switch\n");
208 break;
209 }
210 return 0;
211 }
212
213 void
214 sim_io_flush_stdoutput(void)
215 {
216 switch (CURRENT_STDIO) {
217 case DO_USE_STDIO:
218 fflush (stdout);
219 break;
220 case DONT_USE_STDIO:
221 break;
222 default:
223 error("sim_io_flush_stdoutput: invalid switch\n");
224 break;
225 }
226 }
227
228 void
229 sim_io_error (SIM_DESC sd, const char *msg, ...)
230 {
231 va_list ap;
232 va_start(ap, msg);
233 vprintf(msg, ap);
234 printf("\n");
235 va_end(ap);
236
237 /* any final clean up */
238 if (ppc_trace[trace_print_info] && simulation != NULL)
239 psim_print_info (simulation, ppc_trace[trace_print_info]);
240
241 exit (1);
242 }
243
244
245 void *
246 zalloc(long size)
247 {
248 void *memory = malloc(size);
249 if (memory == NULL)
250 error("zalloc failed\n");
251 memset(memory, 0, size);
252 return memory;
253 }
254
255 /* When a CNTRL-C occures, queue an event to shut down the simulation */
256
257 static RETSIGTYPE
258 cntrl_c(int sig)
259 {
260 psim_stop (simulation);
261 }
262
263
264 int
265 main(int argc, char **argv)
266 {
267 const char *name_of_file;
268 char *arg_;
269 psim_status status;
270 device *root = psim_tree();
271
272 /* parse the arguments */
273 argv = psim_options (root, argv + 1, SIM_OPEN_STANDALONE);
274 if (argv[0] == NULL) {
275 if (ppc_trace[trace_opts]) {
276 print_options ();
277 return 0;
278 } else {
279 psim_usage (0, 0, SIM_OPEN_STANDALONE);
280 }
281 }
282 name_of_file = argv[0];
283
284 if (ppc_trace[trace_opts])
285 print_options ();
286
287 /* create the simulator */
288 simulation = psim_create(name_of_file, root);
289
290 /* fudge the environment so that _=prog-name */
291 arg_ = (char*)zalloc(strlen(argv[0]) + strlen("_=") + 1);
292 strcpy(arg_, "_=");
293 strcat(arg_, argv[0]);
294 putenv(arg_);
295
296 /* initialize it */
297 psim_init(simulation);
298 psim_stack(simulation, argv, environ);
299
300 {
301 RETSIGTYPE (*prev) ();
302 prev = signal(SIGINT, cntrl_c);
303 psim_run(simulation);
304 signal(SIGINT, prev);
305 }
306
307 /* any final clean up */
308 if (ppc_trace[trace_print_info])
309 psim_print_info (simulation, ppc_trace[trace_print_info]);
310
311 /* why did we stop */
312 status = psim_get_status(simulation);
313 switch (status.reason) {
314 case was_continuing:
315 error("psim: continuing while stopped!\n");
316 return 0;
317 case was_trap:
318 error("psim: no trap insn\n");
319 return 0;
320 case was_exited:
321 return status.signal;
322 case was_signalled:
323 printf ("%s: Caught signal %d at address 0x%lx\n",
324 name_of_file, (int)status.signal,
325 (long)status.program_counter);
326 return status.signal;
327 default:
328 error("unknown halt condition\n");
329 return 0;
330 }
331 }
This page took 0.036284 seconds and 4 git commands to generate.