* Make-common.in (DEP, COMMON_DEP_CFLAGS): Define.
[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 This allows simulators, etc. to support arbitrary libraries
575 without having to be recompiled.
576 E.g. maybe someone will want to use something other than newlib.
577
578 If an error occurs, the existing mapping is not changed. */
579
580 CB_RC
581 cb_read_target_syscall_maps (cb, file)
582 host_callback *cb;
583 const char *file;
584 {
585 CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
586 const char *stat_map;
587 FILE *f;
588
589 if ((f = fopen (file, "r")) == NULL)
590 return CB_RC_ACCESS;
591
592 /* ... read in and parse file ... */
593
594 fclose (f);
595 return CB_RC_NO_MEM; /* FIXME:wip */
596
597 /* Free storage allocated for any existing maps. */
598 if (cb->syscall_map)
599 free (cb->syscall_map);
600 if (cb->errno_map)
601 free (cb->errno_map);
602 if (cb->open_map)
603 free (cb->open_map);
604 if (cb->signal_map)
605 free (cb->signal_map);
606 if (cb->stat_map)
607 free ((PTR) cb->stat_map);
608
609 cb->syscall_map = syscall_map;
610 cb->errno_map = errno_map;
611 cb->open_map = open_map;
612 cb->signal_map = signal_map;
613 cb->stat_map = stat_map;
614
615 return CB_RC_OK;
616 }
617
618 /* Translate the target's version of a syscall number to the host's.
619 This isn't actually the host's version, rather a canonical form.
620 ??? Perhaps this should be renamed to ..._canon_syscall. */
621
622 int
623 cb_target_to_host_syscall (cb, target_val)
624 host_callback *cb;
625 int target_val;
626 {
627 CB_TARGET_DEFS_MAP *m;
628
629 for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
630 if (m->target_val == target_val)
631 return m->host_val;
632
633 return -1;
634 }
635
636 /* FIXME: sort tables if large.
637 Alternatively, an obvious improvement for errno conversion is
638 to machine generate a function with a large switch(). */
639
640 /* Translate the host's version of errno to the target's. */
641
642 int
643 cb_host_to_target_errno (cb, host_val)
644 host_callback *cb;
645 int host_val;
646 {
647 CB_TARGET_DEFS_MAP *m;
648
649 for (m = &cb->errno_map[0]; m->host_val; ++m)
650 if (m->host_val == host_val)
651 return m->target_val;
652
653 /* ??? Which error to return in this case is up for grabs.
654 Note that some missing values may have standard alternatives.
655 For now return 0 and require caller to deal with it. */
656 return 0;
657 }
658
659 /* Given a set of target bitmasks for the open system call,
660 return the host equivalent.
661 Mapping open flag values is best done by looping so there's no need
662 to machine generate this function. */
663
664 int
665 cb_target_to_host_open (cb, target_val)
666 host_callback *cb;
667 int target_val;
668 {
669 int host_val = 0;
670 CB_TARGET_DEFS_MAP *m;
671
672 for (m = &cb->open_map[0]; m->host_val != -1; ++m)
673 {
674 switch (m->target_val)
675 {
676 /* O_RDONLY can be (and usually is) 0 which needs to be treated
677 specially. */
678 case TARGET_O_RDONLY :
679 case TARGET_O_WRONLY :
680 case TARGET_O_RDWR :
681 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
682 == m->target_val)
683 host_val |= m->host_val;
684 /* Handle the host/target differentiating between binary and
685 text mode. Only one case is of importance */
686 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
687 host_val |= O_BINARY;
688 #endif
689 break;
690 default :
691 if ((m->target_val & target_val) == m->target_val)
692 host_val |= m->host_val;
693 break;
694 }
695 }
696
697 return host_val;
698 }
699
700 /* Utility for cb_host_to_target_stat to store values in the target's
701 stat struct. */
702
703 static void
704 store (p, size, val, big_p)
705 char *p;
706 int size;
707 long val; /* ??? must be as big as target word size */
708 int big_p;
709 {
710 if (big_p)
711 {
712 p += size;
713 while (size-- > 0)
714 {
715 *--p = val;
716 val >>= 8;
717 }
718 }
719 else
720 {
721 while (size-- > 0)
722 {
723 *p++ = val;
724 val >>= 8;
725 }
726 }
727 }
728
729 /* Translate a host's stat struct into a target's.
730
731 BIG_P is non-zero if the target is big-endian.
732 The result is the size of the target's stat struct. */
733
734 int
735 cb_host_to_target_stat (cb, hs, ts, big_p)
736 host_callback *cb;
737 const struct stat *hs;
738 PTR ts;
739 int big_p;
740 {
741 const char *m = cb->stat_map;
742 char *p = ts;
743
744 while (m)
745 {
746 char *q = strchr (m, ',');
747 int size;
748
749 /* FIXME: Use sscanf? */
750 if (q == NULL)
751 {
752 /* FIXME: print error message */
753 return;
754 }
755 size = atoi (q + 1);
756 if (size == 0)
757 {
758 /* FIXME: print error message */
759 return;
760 }
761
762 if (strncmp (m, "st_dev", q - m) == 0)
763 store (p, size, hs->st_dev, big_p);
764 else if (strncmp (m, "st_ino", q - m) == 0)
765 store (p, size, hs->st_ino, big_p);
766 /* FIXME:wip */
767 else
768 store (p, size, 0, big_p); /* unsupported field, store 0 */
769
770 p += size;
771 m = strchr (q, ':');
772 if (m)
773 ++m;
774 }
775 }
776 \f
777 /* Cover functions to the vfprintf callbacks.
778
779 ??? If one thinks of the callbacks as a subsystem onto itself [or part of
780 a larger "remote target subsystem"] with a well defined interface, then
781 one would think that the subsystem would provide these. However, until
782 one is allowed to create such a subsystem (with its own source tree
783 independent of any particular user), such a critter can't exist. Thus
784 these functions are here for the time being. */
785
786 void
787 sim_cb_printf (host_callback *p, const char *fmt, ...)
788 {
789 va_list ap;
790
791 va_start (ap, fmt);
792 p->vprintf_filtered (p, fmt, ap);
793 va_end (ap);
794 }
795
796 void
797 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
798 {
799 va_list ap;
800
801 va_start (ap, fmt);
802 p->evprintf_filtered (p, fmt, ap);
803 va_end (ap);
804 }
This page took 0.044954 seconds and 5 git commands to generate.