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