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