xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/callback.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /* Remote target callback routines.
2    Copyright 1995-2014 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 3 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 /* This file provides a standard way for targets to talk to the host OS
21    level.  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "cconfig.h"
25 #endif
26 #include "config.h"
27 #include "ansidecl.h"
28 #include <stdarg.h>
29 #include <stdio.h>
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif
33 #ifdef HAVE_STRING_H
34 #include <string.h>
35 #else
36 #ifdef HAVE_STRINGS_H
37 #include <strings.h>
38 #endif
39 #endif
40 #ifdef HAVE_LIMITS_H
41 /* For PIPE_BUF.  */
42 #include <limits.h>
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 "gdb/callback.h"
50 #include "targ-vals.h"
51 /* For xmalloc.  */
52 #include "libiberty.h"
53 
54 #ifdef HAVE_UNISTD_H
55 #include <unistd.h>
56 #endif
57 
58 #ifndef PIPE_BUF
59 #define PIPE_BUF 512
60 #endif
61 
62 /* ??? sim_cb_printf should be cb_printf, but until the callback support is
63    broken out of the simulator directory, these are here to not require
64    sim-utils.h.  */
65 void sim_cb_printf (host_callback *, const char *, ...);
66 void sim_cb_eprintf (host_callback *, const char *, ...);
67 
68 extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
69 extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
70 extern CB_TARGET_DEFS_MAP cb_init_open_map[];
71 
72 extern int system (const char *);
73 
74 static int os_init (host_callback *);
75 static int os_shutdown (host_callback *);
76 static int os_unlink (host_callback *, const char *);
77 static long os_time (host_callback *, long *);
78 static int os_system (host_callback *, const char *);
79 static int os_rename (host_callback *, const char *, const char *);
80 static int os_write_stdout (host_callback *, const char *, int);
81 static void os_flush_stdout (host_callback *);
82 static int os_write_stderr (host_callback *, const char *, int);
83 static void os_flush_stderr (host_callback *);
84 static int os_write (host_callback *, int, const char *, int);
85 static int os_read_stdin (host_callback *, char *, int);
86 static int os_read (host_callback *, int, char *, int);
87 static int os_open (host_callback *, const char *, int);
88 static int os_lseek (host_callback *, int, long, int);
89 static int os_isatty (host_callback *, int);
90 static int os_get_errno (host_callback *);
91 static int os_close (host_callback *, int);
92 static void os_vprintf_filtered (host_callback *, const char *, va_list);
93 static void os_evprintf_filtered (host_callback *, const char *, va_list);
94 static void os_error (host_callback *, const char *, ...)
95 #ifdef __GNUC__
96   __attribute__ ((__noreturn__))
97 #endif
98   ;
99 static int fdmap (host_callback *, int);
100 static int fdbad (host_callback *, int);
101 static int wrap (host_callback *, int);
102 
103 /* Set the callback copy of errno from what we see now.  */
104 
105 static int
106 wrap (p, val)
107      host_callback *p;
108      int val;
109 {
110   p->last_errno = errno;
111   return val;
112 }
113 
114 /* Make sure the FD provided is ok.  If not, return non-zero
115    and set errno. */
116 
117 static int
118 fdbad (p, fd)
119      host_callback *p;
120      int fd;
121 {
122   if (fd < 0 || fd > MAX_CALLBACK_FDS || p->fd_buddy[fd] < 0)
123     {
124       p->last_errno = EBADF;
125       return -1;
126     }
127   return 0;
128 }
129 
130 static int
131 fdmap (p, fd)
132      host_callback *p;
133      int fd;
134 {
135   return p->fdmap[fd];
136 }
137 
138 static int
139 os_close (p, fd)
140      host_callback *p;
141      int fd;
142 {
143   int result;
144   int i, next;
145 
146   result = fdbad (p, fd);
147   if (result)
148     return result;
149   /* If this file descripter has one or more buddies (originals /
150      duplicates from a dup), just remove it from the circular list.  */
151   for (i = fd; (next = p->fd_buddy[i]) != fd; )
152     i = next;
153   if (fd != i)
154     p->fd_buddy[i] = p->fd_buddy[fd];
155   else
156     {
157       if (p->ispipe[fd])
158 	{
159 	  int other = p->ispipe[fd];
160 	  int reader, writer;
161 
162 	  if (other > 0)
163 	    {
164 	      /* Closing the read side.  */
165 	      reader = fd;
166 	      writer = other;
167 	    }
168 	  else
169 	    {
170 	      /* Closing the write side.  */
171 	      writer = fd;
172 	      reader = -other;
173 	    }
174 
175 	  /* If there was data in the buffer, make a last "now empty"
176 	     call, then deallocate data.  */
177 	  if (p->pipe_buffer[writer].buffer != NULL)
178 	    {
179 	      (*p->pipe_empty) (p, reader, writer);
180 	      free (p->pipe_buffer[writer].buffer);
181 	      p->pipe_buffer[writer].buffer = NULL;
182 	    }
183 
184 	  /* Clear pipe data for this side.  */
185 	  p->pipe_buffer[fd].size = 0;
186 	  p->ispipe[fd] = 0;
187 
188 	  /* If this was the first close, mark the other side as the
189 	     only remaining side.  */
190 	  if (fd != abs (other))
191 	    p->ispipe[abs (other)] = -other;
192 	  p->fd_buddy[fd] = -1;
193 	  return 0;
194 	}
195 
196       result = wrap (p, close (fdmap (p, fd)));
197     }
198   p->fd_buddy[fd] = -1;
199 
200   return result;
201 }
202 
203 
204 /* taken from gdb/util.c:notice_quit() - should be in a library */
205 
206 
207 #if defined(__GO32__) || defined (_MSC_VER)
208 static int
209 os_poll_quit (p)
210      host_callback *p;
211 {
212 #if defined(__GO32__)
213   int kbhit ();
214   int getkey ();
215   if (kbhit ())
216     {
217       int k = getkey ();
218       if (k == 1)
219 	{
220 	  return 1;
221 	}
222       else if (k == 2)
223 	{
224 	  return 1;
225 	}
226       else
227 	{
228 	  sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
229 	}
230     }
231 #endif
232 #if defined (_MSC_VER)
233   /* NB - this will not compile! */
234   int k = win32pollquit ();
235   if (k == 1)
236     return 1;
237   else if (k == 2)
238     return 1;
239 #endif
240   return 0;
241 }
242 #else
243 #define os_poll_quit 0
244 #endif /* defined(__GO32__) || defined(_MSC_VER) */
245 
246 static int
247 os_get_errno (p)
248      host_callback *p;
249 {
250   return cb_host_to_target_errno (p, p->last_errno);
251 }
252 
253 
254 static int
255 os_isatty (p, fd)
256      host_callback *p;
257      int fd;
258 {
259   int result;
260 
261   result = fdbad (p, fd);
262   if (result)
263     return result;
264   result = wrap (p, isatty (fdmap (p, fd)));
265 
266   return result;
267 }
268 
269 static int
270 os_lseek (p, fd, off, way)
271      host_callback *p;
272      int fd;
273      long off;
274      int way;
275 {
276   int result;
277 
278   result = fdbad (p, fd);
279   if (result)
280     return result;
281   result = wrap (p, lseek (fdmap (p, fd), off, way));
282   return result;
283 }
284 
285 static int
286 os_open (p, name, flags)
287      host_callback *p;
288      const char *name;
289      int flags;
290 {
291   int i;
292   for (i = 0; i < MAX_CALLBACK_FDS; i++)
293     {
294       if (p->fd_buddy[i] < 0)
295 	{
296 	  int f = open (name, cb_target_to_host_open (p, flags), 0644);
297 	  if (f < 0)
298 	    {
299 	      p->last_errno = errno;
300 	      return f;
301 	    }
302 	  p->fd_buddy[i] = i;
303 	  p->fdmap[i] = f;
304 	  return i;
305 	}
306     }
307   p->last_errno = EMFILE;
308   return -1;
309 }
310 
311 static int
312 os_read (p, fd, buf, len)
313      host_callback *p;
314      int fd;
315      char *buf;
316      int len;
317 {
318   int result;
319 
320   result = fdbad (p, fd);
321   if (result)
322     return result;
323   if (p->ispipe[fd])
324     {
325       int writer = p->ispipe[fd];
326 
327       /* Can't read from the write-end.  */
328       if (writer < 0)
329 	{
330 	  p->last_errno = EBADF;
331 	  return -1;
332 	}
333 
334       /* Nothing to read if nothing is written.  */
335       if (p->pipe_buffer[writer].size == 0)
336 	return 0;
337 
338       /* Truncate read request size to buffer size minus what's already
339          read.  */
340       if (len > p->pipe_buffer[writer].size - p->pipe_buffer[fd].size)
341 	len = p->pipe_buffer[writer].size - p->pipe_buffer[fd].size;
342 
343       memcpy (buf, p->pipe_buffer[writer].buffer + p->pipe_buffer[fd].size,
344 	      len);
345 
346       /* Account for what we just read.  */
347       p->pipe_buffer[fd].size += len;
348 
349       /* If we've read everything, empty and deallocate the buffer and
350 	 signal buffer-empty to client.  (This isn't expected to be a
351 	 hot path in the simulator, so we don't hold on to the buffer.)  */
352       if (p->pipe_buffer[fd].size == p->pipe_buffer[writer].size)
353 	{
354 	  free (p->pipe_buffer[writer].buffer);
355 	  p->pipe_buffer[writer].buffer = NULL;
356 	  p->pipe_buffer[fd].size = 0;
357 	  p->pipe_buffer[writer].size = 0;
358 	  (*p->pipe_empty) (p, fd, writer);
359 	}
360 
361       return len;
362     }
363 
364   result = wrap (p, read (fdmap (p, fd), buf, len));
365   return result;
366 }
367 
368 static int
369 os_read_stdin (p, buf, len)
370      host_callback *p;
371      char *buf;
372      int len;
373 {
374   return wrap (p, read (0, buf, len));
375 }
376 
377 static int
378 os_write (p, fd, buf, len)
379      host_callback *p;
380      int fd;
381      const char *buf;
382      int len;
383 {
384   int result;
385   int real_fd;
386 
387   result = fdbad (p, fd);
388   if (result)
389     return result;
390 
391   if (p->ispipe[fd])
392     {
393       int reader = -p->ispipe[fd];
394 
395       /* Can't write to the read-end.  */
396       if (reader < 0)
397 	{
398 	  p->last_errno = EBADF;
399 	  return -1;
400 	}
401 
402       /* Can't write to pipe with closed read end.
403 	 FIXME: We should send a SIGPIPE.  */
404       if (reader == fd)
405 	{
406 	  p->last_errno = EPIPE;
407 	  return -1;
408 	}
409 
410       /* As a sanity-check, we bail out it the buffered contents is much
411 	 larger than the size of the buffer on the host.  We don't want
412 	 to run out of memory in the simulator due to a target program
413 	 bug if we can help it.  Unfortunately, regarding the value that
414 	 reaches the simulated program, it's no use returning *less*
415 	 than the requested amount, because cb_syscall loops calling
416 	 this function until the whole amount is done.  */
417       if (p->pipe_buffer[fd].size + len > 10 * PIPE_BUF)
418 	{
419 	  p->last_errno = EFBIG;
420 	  return -1;
421 	}
422 
423       p->pipe_buffer[fd].buffer
424 	= xrealloc (p->pipe_buffer[fd].buffer, p->pipe_buffer[fd].size + len);
425       memcpy (p->pipe_buffer[fd].buffer + p->pipe_buffer[fd].size,
426 	      buf, len);
427       p->pipe_buffer[fd].size += len;
428 
429       (*p->pipe_nonempty) (p, reader, fd);
430       return len;
431     }
432 
433   real_fd = fdmap (p, fd);
434   switch (real_fd)
435     {
436     default:
437       result = wrap (p, write (real_fd, buf, len));
438       break;
439     case 1:
440       result = p->write_stdout (p, buf, len);
441       break;
442     case 2:
443       result = p->write_stderr (p, buf, len);
444       break;
445     }
446   return result;
447 }
448 
449 static int
450 os_write_stdout (p, buf, len)
451      host_callback *p ATTRIBUTE_UNUSED;
452      const char *buf;
453      int len;
454 {
455   return fwrite (buf, 1, len, stdout);
456 }
457 
458 static void
459 os_flush_stdout (p)
460      host_callback *p ATTRIBUTE_UNUSED;
461 {
462   fflush (stdout);
463 }
464 
465 static int
466 os_write_stderr (p, buf, len)
467      host_callback *p ATTRIBUTE_UNUSED;
468      const char *buf;
469      int len;
470 {
471   return fwrite (buf, 1, len, stderr);
472 }
473 
474 static void
475 os_flush_stderr (p)
476      host_callback *p ATTRIBUTE_UNUSED;
477 {
478   fflush (stderr);
479 }
480 
481 static int
482 os_rename (p, f1, f2)
483      host_callback *p;
484      const char *f1;
485      const char *f2;
486 {
487   return wrap (p, rename (f1, f2));
488 }
489 
490 
491 static int
492 os_system (p, s)
493      host_callback *p;
494      const char *s;
495 {
496   return wrap (p, system (s));
497 }
498 
499 static long
500 os_time (p, t)
501      host_callback *p;
502      long *t;
503 {
504   long v = (long)time(NULL);
505 
506   if (t != NULL)
507     *t = v;
508   return wrap (p, v);
509 }
510 
511 
512 static int
513 os_unlink (p, f1)
514      host_callback *p;
515      const char *f1;
516 {
517   return wrap (p, unlink (f1));
518 }
519 
520 static int
521 os_stat (p, file, buf)
522      host_callback *p;
523      const char *file;
524      struct stat *buf;
525 {
526   /* ??? There is an issue of when to translate to the target layout.
527      One could do that inside this function, or one could have the
528      caller do it.  It's more flexible to let the caller do it, though
529      I'm not sure the flexibility will ever be useful.  */
530   return wrap (p, stat (file, buf));
531 }
532 
533 static int
534 os_fstat (p, fd, buf)
535      host_callback *p;
536      int fd;
537      struct stat *buf;
538 {
539   if (fdbad (p, fd))
540     return -1;
541 
542   if (p->ispipe[fd])
543     {
544 #if defined (HAVE_STRUCT_STAT_ST_ATIME) || defined (HAVE_STRUCT_STAT_ST_CTIME) || defined (HAVE_STRUCT_STAT_ST_MTIME)
545       time_t t = (*p->time) (p, NULL);
546 #endif
547 
548       /* We have to fake the struct stat contents, since the pipe is
549 	 made up in the simulator.  */
550       memset (buf, 0, sizeof (*buf));
551 
552 #ifdef HAVE_STRUCT_STAT_ST_MODE
553       buf->st_mode = S_IFIFO;
554 #endif
555 
556       /* If more accurate tracking than current-time is needed (for
557 	 example, on GNU/Linux we get accurate numbers), the p->time
558 	 callback (which may be something other than os_time) should
559 	 happen for each read and write, and we'd need to keep track of
560 	 atime, ctime and mtime.  */
561 #ifdef HAVE_STRUCT_STAT_ST_ATIME
562       buf->st_atime = t;
563 #endif
564 #ifdef HAVE_STRUCT_STAT_ST_CTIME
565       buf->st_ctime = t;
566 #endif
567 #ifdef HAVE_STRUCT_STAT_ST_MTIME
568       buf->st_mtime = t;
569 #endif
570       return 0;
571     }
572 
573   /* ??? There is an issue of when to translate to the target layout.
574      One could do that inside this function, or one could have the
575      caller do it.  It's more flexible to let the caller do it, though
576      I'm not sure the flexibility will ever be useful.  */
577   return wrap (p, fstat (fdmap (p, fd), buf));
578 }
579 
580 static int
581 os_lstat (p, file, buf)
582      host_callback *p;
583      const char *file;
584      struct stat *buf;
585 {
586   /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat.  */
587 #ifdef HAVE_LSTAT
588   return wrap (p, lstat (file, buf));
589 #else
590   return wrap (p, stat (file, buf));
591 #endif
592 }
593 
594 static int
595 os_ftruncate (p, fd, len)
596      host_callback *p;
597      int fd;
598      long len;
599 {
600   int result;
601 
602   result = fdbad (p, fd);
603   if (p->ispipe[fd])
604     {
605       p->last_errno = EINVAL;
606       return -1;
607     }
608   if (result)
609     return result;
610 #ifdef HAVE_FTRUNCATE
611   result = wrap (p, ftruncate (fdmap (p, fd), len));
612 #else
613   p->last_errno = EINVAL;
614   result = -1;
615 #endif
616   return result;
617 }
618 
619 static int
620 os_truncate (p, file, len)
621      host_callback *p;
622      const char *file;
623      long len;
624 {
625 #ifdef HAVE_TRUNCATE
626   return wrap (p, truncate (file, len));
627 #else
628   p->last_errno = EINVAL;
629   return -1;
630 #endif
631 }
632 
633 static int
634 os_pipe (p, filedes)
635      host_callback *p;
636      int *filedes;
637 {
638   int i;
639 
640   /* We deliberately don't use fd 0.  It's probably stdin anyway.  */
641   for (i = 1; i < MAX_CALLBACK_FDS; i++)
642     {
643       int j;
644 
645       if (p->fd_buddy[i] < 0)
646 	for (j = i + 1; j < MAX_CALLBACK_FDS; j++)
647 	  if (p->fd_buddy[j] < 0)
648 	    {
649 	      /* Found two free fd:s.  Set stat to allocated and mark
650 		 pipeness.  */
651 	      p->fd_buddy[i] = i;
652 	      p->fd_buddy[j] = j;
653 	      p->ispipe[i] = j;
654 	      p->ispipe[j] = -i;
655 	      filedes[0] = i;
656 	      filedes[1] = j;
657 
658 	      /* Poison the FD map to make bugs apparent.  */
659 	      p->fdmap[i] = -1;
660 	      p->fdmap[j] = -1;
661 	      return 0;
662 	    }
663     }
664 
665   p->last_errno = EMFILE;
666   return -1;
667 }
668 
669 /* Stub functions for pipe support.  They should always be overridden in
670    targets using the pipe support, but that's up to the target.  */
671 
672 /* Called when the simulator says that the pipe at (reader, writer) is
673    now empty (so the writer should leave its waiting state).  */
674 
675 static void
676 os_pipe_empty (p, reader, writer)
677      host_callback *p;
678      int reader;
679      int writer;
680 {
681 }
682 
683 /* Called when the simulator says the pipe at (reader, writer) is now
684    non-empty (so the writer should wait).  */
685 
686 static void
687 os_pipe_nonempty (p, reader, writer)
688      host_callback *p;
689      int reader;
690      int writer;
691 {
692 }
693 
694 static int
695 os_shutdown (p)
696      host_callback *p;
697 {
698   int i, next, j;
699   for (i = 0; i < MAX_CALLBACK_FDS; i++)
700     {
701       int do_close = 1;
702 
703       /* Zero out all pipe state.  Don't call callbacks for non-empty
704 	 pipes; the target program has likely terminated at this point
705 	 or we're called at initialization time.  */
706       p->ispipe[i] = 0;
707       p->pipe_buffer[i].size = 0;
708       p->pipe_buffer[i].buffer = NULL;
709 
710       next = p->fd_buddy[i];
711       if (next < 0)
712 	continue;
713       do
714 	{
715 	  j = next;
716 	  if (j == MAX_CALLBACK_FDS)
717 	    do_close = 0;
718 	  next = p->fd_buddy[j];
719 	  p->fd_buddy[j] = -1;
720 	  /* At the initial call of os_init, we got -1, 0, 0, 0, ...  */
721 	  if (next < 0)
722 	    {
723 	      p->fd_buddy[i] = -1;
724 	      do_close = 0;
725 	      break;
726 	    }
727 	}
728       while (j != i);
729       if (do_close)
730 	close (p->fdmap[i]);
731     }
732   return 1;
733 }
734 
735 static int
736 os_init (p)
737      host_callback *p;
738 {
739   int i;
740 
741   os_shutdown (p);
742   for (i = 0; i < 3; i++)
743     {
744       p->fdmap[i] = i;
745       p->fd_buddy[i] = i - 1;
746     }
747   p->fd_buddy[0] = MAX_CALLBACK_FDS;
748   p->fd_buddy[MAX_CALLBACK_FDS] = 2;
749 
750   p->syscall_map = cb_init_syscall_map;
751   p->errno_map = cb_init_errno_map;
752   p->open_map = cb_init_open_map;
753 
754   return 1;
755 }
756 
757 /* DEPRECATED */
758 
759 /* VARARGS */
760 static void
761 os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
762 {
763   va_list args;
764   va_start (args, format);
765 
766   vfprintf (stdout, format, args);
767   va_end (args);
768 }
769 
770 /* VARARGS */
771 static void
772 os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
773 {
774   vprintf (format, args);
775 }
776 
777 /* VARARGS */
778 static void
779 os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
780 {
781   vfprintf (stderr, format, args);
782 }
783 
784 /* VARARGS */
785 static void
786 os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
787 {
788   va_list args;
789   va_start (args, format);
790 
791   vfprintf (stderr, format, args);
792   fprintf (stderr, "\n");
793 
794   va_end (args);
795   exit (1);
796 }
797 
798 host_callback default_callback =
799 {
800   os_close,
801   os_get_errno,
802   os_isatty,
803   os_lseek,
804   os_open,
805   os_read,
806   os_read_stdin,
807   os_rename,
808   os_system,
809   os_time,
810   os_unlink,
811   os_write,
812   os_write_stdout,
813   os_flush_stdout,
814   os_write_stderr,
815   os_flush_stderr,
816 
817   os_stat,
818   os_fstat,
819   os_lstat,
820 
821   os_ftruncate,
822   os_truncate,
823 
824   os_pipe,
825   os_pipe_empty,
826   os_pipe_nonempty,
827 
828   os_poll_quit,
829 
830   os_shutdown,
831   os_init,
832 
833   os_printf_filtered,  /* deprecated */
834 
835   os_vprintf_filtered,
836   os_evprintf_filtered,
837   os_error,
838 
839   0, 		/* last errno */
840 
841   { 0, },	/* fdmap */
842   { -1, },	/* fd_buddy */
843   { 0, },	/* ispipe */
844   { { 0, 0 }, }, /* pipe_buffer */
845 
846   0, /* syscall_map */
847   0, /* errno_map */
848   0, /* open_map */
849   0, /* signal_map */
850   0, /* stat_map */
851 
852   /* Defaults expected to be overridden at initialization, where needed.  */
853   BFD_ENDIAN_UNKNOWN, /* target_endian */
854   4, /* target_sizeof_int */
855 
856   HOST_CALLBACK_MAGIC,
857 };
858 
859 /* Read in a file describing the target's system call values.
860    E.g. maybe someone will want to use something other than newlib.
861    This assumes that the basic system call recognition and value passing/
862    returning is supported.  So maybe some coding/recompilation will be
863    necessary, but not as much.
864 
865    If an error occurs, the existing mapping is not changed.  */
866 
867 CB_RC
868 cb_read_target_syscall_maps (cb, file)
869      host_callback *cb;
870      const char *file;
871 {
872   CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
873   const char *stat_map;
874   FILE *f;
875 
876   if ((f = fopen (file, "r")) == NULL)
877     return CB_RC_ACCESS;
878 
879   /* ... read in and parse file ... */
880 
881   fclose (f);
882   return CB_RC_NO_MEM; /* FIXME:wip */
883 
884   /* Free storage allocated for any existing maps.  */
885   if (cb->syscall_map)
886     free (cb->syscall_map);
887   if (cb->errno_map)
888     free (cb->errno_map);
889   if (cb->open_map)
890     free (cb->open_map);
891   if (cb->signal_map)
892     free (cb->signal_map);
893   if (cb->stat_map)
894     free ((PTR) cb->stat_map);
895 
896   cb->syscall_map = syscall_map;
897   cb->errno_map = errno_map;
898   cb->open_map = open_map;
899   cb->signal_map = signal_map;
900   cb->stat_map = stat_map;
901 
902   return CB_RC_OK;
903 }
904 
905 /* Translate the target's version of a syscall number to the host's.
906    This isn't actually the host's version, rather a canonical form.
907    ??? Perhaps this should be renamed to ..._canon_syscall.  */
908 
909 int
910 cb_target_to_host_syscall (cb, target_val)
911      host_callback *cb;
912      int target_val;
913 {
914   CB_TARGET_DEFS_MAP *m;
915 
916   for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
917     if (m->target_val == target_val)
918       return m->host_val;
919 
920   return -1;
921 }
922 
923 /* FIXME: sort tables if large.
924    Alternatively, an obvious improvement for errno conversion is
925    to machine generate a function with a large switch().  */
926 
927 /* Translate the host's version of errno to the target's.  */
928 
929 int
930 cb_host_to_target_errno (cb, host_val)
931      host_callback *cb;
932      int host_val;
933 {
934   CB_TARGET_DEFS_MAP *m;
935 
936   for (m = &cb->errno_map[0]; m->host_val; ++m)
937     if (m->host_val == host_val)
938       return m->target_val;
939 
940   /* ??? Which error to return in this case is up for grabs.
941      Note that some missing values may have standard alternatives.
942      For now return 0 and require caller to deal with it.  */
943   return 0;
944 }
945 
946 /* Given a set of target bitmasks for the open system call,
947    return the host equivalent.
948    Mapping open flag values is best done by looping so there's no need
949    to machine generate this function.  */
950 
951 int
952 cb_target_to_host_open (cb, target_val)
953      host_callback *cb;
954      int target_val;
955 {
956   int host_val = 0;
957   CB_TARGET_DEFS_MAP *m;
958 
959   for (m = &cb->open_map[0]; m->host_val != -1; ++m)
960     {
961       switch (m->target_val)
962 	{
963 	  /* O_RDONLY can be (and usually is) 0 which needs to be treated
964 	     specially.  */
965 	case TARGET_O_RDONLY :
966 	case TARGET_O_WRONLY :
967 	case TARGET_O_RDWR :
968 	  if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
969 	      == m->target_val)
970 	    host_val |= m->host_val;
971 	  /* Handle the host/target differentiating between binary and
972              text mode.  Only one case is of importance */
973 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
974 	  host_val |= O_BINARY;
975 #endif
976 	  break;
977 	default :
978 	  if ((m->target_val & target_val) == m->target_val)
979 	    host_val |= m->host_val;
980 	  break;
981 	}
982     }
983 
984   return host_val;
985 }
986 
987 /* Utility for e.g. cb_host_to_target_stat to store values in the target's
988    stat struct.  */
989 
990 void
991 cb_store_target_endian (cb, p, size, val)
992      host_callback *cb;
993      char *p;
994      int size;
995      long val; /* ??? must be as big as target word size */
996 {
997   if (cb->target_endian == BFD_ENDIAN_BIG)
998     {
999       p += size;
1000       while (size-- > 0)
1001 	{
1002 	  *--p = val;
1003 	  val >>= 8;
1004 	}
1005     }
1006   else
1007     {
1008       while (size-- > 0)
1009 	{
1010 	  *p++ = val;
1011 	  val >>= 8;
1012 	}
1013     }
1014 }
1015 
1016 /* Translate a host's stat struct into a target's.
1017    If HS is NULL, just compute the length of the buffer required,
1018    TS is ignored.
1019 
1020    The result is the size of the target's stat struct,
1021    or zero if an error occurred during the translation.  */
1022 
1023 int
1024 cb_host_to_target_stat (cb, hs, ts)
1025      host_callback *cb;
1026      const struct stat *hs;
1027      PTR ts;
1028 {
1029   const char *m = cb->stat_map;
1030   char *p;
1031 
1032   if (hs == NULL)
1033     ts = NULL;
1034   p = ts;
1035 
1036   while (m)
1037     {
1038       char *q = strchr (m, ',');
1039       int size;
1040 
1041       /* FIXME: Use sscanf? */
1042       if (q == NULL)
1043 	{
1044 	  /* FIXME: print error message */
1045 	  return 0;
1046 	}
1047       size = atoi (q + 1);
1048       if (size == 0)
1049 	{
1050 	  /* FIXME: print error message */
1051 	  return 0;
1052 	}
1053 
1054       if (hs != NULL)
1055 	{
1056 	  if (0)
1057 	    ;
1058 	  /* Defined here to avoid emacs indigestion on a lone "else".  */
1059 #undef ST_x
1060 #define ST_x(FLD)					\
1061 	  else if (strncmp (m, #FLD, q - m) == 0)	\
1062 	    cb_store_target_endian (cb, p, size, hs->FLD)
1063 
1064 #ifdef HAVE_STRUCT_STAT_ST_DEV
1065 	  ST_x (st_dev);
1066 #endif
1067 #ifdef HAVE_STRUCT_STAT_ST_INO
1068 	  ST_x (st_ino);
1069 #endif
1070 #ifdef HAVE_STRUCT_STAT_ST_MODE
1071 	  ST_x (st_mode);
1072 #endif
1073 #ifdef HAVE_STRUCT_STAT_ST_NLINK
1074 	  ST_x (st_nlink);
1075 #endif
1076 #ifdef HAVE_STRUCT_STAT_ST_UID
1077 	  ST_x (st_uid);
1078 #endif
1079 #ifdef HAVE_STRUCT_STAT_ST_GID
1080 	  ST_x (st_gid);
1081 #endif
1082 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1083 	  ST_x (st_rdev);
1084 #endif
1085 #ifdef HAVE_STRUCT_STAT_ST_SIZE
1086 	  ST_x (st_size);
1087 #endif
1088 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1089 	  ST_x (st_blksize);
1090 #endif
1091 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1092 	  ST_x (st_blocks);
1093 #endif
1094 #ifdef HAVE_STRUCT_STAT_ST_ATIME
1095 	  ST_x (st_atime);
1096 #endif
1097 #ifdef HAVE_STRUCT_STAT_ST_MTIME
1098 	  ST_x (st_mtime);
1099 #endif
1100 #ifdef HAVE_STRUCT_STAT_ST_CTIME
1101 	  ST_x (st_ctime);
1102 #endif
1103 #undef ST_x
1104 	  /* FIXME:wip */
1105 	  else
1106 	    /* Unsupported field, store 0.  */
1107 	    cb_store_target_endian (cb, p, size, 0);
1108 	}
1109 
1110       p += size;
1111       m = strchr (q, ':');
1112       if (m)
1113 	++m;
1114     }
1115 
1116   return p - (char *) ts;
1117 }
1118 
1119 /* Cover functions to the vfprintf callbacks.
1120 
1121    ??? If one thinks of the callbacks as a subsystem onto itself [or part of
1122    a larger "remote target subsystem"] with a well defined interface, then
1123    one would think that the subsystem would provide these.  However, until
1124    one is allowed to create such a subsystem (with its own source tree
1125    independent of any particular user), such a critter can't exist.  Thus
1126    these functions are here for the time being.  */
1127 
1128 void
1129 sim_cb_printf (host_callback *p, const char *fmt, ...)
1130 {
1131   va_list ap;
1132 
1133   va_start (ap, fmt);
1134   p->vprintf_filtered (p, fmt, ap);
1135   va_end (ap);
1136 }
1137 
1138 void
1139 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
1140 {
1141   va_list ap;
1142 
1143   va_start (ap, fmt);
1144   p->evprintf_filtered (p, fmt, ap);
1145   va_end (ap);
1146 }
1147 
1148 int
1149 cb_is_stdin (host_callback *cb, int fd)
1150 {
1151   return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 0;
1152 }
1153 
1154 int
1155 cb_is_stdout (host_callback *cb, int fd)
1156 {
1157   return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 1;
1158 }
1159 
1160 int
1161 cb_is_stderr (host_callback *cb, int fd)
1162 {
1163   return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 2;
1164 }
1165