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