* Make-common.in (DEP, COMMON_DEP_CFLAGS): Define.
authorDoug Evans <dje@google.com>
Mon, 17 Nov 1997 23:09:08 +0000 (23:09 +0000)
committerDoug Evans <dje@google.com>
Mon, 17 Nov 1997 23:09:08 +0000 (23:09 +0000)
(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
sim/common/ChangeLog
sim/common/Make-common.in
sim/common/callback.c
sim/common/syscall.c [new file with mode: 0644]

index 7dd8777..e61d75e 100644 (file)
@@ -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:
index 87877de..abc3d86 100644 (file)
@@ -1,3 +1,56 @@
+Mon Nov 17 14:15:31 1997  Doug Evans  <devans@seba.cygnus.com>
+
+       * 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  <cagney@b1.cygnus.com>
+
+       * 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  <cagney@b1.cygnus.com>
+
+       * sim-core.c (sim_core_signal): Print the address of the
+       instruction.
+
 Thu Nov 13 11:49:41 1997  Doug Evans  <devans@seba.cygnus.com>
 
        * sim-base.h (sim_state_base): Move `magic' to end of struct.
index f2a289f..bb04b97 100644 (file)
@@ -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
 
index 0cd5cae..f619310 100644 (file)
@@ -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.  */
 #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"
 
 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,
 };
 \f
-/* 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;
+    }
+}
 \f
 /* Cover functions to the vfprintf callbacks.
 
diff --git a/sim/common/syscall.c b/sim/common/syscall.c
new file mode 100644 (file)
index 0000000..4bbb0c5
--- /dev/null
@@ -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 <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include "callback.h"
+#include "remote-sim.h"
+#include "targ-vals.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#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;
+}