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