1 /* Remote target callback routines.
2 Copyright 1995, 1996, 1997, 2000, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions.
6 This file is part of GDB.
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.
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.
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. */
22 /* This file provides a standard way for targets to talk to the host OS
29 #ifdef ANSI_PROTOTYPES
48 #include <sys/types.h>
50 #include "gdb/callback.h"
51 #include "targ-vals.h"
57 /* ??? sim_cb_printf should be cb_printf, but until the callback support is
58 broken out of the simulator directory, these are here to not require
60 void sim_cb_printf
PARAMS ((host_callback
*, const char *, ...));
61 void sim_cb_eprintf
PARAMS ((host_callback
*, const char *, ...));
63 extern CB_TARGET_DEFS_MAP cb_init_syscall_map
[];
64 extern CB_TARGET_DEFS_MAP cb_init_errno_map
[];
65 extern CB_TARGET_DEFS_MAP cb_init_open_map
[];
67 extern int system
PARAMS ((const char *));
69 static int os_init
PARAMS ((host_callback
*));
70 static int os_shutdown
PARAMS ((host_callback
*));
71 static int os_unlink
PARAMS ((host_callback
*, const char *));
72 static long os_time
PARAMS ((host_callback
*, long *));
73 static int os_system
PARAMS ((host_callback
*, const char *));
74 static int os_rename
PARAMS ((host_callback
*, const char *, const char *));
75 static int os_write_stdout
PARAMS ((host_callback
*, const char *, int));
76 static void os_flush_stdout
PARAMS ((host_callback
*));
77 static int os_write_stderr
PARAMS ((host_callback
*, const char *, int));
78 static void os_flush_stderr
PARAMS ((host_callback
*));
79 static int os_write
PARAMS ((host_callback
*, int, const char *, int));
80 static int os_read_stdin
PARAMS ((host_callback
*, char *, int));
81 static int os_read
PARAMS ((host_callback
*, int, char *, int));
82 static int os_open
PARAMS ((host_callback
*, const char *, int));
83 static int os_lseek
PARAMS ((host_callback
*, int, long, int));
84 static int os_isatty
PARAMS ((host_callback
*, int));
85 static int os_get_errno
PARAMS ((host_callback
*));
86 static int os_close
PARAMS ((host_callback
*, int));
87 static void os_vprintf_filtered
PARAMS ((host_callback
*, const char *, va_list));
88 static void os_evprintf_filtered
PARAMS ((host_callback
*, const char *, va_list));
89 static void os_error
PARAMS ((host_callback
*, const char *, ...));
90 static int fdmap
PARAMS ((host_callback
*, int));
91 static int fdbad
PARAMS ((host_callback
*, int));
92 static int wrap
PARAMS ((host_callback
*, int));
94 /* Set the callback copy of errno from what we see now. */
101 p
->last_errno
= errno
;
105 /* Make sure the FD provided is ok. If not, return non-zero
113 if (fd
< 0 || fd
> MAX_CALLBACK_FDS
|| p
->fd_buddy
[fd
] < 0)
115 p
->last_errno
= EINVAL
;
137 result
= fdbad (p
, fd
);
140 /* If this file descripter has one or more buddies (originals /
141 duplicates from a dup), just remove it from the circular list. */
142 for (i
= fd
; (next
= p
->fd_buddy
[i
]) != fd
; )
145 p
->fd_buddy
[i
] = p
->fd_buddy
[fd
];
147 result
= wrap (p
, close (fdmap (p
, fd
)));
148 p
->fd_buddy
[fd
] = -1;
154 /* taken from gdb/util.c:notice_quit() - should be in a library */
157 #if defined(__GO32__) || defined (_MSC_VER)
162 #if defined(__GO32__)
178 sim_cb_eprintf (p
, "CTRL-A to quit, CTRL-B to quit harder\n");
182 #if defined (_MSC_VER)
183 /* NB - this will not compile! */
184 int k
= win32pollquit();
193 #define os_poll_quit 0
194 #endif /* defined(__GO32__) || defined(_MSC_VER) */
200 return cb_host_to_target_errno (p
, p
->last_errno
);
211 result
= fdbad (p
, fd
);
214 result
= wrap (p
, isatty (fdmap (p
, fd
)));
220 os_lseek (p
, fd
, off
, way
)
228 result
= fdbad (p
, fd
);
231 result
= lseek (fdmap (p
, fd
), off
, way
);
236 os_open (p
, name
, flags
)
242 for (i
= 0; i
< MAX_CALLBACK_FDS
; i
++)
244 if (p
->fd_buddy
[i
] < 0)
246 int f
= open (name
, cb_target_to_host_open (p
, flags
), 0644);
249 p
->last_errno
= errno
;
257 p
->last_errno
= EMFILE
;
262 os_read (p
, fd
, buf
, len
)
270 result
= fdbad (p
, fd
);
273 result
= wrap (p
, read (fdmap (p
, fd
), buf
, len
));
278 os_read_stdin (p
, buf
, len
)
283 return wrap (p
, read (0, buf
, len
));
287 os_write (p
, fd
, buf
, len
)
296 result
= fdbad (p
, fd
);
299 real_fd
= fdmap (p
, fd
);
303 result
= wrap (p
, write (real_fd
, buf
, len
));
306 result
= p
->write_stdout (p
, buf
, len
);
309 result
= p
->write_stderr (p
, buf
, len
);
316 os_write_stdout (p
, buf
, len
)
317 host_callback
*p ATTRIBUTE_UNUSED
;
321 return fwrite (buf
, 1, len
, stdout
);
326 host_callback
*p ATTRIBUTE_UNUSED
;
332 os_write_stderr (p
, buf
, len
)
333 host_callback
*p ATTRIBUTE_UNUSED
;
337 return fwrite (buf
, 1, len
, stderr
);
342 host_callback
*p ATTRIBUTE_UNUSED
;
348 os_rename (p
, f1
, f2
)
353 return wrap (p
, rename (f1
, f2
));
362 return wrap (p
, system (s
));
370 return wrap (p
, time (t
));
379 return wrap (p
, unlink (f1
));
383 os_stat (p
, file
, buf
)
388 /* ??? There is an issue of when to translate to the target layout.
389 One could do that inside this function, or one could have the
390 caller do it. It's more flexible to let the caller do it, though
391 I'm not sure the flexibility will ever be useful. */
392 return wrap (p
, stat (file
, buf
));
396 os_fstat (p
, fd
, buf
)
403 /* ??? There is an issue of when to translate to the target layout.
404 One could do that inside this function, or one could have the
405 caller do it. It's more flexible to let the caller do it, though
406 I'm not sure the flexibility will ever be useful. */
407 return wrap (p
, fstat (fdmap (p
, fd
), buf
));
411 os_lstat (p
, file
, buf
)
416 /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat. */
417 return wrap (p
, lstat (file
, buf
));
421 os_ftruncate (p
, fd
, len
)
428 result
= fdbad (p
, fd
);
431 result
= wrap (p
, ftruncate (fdmap (p
, fd
), len
));
436 os_truncate (p
, file
, len
)
441 return wrap (p
, truncate (file
, len
));
449 for (i
= 0; i
< MAX_CALLBACK_FDS
; i
++)
453 next
= p
->fd_buddy
[i
];
459 if (j
== MAX_CALLBACK_FDS
)
461 next
= p
->fd_buddy
[j
];
463 /* At the initial call of os_init, we got -1, 0, 0, 0, ... */
485 for (i
= 0; i
< 3; i
++)
488 p
->fd_buddy
[i
] = i
- 1;
490 p
->fd_buddy
[0] = MAX_CALLBACK_FDS
;
491 p
->fd_buddy
[MAX_CALLBACK_FDS
] = 2;
493 p
->syscall_map
= cb_init_syscall_map
;
494 p
->errno_map
= cb_init_errno_map
;
495 p
->open_map
= cb_init_open_map
;
504 #ifdef ANSI_PROTOTYPES
505 os_printf_filtered (host_callback
*p ATTRIBUTE_UNUSED
, const char *format
, ...)
507 os_printf_filtered (p
, va_alist
)
513 #ifdef ANSI_PROTOTYPES
514 va_start (args
, format
);
519 format
= va_arg (args
, char *);
522 vfprintf (stdout
, format
, args
);
528 #ifdef ANSI_PROTOTYPES
529 os_vprintf_filtered (host_callback
*p ATTRIBUTE_UNUSED
, const char *format
, va_list args
)
531 os_vprintf_filtered (p
, format
, args
)
537 vprintf (format
, args
);
542 #ifdef ANSI_PROTOTYPES
543 os_evprintf_filtered (host_callback
*p ATTRIBUTE_UNUSED
, const char *format
, va_list args
)
545 os_evprintf_filtered (p
, format
, args
)
551 vfprintf (stderr
, format
, args
);
556 #ifdef ANSI_PROTOTYPES
557 os_error (host_callback
*p ATTRIBUTE_UNUSED
, const char *format
, ...)
559 os_error (p
, va_alist
)
565 #ifdef ANSI_PROTOTYPES
566 va_start (args
, format
);
571 format
= va_arg (args
, char *);
574 vfprintf (stderr
, format
, args
);
575 fprintf (stderr
, "\n");
581 host_callback default_callback
=
612 os_printf_filtered
, /* deprecated */
615 os_evprintf_filtered
,
621 { -1, }, /* fd_buddy */
629 /* Defaults expected to be overridden at initialization, where needed. */
630 BFD_ENDIAN_UNKNOWN
, /* target_endian */
635 /* Read in a file describing the target's system call values.
636 E.g. maybe someone will want to use something other than newlib.
637 This assumes that the basic system call recognition and value passing/
638 returning is supported. So maybe some coding/recompilation will be
639 necessary, but not as much.
641 If an error occurs, the existing mapping is not changed. */
644 cb_read_target_syscall_maps (cb
, file
)
648 CB_TARGET_DEFS_MAP
*syscall_map
, *errno_map
, *open_map
, *signal_map
;
649 const char *stat_map
;
652 if ((f
= fopen (file
, "r")) == NULL
)
655 /* ... read in and parse file ... */
658 return CB_RC_NO_MEM
; /* FIXME:wip */
660 /* Free storage allocated for any existing maps. */
662 free (cb
->syscall_map
);
664 free (cb
->errno_map
);
668 free (cb
->signal_map
);
670 free ((PTR
) cb
->stat_map
);
672 cb
->syscall_map
= syscall_map
;
673 cb
->errno_map
= errno_map
;
674 cb
->open_map
= open_map
;
675 cb
->signal_map
= signal_map
;
676 cb
->stat_map
= stat_map
;
681 /* Translate the target's version of a syscall number to the host's.
682 This isn't actually the host's version, rather a canonical form.
683 ??? Perhaps this should be renamed to ..._canon_syscall. */
686 cb_target_to_host_syscall (cb
, target_val
)
690 CB_TARGET_DEFS_MAP
*m
;
692 for (m
= &cb
->syscall_map
[0]; m
->target_val
!= -1; ++m
)
693 if (m
->target_val
== target_val
)
699 /* FIXME: sort tables if large.
700 Alternatively, an obvious improvement for errno conversion is
701 to machine generate a function with a large switch(). */
703 /* Translate the host's version of errno to the target's. */
706 cb_host_to_target_errno (cb
, host_val
)
710 CB_TARGET_DEFS_MAP
*m
;
712 for (m
= &cb
->errno_map
[0]; m
->host_val
; ++m
)
713 if (m
->host_val
== host_val
)
714 return m
->target_val
;
716 /* ??? Which error to return in this case is up for grabs.
717 Note that some missing values may have standard alternatives.
718 For now return 0 and require caller to deal with it. */
722 /* Given a set of target bitmasks for the open system call,
723 return the host equivalent.
724 Mapping open flag values is best done by looping so there's no need
725 to machine generate this function. */
728 cb_target_to_host_open (cb
, target_val
)
733 CB_TARGET_DEFS_MAP
*m
;
735 for (m
= &cb
->open_map
[0]; m
->host_val
!= -1; ++m
)
737 switch (m
->target_val
)
739 /* O_RDONLY can be (and usually is) 0 which needs to be treated
741 case TARGET_O_RDONLY
:
742 case TARGET_O_WRONLY
:
744 if ((target_val
& (TARGET_O_RDONLY
| TARGET_O_WRONLY
| TARGET_O_RDWR
))
746 host_val
|= m
->host_val
;
747 /* Handle the host/target differentiating between binary and
748 text mode. Only one case is of importance */
749 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
750 host_val
|= O_BINARY
;
754 if ((m
->target_val
& target_val
) == m
->target_val
)
755 host_val
|= m
->host_val
;
763 /* Utility for e.g. cb_host_to_target_stat to store values in the target's
767 cb_store_target_endian (cb
, p
, size
, val
)
771 long val
; /* ??? must be as big as target word size */
773 if (cb
->target_endian
== BFD_ENDIAN_BIG
)
792 /* Translate a host's stat struct into a target's.
793 If HS is NULL, just compute the length of the buffer required,
796 The result is the size of the target's stat struct,
797 or zero if an error occurred during the translation. */
800 cb_host_to_target_stat (cb
, hs
, ts
)
802 const struct stat
*hs
;
805 const char *m
= cb
->stat_map
;
814 char *q
= strchr (m
, ',');
817 /* FIXME: Use sscanf? */
820 /* FIXME: print error message */
826 /* FIXME: print error message */
834 /* Defined here to avoid emacs indigestion on a lone "else". */
837 else if (strncmp (m, #FLD, q - m) == 0) \
838 cb_store_target_endian (cb, p, size, hs->FLD)
840 #ifdef HAVE_STRUCT_STAT_ST_DEV
843 #ifdef HAVE_STRUCT_STAT_ST_INO
846 #ifdef HAVE_STRUCT_STAT_ST_MODE
849 #ifdef HAVE_STRUCT_STAT_ST_NLINK
852 #ifdef HAVE_STRUCT_STAT_ST_UID
855 #ifdef HAVE_STRUCT_STAT_ST_GID
858 #ifdef HAVE_STRUCT_STAT_ST_RDEV
861 #ifdef HAVE_STRUCT_STAT_ST_SIZE
864 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
867 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
870 #ifdef HAVE_STRUCT_STAT_ST_ATIME
873 #ifdef HAVE_STRUCT_STAT_ST_MTIME
876 #ifdef HAVE_STRUCT_STAT_ST_CTIME
882 /* Unsupported field, store 0. */
883 cb_store_target_endian (cb
, p
, size
, 0);
892 return p
- (char *) ts
;
895 /* Cover functions to the vfprintf callbacks.
897 ??? If one thinks of the callbacks as a subsystem onto itself [or part of
898 a larger "remote target subsystem"] with a well defined interface, then
899 one would think that the subsystem would provide these. However, until
900 one is allowed to create such a subsystem (with its own source tree
901 independent of any particular user), such a critter can't exist. Thus
902 these functions are here for the time being. */
905 sim_cb_printf (host_callback
*p
, const char *fmt
, ...)
910 p
->vprintf_filtered (p
, fmt
, ap
);
915 sim_cb_eprintf (host_callback
*p
, const char *fmt
, ...)
920 p
->evprintf_filtered (p
, fmt
, ap
);