sim: mn10300: tweak engine halt hook
[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 <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_pipe (host_callback *p, int *filedes)
561 {
562 int i;
563
564 /* We deliberately don't use fd 0. It's probably stdin anyway. */
565 for (i = 1; i < MAX_CALLBACK_FDS; i++)
566 {
567 int j;
568
569 if (p->fd_buddy[i] < 0)
570 for (j = i + 1; j < MAX_CALLBACK_FDS; j++)
571 if (p->fd_buddy[j] < 0)
572 {
573 /* Found two free fd:s. Set stat to allocated and mark
574 pipeness. */
575 p->fd_buddy[i] = i;
576 p->fd_buddy[j] = j;
577 p->ispipe[i] = j;
578 p->ispipe[j] = -i;
579 filedes[0] = i;
580 filedes[1] = j;
581
582 /* Poison the FD map to make bugs apparent. */
583 p->fdmap[i] = -1;
584 p->fdmap[j] = -1;
585 return 0;
586 }
587 }
588
589 p->last_errno = EMFILE;
590 return -1;
591 }
592
593 /* Stub functions for pipe support. They should always be overridden in
594 targets using the pipe support, but that's up to the target. */
595
596 /* Called when the simulator says that the pipe at (reader, writer) is
597 now empty (so the writer should leave its waiting state). */
598
599 static void
600 os_pipe_empty (host_callback *p, int reader, int writer)
601 {
602 }
603
604 /* Called when the simulator says the pipe at (reader, writer) is now
605 non-empty (so the writer should wait). */
606
607 static void
608 os_pipe_nonempty (host_callback *p, int reader, int writer)
609 {
610 }
611
612 static int
613 os_shutdown (host_callback *p)
614 {
615 int i, next, j;
616 for (i = 0; i < MAX_CALLBACK_FDS; i++)
617 {
618 int do_close = 1;
619
620 /* Zero out all pipe state. Don't call callbacks for non-empty
621 pipes; the target program has likely terminated at this point
622 or we're called at initialization time. */
623 p->ispipe[i] = 0;
624 p->pipe_buffer[i].size = 0;
625 p->pipe_buffer[i].buffer = NULL;
626
627 next = p->fd_buddy[i];
628 if (next < 0)
629 continue;
630 do
631 {
632 j = next;
633 if (j == MAX_CALLBACK_FDS)
634 do_close = 0;
635 next = p->fd_buddy[j];
636 p->fd_buddy[j] = -1;
637 /* At the initial call of os_init, we got -1, 0, 0, 0, ... */
638 if (next < 0)
639 {
640 p->fd_buddy[i] = -1;
641 do_close = 0;
642 break;
643 }
644 }
645 while (j != i);
646 if (do_close)
647 close (p->fdmap[i]);
648 }
649 return 1;
650 }
651
652 static int
653 os_init (host_callback *p)
654 {
655 int i;
656
657 os_shutdown (p);
658 for (i = 0; i < 3; i++)
659 {
660 p->fdmap[i] = i;
661 p->fd_buddy[i] = i - 1;
662 }
663 p->fd_buddy[0] = MAX_CALLBACK_FDS;
664 p->fd_buddy[MAX_CALLBACK_FDS] = 2;
665
666 p->syscall_map = cb_init_syscall_map;
667 p->errno_map = cb_init_errno_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_pipe,
741 os_pipe_empty,
742 os_pipe_nonempty,
743
744 os_poll_quit,
745
746 os_shutdown,
747 os_init,
748
749 os_printf_filtered, /* deprecated */
750
751 os_vprintf_filtered,
752 os_evprintf_filtered,
753 os_error,
754
755 0, /* last errno */
756
757 { 0, }, /* fdmap */
758 { -1, }, /* fd_buddy */
759 { 0, }, /* ispipe */
760 { { 0, 0 }, }, /* pipe_buffer */
761
762 0, /* syscall_map */
763 0, /* errno_map */
764 0, /* open_map */
765 0, /* signal_map */
766 0, /* stat_map */
767
768 /* Defaults expected to be overridden at initialization, where needed. */
769 BFD_ENDIAN_UNKNOWN, /* target_endian */
770 4, /* target_sizeof_int */
771
772 HOST_CALLBACK_MAGIC,
773 };
774 \f
775 /* Read in a file describing the target's system call values.
776 E.g. maybe someone will want to use something other than newlib.
777 This assumes that the basic system call recognition and value passing/
778 returning is supported. So maybe some coding/recompilation will be
779 necessary, but not as much.
780
781 If an error occurs, the existing mapping is not changed. */
782
783 CB_RC
784 cb_read_target_syscall_maps (host_callback *cb, const char *file)
785 {
786 CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
787 const char *stat_map;
788 FILE *f;
789
790 if ((f = fopen (file, "r")) == NULL)
791 return CB_RC_ACCESS;
792
793 /* ... read in and parse file ... */
794
795 fclose (f);
796 return CB_RC_NO_MEM; /* FIXME:wip */
797
798 /* Free storage allocated for any existing maps. */
799 if (cb->syscall_map)
800 free (cb->syscall_map);
801 if (cb->errno_map)
802 free (cb->errno_map);
803 if (cb->open_map)
804 free (cb->open_map);
805 if (cb->signal_map)
806 free (cb->signal_map);
807 if (cb->stat_map)
808 free ((PTR) cb->stat_map);
809
810 cb->syscall_map = syscall_map;
811 cb->errno_map = errno_map;
812 cb->open_map = open_map;
813 cb->signal_map = signal_map;
814 cb->stat_map = stat_map;
815
816 return CB_RC_OK;
817 }
818
819 /* General utility functions to search a map for a value. */
820
821 static const CB_TARGET_DEFS_MAP *
822 cb_target_map_entry (const CB_TARGET_DEFS_MAP map[], int target_val)
823 {
824 const CB_TARGET_DEFS_MAP *m;
825
826 for (m = &map[0]; m->target_val != -1; ++m)
827 if (m->target_val == target_val)
828 return m;
829
830 return NULL;
831 }
832
833 static const CB_TARGET_DEFS_MAP *
834 cb_host_map_entry (const CB_TARGET_DEFS_MAP map[], int host_val)
835 {
836 const CB_TARGET_DEFS_MAP *m;
837
838 for (m = &map[0]; m->host_val != -1; ++m)
839 if (m->host_val == host_val)
840 return m;
841
842 return NULL;
843 }
844
845 /* Translate the target's version of a syscall number to the host's.
846 This isn't actually the host's version, rather a canonical form.
847 ??? Perhaps this should be renamed to ..._canon_syscall. */
848
849 int
850 cb_target_to_host_syscall (host_callback *cb, int target_val)
851 {
852 const CB_TARGET_DEFS_MAP *m =
853 cb_target_map_entry (cb->syscall_map, target_val);
854
855 return m ? m->host_val : -1;
856 }
857
858 /* FIXME: sort tables if large.
859 Alternatively, an obvious improvement for errno conversion is
860 to machine generate a function with a large switch(). */
861
862 /* Translate the host's version of errno to the target's. */
863
864 int
865 cb_host_to_target_errno (host_callback *cb, int host_val)
866 {
867 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->errno_map, host_val);
868
869 /* ??? Which error to return in this case is up for grabs.
870 Note that some missing values may have standard alternatives.
871 For now return 0 and require caller to deal with it. */
872 return m ? m->target_val : 0;
873 }
874
875 /* Given a set of target bitmasks for the open system call,
876 return the host equivalent.
877 Mapping open flag values is best done by looping so there's no need
878 to machine generate this function. */
879
880 int
881 cb_target_to_host_open (host_callback *cb, int target_val)
882 {
883 int host_val = 0;
884 CB_TARGET_DEFS_MAP *m;
885
886 for (m = &cb->open_map[0]; m->host_val != -1; ++m)
887 {
888 switch (m->target_val)
889 {
890 /* O_RDONLY can be (and usually is) 0 which needs to be treated
891 specially. */
892 case TARGET_O_RDONLY :
893 case TARGET_O_WRONLY :
894 case TARGET_O_RDWR :
895 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
896 == m->target_val)
897 host_val |= m->host_val;
898 /* Handle the host/target differentiating between binary and
899 text mode. Only one case is of importance */
900 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
901 host_val |= O_BINARY;
902 #endif
903 break;
904 default :
905 if ((m->target_val & target_val) == m->target_val)
906 host_val |= m->host_val;
907 break;
908 }
909 }
910
911 return host_val;
912 }
913
914 /* Utility for e.g. cb_host_to_target_stat to store values in the target's
915 stat struct.
916
917 ??? The "val" must be as big as target word size. */
918
919 void
920 cb_store_target_endian (host_callback *cb, char *p, int size, long val)
921 {
922 if (cb->target_endian == BFD_ENDIAN_BIG)
923 {
924 p += size;
925 while (size-- > 0)
926 {
927 *--p = val;
928 val >>= 8;
929 }
930 }
931 else
932 {
933 while (size-- > 0)
934 {
935 *p++ = val;
936 val >>= 8;
937 }
938 }
939 }
940
941 /* Translate a host's stat struct into a target's.
942 If HS is NULL, just compute the length of the buffer required,
943 TS is ignored.
944
945 The result is the size of the target's stat struct,
946 or zero if an error occurred during the translation. */
947
948 int
949 cb_host_to_target_stat (host_callback *cb, const struct stat *hs, void *ts)
950 {
951 const char *m = cb->stat_map;
952 char *p;
953
954 if (hs == NULL)
955 ts = NULL;
956 p = ts;
957
958 while (m)
959 {
960 char *q = strchr (m, ',');
961 int size;
962
963 /* FIXME: Use sscanf? */
964 if (q == NULL)
965 {
966 /* FIXME: print error message */
967 return 0;
968 }
969 size = atoi (q + 1);
970 if (size == 0)
971 {
972 /* FIXME: print error message */
973 return 0;
974 }
975
976 if (hs != NULL)
977 {
978 if (0)
979 ;
980 /* Defined here to avoid emacs indigestion on a lone "else". */
981 #undef ST_x
982 #define ST_x(FLD) \
983 else if (strncmp (m, #FLD, q - m) == 0) \
984 cb_store_target_endian (cb, p, size, hs->FLD)
985
986 #ifdef HAVE_STRUCT_STAT_ST_DEV
987 ST_x (st_dev);
988 #endif
989 #ifdef HAVE_STRUCT_STAT_ST_INO
990 ST_x (st_ino);
991 #endif
992 #ifdef HAVE_STRUCT_STAT_ST_MODE
993 ST_x (st_mode);
994 #endif
995 #ifdef HAVE_STRUCT_STAT_ST_NLINK
996 ST_x (st_nlink);
997 #endif
998 #ifdef HAVE_STRUCT_STAT_ST_UID
999 ST_x (st_uid);
1000 #endif
1001 #ifdef HAVE_STRUCT_STAT_ST_GID
1002 ST_x (st_gid);
1003 #endif
1004 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1005 ST_x (st_rdev);
1006 #endif
1007 #ifdef HAVE_STRUCT_STAT_ST_SIZE
1008 ST_x (st_size);
1009 #endif
1010 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1011 ST_x (st_blksize);
1012 #endif
1013 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1014 ST_x (st_blocks);
1015 #endif
1016 #ifdef HAVE_STRUCT_STAT_ST_ATIME
1017 ST_x (st_atime);
1018 #endif
1019 #ifdef HAVE_STRUCT_STAT_ST_MTIME
1020 ST_x (st_mtime);
1021 #endif
1022 #ifdef HAVE_STRUCT_STAT_ST_CTIME
1023 ST_x (st_ctime);
1024 #endif
1025 #undef ST_x
1026 /* FIXME:wip */
1027 else
1028 /* Unsupported field, store 0. */
1029 cb_store_target_endian (cb, p, size, 0);
1030 }
1031
1032 p += size;
1033 m = strchr (q, ':');
1034 if (m)
1035 ++m;
1036 }
1037
1038 return p - (char *) ts;
1039 }
1040 \f
1041 /* Cover functions to the vfprintf callbacks.
1042
1043 ??? If one thinks of the callbacks as a subsystem onto itself [or part of
1044 a larger "remote target subsystem"] with a well defined interface, then
1045 one would think that the subsystem would provide these. However, until
1046 one is allowed to create such a subsystem (with its own source tree
1047 independent of any particular user), such a critter can't exist. Thus
1048 these functions are here for the time being. */
1049
1050 void
1051 sim_cb_printf (host_callback *p, const char *fmt, ...)
1052 {
1053 va_list ap;
1054
1055 va_start (ap, fmt);
1056 p->vprintf_filtered (p, fmt, ap);
1057 va_end (ap);
1058 }
1059
1060 void
1061 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
1062 {
1063 va_list ap;
1064
1065 va_start (ap, fmt);
1066 p->evprintf_filtered (p, fmt, ap);
1067 va_end (ap);
1068 }
1069
1070 int
1071 cb_is_stdin (host_callback *cb, int fd)
1072 {
1073 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 0;
1074 }
1075
1076 int
1077 cb_is_stdout (host_callback *cb, int fd)
1078 {
1079 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 1;
1080 }
1081
1082 int
1083 cb_is_stderr (host_callback *cb, int fd)
1084 {
1085 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 2;
1086 }
1087 \f
1088 const char *
1089 cb_host_str_syscall (host_callback *cb, int host_val)
1090 {
1091 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->syscall_map, host_val);
1092
1093 return m ? m->name : NULL;
1094 }
1095
1096 const char *
1097 cb_host_str_errno (host_callback *cb, int host_val)
1098 {
1099 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->errno_map, host_val);
1100
1101 return m ? m->name : NULL;
1102 }
1103
1104 const char *
1105 cb_host_str_signal (host_callback *cb, int host_val)
1106 {
1107 const CB_TARGET_DEFS_MAP *m = cb_host_map_entry (cb->signal_map, host_val);
1108
1109 return m ? m->name : NULL;
1110 }
1111
1112 const char *
1113 cb_target_str_syscall (host_callback *cb, int target_val)
1114 {
1115 const CB_TARGET_DEFS_MAP *m =
1116 cb_target_map_entry (cb->syscall_map, target_val);
1117
1118 return m ? m->name : NULL;
1119 }
1120
1121 const char *
1122 cb_target_str_errno (host_callback *cb, int target_val)
1123 {
1124 const CB_TARGET_DEFS_MAP *m =
1125 cb_target_map_entry (cb->errno_map, target_val);
1126
1127 return m ? m->name : NULL;
1128 }
1129
1130 const char *
1131 cb_target_str_signal (host_callback *cb, int target_val)
1132 {
1133 const CB_TARGET_DEFS_MAP *m =
1134 cb_target_map_entry (cb->signal_map, target_val);
1135
1136 return m ? m->name : NULL;
1137 }
This page took 0.057451 seconds and 4 git commands to generate.