1/* Remote target callback routines.
2   Copyright 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2007, 2008, 2009, 2010,
3   2011 Free Software Foundation, Inc.
4   Contributed by Cygnus Solutions.
5
6   This file is part of GDB.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
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 "cconfig.h"
26#endif
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.  */
65void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
66void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
67
68extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
69extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
70extern CB_TARGET_DEFS_MAP cb_init_open_map[];
71
72extern int system PARAMS ((const char *));
73
74static int os_init PARAMS ((host_callback *));
75static int os_shutdown PARAMS ((host_callback *));
76static int os_unlink PARAMS ((host_callback *, const char *));
77static long os_time PARAMS ((host_callback *, long *));
78static int os_system PARAMS ((host_callback *, const char *));
79static int os_rename PARAMS ((host_callback *, const char *, const char *));
80static int os_write_stdout PARAMS ((host_callback *, const char *, int));
81static void os_flush_stdout PARAMS ((host_callback *));
82static int os_write_stderr PARAMS ((host_callback *, const char *, int));
83static void os_flush_stderr PARAMS ((host_callback *));
84static int os_write PARAMS ((host_callback *, int, const char *, int));
85static int os_read_stdin PARAMS ((host_callback *, char *, int));
86static int os_read PARAMS ((host_callback *, int, char *, int));
87static int os_open PARAMS ((host_callback *, const char *, int));
88static int os_lseek PARAMS ((host_callback *, int, long, int));
89static int os_isatty PARAMS ((host_callback *, int));
90static int os_get_errno PARAMS ((host_callback *));
91static int os_close PARAMS ((host_callback *, int));
92static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
93static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
94static void os_error PARAMS ((host_callback *, const char *, ...))
95#ifdef __GNUC__
96  __attribute__ ((__noreturn__))
97#endif
98  ;
99static int fdmap PARAMS ((host_callback *, int));
100static int fdbad PARAMS ((host_callback *, int));
101static int wrap PARAMS ((host_callback *, int));
102
103/* Set the callback copy of errno from what we see now.  */
104
105static int
106wrap (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
117static int
118fdbad (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
130static int
131fdmap (p, fd)
132     host_callback *p;
133     int fd;
134{
135  return p->fdmap[fd];
136}
137
138static int
139os_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)
208static int
209os_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
246static int
247os_get_errno (p)
248     host_callback *p;
249{
250  return cb_host_to_target_errno (p, p->last_errno);
251}
252
253
254static int
255os_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
269static int
270os_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
285static int
286os_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
311static int
312os_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
368static int
369os_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
377static int
378os_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
449static int
450os_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
458static void
459os_flush_stdout (p)
460     host_callback *p ATTRIBUTE_UNUSED;
461{
462  fflush (stdout);
463}
464
465static int
466os_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
474static void
475os_flush_stderr (p)
476     host_callback *p ATTRIBUTE_UNUSED;
477{
478  fflush (stderr);
479}
480
481static int
482os_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
491static int
492os_system (p, s)
493     host_callback *p;
494     const char *s;
495{
496  return wrap (p, system (s));
497}
498
499static long
500os_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
512static int
513os_unlink (p, f1)
514     host_callback *p;
515     const char *f1;
516{
517  return wrap (p, unlink (f1));
518}
519
520static int
521os_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
533static int
534os_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
580static int
581os_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
594static int
595os_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
619static int
620os_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
633static int
634os_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
675static void
676os_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
686static void
687os_pipe_nonempty (p, reader, writer)
688     host_callback *p;
689     int reader;
690     int writer;
691{
692}
693
694static int
695os_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
735static int
736os_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 */
760static void
761os_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 */
771static void
772os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
773{
774  vprintf (format, args);
775}
776
777/* VARARGS */
778static void
779os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
780{
781  vfprintf (stderr, format, args);
782}
783
784/* VARARGS */
785static void
786os_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
798host_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
867CB_RC
868cb_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
909int
910cb_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
929int
930cb_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
951int
952cb_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
990void
991cb_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
1023int
1024cb_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
1128void
1129sim_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
1138void
1139sim_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
1148int
1149cb_is_stdin (host_callback *cb, int fd)
1150{
1151  return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 0;
1152}
1153
1154int
1155cb_is_stdout (host_callback *cb, int fd)
1156{
1157  return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 1;
1158}
1159
1160int
1161cb_is_stderr (host_callback *cb, int fd)
1162{
1163  return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 2;
1164}
1165