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