* syscall.c (cb_syscall) <case CB_SYS_lstat>: New case.
[platform/upstream/binutils.git] / sim / common / callback.c
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 
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 
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 
122 fdmap (p, fd)
123      host_callback *p;
124      int fd;
125 {
126   return p->fdmap[fd];
127 }
128
129 static int 
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
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 
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 
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 
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 
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 
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 
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 
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 
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
325 os_flush_stdout (p)
326      host_callback *p ATTRIBUTE_UNUSED;
327 {
328   fflush (stdout);
329 }
330
331 static int 
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
341 os_flush_stderr (p)
342      host_callback *p ATTRIBUTE_UNUSED;
343 {
344   fflush (stderr);
345 }
346
347 static int 
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
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 
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 
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
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
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
411 os_lstat (p, file, buf)
412      host_callback *p;
413      const char *file;
414      struct stat *buf;
415 {
416   /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat.  */
417   return wrap (p, lstat (file, buf));
418 }
419
420 static int 
421 os_ftruncate (p, fd, len)
422      host_callback *p;
423      int fd;
424      long len;
425 {
426   int result;
427
428   result = fdbad (p, fd);
429   if (result)
430     return result;
431   result = wrap (p, ftruncate (fdmap (p, fd), len));
432   return result;
433 }
434
435 static int
436 os_truncate (p, file, len)
437      host_callback *p;
438      const char *file;
439      long len;
440 {
441   return wrap (p, truncate (file, len));
442 }
443
444 static int
445 os_shutdown (p)
446      host_callback *p;
447 {
448   int i, next, j;
449   for (i = 0; i < MAX_CALLBACK_FDS; i++)
450     {
451       int do_close = 1;
452
453       next = p->fd_buddy[i];
454       if (next < 0)
455         continue;
456       do
457         {
458           j = next;
459           if (j == MAX_CALLBACK_FDS)
460             do_close = 0;
461           next = p->fd_buddy[j];
462           p->fd_buddy[j] = -1;
463           /* At the initial call of os_init, we got -1, 0, 0, 0, ...  */
464           if (next < 0)
465             {
466               p->fd_buddy[i] = -1;
467               do_close = 0;
468               break;
469             }
470         }
471       while (j != i);
472       if (do_close)
473         close (p->fdmap[i]);
474     }
475   return 1;
476 }
477
478 static int
479 os_init (p)
480      host_callback *p;
481 {
482   int i;
483
484   os_shutdown (p);
485   for (i = 0; i < 3; i++)
486     {
487       p->fdmap[i] = i;
488       p->fd_buddy[i] = i - 1;
489     }
490   p->fd_buddy[0] = MAX_CALLBACK_FDS;
491   p->fd_buddy[MAX_CALLBACK_FDS] = 2;
492
493   p->syscall_map = cb_init_syscall_map;
494   p->errno_map = cb_init_errno_map;
495   p->open_map = cb_init_open_map;
496
497   return 1;
498 }
499
500 /* DEPRECATED */
501
502 /* VARARGS */
503 static void
504 #ifdef ANSI_PROTOTYPES
505 os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
506 #else
507 os_printf_filtered (p, va_alist)
508      host_callback *p;
509      va_dcl
510 #endif
511 {
512   va_list args;
513 #ifdef ANSI_PROTOTYPES
514   va_start (args, format);
515 #else
516   char *format;
517
518   va_start (args);
519   format = va_arg (args, char *);
520 #endif
521
522   vfprintf (stdout, format, args);
523   va_end (args);
524 }
525
526 /* VARARGS */
527 static void
528 #ifdef ANSI_PROTOTYPES
529 os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
530 #else
531 os_vprintf_filtered (p, format, args)
532      host_callback *p;
533      const char *format;
534      va_list args;
535 #endif
536 {
537   vprintf (format, args);
538 }
539
540 /* VARARGS */
541 static void
542 #ifdef ANSI_PROTOTYPES
543 os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
544 #else
545 os_evprintf_filtered (p, format, args)
546      host_callback *p;
547      const char *format;
548      va_list args;
549 #endif
550 {
551   vfprintf (stderr, format, args);
552 }
553
554 /* VARARGS */
555 static void
556 #ifdef ANSI_PROTOTYPES
557 os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
558 #else
559 os_error (p, va_alist)
560      host_callback *p;
561      va_dcl
562 #endif
563 {
564   va_list args;
565 #ifdef ANSI_PROTOTYPES
566   va_start (args, format);
567 #else
568   char *format;
569
570   va_start (args);
571   format = va_arg (args, char *);
572 #endif
573
574   vfprintf (stderr, format, args);
575   fprintf (stderr, "\n");
576
577   va_end (args);
578   exit (1);
579 }
580
581 host_callback default_callback =
582 {
583   os_close,
584   os_get_errno,
585   os_isatty,
586   os_lseek,
587   os_open,
588   os_read,
589   os_read_stdin,
590   os_rename,
591   os_system,
592   os_time,
593   os_unlink,
594   os_write,
595   os_write_stdout,
596   os_flush_stdout,
597   os_write_stderr,
598   os_flush_stderr,
599
600   os_stat,
601   os_fstat,
602   os_lstat,
603
604   os_ftruncate,
605   os_truncate,
606
607   os_poll_quit,
608
609   os_shutdown,
610   os_init,
611
612   os_printf_filtered,  /* deprecated */
613
614   os_vprintf_filtered,
615   os_evprintf_filtered,
616   os_error,
617
618   0,            /* last errno */
619
620   { 0, },       /* fdmap */
621   { -1, },      /* fd_buddy */
622
623   0, /* syscall_map */
624   0, /* errno_map */
625   0, /* open_map */
626   0, /* signal_map */
627   0, /* stat_map */
628         
629   HOST_CALLBACK_MAGIC,
630 };
631 \f
632 /* Read in a file describing the target's system call values.
633    E.g. maybe someone will want to use something other than newlib.
634    This assumes that the basic system call recognition and value passing/
635    returning is supported.  So maybe some coding/recompilation will be
636    necessary, but not as much.
637
638    If an error occurs, the existing mapping is not changed.  */
639
640 CB_RC
641 cb_read_target_syscall_maps (cb, file)
642      host_callback *cb;
643      const char *file;
644 {
645   CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
646   const char *stat_map;
647   FILE *f;
648
649   if ((f = fopen (file, "r")) == NULL)
650     return CB_RC_ACCESS;
651
652   /* ... read in and parse file ... */
653
654   fclose (f);
655   return CB_RC_NO_MEM; /* FIXME:wip */
656
657   /* Free storage allocated for any existing maps.  */
658   if (cb->syscall_map)
659     free (cb->syscall_map);
660   if (cb->errno_map)
661     free (cb->errno_map);
662   if (cb->open_map)
663     free (cb->open_map);
664   if (cb->signal_map)
665     free (cb->signal_map);
666   if (cb->stat_map)
667     free ((PTR) cb->stat_map);
668
669   cb->syscall_map = syscall_map;
670   cb->errno_map = errno_map;
671   cb->open_map = open_map;
672   cb->signal_map = signal_map;
673   cb->stat_map = stat_map;
674
675   return CB_RC_OK;
676 }
677
678 /* Translate the target's version of a syscall number to the host's.
679    This isn't actually the host's version, rather a canonical form.
680    ??? Perhaps this should be renamed to ..._canon_syscall.  */
681
682 int
683 cb_target_to_host_syscall (cb, target_val)
684      host_callback *cb;
685      int target_val;
686 {
687   CB_TARGET_DEFS_MAP *m;
688
689   for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
690     if (m->target_val == target_val)
691       return m->host_val;
692
693   return -1;
694 }
695
696 /* FIXME: sort tables if large.
697    Alternatively, an obvious improvement for errno conversion is
698    to machine generate a function with a large switch().  */
699
700 /* Translate the host's version of errno to the target's.  */
701
702 int
703 cb_host_to_target_errno (cb, host_val)
704      host_callback *cb;
705      int host_val;
706 {
707   CB_TARGET_DEFS_MAP *m;
708
709   for (m = &cb->errno_map[0]; m->host_val; ++m)
710     if (m->host_val == host_val)
711       return m->target_val;
712
713   /* ??? Which error to return in this case is up for grabs.
714      Note that some missing values may have standard alternatives.
715      For now return 0 and require caller to deal with it.  */
716   return 0;
717 }
718
719 /* Given a set of target bitmasks for the open system call,
720    return the host equivalent.
721    Mapping open flag values is best done by looping so there's no need
722    to machine generate this function.  */
723
724 int
725 cb_target_to_host_open (cb, target_val)
726      host_callback *cb;
727      int target_val;
728 {
729   int host_val = 0;
730   CB_TARGET_DEFS_MAP *m;
731
732   for (m = &cb->open_map[0]; m->host_val != -1; ++m)
733     {
734       switch (m->target_val)
735         {
736           /* O_RDONLY can be (and usually is) 0 which needs to be treated
737              specially.  */
738         case TARGET_O_RDONLY :
739         case TARGET_O_WRONLY :
740         case TARGET_O_RDWR :
741           if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
742               == m->target_val)
743             host_val |= m->host_val;
744           /* Handle the host/target differentiating between binary and
745              text mode.  Only one case is of importance */
746 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
747           host_val |= O_BINARY;
748 #endif
749           break;
750         default :
751           if ((m->target_val & target_val) == m->target_val)
752             host_val |= m->host_val;
753           break;
754         }
755     }
756
757   return host_val;
758 }
759
760 /* Utility for cb_host_to_target_stat to store values in the target's
761    stat struct.  */
762
763 static void
764 store (p, size, val, big_p)
765      char *p;
766      int size;
767      long val; /* ??? must be as big as target word size */
768      int big_p;
769 {
770   if (big_p)
771     {
772       p += size;
773       while (size-- > 0)
774         {
775           *--p = val;
776           val >>= 8;
777         }
778     }
779   else
780     {
781       while (size-- > 0)
782         {
783           *p++ = val;
784           val >>= 8;
785         }
786     }
787 }
788
789 /* Translate a host's stat struct into a target's.
790    If HS is NULL, just compute the length of the buffer required,
791    TS is ignored.
792
793    The result is the size of the target's stat struct,
794    or zero if an error occurred during the translation.  */
795
796 int
797 cb_host_to_target_stat (cb, hs, ts)
798      host_callback *cb;
799      const struct stat *hs;
800      PTR ts;
801 {
802   const char *m = cb->stat_map;
803   char *p;
804   int big_p = 0;
805
806   if (hs == NULL)
807     ts = NULL;
808   p = ts;
809
810   while (m)
811     {
812       char *q = strchr (m, ',');
813       int size;
814
815       /* FIXME: Use sscanf? */
816       if (q == NULL)
817         {
818           /* FIXME: print error message */
819           return 0;
820         }
821       size = atoi (q + 1);
822       if (size == 0)
823         {
824           /* FIXME: print error message */
825           return 0;
826         }
827
828       if (hs != NULL)
829         {
830           if (0)
831             ;
832           /* Defined here to avoid emacs indigestion on a lone "else".  */
833 #undef ST_x
834 #define ST_x(FLD)                                       \
835           else if (strncmp (m, #FLD, q - m) == 0)       \
836             store (p, size, hs->FLD, big_p)
837
838 #ifdef HAVE_STRUCT_STAT_ST_DEV
839           ST_x (st_dev);
840 #endif
841 #ifdef HAVE_STRUCT_STAT_ST_INO
842           ST_x (st_ino);
843 #endif
844 #ifdef HAVE_STRUCT_STAT_ST_MODE
845           ST_x (st_mode);
846 #endif
847 #ifdef HAVE_STRUCT_STAT_ST_NLINK
848           ST_x (st_nlink);
849 #endif
850 #ifdef HAVE_STRUCT_STAT_ST_UID
851           ST_x (st_uid);
852 #endif
853 #ifdef HAVE_STRUCT_STAT_ST_GID
854           ST_x (st_gid);
855 #endif
856 #ifdef HAVE_STRUCT_STAT_ST_RDEV
857           ST_x (st_rdev);
858 #endif
859 #ifdef HAVE_STRUCT_STAT_ST_SIZE
860           ST_x (st_size);
861 #endif
862 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
863           ST_x (st_blksize);
864 #endif
865 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
866           ST_x (st_blocks);
867 #endif
868 #ifdef HAVE_STRUCT_STAT_ST_ATIME
869           ST_x (st_atime);
870 #endif
871 #ifdef HAVE_STRUCT_STAT_ST_MTIME
872           ST_x (st_mtime);
873 #endif
874 #ifdef HAVE_STRUCT_STAT_ST_CTIME
875           ST_x (st_ctime);
876 #endif
877 #undef ST_x
878           /* FIXME:wip */
879           else
880             store (p, size, 0, big_p); /* unsupported field, store 0 */
881         }
882
883       p += size;
884       m = strchr (q, ':');
885       if (m)
886         ++m;
887     }
888
889   return p - (char *) ts;
890 }
891 \f
892 /* Cover functions to the vfprintf callbacks.
893
894    ??? If one thinks of the callbacks as a subsystem onto itself [or part of
895    a larger "remote target subsystem"] with a well defined interface, then
896    one would think that the subsystem would provide these.  However, until
897    one is allowed to create such a subsystem (with its own source tree
898    independent of any particular user), such a critter can't exist.  Thus
899    these functions are here for the time being.  */
900
901 void
902 sim_cb_printf (host_callback *p, const char *fmt, ...)
903 {
904   va_list ap;
905
906   va_start (ap, fmt);
907   p->vprintf_filtered (p, fmt, ap);
908   va_end (ap);
909 }
910
911 void
912 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
913 {
914   va_list ap;
915
916   va_start (ap, fmt);
917   p->evprintf_filtered (p, fmt, ap);
918   va_end (ap);
919 }