]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/callback.c
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / common / callback.c
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
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
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
131 fdmap (p, fd)
132 host_callback *p;
133 int fd;
134 {
135 return p->fdmap[fd];
136 }
137
138 static int
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
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
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
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
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
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
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
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
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
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
459 os_flush_stdout (p)
460 host_callback *p ATTRIBUTE_UNUSED;
461 {
462 fflush (stdout);
463 }
464
465 static int
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
475 os_flush_stderr (p)
476 host_callback *p ATTRIBUTE_UNUSED;
477 {
478 fflush (stderr);
479 }
480
481 static int
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
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
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
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
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
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
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
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
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
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
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
683 os_pipe_nonempty (p, reader, writer)
684 host_callback *p;
685 int reader;
686 int writer;
687 {
688 }
689
690 static int
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
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
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
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
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
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 \f
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
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
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
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
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
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
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 \f
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
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
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
1145 cb_is_stdin (host_callback *cb, int fd)
1146 {
1147 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 0;
1148 }
1149
1150 int
1151 cb_is_stdout (host_callback *cb, int fd)
1152 {
1153 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 1;
1154 }
1155
1156 int
1157 cb_is_stderr (host_callback *cb, int fd)
1158 {
1159 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 2;
1160 }