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