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