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