* sim-io.c (sim_io_getstring): Delete unused len2. (sim_io_syscalls):
[external/binutils.git] / sim / common / sim-io.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 "sim-main.h"
23 #include "sim-io.h"
24 #include "targ-vals.h"
25
26 /* See the file include/callbacks.h for a description */
27
28
29 int
30 sim_io_init(SIM_DESC sd)
31 {
32   return STATE_CALLBACK (sd)->init (STATE_CALLBACK (sd));
33 }
34
35
36 int
37 sim_io_shutdown(SIM_DESC sd)
38 {
39   return STATE_CALLBACK (sd)->shutdown (STATE_CALLBACK (sd));
40 }
41
42
43 int
44 sim_io_unlink(SIM_DESC sd,
45               const char *f1)
46 {
47   return STATE_CALLBACK (sd)->unlink (STATE_CALLBACK (sd), f1);
48 }
49
50
51 long
52 sim_io_time(SIM_DESC sd,
53             long *t)
54 {
55   return STATE_CALLBACK (sd)->time (STATE_CALLBACK (sd), t);
56 }
57
58
59 int
60 sim_io_system(SIM_DESC sd, const char *s)
61 {
62   return STATE_CALLBACK (sd)->system (STATE_CALLBACK (sd), s);
63 }
64
65
66 int
67 sim_io_rename(SIM_DESC sd,
68               const char *f1,
69               const char *f2)
70 {
71   return STATE_CALLBACK (sd)->rename (STATE_CALLBACK (sd), f1, f2);
72 }
73
74
75 int
76 sim_io_write_stdout(SIM_DESC sd,
77                     const char *buf,
78                     int len)
79 {
80   switch (CURRENT_STDIO) {
81   case DO_USE_STDIO:
82     return STATE_CALLBACK (sd)->write_stdout (STATE_CALLBACK (sd), buf, len);
83     break;
84   case DONT_USE_STDIO:
85     return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 1, buf, len);
86     break;
87   default:
88     sim_io_error (sd, "sim_io_write_stdout: unaccounted switch\n");
89     break;
90   }
91   return 0;
92 }
93
94
95 void
96 sim_io_flush_stdout(SIM_DESC sd)
97 {
98   switch (CURRENT_STDIO) {
99   case DO_USE_STDIO:
100     STATE_CALLBACK (sd)->flush_stdout (STATE_CALLBACK (sd));
101     break;
102   case DONT_USE_STDIO:
103     break;
104   default:
105     sim_io_error (sd, "sim_io_flush_stdout: unaccounted switch\n");
106     break;
107   }
108 }
109
110
111 int
112 sim_io_write_stderr(SIM_DESC sd,
113                     const char *buf,
114                     int len)
115 {
116   switch (CURRENT_STDIO) {
117   case DO_USE_STDIO:
118     return STATE_CALLBACK (sd)->write_stderr (STATE_CALLBACK (sd), buf, len);
119     break;
120   case DONT_USE_STDIO:
121     return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 2, buf, len);
122     break;
123   default:
124     sim_io_error (sd, "sim_io_write_stderr: unaccounted switch\n");
125     break;
126   }
127   return 0;
128 }
129
130
131 void
132 sim_io_flush_stderr(SIM_DESC sd)
133 {
134   switch (CURRENT_STDIO) {
135   case DO_USE_STDIO:
136     STATE_CALLBACK (sd)->flush_stderr (STATE_CALLBACK (sd));
137     break;
138   case DONT_USE_STDIO:
139     break;
140   default:
141     sim_io_error (sd, "sim_io_flush_stderr: unaccounted switch\n");
142     break;
143   }
144 }
145
146
147 int
148 sim_io_write(SIM_DESC sd,
149              int fd,
150              const char *buf,
151              int len)
152 {
153   return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), fd, buf, len);
154 }
155
156
157 int
158 sim_io_read_stdin(SIM_DESC sd,
159                   char *buf,
160                   int len)
161 {
162   switch (CURRENT_STDIO) {
163   case DO_USE_STDIO:
164     return STATE_CALLBACK (sd)->read_stdin (STATE_CALLBACK (sd), buf, len);
165     break;
166   case DONT_USE_STDIO:
167     return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), 0, buf, len);
168     break;
169   default:
170     sim_io_error (sd, "sim_io_read_stdin: unaccounted switch\n");
171     break;
172   }
173   return 0;
174 }
175
176
177 int
178 sim_io_read(SIM_DESC sd, int fd,
179             char *buf,
180             int len)
181 {
182   return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), fd, buf, len);
183 }
184
185
186 int
187 sim_io_open(SIM_DESC sd,
188             const char *name,
189             int flags)
190 {
191   return STATE_CALLBACK (sd)->open (STATE_CALLBACK (sd), name, flags);
192 }
193
194
195 int
196 sim_io_lseek(SIM_DESC sd,
197              int fd,
198              long off,
199              int way)
200 {
201   return STATE_CALLBACK (sd)->lseek (STATE_CALLBACK (sd), fd, off, way);
202 }
203
204
205 int
206 sim_io_isatty(SIM_DESC sd,
207               int fd)
208 {
209   return STATE_CALLBACK (sd)->isatty (STATE_CALLBACK (sd), fd);
210 }
211
212
213 int
214 sim_io_get_errno(SIM_DESC sd)
215 {
216   return STATE_CALLBACK (sd)->get_errno (STATE_CALLBACK (sd));
217 }
218
219
220 int
221 sim_io_close(SIM_DESC sd,
222              int fd)
223 {
224   return STATE_CALLBACK (sd)->close (STATE_CALLBACK (sd), fd);
225 }
226
227
228 void
229 sim_io_printf(SIM_DESC sd,
230               const char *fmt,
231               ...)
232 {
233   va_list ap;
234   va_start(ap, fmt);
235   STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
236   va_end(ap);
237 }
238
239
240 void
241 sim_io_vprintf(SIM_DESC sd,
242                const char *fmt,
243                va_list ap)
244 {
245   STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
246 }
247
248
249 void
250 sim_io_eprintf(SIM_DESC sd,
251               const char *fmt,
252               ...)
253 {
254   va_list ap;
255   va_start(ap, fmt);
256   STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
257   va_end(ap);
258 }
259
260
261 void
262 sim_io_evprintf(SIM_DESC sd,
263                 const char *fmt,
264                 va_list ap)
265 {
266   STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
267 }
268
269
270 void
271 sim_io_error(SIM_DESC sd,
272              const char *fmt,
273              ...)
274 {
275   if (sd == NULL || STATE_CALLBACK (sd) == NULL) {
276     va_list ap;
277     va_start(ap, fmt);
278     vfprintf (stderr, fmt, ap);
279     va_end(ap);
280     fprintf (stderr, "\n");
281     abort ();
282   }
283   else {
284     va_list ap;
285     va_start(ap, fmt);
286     STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
287     va_end(ap);
288     STATE_CALLBACK (sd)->error (STATE_CALLBACK (sd), "");
289   }
290 }
291
292
293 void
294 sim_io_poll_quit(SIM_DESC sd)
295 {
296   if (STATE_CALLBACK (sd)->poll_quit != NULL)
297     if (STATE_CALLBACK (sd)->poll_quit (STATE_CALLBACK (sd)))
298       sim_stop (sd);
299 }
300
301
302 static char *
303 sim_io_getstring(SIM_DESC sd,
304                  sim_cpu *cpu,
305                  address_word cia,
306                  address_word target_string)
307 {
308   int len = 0;
309   char *buf;
310
311   while (sim_core_read_1 (cpu, cia, sim_core_read_map, target_string+len) != 0)
312     len++;
313
314   buf = NZALLOC (char, len+1);
315   buf[len] = '\0';
316   sim_core_read_buffer (sd, cpu, sim_core_read_map, buf, target_string, len);
317   return buf;
318 }
319
320 void
321 sim_io_syscalls(SIM_DESC sd,
322                 int syscall,
323                 address_word cia,
324                 address_word parm1,
325                 address_word parm2,
326                 address_word parm3,
327                 address_word parm4,
328                 address_word *syscall_return,
329                 address_word *errno_return)
330 {
331   sim_cpu *cpu = STATE_CPU (sd, 0);
332   struct host_callback_struct *callback = STATE_CALLBACK (sd);
333   int len, len2, len3;
334   int ret;
335   char *buf;
336   int fd;
337
338   *errno_return = 0;
339   *syscall_return = 0;
340
341   switch (syscall)
342     {
343     case 1:                     /* exit (status) */
344       sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia, sim_exited, parm1);
345       break;
346
347     case 2:                     /* open (filename, flags, mode) */
348       buf = sim_io_getstring (sd, cpu, cia, parm1);
349       ret = *syscall_return = callback->open (callback, buf, parm2);
350       if (ret < 0)
351         *errno_return = callback->get_errno (callback);
352
353       zfree (buf);
354       break;
355
356     case 3:                     /* close (filedes) */
357       ret = *syscall_return = callback->close (callback, parm1);
358       if (ret < 0)
359         *errno_return = callback->get_errno (callback);
360       break;
361
362     case 4:                     /* read (filedes, buffer, len) */
363       fd = parm1;
364       len = parm3;
365       buf = NZALLOC (char, len);
366
367       if (fd == 0)
368         len2 = sim_io_read_stdin (sd, buf, len);
369       else
370         len2 = sim_io_read (sd, fd, buf, len);
371
372       if (len2 > 0)
373         {
374           len3 = sim_core_write_buffer (sd, cpu, sim_core_write_map, buf, parm2,
375                                         len);
376
377           if (len3 < len2)
378             sim_engine_abort (sd, cpu, cia,
379                               "Could only write back %d bytes for read system call, wanted to write %d\n",
380                               len3, len2);
381
382           *syscall_return = len2;
383         }
384       else
385         *errno_return = callback->get_errno (callback);
386
387       zfree (buf);
388       break;
389
390     case 5:                     /* write (filedes, buffer, len) */
391       fd = parm1;
392       len = parm3;
393       buf = NZALLOC (char, len);
394
395       len = sim_core_read_buffer (sd, cpu, sim_core_read_map, buf, parm2, len);
396       if (fd == 1)
397         {
398           len2 = sim_io_write_stdout (sd, buf, len);
399           sim_io_flush_stdout (sd);
400         }
401       else if (fd == 2)
402         {
403           len2 = sim_io_write_stderr (sd, buf, len);
404           sim_io_flush_stderr (sd);
405         }
406       else
407         len2 = sim_io_write (sd, fd, buf, len);
408
409       if (len2 > 0)
410         *syscall_return = len2;
411       else
412         *errno_return = callback->get_errno (callback);
413
414       zfree (buf);
415       break;
416       
417     case 6:                     /* lseek (filedes, offset, whence) */
418       *errno_return = TARGET_ENOSYS;
419       break;
420
421     case 7:                     /* unlink (filename) */
422       buf = sim_io_getstring (sd, cpu, cia, parm1);
423       ret = *syscall_return = callback->unlink (callback, buf);
424       if (ret < 0)
425         *errno_return = callback->get_errno (callback);
426
427       zfree (buf);
428       break;
429
430     case 8:                     /* getpid () */
431     case 9:                     /* kill (signal, pid) */
432     case 10:                    /* fstat (filedes, packet) */
433     case 11:                    /* reserved for sbrk */
434     case 12:                    /* argvlen () */
435     case 13:                    /* argv () */
436     case 14:                    /* chdir (dir) */
437     case 15:                    /* stat (filename, packet) */
438     case 16:                    /* chmod (filename, mode) */
439     case 17:                    /* utime (filename, packet) */
440     case 18:                    /* time (time_t *) */
441       *errno_return = TARGET_ENOSYS;
442       break;
443
444     default:
445       sim_engine_abort (sd, cpu, cia, "Unknown monitor call %d", syscall);
446       break;
447     }
448
449   if (*errno_return)
450     *syscall_return = -1;
451
452   return;
453 }
454