This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / common / callback.c
1 /* Remote target callback routines.
2    Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* This file provides a standard way for targets to talk to the host OS
22    level.  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include "ansidecl.h"
28 #ifdef ANSI_PROTOTYPES
29 #include <stdarg.h>
30 #else
31 #include <varargs.h>
32 #endif
33 #include <stdio.h>
34 #ifdef HAVE_STDLIB_H
35 #include <stdlib.h>
36 #endif
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #else
40 #ifdef HAVE_STRINGS_H
41 #include <strings.h>
42 #endif
43 #endif
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <time.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include "callback.h"
50 #include "targ-vals.h"
51
52 #ifdef HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif
55
56 /* ??? sim_cb_printf should be cb_printf, but until the callback support is
57    broken out of the simulator directory, these are here to not require
58    sim-utils.h.  */
59 void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
60 void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
61
62 extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
63 extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
64 extern CB_TARGET_DEFS_MAP cb_init_open_map[];
65
66 extern int system PARAMS ((const char *));
67
68 static int os_init PARAMS ((host_callback *));
69 static int os_shutdown PARAMS ((host_callback *));
70 static int os_unlink PARAMS ((host_callback *, const char *));
71 static long os_time PARAMS ((host_callback *, long *));
72 static int os_system PARAMS ((host_callback *, const char *));
73 static int os_rename PARAMS ((host_callback *, const char *, const char *));
74 static int os_write_stdout PARAMS ((host_callback *, const char *, int));
75 static void os_flush_stdout PARAMS ((host_callback *));
76 static int os_write_stderr PARAMS ((host_callback *, const char *, int));
77 static void os_flush_stderr PARAMS ((host_callback *));
78 static int os_write PARAMS ((host_callback *, int, const char *, int));
79 static int os_read_stdin PARAMS ((host_callback *, char *, int));
80 static int os_read PARAMS ((host_callback *, int, char *, int));
81 static int os_open PARAMS ((host_callback *, const char *, int));
82 static int os_lseek PARAMS ((host_callback *, int, long, int));
83 static int os_isatty PARAMS ((host_callback *, int));
84 static int os_get_errno PARAMS ((host_callback *));
85 static int os_close PARAMS ((host_callback *, int));
86 static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
87 static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
88 static void os_error PARAMS ((host_callback *, const char *, ...));
89 static int fdmap PARAMS ((host_callback *, int));
90 static int fdbad PARAMS ((host_callback *, int));
91 static int wrap PARAMS ((host_callback *, int));
92
93 /* Set the callback copy of errno from what we see now.  */
94
95 static int 
96 wrap (p, val)
97      host_callback *p;
98      int val;
99 {
100   p->last_errno = errno;
101   return val;
102 }
103
104 /* Make sure the FD provided is ok.  If not, return non-zero
105    and set errno. */
106
107 static int 
108 fdbad (p, fd)
109      host_callback *p;
110      int fd;
111 {
112   if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
113     {
114       p->last_errno = EINVAL;
115       return -1;
116     }
117   return 0;
118 }
119
120 static int 
121 fdmap (p, fd)
122      host_callback *p;
123      int fd;
124 {
125   return p->fdmap[fd];
126 }
127
128 static int 
129 os_close (p, fd)
130      host_callback *p;
131      int fd;
132 {
133   int result;
134
135   result = fdbad (p, fd);
136   if (result)
137     return result;
138   result = wrap (p, close (fdmap (p, fd)));
139   if (result == 0 && !p->alwaysopen[fd])
140     p->fdopen[fd] = 0;
141
142   return result;
143 }
144
145
146 /* taken from gdb/util.c:notice_quit() - should be in a library */
147
148
149 #if defined(__GO32__) || defined (_MSC_VER)
150 static int
151 os_poll_quit (p)
152      host_callback *p;
153 {
154 #if defined(__GO32__)
155   int kbhit ();
156   int getkey ();
157   if (kbhit ())
158     {
159       int k = getkey ();
160       if (k == 1)
161         {
162           return 1;
163         }
164       else if (k == 2)
165         {
166           return 1;
167         }
168       else 
169         {
170           sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
171         }
172     }
173 #endif
174 #if defined (_MSC_VER)
175   /* NB - this will not compile! */
176   int k = win32pollquit();
177   if (k == 1)
178     return 1;
179   else if (k == 2)
180     return 1;
181 #endif
182   return 0;
183 }
184 #else
185 #define os_poll_quit 0
186 #endif /* defined(__GO32__) || defined(_MSC_VER) */
187
188 static int 
189 os_get_errno (p)
190      host_callback *p;
191 {
192   return cb_host_to_target_errno (p, p->last_errno);
193 }
194
195
196 static int 
197 os_isatty (p, fd)
198      host_callback *p;
199      int fd;
200 {
201   int result;
202
203   result = fdbad (p, fd);
204   if (result)
205     return result;
206   result = wrap (p, isatty (fdmap (p, fd)));
207
208   return result;
209 }
210
211 static int 
212 os_lseek (p, fd, off, way)
213      host_callback *p;
214      int fd;
215      long off;
216      int way;
217 {
218   int result;
219
220   result = fdbad (p, fd);
221   if (result)
222     return result;
223   result = lseek (fdmap (p, fd), off, way);
224   return result;
225 }
226
227 static int 
228 os_open (p, name, flags)
229      host_callback *p;
230      const char *name;
231      int flags;
232 {
233   int i;
234   for (i = 0; i < MAX_CALLBACK_FDS; i++)
235     {
236       if (!p->fdopen[i])
237         {
238           int f = open (name, cb_target_to_host_open (p, flags), 0644);
239           if (f < 0)
240             {
241               p->last_errno = errno;
242               return f;
243             }
244           p->fdopen[i] = 1;
245           p->fdmap[i] = f;
246           return i;
247         }
248     }
249   p->last_errno = EMFILE;
250   return -1;
251 }
252
253 static int 
254 os_read (p, fd, buf, len)
255      host_callback *p;
256      int fd;
257      char *buf;
258      int len;
259 {
260   int result;
261
262   result = fdbad (p, fd);
263   if (result)
264     return result;
265   result = wrap (p, read (fdmap (p, fd), buf, len));
266   return result;
267 }
268
269 static int 
270 os_read_stdin (p, buf, len)
271      host_callback *p;
272      char *buf;
273      int len;
274 {
275   return wrap (p, read (0, buf, len));
276 }
277
278 static int 
279 os_write (p, fd, buf, len)
280      host_callback *p;
281      int fd;
282      const char *buf;
283      int len;
284 {
285   int result;
286   int real_fd;
287
288   result = fdbad (p, fd);
289   if (result)
290     return result;
291   real_fd = fdmap (p, fd);
292   switch (real_fd)
293     {
294     default:
295       result = wrap (p, write (real_fd, buf, len));
296       break;
297     case 1:
298       result = p->write_stdout (p, buf, len);
299       break;
300     case 2:
301       result = p->write_stderr (p, buf, len);
302       break;
303     }
304   return result;
305 }
306
307 static int 
308 os_write_stdout (p, buf, len)
309      host_callback *p ATTRIBUTE_UNUSED;
310      const char *buf;
311      int len;
312 {
313   return fwrite (buf, 1, len, stdout);
314 }
315
316 static void
317 os_flush_stdout (p)
318      host_callback *p ATTRIBUTE_UNUSED;
319 {
320   fflush (stdout);
321 }
322
323 static int 
324 os_write_stderr (p, buf, len)
325      host_callback *p ATTRIBUTE_UNUSED;
326      const char *buf;
327      int len;
328 {
329   return fwrite (buf, 1, len, stderr);
330 }
331
332 static void
333 os_flush_stderr (p)
334      host_callback *p ATTRIBUTE_UNUSED;
335 {
336   fflush (stderr);
337 }
338
339 static int 
340 os_rename (p, f1, f2)
341      host_callback *p;
342      const char *f1;
343      const char *f2;
344 {
345   return wrap (p, rename (f1, f2));
346 }
347
348
349 static int
350 os_system (p, s)
351      host_callback *p;
352      const char *s;
353 {
354   return wrap (p, system (s));
355 }
356
357 static long 
358 os_time (p, t)
359      host_callback *p;
360      long *t;
361 {
362   return wrap (p, time (t));
363 }
364
365
366 static int 
367 os_unlink (p, f1)
368      host_callback *p;
369      const char *f1;
370 {
371   return wrap (p, unlink (f1));
372 }
373
374 static int
375 os_stat (p, file, buf)
376      host_callback *p;
377      const char *file;
378      struct stat *buf;
379 {
380   /* ??? There is an issue of when to translate to the target layout.
381      One could do that inside this function, or one could have the
382      caller do it.  It's more flexible to let the caller do it, though
383      I'm not sure the flexibility will ever be useful.  */
384   return wrap (p, stat (file, buf));
385 }
386
387 static int
388 os_fstat (p, fd, buf)
389      host_callback *p;
390      int fd;
391      struct stat *buf;
392 {
393   if (fdbad (p, fd))
394     return -1;
395   /* ??? There is an issue of when to translate to the target layout.
396      One could do that inside this function, or one could have the
397      caller do it.  It's more flexible to let the caller do it, though
398      I'm not sure the flexibility will ever be useful.  */
399   return wrap (p, fstat (fdmap (p, fd), buf));
400 }
401
402 static int
403 os_shutdown (p)
404      host_callback *p;
405 {
406   int i;
407   for (i = 0; i < MAX_CALLBACK_FDS; i++)
408     {
409       if (p->fdopen[i] && !p->alwaysopen[i]) {
410         close (p->fdmap[i]);
411         p->fdopen[i] = 0;
412       }
413     }
414   return 1;
415 }
416
417 static int
418 os_init (p)
419      host_callback *p;
420 {
421   int i;
422
423   os_shutdown (p);
424   for (i = 0; i < 3; i++)
425     {
426       p->fdmap[i] = i;
427       p->fdopen[i] = 1;
428       p->alwaysopen[i] = 1;
429     }
430
431   p->syscall_map = cb_init_syscall_map;
432   p->errno_map = cb_init_errno_map;
433   p->open_map = cb_init_open_map;
434
435   return 1;
436 }
437
438 /* DEPRECIATED */
439
440 /* VARARGS */
441 static void
442 #ifdef ANSI_PROTOTYPES
443 os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
444 #else
445 os_printf_filtered (p, va_alist)
446      host_callback *p;
447      va_dcl
448 #endif
449 {
450   va_list args;
451 #ifdef ANSI_PROTOTYPES
452   va_start (args, format);
453 #else
454   char *format;
455
456   va_start (args);
457   format = va_arg (args, char *);
458 #endif
459
460   vfprintf (stdout, format, args);
461   va_end (args);
462 }
463
464 /* VARARGS */
465 static void
466 #ifdef ANSI_PROTOTYPES
467 os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
468 #else
469 os_vprintf_filtered (p, format, args)
470      host_callback *p;
471      const char *format;
472      va_list args;
473 #endif
474 {
475   vprintf (format, args);
476 }
477
478 /* VARARGS */
479 static void
480 #ifdef ANSI_PROTOTYPES
481 os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
482 #else
483 os_evprintf_filtered (p, format, args)
484      host_callback *p;
485      const char *format;
486      va_list args;
487 #endif
488 {
489   vfprintf (stderr, format, args);
490 }
491
492 /* VARARGS */
493 static void
494 #ifdef ANSI_PROTOTYPES
495 os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
496 #else
497 os_error (p, va_alist)
498      host_callback *p;
499      va_dcl
500 #endif
501 {
502   va_list args;
503 #ifdef ANSI_PROTOTYPES
504   va_start (args, format);
505 #else
506   char *format;
507
508   va_start (args);
509   format = va_arg (args, char *);
510 #endif
511
512   vfprintf (stderr, format, args);
513   fprintf (stderr, "\n");
514
515   va_end (args);
516   exit (1);
517 }
518
519 host_callback default_callback =
520 {
521   os_close,
522   os_get_errno,
523   os_isatty,
524   os_lseek,
525   os_open,
526   os_read,
527   os_read_stdin,
528   os_rename,
529   os_system,
530   os_time,
531   os_unlink,
532   os_write,
533   os_write_stdout,
534   os_flush_stdout,
535   os_write_stderr,
536   os_flush_stderr,
537
538   os_stat,
539   os_fstat,
540
541   os_poll_quit,
542
543   os_shutdown,
544   os_init,
545
546   os_printf_filtered,  /* deprecated */
547
548   os_vprintf_filtered,
549   os_evprintf_filtered,
550   os_error,
551
552   0,            /* last errno */
553
554   { 0, },       /* fdmap */
555   { 0, },       /* fdopen */
556   { 0, },       /* alwaysopen */
557
558   0, /* syscall_map */
559   0, /* errno_map */
560   0, /* open_map */
561   0, /* signal_map */
562   0, /* stat_map */
563         
564   HOST_CALLBACK_MAGIC,
565 };
566 \f
567 /* Read in a file describing the target's system call values.
568    E.g. maybe someone will want to use something other than newlib.
569    This assumes that the basic system call recognition and value passing/
570    returning is supported.  So maybe some coding/recompilation will be
571    necessary, but not as much.
572
573    If an error occurs, the existing mapping is not changed.  */
574
575 CB_RC
576 cb_read_target_syscall_maps (cb, file)
577      host_callback *cb;
578      const char *file;
579 {
580   CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
581   const char *stat_map;
582   FILE *f;
583
584   if ((f = fopen (file, "r")) == NULL)
585     return CB_RC_ACCESS;
586
587   /* ... read in and parse file ... */
588
589   fclose (f);
590   return CB_RC_NO_MEM; /* FIXME:wip */
591
592   /* Free storage allocated for any existing maps.  */
593   if (cb->syscall_map)
594     free (cb->syscall_map);
595   if (cb->errno_map)
596     free (cb->errno_map);
597   if (cb->open_map)
598     free (cb->open_map);
599   if (cb->signal_map)
600     free (cb->signal_map);
601   if (cb->stat_map)
602     free ((PTR) cb->stat_map);
603
604   cb->syscall_map = syscall_map;
605   cb->errno_map = errno_map;
606   cb->open_map = open_map;
607   cb->signal_map = signal_map;
608   cb->stat_map = stat_map;
609
610   return CB_RC_OK;
611 }
612
613 /* Translate the target's version of a syscall number to the host's.
614    This isn't actually the host's version, rather a canonical form.
615    ??? Perhaps this should be renamed to ..._canon_syscall.  */
616
617 int
618 cb_target_to_host_syscall (cb, target_val)
619      host_callback *cb;
620      int target_val;
621 {
622   CB_TARGET_DEFS_MAP *m;
623
624   for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
625     if (m->target_val == target_val)
626       return m->host_val;
627
628   return -1;
629 }
630
631 /* FIXME: sort tables if large.
632    Alternatively, an obvious improvement for errno conversion is
633    to machine generate a function with a large switch().  */
634
635 /* Translate the host's version of errno to the target's.  */
636
637 int
638 cb_host_to_target_errno (cb, host_val)
639      host_callback *cb;
640      int host_val;
641 {
642   CB_TARGET_DEFS_MAP *m;
643
644   for (m = &cb->errno_map[0]; m->host_val; ++m)
645     if (m->host_val == host_val)
646       return m->target_val;
647
648   /* ??? Which error to return in this case is up for grabs.
649      Note that some missing values may have standard alternatives.
650      For now return 0 and require caller to deal with it.  */
651   return 0;
652 }
653
654 /* Given a set of target bitmasks for the open system call,
655    return the host equivalent.
656    Mapping open flag values is best done by looping so there's no need
657    to machine generate this function.  */
658
659 int
660 cb_target_to_host_open (cb, target_val)
661      host_callback *cb;
662      int target_val;
663 {
664   int host_val = 0;
665   CB_TARGET_DEFS_MAP *m;
666
667   for (m = &cb->open_map[0]; m->host_val != -1; ++m)
668     {
669       switch (m->target_val)
670         {
671           /* O_RDONLY can be (and usually is) 0 which needs to be treated
672              specially.  */
673         case TARGET_O_RDONLY :
674         case TARGET_O_WRONLY :
675         case TARGET_O_RDWR :
676           if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
677               == m->target_val)
678             host_val |= m->host_val;
679           /* Handle the host/target differentiating between binary and
680              text mode.  Only one case is of importance */
681 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
682           host_val |= O_BINARY;
683 #endif
684           break;
685         default :
686           if ((m->target_val & target_val) == m->target_val)
687             host_val |= m->host_val;
688           break;
689         }
690     }
691
692   return host_val;
693 }
694
695 /* Utility for cb_host_to_target_stat to store values in the target's
696    stat struct.  */
697
698 static void
699 store (p, size, val, big_p)
700      char *p;
701      int size;
702      long val; /* ??? must be as big as target word size */
703      int big_p;
704 {
705   if (big_p)
706     {
707       p += size;
708       while (size-- > 0)
709         {
710           *--p = val;
711           val >>= 8;
712         }
713     }
714   else
715     {
716       while (size-- > 0)
717         {
718           *p++ = val;
719           val >>= 8;
720         }
721     }
722 }
723
724 /* Translate a host's stat struct into a target's.
725    If HS is NULL, just compute the length of the buffer required,
726    TS is ignored.
727
728    The result is the size of the target's stat struct,
729    or zero if an error occured during the translation.  */
730
731 int
732 cb_host_to_target_stat (cb, hs, ts)
733      host_callback *cb;
734      const struct stat *hs;
735      PTR ts;
736 {
737   const char *m = cb->stat_map;
738   char *p;
739   int big_p = 0;
740
741   if (hs == NULL)
742     ts = NULL;
743   p = ts;
744
745   while (m)
746     {
747       char *q = strchr (m, ',');
748       int size;
749
750       /* FIXME: Use sscanf? */
751       if (q == NULL)
752         {
753           /* FIXME: print error message */
754           return 0;
755         }
756       size = atoi (q + 1);
757       if (size == 0)
758         {
759           /* FIXME: print error message */
760           return 0;
761         }
762
763       if (hs != NULL)
764         {
765           if (strncmp (m, "st_dev", q - m) == 0)
766             store (p, size, hs->st_dev, big_p);
767           else if (strncmp (m, "st_ino", q - m) == 0)
768             store (p, size, hs->st_ino, big_p);
769           /* FIXME:wip */
770           else
771             store (p, size, 0, big_p); /* unsupported field, store 0 */
772         }
773
774       p += size;
775       m = strchr (q, ':');
776       if (m)
777         ++m;
778     }
779
780   return p - (char *) ts;
781 }
782 \f
783 /* Cover functions to the vfprintf callbacks.
784
785    ??? If one thinks of the callbacks as a subsystem onto itself [or part of
786    a larger "remote target subsystem"] with a well defined interface, then
787    one would think that the subsystem would provide these.  However, until
788    one is allowed to create such a subsystem (with its own source tree
789    independent of any particular user), such a critter can't exist.  Thus
790    these functions are here for the time being.  */
791
792 void
793 sim_cb_printf (host_callback *p, const char *fmt, ...)
794 {
795   va_list ap;
796
797   va_start (ap, fmt);
798   p->vprintf_filtered (p, fmt, ap);
799   va_end (ap);
800 }
801
802 void
803 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
804 {
805   va_list ap;
806
807   va_start (ap, fmt);
808   p->evprintf_filtered (p, fmt, ap);
809   va_end (ap);
810 }