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