]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/ppc/main.c
sim:
[thirdparty/binutils-gdb.git] / sim / ppc / main.c
index 122794007ac8a3f592d69e156d53824ff4b30ea3..6be9054f38d7028ac822527757b746d4bd2595a5 100644 (file)
@@ -1,6 +1,6 @@
 /*  This file is part of the program psim.
 
-    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
 
     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
 
 
 #include <stdarg.h>
-#include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
+#include <fcntl.h>
+
+#include <signal.h>
 
 #include "psim.h"
+#include "options.h"
+#include "device.h" /* FIXME: psim should provide the interface */
+#include "events.h" /* FIXME: psim should provide the interface */
+
+#include "bfd.h"
+#include "gdb/callback.h"
+#include "gdb/remote-sim.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
+#include <errno.h>
+
+#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
+#undef WITH_STDIO
+#define WITH_STDIO DO_USE_STDIO
+#endif
+
 
 extern char **environ;
-extern char *optarg;
-extern int optind;
-extern int optopt;
-extern int opterr;
+
+static psim *simulation = NULL;
+
+
+void
+sim_io_poll_quit (void)
+{
+  /* nothing to do */
+}
+
+void
+sim_io_printf_filtered(const char *msg, ...)
+{
+  va_list ap;
+  va_start(ap, msg);
+  vprintf(msg, ap);
+  va_end(ap);
+}
 
 void
-printf_filtered(const char *msg, ...)
+error (const char *msg, ...)
 {
   va_list ap;
   va_start(ap, msg);
   vprintf(msg, ap);
+  printf("\n");
   va_end(ap);
+
+  /* any final clean up */
+  if (ppc_trace[trace_print_info] && simulation != NULL)
+    psim_print_info (simulation, ppc_trace[trace_print_info]);
+
+  exit (1);
+}
+
+int
+sim_io_write_stdout(const char *buf,
+                   int sizeof_buf)
+{
+  switch (CURRENT_STDIO) {
+  case DO_USE_STDIO:
+    {
+      int i;
+      for (i = 0; i < sizeof_buf; i++) {
+       putchar(buf[i]);
+      }
+      return i;
+    }
+    break;
+  case DONT_USE_STDIO:
+    return write(1, buf, sizeof_buf);
+    break;
+  default:
+    error("sim_io_write_stdout: invalid switch\n");
+  }
+  return 0;
+}
+
+int
+sim_io_write_stderr(const char *buf,
+                   int sizeof_buf)
+{
+  switch (CURRENT_STDIO) {
+  case DO_USE_STDIO:
+    {
+      int i;
+      for (i = 0; i < sizeof_buf; i++) {
+       fputc(buf[i], stderr);
+      }
+      return i;
+    }
+    break;
+  case DONT_USE_STDIO:
+    return write(2, buf, sizeof_buf);
+    break;
+  default:
+    error("sim_io_write_stdout: invalid switch\n");
+  }
+  return 0;
+}
+
+int
+sim_io_read_stdin(char *buf,
+                 int sizeof_buf)
+{
+  switch (CURRENT_STDIO) {
+  case DO_USE_STDIO:
+    if (sizeof_buf > 1) {
+      if (fgets(buf, sizeof_buf, stdin) != NULL)
+       return strlen(buf);
+    }
+    else if (sizeof_buf == 1) {
+      char b[2];
+      if (fgets(b, sizeof(b), stdin) != NULL) {
+       memcpy(buf, b, strlen(b));
+       return strlen(b);
+      }
+    }
+    else if (sizeof_buf == 0)
+      return 0;
+    return sim_io_eof;
+    break;
+  case DONT_USE_STDIO:
+#if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL)
+    {
+      /* check for input */
+      int flags;
+      int status;
+      int nr_read;
+      int result;
+      /* get the old status */
+      flags = fcntl(0, F_GETFL, 0);
+      if (flags == -1) {
+       perror("sim_io_read_stdin");
+       return sim_io_eof;
+      }
+      /* temp, disable blocking IO */
+      status = fcntl(0, F_SETFL, flags | O_NDELAY);
+      if (status == -1) {
+       perror("sim_io_read_stdin");
+       return sim_io_eof;
+      }
+      /* try for input */
+      nr_read = read(0, buf, sizeof_buf);
+      if (nr_read > 0
+         || (nr_read == 0 && sizeof_buf == 0))
+       result = nr_read;
+      else if (nr_read == 0)
+       result = sim_io_eof;
+      else { /* nr_read < 0 */
+       if (errno == EAGAIN)
+         result = sim_io_not_ready;
+       else 
+         result = sim_io_eof;
+      }
+      /* return to regular vewing */
+      status = fcntl(0, F_SETFL, flags);
+      if (status == -1) {
+       perror("sim_io_read_stdin");
+       return sim_io_eof;
+      }
+      return result;
+    }
+    break;
+#endif
+  default:
+    error("sim_io_read_stdin: invalid switch\n");
+    break;
+  }
+  return 0;
+}
+
+void
+sim_io_flush_stdoutput(void)
+{
+  switch (CURRENT_STDIO) {
+  case DO_USE_STDIO:
+    fflush (stdout);
+    break;
+  case DONT_USE_STDIO:
+    break;
+  default:
+    error("sim_io_flush_stdoutput: invalid switch\n");
+    break;
+  }
 }
 
 void
-error (char *msg, ...)
+sim_io_error (SIM_DESC sd, const char *msg, ...)
 {
   va_list ap;
   va_start(ap, msg);
   vprintf(msg, ap);
+  printf("\n");
   va_end(ap);
+
+  /* any final clean up */
+  if (ppc_trace[trace_print_info] && simulation != NULL)
+    psim_print_info (simulation, ppc_trace[trace_print_info]);
+
   exit (1);
 }
 
+
 void *
 zalloc(long size)
 {
   void *memory = malloc(size);
   if (memory == NULL)
-    error("zmalloc failed\n");
-  bzero(memory, size);
+    error("zalloc failed\n");
+  memset(memory, 0, size);
   return memory;
 }
 
@@ -67,86 +259,64 @@ zfree(void *chunk)
   free(chunk);
 }
 
-static void
-usage(void)
+/* When a CNTRL-C occures, queue an event to shut down the simulation */
+
+static RETSIGTYPE
+cntrl_c(int sig)
 {
-  error ("Usage: psim [ -a -p -c -C -s -i -I -t -g ] <image> [ <image-args> ... ]\n");
+  psim_stop (simulation);
 }
 
+
 int
 main(int argc, char **argv)
 {
-  psim *system;
   const char *name_of_file;
   char *arg_;
-  unsigned_word stack_pointer;
   psim_status status;
-  int letter;
-  int i;
-  int print_info = 0;
+  device *root = psim_tree();
 
-  /* check for arguments -- note sim_calls.c also contains argument processing
-     code for the simulator linked within gdb.  */
-  while ((letter = getopt (argc, argv, "acCiIpstg")) != EOF)
-    {
-      switch (letter) {
-      case 'a':
-       for (i = 0; i < nr_trace; i++)
-         ppc_trace[i] = 1;
-       break;
-      case 'p':
-       ppc_trace[trace_cpu] = ppc_trace[trace_semantics] = 1;
-       break;
-      case 'c':
-       ppc_trace[trace_core] = 1;
-       break;
-      case 'C':
-       ppc_trace[trace_console_device] = 1;
-       break;
-      case 's':
-       ppc_trace[trace_create_stack] = 1;
-       break;
-      case 'i':
-       ppc_trace[trace_icu_device] = 1;
-       break;
-      case 'I':
-       print_info = 1;
-       break;
-      case 't':
-       ppc_trace[trace_device_tree] = 1;
-       break;
-      case 'g':
-       ppc_trace[trace_gdb] = 1;
-       break;
-      default:
-       usage();
-      }
+  /* parse the arguments */
+  argv = psim_options(root, argv + 1);
+  if (argv[0] == NULL) {
+    if (ppc_trace[trace_opts]) {
+      print_options ();
+      return 0;
+    } else {
+      psim_usage(0, 0);
     }
-  if (optind >= argc)
-    usage();
-  name_of_file = argv[optind];
+  }
+  name_of_file = argv[0];
+
+  if (ppc_trace[trace_opts])
+    print_options ();
 
   /* create the simulator */
-  system = psim_create(name_of_file, ((WITH_SMP > 0) ? WITH_SMP : 1));
+  simulation = psim_create(name_of_file, root);
 
   /* fudge the environment so that _=prog-name */
-  arg_ = (char*)zalloc(strlen(argv[optind]) + strlen("_=") + 1);
+  arg_ = (char*)zalloc(strlen(argv[0]) + strlen("_=") + 1);
   strcpy(arg_, "_=");
-  strcat(arg_, argv[optind]);
+  strcat(arg_, argv[0]);
   putenv(arg_);
 
   /* initialize it */
-  psim_init(system);
-  psim_stack(system, &argv[optind], environ);
+  psim_init(simulation);
+  psim_stack(simulation, argv, environ);
 
-  psim_run(system);
+  {
+    RETSIGTYPE (*prev) ();
+    prev = signal(SIGINT, cntrl_c);
+    psim_run(simulation);
+    signal(SIGINT, prev);
+  }
 
   /* any final clean up */
-  if (print_info)
-    psim_print_info (system, 1);
+  if (ppc_trace[trace_print_info])
+    psim_print_info (simulation, ppc_trace[trace_print_info]);
 
   /* why did we stop */
-  status = psim_get_status(system);
+  status = psim_get_status(simulation);
   switch (status.reason) {
   case was_continuing:
     error("psim: continuing while stoped!\n");
@@ -158,8 +328,8 @@ main(int argc, char **argv)
     return status.signal;
   case was_signalled:
     printf ("%s: Caught signal %d at address 0x%lx\n",
-           name_of_file, (int)status.signal,
-           (long)status.program_counter);
+           name_of_file, (int)status.signal,
+           (long)status.program_counter);
     return status.signal;
   default:
     error("unknown halt condition\n");