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