New version from Andrew; Portability fixes on top of that
[deliverable/binutils-gdb.git] / sim / ppc / main.c
CommitLineData
4f35cbff
MM
1/* This file is part of the program psim.
2
262faa54 3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4f35cbff
MM
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>
4f35cbff 23#include <stdio.h>
2e913166 24#include <fcntl.h>
4f35cbff
MM
25
26#include "psim.h"
28816f45 27#include "options.h"
262faa54 28#include "device.h" /* FIXME: psim should provide the interface */
4f35cbff 29
c494cadd
MM
30#ifdef HAVE_STDLIB_H
31#include <stdlib.h>
32#endif
33
73c4941b
MM
34#ifdef HAVE_UNISTD_H
35#include <unistd.h>
36#endif
37
c494cadd
MM
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
5c04f4f7
MM
46#include <errno.h>
47
2e913166
MM
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
4f35cbff 54extern char **environ;
4f35cbff 55
2e913166
MM
56static psim *simulation = NULL;
57
58
4f35cbff 59void
2e913166 60sim_io_printf_filtered(const char *msg, ...)
4f35cbff
MM
61{
62 va_list ap;
63 va_start(ap, msg);
64 vprintf(msg, ap);
22ddef46 65 va_end(ap);
4f35cbff
MM
66}
67
68void
69error (char *msg, ...)
70{
71 va_list ap;
72 va_start(ap, msg);
73 vprintf(msg, ap);
5c04f4f7 74 printf("\n");
22ddef46 75 va_end(ap);
2e913166
MM
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
4f35cbff
MM
81 exit (1);
82}
83
2e913166
MM
84int
85sim_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 }
5c04f4f7 104 return 0;
2e913166
MM
105}
106
107int
108sim_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 }
5c04f4f7 127 return 0;
2e913166
MM
128}
129
130int
131sim_io_read_stdin(char *buf,
132 int sizeof_buf)
133{
134 switch (CURRENT_STDIO) {
135 case DO_USE_STDIO:
5c04f4f7
MM
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;
2e913166
MM
150 break;
151 case DONT_USE_STDIO:
152 {
153 /* check for input */
154 int flags;
155 int status;
156 int nr_read;
5c04f4f7 157 int result;
2e913166
MM
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 */
5c04f4f7
MM
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 }
2e913166
MM
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 }
5c04f4f7 189 return result;
2e913166
MM
190 }
191 break;
192 default:
193 error("sim_io_read_stdin: invalid switch\n");
194 break;
195 }
5c04f4f7 196 return 0;
2e913166
MM
197}
198
199void
200sim_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
4f35cbff
MM
215void *
216zalloc(long size)
217{
218 void *memory = malloc(size);
219 if (memory == NULL)
220 error("zmalloc failed\n");
1dc7c0ed 221 memset(memory, 0, size);
4f35cbff
MM
222 return memory;
223}
224
225void
226zfree(void *chunk)
227{
228 free(chunk);
229}
230
4f35cbff
MM
231int
232main(int argc, char **argv)
233{
4f35cbff
MM
234 const char *name_of_file;
235 char *arg_;
4f35cbff 236 psim_status status;
262faa54
MM
237 device *root = psim_tree();
238
239 /* parse the arguments */
240 argv = psim_options(root, argv + 1);
5c04f4f7
MM
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 }
262faa54 249 name_of_file = argv[0];
4f35cbff 250
28816f45
MM
251 if (ppc_trace[trace_opts])
252 print_options ();
253
4f35cbff 254 /* create the simulator */
2e913166 255 simulation = psim_create(name_of_file, root);
4f35cbff
MM
256
257 /* fudge the environment so that _=prog-name */
262faa54 258 arg_ = (char*)zalloc(strlen(argv[0]) + strlen("_=") + 1);
4f35cbff 259 strcpy(arg_, "_=");
262faa54 260 strcat(arg_, argv[0]);
4f35cbff
MM
261 putenv(arg_);
262
263 /* initialize it */
2e913166
MM
264 psim_init(simulation);
265 psim_stack(simulation, argv, environ);
4f35cbff 266
2e913166 267 psim_run(simulation);
4f35cbff 268
22ddef46 269 /* any final clean up */
262faa54 270 if (ppc_trace[trace_print_info])
2e913166 271 psim_print_info (simulation, ppc_trace[trace_print_info]);
83d96c6e 272
4f35cbff 273 /* why did we stop */
2e913166 274 status = psim_get_status(simulation);
4f35cbff
MM
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:
22ddef46 285 printf ("%s: Caught signal %d at address 0x%lx\n",
a983c8f0
MM
286 name_of_file, (int)status.signal,
287 (long)status.program_counter);
4f35cbff
MM
288 return status.signal;
289 default:
290 error("unknown halt condition\n");
291 return 0;
292 }
293}
This page took 0.073397 seconds and 4 git commands to generate.