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