1 /* Remote target callback routines.
2    Copyright 1995, 1996, 1997, 2000, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4    Contributed by Cygnus Solutions.
5 
6    This file is part of GDB.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free Software
20    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21 
22 /* This file provides a standard way for targets to talk to the host OS
23    level.  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "cconfig.h"
27 #endif
28 #include "ansidecl.h"
29 #ifdef ANSI_PROTOTYPES
30 #include <stdarg.h>
31 #else
32 #include <varargs.h>
33 #endif
34 #include <stdio.h>
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #ifdef HAVE_STRING_H
39 #include <string.h>
40 #else
41 #ifdef HAVE_STRINGS_H
42 #include <strings.h>
43 #endif
44 #endif
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <time.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include "gdb/callback.h"
51 #include "targ-vals.h"
52 
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56 
57 /* ??? sim_cb_printf should be cb_printf, but until the callback support is
58    broken out of the simulator directory, these are here to not require
59    sim-utils.h.  */
60 void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
61 void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
62 
63 extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
64 extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
65 extern CB_TARGET_DEFS_MAP cb_init_open_map[];
66 
67 extern int system PARAMS ((const char *));
68 
69 static int os_init PARAMS ((host_callback *));
70 static int os_shutdown PARAMS ((host_callback *));
71 static int os_unlink PARAMS ((host_callback *, const char *));
72 static long os_time PARAMS ((host_callback *, long *));
73 static int os_system PARAMS ((host_callback *, const char *));
74 static int os_rename PARAMS ((host_callback *, const char *, const char *));
75 static int os_write_stdout PARAMS ((host_callback *, const char *, int));
76 static void os_flush_stdout PARAMS ((host_callback *));
77 static int os_write_stderr PARAMS ((host_callback *, const char *, int));
78 static void os_flush_stderr PARAMS ((host_callback *));
79 static int os_write PARAMS ((host_callback *, int, const char *, int));
80 static int os_read_stdin PARAMS ((host_callback *, char *, int));
81 static int os_read PARAMS ((host_callback *, int, char *, int));
82 static int os_open PARAMS ((host_callback *, const char *, int));
83 static int os_lseek PARAMS ((host_callback *, int, long, int));
84 static int os_isatty PARAMS ((host_callback *, int));
85 static int os_get_errno PARAMS ((host_callback *));
86 static int os_close PARAMS ((host_callback *, int));
87 static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
88 static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
89 static void os_error PARAMS ((host_callback *, const char *, ...));
90 static int fdmap PARAMS ((host_callback *, int));
91 static int fdbad PARAMS ((host_callback *, int));
92 static int wrap PARAMS ((host_callback *, int));
93 
94 /* Set the callback copy of errno from what we see now.  */
95 
96 static int
wrap(p,val)97 wrap (p, val)
98      host_callback *p;
99      int val;
100 {
101   p->last_errno = errno;
102   return val;
103 }
104 
105 /* Make sure the FD provided is ok.  If not, return non-zero
106    and set errno. */
107 
108 static int
fdbad(p,fd)109 fdbad (p, fd)
110      host_callback *p;
111      int fd;
112 {
113   if (fd < 0 || fd > MAX_CALLBACK_FDS || p->fd_buddy[fd] < 0)
114     {
115       p->last_errno = EINVAL;
116       return -1;
117     }
118   return 0;
119 }
120 
121 static int
fdmap(p,fd)122 fdmap (p, fd)
123      host_callback *p;
124      int fd;
125 {
126   return p->fdmap[fd];
127 }
128 
129 static int
os_close(p,fd)130 os_close (p, fd)
131      host_callback *p;
132      int fd;
133 {
134   int result;
135   int i, next;
136 
137   result = fdbad (p, fd);
138   if (result)
139     return result;
140   /* If this file descripter has one or more buddies (originals /
141      duplicates from a dup), just remove it from the circular list.  */
142   for (i = fd; (next = p->fd_buddy[i]) != fd; )
143     i = next;
144   if (fd != i)
145     p->fd_buddy[i] = p->fd_buddy[fd];
146   else
147     result = wrap (p, close (fdmap (p, fd)));
148   p->fd_buddy[fd] = -1;
149 
150   return result;
151 }
152 
153 
154 /* taken from gdb/util.c:notice_quit() - should be in a library */
155 
156 
157 #if defined(__GO32__) || defined (_MSC_VER)
158 static int
os_poll_quit(p)159 os_poll_quit (p)
160      host_callback *p;
161 {
162 #if defined(__GO32__)
163   int kbhit ();
164   int getkey ();
165   if (kbhit ())
166     {
167       int k = getkey ();
168       if (k == 1)
169 	{
170 	  return 1;
171 	}
172       else if (k == 2)
173 	{
174 	  return 1;
175 	}
176       else
177 	{
178 	  sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
179 	}
180     }
181 #endif
182 #if defined (_MSC_VER)
183   /* NB - this will not compile! */
184   int k = win32pollquit();
185   if (k == 1)
186     return 1;
187   else if (k == 2)
188     return 1;
189 #endif
190   return 0;
191 }
192 #else
193 #define os_poll_quit 0
194 #endif /* defined(__GO32__) || defined(_MSC_VER) */
195 
196 static int
os_get_errno(p)197 os_get_errno (p)
198      host_callback *p;
199 {
200   return cb_host_to_target_errno (p, p->last_errno);
201 }
202 
203 
204 static int
os_isatty(p,fd)205 os_isatty (p, fd)
206      host_callback *p;
207      int fd;
208 {
209   int result;
210 
211   result = fdbad (p, fd);
212   if (result)
213     return result;
214   result = wrap (p, isatty (fdmap (p, fd)));
215 
216   return result;
217 }
218 
219 static int
os_lseek(p,fd,off,way)220 os_lseek (p, fd, off, way)
221      host_callback *p;
222      int fd;
223      long off;
224      int way;
225 {
226   int result;
227 
228   result = fdbad (p, fd);
229   if (result)
230     return result;
231   result = lseek (fdmap (p, fd), off, way);
232   return result;
233 }
234 
235 static int
os_open(p,name,flags)236 os_open (p, name, flags)
237      host_callback *p;
238      const char *name;
239      int flags;
240 {
241   int i;
242   for (i = 0; i < MAX_CALLBACK_FDS; i++)
243     {
244       if (p->fd_buddy[i] < 0)
245 	{
246 	  int f = open (name, cb_target_to_host_open (p, flags), 0644);
247 	  if (f < 0)
248 	    {
249 	      p->last_errno = errno;
250 	      return f;
251 	    }
252 	  p->fd_buddy[i] = i;
253 	  p->fdmap[i] = f;
254 	  return i;
255 	}
256     }
257   p->last_errno = EMFILE;
258   return -1;
259 }
260 
261 static int
os_read(p,fd,buf,len)262 os_read (p, fd, buf, len)
263      host_callback *p;
264      int fd;
265      char *buf;
266      int len;
267 {
268   int result;
269 
270   result = fdbad (p, fd);
271   if (result)
272     return result;
273   result = wrap (p, read (fdmap (p, fd), buf, len));
274   return result;
275 }
276 
277 static int
os_read_stdin(p,buf,len)278 os_read_stdin (p, buf, len)
279      host_callback *p;
280      char *buf;
281      int len;
282 {
283   return wrap (p, read (0, buf, len));
284 }
285 
286 static int
os_write(p,fd,buf,len)287 os_write (p, fd, buf, len)
288      host_callback *p;
289      int fd;
290      const char *buf;
291      int len;
292 {
293   int result;
294   int real_fd;
295 
296   result = fdbad (p, fd);
297   if (result)
298     return result;
299   real_fd = fdmap (p, fd);
300   switch (real_fd)
301     {
302     default:
303       result = wrap (p, write (real_fd, buf, len));
304       break;
305     case 1:
306       result = p->write_stdout (p, buf, len);
307       break;
308     case 2:
309       result = p->write_stderr (p, buf, len);
310       break;
311     }
312   return result;
313 }
314 
315 static int
os_write_stdout(p,buf,len)316 os_write_stdout (p, buf, len)
317      host_callback *p ATTRIBUTE_UNUSED;
318      const char *buf;
319      int len;
320 {
321   return fwrite (buf, 1, len, stdout);
322 }
323 
324 static void
os_flush_stdout(p)325 os_flush_stdout (p)
326      host_callback *p ATTRIBUTE_UNUSED;
327 {
328   fflush (stdout);
329 }
330 
331 static int
os_write_stderr(p,buf,len)332 os_write_stderr (p, buf, len)
333      host_callback *p ATTRIBUTE_UNUSED;
334      const char *buf;
335      int len;
336 {
337   return fwrite (buf, 1, len, stderr);
338 }
339 
340 static void
os_flush_stderr(p)341 os_flush_stderr (p)
342      host_callback *p ATTRIBUTE_UNUSED;
343 {
344   fflush (stderr);
345 }
346 
347 static int
os_rename(p,f1,f2)348 os_rename (p, f1, f2)
349      host_callback *p;
350      const char *f1;
351      const char *f2;
352 {
353   return wrap (p, rename (f1, f2));
354 }
355 
356 
357 static int
os_system(p,s)358 os_system (p, s)
359      host_callback *p;
360      const char *s;
361 {
362   return wrap (p, system (s));
363 }
364 
365 static long
os_time(p,t)366 os_time (p, t)
367      host_callback *p;
368      long *t;
369 {
370   return wrap (p, time (t));
371 }
372 
373 
374 static int
os_unlink(p,f1)375 os_unlink (p, f1)
376      host_callback *p;
377      const char *f1;
378 {
379   return wrap (p, unlink (f1));
380 }
381 
382 static int
os_stat(p,file,buf)383 os_stat (p, file, buf)
384      host_callback *p;
385      const char *file;
386      struct stat *buf;
387 {
388   /* ??? There is an issue of when to translate to the target layout.
389      One could do that inside this function, or one could have the
390      caller do it.  It's more flexible to let the caller do it, though
391      I'm not sure the flexibility will ever be useful.  */
392   return wrap (p, stat (file, buf));
393 }
394 
395 static int
os_fstat(p,fd,buf)396 os_fstat (p, fd, buf)
397      host_callback *p;
398      int fd;
399      struct stat *buf;
400 {
401   if (fdbad (p, fd))
402     return -1;
403   /* ??? There is an issue of when to translate to the target layout.
404      One could do that inside this function, or one could have the
405      caller do it.  It's more flexible to let the caller do it, though
406      I'm not sure the flexibility will ever be useful.  */
407   return wrap (p, fstat (fdmap (p, fd), buf));
408 }
409 
410 static int
os_ftruncate(p,fd,len)411 os_ftruncate (p, fd, len)
412      host_callback *p;
413      int fd;
414      long len;
415 {
416   int result;
417 
418   result = fdbad (p, fd);
419   if (result)
420     return result;
421   result = wrap (p, ftruncate (fdmap (p, fd), len));
422   return result;
423 }
424 
425 static int
os_truncate(p,file,len)426 os_truncate (p, file, len)
427      host_callback *p;
428      const char *file;
429      long len;
430 {
431   return wrap (p, truncate (file, len));
432 }
433 
434 static int
os_shutdown(p)435 os_shutdown (p)
436      host_callback *p;
437 {
438   int i, next, j;
439   for (i = 0; i < MAX_CALLBACK_FDS; i++)
440     {
441       int do_close = 1;
442 
443       next = p->fd_buddy[i];
444       if (next < 0)
445 	continue;
446       do
447 	{
448 	  j = next;
449 	  if (j == MAX_CALLBACK_FDS)
450 	    do_close = 0;
451 	  next = p->fd_buddy[j];
452 	  p->fd_buddy[j] = -1;
453 	  /* At the initial call of os_init, we got -1, 0, 0, 0, ...  */
454 	  if (next < 0)
455 	    {
456 	      p->fd_buddy[i] = -1;
457 	      do_close = 0;
458 	      break;
459 	    }
460 	}
461       while (j != i);
462       if (do_close)
463 	close (p->fdmap[i]);
464     }
465   return 1;
466 }
467 
468 static int
os_init(p)469 os_init (p)
470      host_callback *p;
471 {
472   int i;
473 
474   os_shutdown (p);
475   for (i = 0; i < 3; i++)
476     {
477       p->fdmap[i] = i;
478       p->fd_buddy[i] = i - 1;
479     }
480   p->fd_buddy[0] = MAX_CALLBACK_FDS;
481   p->fd_buddy[MAX_CALLBACK_FDS] = 2;
482 
483   p->syscall_map = cb_init_syscall_map;
484   p->errno_map = cb_init_errno_map;
485   p->open_map = cb_init_open_map;
486 
487   return 1;
488 }
489 
490 /* DEPRECATED */
491 
492 /* VARARGS */
493 static void
494 #ifdef ANSI_PROTOTYPES
os_printf_filtered(host_callback * p ATTRIBUTE_UNUSED,const char * format,...)495 os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
496 #else
497 os_printf_filtered (p, va_alist)
498      host_callback *p;
499      va_dcl
500 #endif
501 {
502   va_list args;
503 #ifdef ANSI_PROTOTYPES
504   va_start (args, format);
505 #else
506   char *format;
507 
508   va_start (args);
509   format = va_arg (args, char *);
510 #endif
511 
512   vfprintf (stdout, format, args);
513   va_end (args);
514 }
515 
516 /* VARARGS */
517 static void
518 #ifdef ANSI_PROTOTYPES
os_vprintf_filtered(host_callback * p ATTRIBUTE_UNUSED,const char * format,va_list args)519 os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
520 #else
521 os_vprintf_filtered (p, format, args)
522      host_callback *p;
523      const char *format;
524      va_list args;
525 #endif
526 {
527   vprintf (format, args);
528 }
529 
530 /* VARARGS */
531 static void
532 #ifdef ANSI_PROTOTYPES
os_evprintf_filtered(host_callback * p ATTRIBUTE_UNUSED,const char * format,va_list args)533 os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
534 #else
535 os_evprintf_filtered (p, format, args)
536      host_callback *p;
537      const char *format;
538      va_list args;
539 #endif
540 {
541   vfprintf (stderr, format, args);
542 }
543 
544 /* VARARGS */
545 static void
546 #ifdef ANSI_PROTOTYPES
os_error(host_callback * p ATTRIBUTE_UNUSED,const char * format,...)547 os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
548 #else
549 os_error (p, va_alist)
550      host_callback *p;
551      va_dcl
552 #endif
553 {
554   va_list args;
555 #ifdef ANSI_PROTOTYPES
556   va_start (args, format);
557 #else
558   char *format;
559 
560   va_start (args);
561   format = va_arg (args, char *);
562 #endif
563 
564   vfprintf (stderr, format, args);
565   fprintf (stderr, "\n");
566 
567   va_end (args);
568   exit (1);
569 }
570 
571 host_callback default_callback =
572 {
573   os_close,
574   os_get_errno,
575   os_isatty,
576   os_lseek,
577   os_open,
578   os_read,
579   os_read_stdin,
580   os_rename,
581   os_system,
582   os_time,
583   os_unlink,
584   os_write,
585   os_write_stdout,
586   os_flush_stdout,
587   os_write_stderr,
588   os_flush_stderr,
589 
590   os_stat,
591   os_fstat,
592 
593   os_ftruncate,
594   os_truncate,
595 
596   os_poll_quit,
597 
598   os_shutdown,
599   os_init,
600 
601   os_printf_filtered,  /* deprecated */
602 
603   os_vprintf_filtered,
604   os_evprintf_filtered,
605   os_error,
606 
607   0, 		/* last errno */
608 
609   { 0, },	/* fdmap */
610   { -1, },	/* fd_buddy */
611 
612   0, /* syscall_map */
613   0, /* errno_map */
614   0, /* open_map */
615   0, /* signal_map */
616   0, /* stat_map */
617 
618   HOST_CALLBACK_MAGIC,
619 };
620 
621 /* Read in a file describing the target's system call values.
622    E.g. maybe someone will want to use something other than newlib.
623    This assumes that the basic system call recognition and value passing/
624    returning is supported.  So maybe some coding/recompilation will be
625    necessary, but not as much.
626 
627    If an error occurs, the existing mapping is not changed.  */
628 
629 CB_RC
cb_read_target_syscall_maps(cb,file)630 cb_read_target_syscall_maps (cb, file)
631      host_callback *cb;
632      const char *file;
633 {
634   CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
635   const char *stat_map;
636   FILE *f;
637 
638   if ((f = fopen (file, "r")) == NULL)
639     return CB_RC_ACCESS;
640 
641   /* ... read in and parse file ... */
642 
643   fclose (f);
644   return CB_RC_NO_MEM; /* FIXME:wip */
645 
646   /* Free storage allocated for any existing maps.  */
647   if (cb->syscall_map)
648     free (cb->syscall_map);
649   if (cb->errno_map)
650     free (cb->errno_map);
651   if (cb->open_map)
652     free (cb->open_map);
653   if (cb->signal_map)
654     free (cb->signal_map);
655   if (cb->stat_map)
656     free ((PTR) cb->stat_map);
657 
658   cb->syscall_map = syscall_map;
659   cb->errno_map = errno_map;
660   cb->open_map = open_map;
661   cb->signal_map = signal_map;
662   cb->stat_map = stat_map;
663 
664   return CB_RC_OK;
665 }
666 
667 /* Translate the target's version of a syscall number to the host's.
668    This isn't actually the host's version, rather a canonical form.
669    ??? Perhaps this should be renamed to ..._canon_syscall.  */
670 
671 int
cb_target_to_host_syscall(cb,target_val)672 cb_target_to_host_syscall (cb, target_val)
673      host_callback *cb;
674      int target_val;
675 {
676   CB_TARGET_DEFS_MAP *m;
677 
678   for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
679     if (m->target_val == target_val)
680       return m->host_val;
681 
682   return -1;
683 }
684 
685 /* FIXME: sort tables if large.
686    Alternatively, an obvious improvement for errno conversion is
687    to machine generate a function with a large switch().  */
688 
689 /* Translate the host's version of errno to the target's.  */
690 
691 int
cb_host_to_target_errno(cb,host_val)692 cb_host_to_target_errno (cb, host_val)
693      host_callback *cb;
694      int host_val;
695 {
696   CB_TARGET_DEFS_MAP *m;
697 
698   for (m = &cb->errno_map[0]; m->host_val; ++m)
699     if (m->host_val == host_val)
700       return m->target_val;
701 
702   /* ??? Which error to return in this case is up for grabs.
703      Note that some missing values may have standard alternatives.
704      For now return 0 and require caller to deal with it.  */
705   return 0;
706 }
707 
708 /* Given a set of target bitmasks for the open system call,
709    return the host equivalent.
710    Mapping open flag values is best done by looping so there's no need
711    to machine generate this function.  */
712 
713 int
cb_target_to_host_open(cb,target_val)714 cb_target_to_host_open (cb, target_val)
715      host_callback *cb;
716      int target_val;
717 {
718   int host_val = 0;
719   CB_TARGET_DEFS_MAP *m;
720 
721   for (m = &cb->open_map[0]; m->host_val != -1; ++m)
722     {
723       switch (m->target_val)
724 	{
725 	  /* O_RDONLY can be (and usually is) 0 which needs to be treated
726 	     specially.  */
727 	case TARGET_O_RDONLY :
728 	case TARGET_O_WRONLY :
729 	case TARGET_O_RDWR :
730 	  if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
731 	      == m->target_val)
732 	    host_val |= m->host_val;
733 	  /* Handle the host/target differentiating between binary and
734              text mode.  Only one case is of importance */
735 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
736 	  host_val |= O_BINARY;
737 #endif
738 	  break;
739 	default :
740 	  if ((m->target_val & target_val) == m->target_val)
741 	    host_val |= m->host_val;
742 	  break;
743 	}
744     }
745 
746   return host_val;
747 }
748 
749 /* Utility for cb_host_to_target_stat to store values in the target's
750    stat struct.  */
751 
752 static void
store(p,size,val,big_p)753 store (p, size, val, big_p)
754      char *p;
755      int size;
756      long val; /* ??? must be as big as target word size */
757      int big_p;
758 {
759   if (big_p)
760     {
761       p += size;
762       while (size-- > 0)
763 	{
764 	  *--p = val;
765 	  val >>= 8;
766 	}
767     }
768   else
769     {
770       while (size-- > 0)
771 	{
772 	  *p++ = val;
773 	  val >>= 8;
774 	}
775     }
776 }
777 
778 /* Translate a host's stat struct into a target's.
779    If HS is NULL, just compute the length of the buffer required,
780    TS is ignored.
781 
782    The result is the size of the target's stat struct,
783    or zero if an error occurred during the translation.  */
784 
785 int
cb_host_to_target_stat(cb,hs,ts)786 cb_host_to_target_stat (cb, hs, ts)
787      host_callback *cb;
788      const struct stat *hs;
789      PTR ts;
790 {
791   const char *m = cb->stat_map;
792   char *p;
793   int big_p = 0;
794 
795   if (hs == NULL)
796     ts = NULL;
797   p = ts;
798 
799   while (m)
800     {
801       char *q = strchr (m, ',');
802       int size;
803 
804       /* FIXME: Use sscanf? */
805       if (q == NULL)
806 	{
807 	  /* FIXME: print error message */
808 	  return 0;
809 	}
810       size = atoi (q + 1);
811       if (size == 0)
812 	{
813 	  /* FIXME: print error message */
814 	  return 0;
815 	}
816 
817       if (hs != NULL)
818 	{
819 	  if (strncmp (m, "st_dev", q - m) == 0)
820 	    store (p, size, hs->st_dev, big_p);
821 	  else if (strncmp (m, "st_ino", q - m) == 0)
822 	    store (p, size, hs->st_ino, big_p);
823 	  /* FIXME:wip */
824 	  else
825 	    store (p, size, 0, big_p); /* unsupported field, store 0 */
826 	}
827 
828       p += size;
829       m = strchr (q, ':');
830       if (m)
831 	++m;
832     }
833 
834   return p - (char *) ts;
835 }
836 
837 /* Cover functions to the vfprintf callbacks.
838 
839    ??? If one thinks of the callbacks as a subsystem onto itself [or part of
840    a larger "remote target subsystem"] with a well defined interface, then
841    one would think that the subsystem would provide these.  However, until
842    one is allowed to create such a subsystem (with its own source tree
843    independent of any particular user), such a critter can't exist.  Thus
844    these functions are here for the time being.  */
845 
846 void
sim_cb_printf(host_callback * p,const char * fmt,...)847 sim_cb_printf (host_callback *p, const char *fmt, ...)
848 {
849   va_list ap;
850 
851   va_start (ap, fmt);
852   p->vprintf_filtered (p, fmt, ap);
853   va_end (ap);
854 }
855 
856 void
sim_cb_eprintf(host_callback * p,const char * fmt,...)857 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
858 {
859   va_list ap;
860 
861   va_start (ap, fmt);
862   p->evprintf_filtered (p, fmt, ap);
863   va_end (ap);
864 }
865