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