aboutsummaryrefslogtreecommitdiff
path: root/sim/common/callback.c
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>1999-04-16 01:34:07 +0000
committerStan Shebs <shebs@codesourcery.com>1999-04-16 01:34:07 +0000
commit071ea11e85eb9d529cc5eb3d35f6247466a21b99 (patch)
tree5deda65b8d7b04d1f4cbc534c3206d328e1267ec /sim/common/callback.c
parent1730ec6b1848f0f32154277f788fb29f88d8475b (diff)
downloadgdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.zip
gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.gz
gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.bz2
Initial creation of sourceware repository
Diffstat (limited to 'sim/common/callback.c')
-rw-r--r--sim/common/callback.c808
1 files changed, 0 insertions, 808 deletions
diff --git a/sim/common/callback.c b/sim/common/callback.c
deleted file mode 100644
index 068cea2..0000000
--- a/sim/common/callback.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/* Remote target callback routines.
- Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
- Contributed by Cygnus Solutions.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GAS; see the file COPYING. If not, write to the Free Software
- Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* This file provides a standard way for targets to talk to the host OS
- level. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "ansidecl.h"
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "callback.h"
-#include "targ-vals.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-/* ??? sim_cb_printf should be cb_printf, but until the callback support is
- broken out of the simulator directory, these are here to not require
- sim-utils.h. */
-void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
-void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
-
-extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
-extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
-extern CB_TARGET_DEFS_MAP cb_init_open_map[];
-
-extern int system PARAMS ((const char *));
-
-static int os_init PARAMS ((host_callback *));
-static int os_shutdown PARAMS ((host_callback *));
-static int os_unlink PARAMS ((host_callback *, const char *));
-static long os_time PARAMS ((host_callback *, long *));
-static int os_system PARAMS ((host_callback *, const char *));
-static int os_rename PARAMS ((host_callback *, const char *, const char *));
-static int os_write_stdout PARAMS ((host_callback *, const char *, int));
-static void os_flush_stdout PARAMS ((host_callback *));
-static int os_write_stderr PARAMS ((host_callback *, const char *, int));
-static void os_flush_stderr PARAMS ((host_callback *));
-static int os_write PARAMS ((host_callback *, int, const char *, int));
-static int os_read_stdin PARAMS ((host_callback *, char *, int));
-static int os_read PARAMS ((host_callback *, int, char *, int));
-static int os_open PARAMS ((host_callback *, const char *, int));
-static int os_lseek PARAMS ((host_callback *, int, long, int));
-static int os_isatty PARAMS ((host_callback *, int));
-static int os_get_errno PARAMS ((host_callback *));
-static int os_close PARAMS ((host_callback *, int));
-static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
-static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
-static void os_error PARAMS ((host_callback *, const char *, ...));
-static int fdmap PARAMS ((host_callback *, int));
-static int fdbad PARAMS ((host_callback *, int));
-static int wrap PARAMS ((host_callback *, int));
-static int enosys PARAMS ((host_callback *, int));
-
-/* Set the callback copy of errno from what we see now. */
-
-static int
-wrap (p, val)
- host_callback *p;
- int val;
-{
- p->last_errno = errno;
- return val;
-}
-
-/* Return a value indicating the system call isn't present. */
-
-static int
-enosys (p, result)
- host_callback *p;
- int result;
-{
-#ifdef ENOSYS
- p->last_errno = ENOSYS;
-#else
- p->last_errno = EINVAL;
-#endif
- return result;
-}
-
-/* Make sure the FD provided is ok. If not, return non-zero
- and set errno. */
-
-static int
-fdbad (p, fd)
- host_callback *p;
- int fd;
-{
- if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
- {
- p->last_errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-static int
-fdmap (p, fd)
- host_callback *p;
- int fd;
-{
- return p->fdmap[fd];
-}
-
-static int
-os_close (p, fd)
- host_callback *p;
- int fd;
-{
- int result;
-
- result = fdbad (p, fd);
- if (result)
- return result;
- result = wrap (p, close (fdmap (p, fd)));
- if(result == 0 && !p->alwaysopen[fd])
- p->fdopen[fd] = 0;
-
- return result;
-}
-
-
-/* taken from gdb/util.c:notice_quit() - should be in a library */
-
-
-#if defined(__GO32__) || defined (_MSC_VER)
-static int
-os_poll_quit (p)
- host_callback *p;
-{
-#if defined(__GO32__)
- int kbhit ();
- int getkey ();
- if (kbhit ())
- {
- int k = getkey ();
- if (k == 1)
- {
- return 1;
- }
- else if (k == 2)
- {
- return 1;
- }
- else
- {
- sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
- }
- }
-#endif
-#if defined (_MSC_VER)
- /* NB - this will not compile! */
- int k = win32pollquit();
- if (k == 1)
- return 1;
- else if (k == 2)
- return 1;
-#endif
- return 0;
-}
-#else
-#define os_poll_quit 0
-#endif /* defined(__GO32__) || defined(_MSC_VER) */
-
-static int
-os_get_errno (p)
- host_callback *p;
-{
- return cb_host_to_target_errno (p, p->last_errno);
-}
-
-
-static int
-os_isatty (p, fd)
- host_callback *p;
- int fd;
-{
- int result;
-
- result = fdbad (p, fd);
- if (result)
- return result;
- result = wrap (p, isatty (fdmap (p, fd)));
-
- return result;
-}
-
-static int
-os_lseek (p, fd, off, way)
- host_callback *p;
- int fd;
- long off;
- int way;
-{
- int result;
-
- result = fdbad (p, fd);
- if (result)
- return result;
- result = lseek (fdmap (p, fd), off, way);
- return result;
-}
-
-static int
-os_open (p, name, flags)
- host_callback *p;
- const char *name;
- int flags;
-{
- int i;
- for (i = 0; i < MAX_CALLBACK_FDS; i++)
- {
- if (!p->fdopen[i])
- {
- int f = open (name, cb_target_to_host_open (p, flags), 0644);
- if (f < 0)
- {
- p->last_errno = errno;
- return f;
- }
- p->fdopen[i] = 1;
- p->fdmap[i] = f;
- return i;
- }
- }
- p->last_errno = EMFILE;
- return -1;
-}
-
-static int
-os_read (p, fd, buf, len)
- host_callback *p;
- int fd;
- char *buf;
- int len;
-{
- int result;
-
- result = fdbad (p, fd);
- if (result)
- return result;
- result = wrap (p, read (fdmap (p, fd), buf, len));
- return result;
-}
-
-static int
-os_read_stdin (p, buf, len)
- host_callback *p;
- char *buf;
- int len;
-{
- return wrap (p, read (0, buf, len));
-}
-
-static int
-os_write (p, fd, buf, len)
- host_callback *p;
- int fd;
- const char *buf;
- int len;
-{
- int result;
- int real_fd;
-
- result = fdbad (p, fd);
- if (result)
- return result;
- real_fd = fdmap (p, fd);
- switch (real_fd)
- {
- default:
- result = wrap (p, write (real_fd, buf, len));
- break;
- case 1:
- result = p->write_stdout (p, buf, len);
- break;
- case 2:
- result = p->write_stderr (p, buf, len);
- break;
- }
- return result;
-}
-
-static int
-os_write_stdout (p, buf, len)
- host_callback *p;
- const char *buf;
- int len;
-{
- return fwrite(buf, 1, len, stdout);
-}
-
-static void
-os_flush_stdout (p)
- host_callback *p;
-{
- fflush (stdout);
-}
-
-static int
-os_write_stderr (p, buf, len)
- host_callback *p;
- const char *buf;
- int len;
-{
- return fwrite(buf, 1, len, stderr);
-}
-
-static void
-os_flush_stderr (p)
- host_callback *p;
-{
- fflush (stderr);
-}
-
-static int
-os_rename (p, f1, f2)
- host_callback *p;
- const char *f1;
- const char *f2;
-{
- return wrap (p, rename (f1, f2));
-}
-
-
-static int
-os_system (p, s)
- host_callback *p;
- const char *s;
-{
- return wrap (p, system (s));
-}
-
-static long
-os_time (p, t)
- host_callback *p;
- long *t;
-{
- return wrap (p, time (t));
-}
-
-
-static int
-os_unlink (p, f1)
- host_callback *p;
- const char *f1;
-{
- return wrap (p, unlink (f1));
-}
-
-static int
-os_stat (p, file, buf)
- host_callback *p;
- const char *file;
- PTR buf;
-{
- return wrap (p, stat (file, buf));
-}
-
-static int
-os_fstat (p, fd, buf)
- host_callback *p;
- int fd;
- PTR buf;
-{
- return wrap (p, fstat (fd, buf));
-}
-
-static int
-os_shutdown (p)
- host_callback *p;
-{
- int i;
- for (i = 0; i < MAX_CALLBACK_FDS; i++)
- {
- if (p->fdopen[i] && !p->alwaysopen[i]) {
- close (p->fdmap[i]);
- p->fdopen[i] = 0;
- }
- }
- return 1;
-}
-
-static int
-os_init (p)
- host_callback *p;
-{
- int i;
-
- os_shutdown (p);
- for (i = 0; i < 3; i++)
- {
- p->fdmap[i] = i;
- p->fdopen[i] = 1;
- p->alwaysopen[i] = 1;
- }
-
- p->syscall_map = cb_init_syscall_map;
- p->errno_map = cb_init_errno_map;
- p->open_map = cb_init_open_map;
-
- return 1;
-}
-
-/* DEPRECIATED */
-
-/* VARARGS */
-static void
-#ifdef ANSI_PROTOTYPES
-os_printf_filtered (host_callback *p, const char *format, ...)
-#else
-os_printf_filtered (p, va_alist)
- host_callback *p;
- va_dcl
-#endif
-{
- va_list args;
-#ifdef ANSI_PROTOTYPES
- va_start (args, format);
-#else
- char *format;
-
- va_start (args);
- format = va_arg (args, char *);
-#endif
-
- vfprintf (stdout, format, args);
- va_end (args);
-}
-
-/* VARARGS */
-static void
-#ifdef ANSI_PROTOTYPES
-os_vprintf_filtered (host_callback *p, const char *format, va_list args)
-#else
-os_vprintf_filtered (p, format, args)
- host_callback *p;
- const char *format;
- va_list args;
-#endif
-{
- vprintf (format, args);
-}
-
-/* VARARGS */
-static void
-#ifdef ANSI_PROTOTYPES
-os_evprintf_filtered (host_callback *p, const char *format, va_list args)
-#else
-os_evprintf_filtered (p, format, args)
- host_callback *p;
- const char *format;
- va_list args;
-#endif
-{
- vfprintf (stderr, format, args);
-}
-
-/* VARARGS */
-static void
-#ifdef ANSI_PROTOTYPES
-os_error (host_callback *p, const char *format, ...)
-#else
-os_error (p, va_alist)
- host_callback *p;
- va_dcl
-#endif
-{
- va_list args;
-#ifdef ANSI_PROTOTYPES
- va_start (args, format);
-#else
- char *format;
-
- va_start (args);
- format = va_arg (args, char *);
-#endif
-
- vfprintf (stderr, format, args);
- fprintf (stderr, "\n");
-
- va_end (args);
- exit (1);
-}
-
-host_callback default_callback =
-{
- os_close,
- os_get_errno,
- os_isatty,
- os_lseek,
- os_open,
- os_read,
- os_read_stdin,
- os_rename,
- os_system,
- os_time,
- os_unlink,
- os_write,
- os_write_stdout,
- os_flush_stdout,
- os_write_stderr,
- os_flush_stderr,
-
- os_stat,
- os_fstat,
-
- os_poll_quit,
-
- os_shutdown,
- os_init,
-
- os_printf_filtered, /* deprecated */
-
- os_vprintf_filtered,
- os_evprintf_filtered,
- os_error,
-
- 0, /* last errno */
-
- { 0, }, /* fdmap */
- { 0, }, /* fdopen */
- { 0, }, /* alwaysopen */
-
- 0, /* syscall_map */
- 0, /* errno_map */
- 0, /* open_map */
- 0, /* signal_map */
- 0, /* stat_map */
-
- HOST_CALLBACK_MAGIC,
-};
-
-/* Read in a file describing the target's system call values.
- E.g. maybe someone will want to use something other than newlib.
- This assumes that the basic system call recognition and value passing/
- returning is supported. So maybe some coding/recompilation will be
- necessary, but not as much.
-
- If an error occurs, the existing mapping is not changed. */
-
-CB_RC
-cb_read_target_syscall_maps (cb, file)
- host_callback *cb;
- const char *file;
-{
- CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
- const char *stat_map;
- FILE *f;
-
- if ((f = fopen (file, "r")) == NULL)
- return CB_RC_ACCESS;
-
- /* ... read in and parse file ... */
-
- fclose (f);
- return CB_RC_NO_MEM; /* FIXME:wip */
-
- /* Free storage allocated for any existing maps. */
- if (cb->syscall_map)
- free (cb->syscall_map);
- if (cb->errno_map)
- free (cb->errno_map);
- if (cb->open_map)
- free (cb->open_map);
- if (cb->signal_map)
- free (cb->signal_map);
- if (cb->stat_map)
- free ((PTR) cb->stat_map);
-
- cb->syscall_map = syscall_map;
- cb->errno_map = errno_map;
- cb->open_map = open_map;
- cb->signal_map = signal_map;
- cb->stat_map = stat_map;
-
- return CB_RC_OK;
-}
-
-/* Translate the target's version of a syscall number to the host's.
- This isn't actually the host's version, rather a canonical form.
- ??? Perhaps this should be renamed to ..._canon_syscall. */
-
-int
-cb_target_to_host_syscall (cb, target_val)
- host_callback *cb;
- int target_val;
-{
- CB_TARGET_DEFS_MAP *m;
-
- for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
- if (m->target_val == target_val)
- return m->host_val;
-
- return -1;
-}
-
-/* FIXME: sort tables if large.
- Alternatively, an obvious improvement for errno conversion is
- to machine generate a function with a large switch(). */
-
-/* Translate the host's version of errno to the target's. */
-
-int
-cb_host_to_target_errno (cb, host_val)
- host_callback *cb;
- int host_val;
-{
- CB_TARGET_DEFS_MAP *m;
-
- for (m = &cb->errno_map[0]; m->host_val; ++m)
- if (m->host_val == host_val)
- return m->target_val;
-
- /* ??? Which error to return in this case is up for grabs.
- Note that some missing values may have standard alternatives.
- For now return 0 and require caller to deal with it. */
- return 0;
-}
-
-/* Given a set of target bitmasks for the open system call,
- return the host equivalent.
- Mapping open flag values is best done by looping so there's no need
- to machine generate this function. */
-
-int
-cb_target_to_host_open (cb, target_val)
- host_callback *cb;
- int target_val;
-{
- int host_val = 0;
- CB_TARGET_DEFS_MAP *m;
-
- for (m = &cb->open_map[0]; m->host_val != -1; ++m)
- {
- switch (m->target_val)
- {
- /* O_RDONLY can be (and usually is) 0 which needs to be treated
- specially. */
- case TARGET_O_RDONLY :
- case TARGET_O_WRONLY :
- case TARGET_O_RDWR :
- if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
- == m->target_val)
- host_val |= m->host_val;
- /* Handle the host/target differentiating between binary and
- text mode. Only one case is of importance */
-#if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
- host_val |= O_BINARY;
-#endif
- break;
- default :
- if ((m->target_val & target_val) == m->target_val)
- host_val |= m->host_val;
- break;
- }
- }
-
- return host_val;
-}
-
-/* Utility for cb_host_to_target_stat to store values in the target's
- stat struct. */
-
-static void
-store (p, size, val, big_p)
- char *p;
- int size;
- long val; /* ??? must be as big as target word size */
- int big_p;
-{
- if (big_p)
- {
- p += size;
- while (size-- > 0)
- {
- *--p = val;
- val >>= 8;
- }
- }
- else
- {
- while (size-- > 0)
- {
- *p++ = val;
- val >>= 8;
- }
- }
-}
-
-/* Translate a host's stat struct into a target's.
-
- BIG_P is non-zero if the target is big-endian.
- The result is the size of the target's stat struct,
- or zero if an error occured during the translation. */
-
-int
-cb_host_to_target_stat (cb, hs, ts, big_p)
- host_callback *cb;
- const struct stat *hs;
- PTR ts;
- int big_p;
-{
- const char *m = cb->stat_map;
- char *p = ts;
-
- while (m)
- {
- char *q = strchr (m, ',');
- int size;
-
- /* FIXME: Use sscanf? */
- if (q == NULL)
- {
- /* FIXME: print error message */
- return 0;
- }
- size = atoi (q + 1);
- if (size == 0)
- {
- /* FIXME: print error message */
- return 0;
- }
-
- if (strncmp (m, "st_dev", q - m) == 0)
- store (p, size, hs->st_dev, big_p);
- else if (strncmp (m, "st_ino", q - m) == 0)
- store (p, size, hs->st_ino, big_p);
- /* FIXME:wip */
- else
- store (p, size, 0, big_p); /* unsupported field, store 0 */
-
- p += size;
- m = strchr (q, ':');
- if (m)
- ++m;
- }
-
- return p - (char *) ts;
-}
-
-/* Cover functions to the vfprintf callbacks.
-
- ??? If one thinks of the callbacks as a subsystem onto itself [or part of
- a larger "remote target subsystem"] with a well defined interface, then
- one would think that the subsystem would provide these. However, until
- one is allowed to create such a subsystem (with its own source tree
- independent of any particular user), such a critter can't exist. Thus
- these functions are here for the time being. */
-
-void
-sim_cb_printf (host_callback *p, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- p->vprintf_filtered (p, fmt, ap);
- va_end (ap);
-}
-
-void
-sim_cb_eprintf (host_callback *p, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- p->evprintf_filtered (p, fmt, ap);
- va_end (ap);
-}