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