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