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