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