From f7abc1ca0cbae80f1910de13c969816d14d8acb2 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Mon, 17 Nov 1997 23:09:08 +0000 Subject: [PATCH] * Make-common.in (DEP, COMMON_DEP_CFLAGS): Define. (LIB_OBJS): Add syscall.o. (gentmap): Pass $(NL_TARGET) to $(CC). (syscall.o): Add rule for. (sim_main_headers): Add $(SIM_EXTRA_DEPS). (sim-bits.o): Depend on $(sim-n-bits_h). (sim-load.o): Depend on callback.h. * Make-common.in (cgen-*.o): Update dependencies, mem-ops.h renamed to cgen-mem.h, sem-ops.h renamed to cgen-ops.h. * cgen-mem.h, cgen-ops.h: New files. * aclocal.m4 (--enable-sim-scache): Pass -DWITH_SCACHE=0 for "=no". * Makefile.in (nltvals.def): Depend on gennltvals.sh. Rewrite build rule. * callback.c: #include string.h or strings.h. #include sys/types.h and sys/stat.h. (cb_init_syscall_map,cb_init_errno_map,cb_init_open_map): Declare. (enosys): New function. (os_get_errno,os_open): Update. (os_stat,os_fstat): New functions. (os_init): Initialize syscall_map, errno_map, open_map. (default_callback): Add entries for os_stat, os_fstat, syscall_map, errno_map, open_map, signal_map, stat_map. (cb_read_target_syscall_maps): New function. (cb_target_to_host_syscall): New function. (cb_host_to_target_errno): Renamed from host_to_target_errno. (cb_target_to_host_open): Renamed from target_to_host_open. (store): New function. (cb_host_to_target_stat): New function. * gentmap.c (sys_tdefs): New global. (gen_targ_vals_h): Output target syscall numbers. (gen_targ_map_c): Update. Output target syscall translation map. * gentvals.sh: New first argument `target'. Preface table with #ifdef NL_TARGET_$target if non-null target passed. * gennltvals.sh: New file. * nltvals.def: Regenerated. --- sim/common/.Sanitize | 4 + sim/common/ChangeLog | 53 ++++++++ sim/common/Make-common.in | 82 +++++++------ sim/common/callback.c | 263 +++++++++++++++++++++++++++++++++++---- sim/common/syscall.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 644 insertions(+), 64 deletions(-) create mode 100644 sim/common/syscall.c diff --git a/sim/common/.Sanitize b/sim/common/.Sanitize index 7dd8777..e61d75e 100644 --- a/sim/common/.Sanitize +++ b/sim/common/.Sanitize @@ -28,6 +28,8 @@ Make-common.in Makefile.in aclocal.m4 callback.c +cgen-mem.h +cgen-ops.h cgen-scache.c cgen-scache.h cgen-sim.h @@ -40,6 +42,7 @@ configure.in configure gdbinit.in genmloop.sh +gennltvals.sh gentmap.c gentvals.sh nltvals.def @@ -99,6 +102,7 @@ sim-utils.h sim-watch.c sim-watch.h sim-xcat.h +syscall.c tconfig.in Things-to-lose: diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 87877de..abc3d86 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,56 @@ +Mon Nov 17 14:15:31 1997 Doug Evans + + * Make-common.in (DEP, COMMON_DEP_CFLAGS): Define. + (LIB_OBJS): Add syscall.o. + (gentmap): Pass $(NL_TARGET) to $(CC). + (syscall.o): Add rule for. + (sim_main_headers): Add $(SIM_EXTRA_DEPS). + (sim-bits.o): Depend on $(sim-n-bits_h). + (sim-load.o): Depend on callback.h. + + * Make-common.in (cgen-*.o): Update dependencies, mem-ops.h renamed to + cgen-mem.h, sem-ops.h renamed to cgen-ops.h. + * cgen-mem.h, cgen-ops.h: New files. + + * aclocal.m4 (--enable-sim-scache): Pass -DWITH_SCACHE=0 for "=no". + + * Makefile.in (nltvals.def): Depend on gennltvals.sh. + Rewrite build rule. + * callback.c: #include string.h or strings.h. + #include sys/types.h and sys/stat.h. + (cb_init_syscall_map,cb_init_errno_map,cb_init_open_map): Declare. + (enosys): New function. + (os_get_errno,os_open): Update. + (os_stat,os_fstat): New functions. + (os_init): Initialize syscall_map, errno_map, open_map. + (default_callback): Add entries for os_stat, os_fstat, syscall_map, + errno_map, open_map, signal_map, stat_map. + (cb_read_target_syscall_maps): New function. + (cb_target_to_host_syscall): New function. + (cb_host_to_target_errno): Renamed from host_to_target_errno. + (cb_target_to_host_open): Renamed from target_to_host_open. + (store): New function. + (cb_host_to_target_stat): New function. + * syscall.c: New file. + * gentmap.c (sys_tdefs): New global. + (gen_targ_vals_h): Output target syscall numbers. + (gen_targ_map_c): Update. Output target syscall translation map. + * gentvals.sh: New first argument `target'. Preface table with + #ifdef NL_TARGET_$target if non-null target passed. + * gennltvals.sh: New file. + * nltvals.def: Regenerated. + +Fri Nov 14 11:33:34 1997 Andrew Cagney + + * sim-n-core.h (sim_core_read_unaligned_N): Return static + sim_core_dummy_M. + (sim_core_dummy_M): Declare. + +Wed Nov 12 18:16:15 1997 Andrew Cagney + + * sim-core.c (sim_core_signal): Print the address of the + instruction. + Thu Nov 13 11:49:41 1997 Doug Evans * sim-base.h (sim_state_base): Move `magic' to end of struct. diff --git a/sim/common/Make-common.in b/sim/common/Make-common.in index f2a289f..bb04b97 100644 --- a/sim/common/Make-common.in +++ b/sim/common/Make-common.in @@ -97,6 +97,8 @@ AR_FLAGS = rc RANLIB = @RANLIB@ MAKEINFO = makeinfo +DEP = $(srcroot)/mkdep + # Each simulator's Makefile.in defines one or more of these variables # to override our settings as necessary. There is no need to define these # in the simulator's Makefile.in if one is using the default value. In fact @@ -158,6 +160,8 @@ CSEARCH = -I. -I$(srcdir) -I../common -I$(srcdir)/../common \ ALL_CFLAGS = $(CONFIG_CFLAGS) $(CSEARCH) $(CFLAGS) BUILD_CFLAGS = -g -O $(CSEARCH) +COMMON_DEP_CFLAGS = $(CONFIG_CFLAGS) $(CSEARCH) + LIBIBERTY_LIB = ../../libiberty/libiberty.a BFD_LIB = ../../bfd/libbfd.a OPCODES_LIB = ../../opcodes/libopcodes.a @@ -167,7 +171,7 @@ LIBDEPS = $(BFD_LIB) $(OPCODES_LIB) $(LIBIBERTY_LIB) \ EXTRA_LIBS = $(BFD_LIB) $(OPCODES_LIB) $(LIBIBERTY_LIB) \ $(CONFIG_LIBS) $(SIM_EXTRA_LIBS) -LIB_OBJS = callback.o targ-map.o $(SIM_OBJS) +LIB_OBJS = callback.o syscall.o targ-map.o $(SIM_OBJS) all: $(SIM_EXTRA_ALL) libsim.a run @@ -193,10 +197,14 @@ callback.o: $(srcdir)/../common/callback.c config.h tconfig.h \ $(srcroot)/include/callback.h targ-vals.h $(CC) -c $(srcdir)/../common/callback.c $(ALL_CFLAGS) +syscall.o: $(srcdir)/../common/syscall.c config.h tconfig.h \ + $(srcroot)/include/callback.h targ-vals.h + $(CC) -c $(srcdir)/../common/syscall.c $(ALL_CFLAGS) + targ-map.o: targ-map.c targ-vals.h gentmap: Makefile $(srcdir)/../common/gentmap.c targ-vals.def - $(CC_FOR_BUILD) $(srcdir)/../common/gentmap.c -o gentmap $(BUILD_CFLAGS) + $(CC_FOR_BUILD) $(srcdir)/../common/gentmap.c -o gentmap $(BUILD_CFLAGS) $(NL_TARGET) targ-vals.h: gentmap rm -f targ-vals.h @@ -226,7 +234,8 @@ sim_main_headers = \ $(srcdir)/../common/sim-events.h \ $(srcdir)/../common/sim-watch.h \ $(srcdir)/../common/sim-assert.h \ - tconfig.h + tconfig.h \ + $(SIM_EXTRA_DEPS) sim-assert_h = $(srcdir)/../common/sim-assert.h sim-endian_h = $(srcdir)/../common/sim-endian.h @@ -250,11 +259,11 @@ BUILT_SRC_FROM_COMMON= \ sim-inline.c sim-abort.o: $(srcdir)/../common/sim-abort.c \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-abort.c $(ALL_CFLAGS) sim-bits.o: $(srcdir)/../common/sim-bits.c $(sim-bits_h) $(sim-n-bits_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-bits.c $(ALL_CFLAGS) sim-config.o: $(srcdir)/../common/sim-config.c $(sim-config_h) \ @@ -262,31 +271,30 @@ sim-config.o: $(srcdir)/../common/sim-config.c $(sim-config_h) \ $(CC) -c $(srcdir)/../common/sim-config.c $(ALL_CFLAGS) sim-core.o: $(srcdir)/../common/sim-core.c $(sim-core_h) $(sim-n-core_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-core.c $(ALL_CFLAGS) sim-endian.o: $(srcdir)/../common/sim-endian.c $(sim-endian_h) $(sim-n-endian_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-endian.c $(ALL_CFLAGS) -sim-engine.o: $(srcdir)/../common/sim-engine.c $(sim_main_headers) $(sim-engine_h) \ - $(SIM_EXTRA_DEPS) +sim-engine.o: $(srcdir)/../common/sim-engine.c $(sim_main_headers) $(sim-engine_h) $(CC) -c $(srcdir)/../common/sim-engine.c $(ALL_CFLAGS) sim-events.o: $(srcdir)/../common/sim-events.c $(sim-events_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-events.c $(ALL_CFLAGS) sim-fpu.o: $(srcdir)/../common/sim-fpu.c $(sim-fpu_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-fpu.c $(ALL_CFLAGS) sim-hload.o: $(srcdir)/../common/sim-hload.c $(sim-assert_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-hload.c $(ALL_CFLAGS) sim-hrw.o: $(srcdir)/../common/sim-hrw.c $(sim-assert_h) \ - $(SIM_EXTRA_DEPS) + $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-hrw.c $(ALL_CFLAGS) sim-inline.c: $(srcdir)/../common/sim-inline.c @@ -295,63 +303,56 @@ sim-inline.c: $(srcdir)/../common/sim-inline.c cat $(srcdir)/../common/$@ >> tmp-$@ $(srcdir)/../../move-if-change tmp-$@ $@ -sim-io.o: $(srcdir)/../common/sim-io.c $(sim_main_headers) $(sim-io_h) \ - $(SIM_EXTRA_DEPS) +sim-io.o: $(srcdir)/../common/sim-io.c $(sim_main_headers) $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-io.c $(ALL_CFLAGS) sim-memopt.o: $(srcdir)/../common/sim-memopt.c $(sim_main_headers) \ - $(sim-io_h) $(SIM_EXTRA_DEPS) + $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-memopt.c $(ALL_CFLAGS) sim-module.o: $(srcdir)/../common/sim-module.c $(sim_main_headers) \ - $(sim-io_h) $(SIM_EXTRA_DEPS) + $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-module.c $(ALL_CFLAGS) sim-options.o: $(srcdir)/../common/sim-options.c $(sim_main_headers) \ - $(sim-options_h) $(sim-io_h) $(SIM_EXTRA_DEPS) + $(sim-options_h) $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-options.c $(ALL_CFLAGS) -sim-reason.o: $(srcdir)/../common/sim-reason.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) +sim-reason.o: $(srcdir)/../common/sim-reason.c $(sim_main_headers) $(CC) -c $(srcdir)/../common/sim-reason.c $(ALL_CFLAGS) -sim-resume.o: $(srcdir)/../common/sim-resume.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) +sim-resume.o: $(srcdir)/../common/sim-resume.c $(sim_main_headers) $(CC) -c $(srcdir)/../common/sim-resume.c $(ALL_CFLAGS) -sim-run.o: $(srcdir)/../common/sim-run.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) +sim-run.o: $(srcdir)/../common/sim-run.c $(sim_main_headers) $(CC) -c $(srcdir)/../common/sim-run.c $(ALL_CFLAGS) -sim-stop.o: $(srcdir)/../common/sim-stop.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) +sim-stop.o: $(srcdir)/../common/sim-stop.c $(sim_main_headers) $(CC) -c $(srcdir)/../common/sim-stop.c $(ALL_CFLAGS) sim-trace.o: $(srcdir)/../common/sim-trace.c $(sim_main_headers) \ - $(sim-options_h) $(sim-io_h) $(SIM_EXTRA_DEPS) + $(sim-options_h) $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-trace.c $(ALL_CFLAGS) sim-profile.o: $(srcdir)/../common/sim-profile.c $(sim_main_headers) \ - $(sim-options_h) $(sim-io_h) $(SIM_EXTRA_DEPS) + $(sim-options_h) $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-profile.c $(ALL_CFLAGS) sim-model.o: $(srcdir)/../common/sim-model.c $(sim_main_headers) \ - $(sim-io_h) $(SIM_EXTRA_DEPS) + $(sim-io_h) $(CC) -c $(srcdir)/../common/sim-model.c $(ALL_CFLAGS) -sim-utils.o: $(srcdir)/../common/sim-utils.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) +sim-utils.o: $(srcdir)/../common/sim-utils.c $(sim_main_headers) $(CC) -c $(srcdir)/../common/sim-utils.c $(ALL_CFLAGS) -sim-watch.o: $(srcdir)/../common/sim-watch.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) +sim-watch.o: $(srcdir)/../common/sim-watch.c $(sim_main_headers) $(CC) -c $(srcdir)/../common/sim-watch.c $(ALL_CFLAGS) -sim-load.o: $(srcdir)/../common/sim-load.c +sim-load.o: $(srcdir)/../common/sim-load.c $(srcroot)/include/callback.h $(CC) -c $(srcdir)/../common/sim-load.c $(ALL_CFLAGS) sim-break.o: $(srcdir)/../common/sim-break.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) $(sim_break_h) + $(sim_break_h) $(CC) -c $(srcdir)/../common/sim-break.c $(ALL_CFLAGS) nrun.o: $(srcdir)/../common/nrun.c config.h tconfig.h \ @@ -361,19 +362,20 @@ nrun.o: $(srcdir)/../common/nrun.c config.h tconfig.h \ # CGEN support. cgen-run.o: $(srcdir)/../common/cgen-run.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) + $(srcdir)/../common/cgen-mem.h $(srcdir)/../common/cgen-ops.h \ + $(srcdir)/../common/cgen-scache.h $(CC) -c $(srcdir)/../common/cgen-run.c $(ALL_CFLAGS) cgen-scache.o: $(srcdir)/../common/cgen-scache.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) $(srcdir)/../common/cgen-scache.h + $(srcdir)/../common/cgen-scache.h $(CC) -c $(srcdir)/../common/cgen-scache.c $(ALL_CFLAGS) cgen-trace.o: $(srcdir)/../common/cgen-trace.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) $(srcdir)/../common/cgen-trace.h + $(srcdir)/../common/cgen-trace.h $(CC) -c $(srcdir)/../common/cgen-trace.c $(ALL_CFLAGS) cgen-utils.o: $(srcdir)/../common/cgen-utils.c $(sim_main_headers) \ - $(SIM_EXTRA_DEPS) mem-ops.h sem-ops.h + $(srcdir)/../common/cgen-mem.h $(srcdir)/../common/cgen-ops.h $(CC) -c $(srcdir)/../common/cgen-utils.c $(ALL_CFLAGS) # Support targets. @@ -405,7 +407,7 @@ clean: $(SIM_EXTRA_CLEAN) rm -f *.[oa] *~ core rm -f run libsim.a rm -f gentmap targ-map.c targ-vals.h - if [ "cd $(srcdir) && pwd" != `pwd` ] ; then \ + if [ ! -f Make-common.in ] ; then \ rm -f $(BUILT_SRC_FROM_COMMON) ; \ fi diff --git a/sim/common/callback.c b/sim/common/callback.c index 0cd5cae..f619310 100644 --- a/sim/common/callback.c +++ b/sim/common/callback.c @@ -1,6 +1,6 @@ -/* Host callback routines for GDB. +/* Remote target callback routines. Copyright 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Cygnus Support. + Contributed by Cygnus Solutions. This file is part of GDB. @@ -15,8 +15,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + 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. */ @@ -34,9 +34,18 @@ #ifdef HAVE_STDLIB_H #include #endif +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif #include #include #include +#include +#include #include "callback.h" #include "targ-vals.h" @@ -50,6 +59,10 @@ 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 *)); @@ -76,6 +89,7 @@ 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. */ @@ -88,6 +102,21 @@ wrap (p, val) 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. */ @@ -130,15 +159,15 @@ os_close (p, fd) } -/* taken from gdb/util.c - should be in a library */ +/* taken from gdb/util.c:notice_quit() - should be in a library */ -#if defined(__GO32__) || defined (_WIN32) +#if defined(__GO32__) || defined (_MSC_VER) static int os_poll_quit (p) host_callback *p; { -#ifndef _MSC_VER +#if defined(__GO32__) int kbhit (); int getkey (); if (kbhit ()) @@ -157,25 +186,26 @@ os_poll_quit (p) sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n"); } } -#else /* !_MSC_VER */ +#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 /* !_MSC_VER */ +#endif return 0; } #else #define os_poll_quit 0 -#endif /* defined(__GO32__) || defined(_WIN32) */ +#endif /* defined(__GO32__) || defined(_MSC_VER) */ static int os_get_errno (p) host_callback *p; { - return host_to_target_errno (p->last_errno); + return cb_host_to_target_errno (p, p->last_errno); } @@ -221,7 +251,7 @@ os_open (p, name, flags) { if (!p->fdopen[i]) { - int f = open (name, target_to_host_open (flags), 0644); + int f = open (name, cb_target_to_host_open (p, flags), 0644); if (f < 0) { p->last_errno = errno; @@ -269,11 +299,24 @@ os_write (p, fd, buf, len) int len; { int result; + int real_fd; result = fdbad (p, fd); if (result) return result; - result = wrap (p, write (fdmap (p, fd), buf, len)); + 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; } @@ -344,6 +387,23 @@ os_unlink (p, 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) @@ -361,17 +421,23 @@ os_shutdown (p) } static int -os_init(p) +os_init (p) host_callback *p; { int i; + os_shutdown (p); - for (i= 0; i < 3; i++) + 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; } @@ -475,12 +541,15 @@ host_callback default_callback = os_write_stderr, os_flush_stderr, + os_stat, + os_fstat, + os_poll_quit, os_shutdown, os_init, - os_printf_filtered, /* depreciated */ + os_printf_filtered, /* deprecated */ os_vprintf_filtered, os_evprintf_filtered, @@ -492,24 +561,92 @@ host_callback default_callback = { 0, }, /* fdopen */ { 0, }, /* alwaysopen */ + 0, /* syscall_map */ + 0, /* errno_map */ + 0, /* open_map */ + 0, /* signal_map */ + 0, /* stat_map */ + HOST_CALLBACK_MAGIC, }; -/* FIXME: Need to add hooks so target can tweak as necessary. */ +/* Read in a file describing the target's system call values. + This allows simulators, etc. to support arbitrary libraries + without having to be recompiled. + E.g. maybe someone will want to use something other than newlib. + + 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. */ -/* FIXME: struct stat conversion is missing. */ +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 -host_to_target_errno (host_val) +cb_host_to_target_errno (cb, host_val) + host_callback *cb; int host_val; { - target_defs_map *m; + CB_TARGET_DEFS_MAP *m; - for (m = &errno_map[0]; m->host_val; ++m) + for (m = &cb->errno_map[0]; m->host_val; ++m) if (m->host_val == host_val) return m->target_val; @@ -525,13 +662,14 @@ host_to_target_errno (host_val) to machine generate this function. */ int -target_to_host_open (target_val) +cb_target_to_host_open (cb, target_val) + host_callback *cb; int target_val; { int host_val = 0; - target_defs_map *m; + CB_TARGET_DEFS_MAP *m; - for (m = &open_map[0]; m->host_val != -1; ++m) + for (m = &cb->open_map[0]; m->host_val != -1; ++m) { switch (m->target_val) { @@ -558,6 +696,83 @@ target_to_host_open (target_val) 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. */ + +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; + } + size = atoi (q + 1); + if (size == 0) + { + /* FIXME: print error message */ + return; + } + + 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; + } +} /* Cover functions to the vfprintf callbacks. diff --git a/sim/common/syscall.c b/sim/common/syscall.c new file mode 100644 index 0000000..4bbb0c5 --- /dev/null +++ b/sim/common/syscall.c @@ -0,0 +1,306 @@ +/* Remote target system call support. + Copyright 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 interface isn't intended to be specific to any particular kind + of remote (hardware, simulator, whatever). As such, support for it + (e.g. sim/common/callback.c) should *not* live in the simulator source + tree, nor should it live in the gdb source tree. K&R C must be + supported. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "ansidecl.h" +#ifdef ANSI_PROTOTYPES +#include +#else +#include +#endif +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include "callback.h" +#include "remote-sim.h" +#include "targ-vals.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +/* When doing file read/writes, do this many bytes at a time. */ +#define FILE_XFR_SIZE 4096 + +/* Maximum length of a path name. */ +#ifndef MAX_PATH_LEN +#define MAX_PATH_LEN 1024 +#endif + +/* Utility of cb_syscall to fetch a path name from the target. + The result is 0 for success or a target errno value. */ + +static int +get_path (cb, sc, buf, buflen, addr) + host_callback *cb; + CB_SYSCALL *sc; + char *buf; + int buflen; + long addr; +{ + char *p, *pend; + + for (p = buf, pend = buf + buflen; p < pend; ++p, ++addr) + { + /* No, it isn't expected that this would cause one transaction with + the remote target for each byte. The target could send the + path name along with the syscall request, and cache the file + name somewhere. */ + unsigned int count = (*sc->read_mem) (cb, sc, addr, p, 1); + + if (count != 1) + return TARGET_EINVAL; + if (*p == 0) + break; + } + if (p == pend) + return TARGET_ENAMETOOLONG; + return 0; +} + +/* Perform a system call on behalf of the target. */ + +CB_RC +cb_syscall (cb, sc) + host_callback *cb; + CB_SYSCALL *sc; +{ + /* ??? Need to consider target word size. */ + long result = 0, errcode = 0; + + switch (cb_target_to_host_syscall (cb, sc->func)) + { +#if 0 /* FIXME: wip */ + case CB_SYS_argvlen : + { + /* Compute how much space is required to store the argv,envp + strings so that the program can allocate the space and then + call SYS_argv to fetch the values. */ + int addr_size = cb->addr_size; + int argc,envc,arglen,envlen; + const char **argv = cb->init_argv; + const char **envp = cb->init_envp; + + argc = arglen = 0; + if (argv) + { + for ( ; argv[argc]; ++argc) + arglen += strlen (argv[argc]) + 1; + } + envc = envlen = 0; + if (envp) + { + for ( ; envp[envc]; ++envc) + envlen += strlen (envp[envc]) + 1; + } + result = arglen + envlen; + break; + } + + case CB_SYS_argv : + { + /* Pointer to target's buffer. */ + SIM_ADDR tbuf = sc->arg1; + /* Buffer size. */ + int bufsize = sc->arg2; + /* Q is the target address of where all the strings go. */ + SIM_ADDR q; + int word_size = cb->word_size; + int i,argc,envc,len; + const char **argv = cb->init_argv; + const char **envp = cb->init_envp; + + argc = 0; + if (argv) + { + for ( ; argv[argc]; ++argc) + { + int len = strlen (argv[argc]); + int written = (*sc->write_mem) (cb, sc, tbuf, argv[argc], len + 1); + if (written != len) + { + result = -1; + errcode = TARGET_EINVAL; + goto FinishSyscall; + } + tbuf = len + 1; + } + } + if ((*sc->write_mem) (cb, sc, tbuf, "", 1) != 1) + { + result = -1; + errcode = TARGET_EINVAL; + goto FinishSyscall; + } + tbuf++; + envc = 0; + if (envp) + { + for ( ; envp[envc]; ++envc) + { + int len = strlen (envp[envc]); + int written = (*sc->write_mem) (cb, sc, tbuf, envp[envc], len + 1); + if (written != len) + { + result = -1; + errcode = TARGET_EINVAL; + goto FinishSyscall; + } + tbuf = len + 1; + } + } + if ((*sc->write_mem) (cb, sc, tbuf, "", 1) != 1) + { + result = -1; + errcode = TARGET_EINVAL; + goto FinishSyscall; + } + result = argc; + sc->result2 = envc; + break; + } +#endif /* wip */ + + case CB_SYS_exit : + /* Caller must catch and handle. */ + break; + + case CB_SYS_open : + { + char path[MAX_PATH_LEN]; + int errcode; + + errcode = get_path (cb, sc, path, MAX_PATH_LEN, sc->arg1); + if (errcode != 0) + { + result = -1; + errcode = errcode; + goto FinishSyscall; + } + result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/); + } + break; + + case CB_SYS_close : + result = (*cb->close) (cb, sc->arg1); + break; + + case CB_SYS_read : + { + /* ??? Perfect handling of error conditions may require only one + call to cb->read. One can't assume all the data is + contiguously stored in host memory so that would require + malloc'ing/free'ing the space. Maybe later. */ + char buf[FILE_XFR_SIZE]; + int fd = sc->arg1; + SIM_ADDR addr = sc->arg2; + size_t count = sc->arg3; + size_t bytes_read = 0; + int bytes_written; + + while (count > 0) + { + result = (int) (*cb->read) (cb, fd, buf, + count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE); + if (result == -1) + goto FinishSyscall; + bytes_written = (*sc->write_mem) (cb, sc, addr, buf, result); + if (bytes_written != result) + { + result = -1; + errcode = TARGET_EINVAL; + goto FinishSyscall; + } + bytes_read += result; + count -= result; + addr += result; + } + result = bytes_read; + } + break; + + case CB_SYS_write : + { + /* ??? Perfect handling of error conditions may require only one + call to cb->write. One can't assume all the data is + contiguously stored in host memory so that would require + malloc'ing/free'ing the space. Maybe later. */ + char buf[FILE_XFR_SIZE]; + int fd = sc->arg1; + SIM_ADDR addr = sc->arg2; + size_t count = sc->arg3; + int bytes_read; + size_t bytes_written = 0; + + while (count > 0) + { + int bytes_to_read = count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE; + bytes_read = (*sc->read_mem) (cb, sc, addr, buf, bytes_to_read); + if (bytes_read != bytes_to_read) + { + result = -1; + errcode = TARGET_EINVAL; + goto FinishSyscall; + } + if (fd == 1) + result = (int) (*cb->write_stdout) (cb, buf, bytes_read); + else + result = (int) (*cb->write) (cb, fd, buf, bytes_read); + if (result == -1) + goto FinishSyscall; + bytes_written += result; + count -= result; + addr += result; + } + result = bytes_written; + } + break; + + default : + result = -1; +#ifdef TARGET_ENOSYS + errcode = TARGET_ENOSYS; +#else + errcode = TARGET_EINVAL; +#endif + break; + } + + FinishSyscall: + sc->result = result; + if (errcode == 0) + sc->errcode = (*cb->get_errno) (cb); + else + sc->errcode = errcode; + + return CB_RC_OK; +} -- 2.7.4