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