New commands ``set architecture'', ``show architecture'' and ``info
authorAndrew Cagney <cagney@redhat.com>
Thu, 28 Aug 1997 10:20:21 +0000 (10:20 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 28 Aug 1997 10:20:21 +0000 (10:20 +0000)
architecture''.  Update SH target to use new target_architecture_hook.

gdb/ChangeLog
gdb/config/sh/tm-sh.h
gdb/defs.h
gdb/remote-e7000.c
gdb/remote-sim.c
gdb/sh-tdep.c
gdb/sh3-rom.c
gdb/top.c

index 5f1aa846329b4c60e6e76c180787fd01f8dffb85..6617cb2bcfad0d3fb6ca42d5f104eb7cb6a6edfe 100644 (file)
@@ -1,3 +1,35 @@
+Thu Aug 28 10:20:04 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * remote-e7000.c (e7000_fetch_registers): Check
+       target_architecture instead of sh_processor_type.
+       (e7000_wait): Ditto.
+
+       * config/sh/tm-sh.h (sh_set_processor_type): Delete prototype.
+
+       * sh3-rom.c (sh3_open): Call set_architecture not
+       sh_set_processor_type.
+       (sh3e_open): Ditto.
+
+       * sh-tdep.c (sh_show_processor_type_command): Delete.
+       (sh_set_processor_type_command): Delete.
+       (sh_target_architecture_hook): Rename from sh_set_processor_type,
+       use AP to determine architecture.
+       (sh_show_regs): Use bfd_mach_sh* types.
+
+       * remote-sim.c (gdbsim_open): Pass --arch=XXX to simulator when
+       architecture was specified explicitly.
+
+       * defs.h (target_architecture, target_architecture_auto,
+       set_architecture, set_architecture_from_file): Declare.
+       (target_architecture_hook): Allow targets to be notified of set
+       arch commands.
+       
+       * top.c (init_main): Add set/show/info architecture commands.
+       (set_architecture, show_architecture, info_architecture): New
+       functions, parse same.
+       (set_architecture_from_file): New function, determine arch from
+       BFD.
+       
 Tue Aug 26 17:13:43 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * remote-sim.c (gdbsim_open): Only pass endianness to sim_open
index 79e4e40b26802f76c1861997694a4f21efb31869..0ec375ccee44e26f00277b9642d70dec30546fd8 100644 (file)
@@ -288,5 +288,3 @@ extern void sh_pop_frame PARAMS ((void));
 
 /* Need this for WinGDB.  See gdb/mswin/{regdoc.h, gdbwin.c, gui.cpp}.  */
 #define TARGET_SH
-
-extern int sh_set_processor_type PARAMS ((char *));
index 94725a9ad54a90e4501482cd24f1e37b50a22ee5..75325480808073bed10d94f289da5d0ea3584025 100644 (file)
@@ -764,6 +764,15 @@ extern int target_byte_order_auto;
 
 extern void set_endian_from_file PARAMS ((bfd *));
 
+/* The target architecture can be set at run-time. */
+extern int target_architecture_auto;
+extern const bfd_arch_info_type *target_architecture;
+extern void set_architecture_from_file PARAMS ((bfd *));
+/* Notify target of a change to the selected architecture. Zero return
+   status indicates that the target did not like the change. */
+extern int (*target_architecture_hook) PARAMS ((const bfd_arch_info_type *ap)); 
+extern void set_architecture PARAMS ((char *arg, int from_tty));
+
 /* Number of bits in a char or unsigned char for the target machine.
    Just like CHAR_BIT in <limits.h> but describes the target machine.  */
 #if !defined (TARGET_CHAR_BIT)
index ccdcc35f62c4ae0881141f3f39ae2a7db6d61a16..20cf774c1b273c7e077855969313a3bee38e0a85 100644 (file)
@@ -46,9 +46,7 @@
 #include "remote-utils.h"
 #include "symfile.h"
 #include <time.h>
-
-//#define DEBUGIFY
-#include "debugify.h"
+#include <ctype.h>
 
 #if 1
 #define HARD_BREAKPOINTS       /* Now handled by set option. */
@@ -89,6 +87,8 @@ static void expect_full_prompt PARAMS ((void));
 
 static void expect_prompt PARAMS ((void));
 
+static int e7000_parse_device PARAMS ((char *args, char *dev_name,
+                                      int baudrate));
 /* Variables. */
 
 static serial_t e7000_desc;
@@ -129,18 +129,16 @@ puts_e7000debug (buf)
     error ("Use \"target e7000 ...\" first.");
 
   if (remote_debug)
-    printf("Sending %s\n", buf);
-  DBG(("Sending %s; waiting for echo...\n", buf));
+    printf_unfiltered ("Sending %s\n", buf);
 
   if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
-    fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
+    fprintf_unfiltered (gdb_stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
 
   /* And expect to see it echoed, unless using the pc interface */
 #if 0
   if (!using_pc)
 #endif
     expect (buf);
-  DBG(("Got echo!n"));
 }
 
 static void
@@ -170,7 +168,8 @@ normal (x)
 }
 
 /* Read a character from the remote system, doing all the fancy timeout
-   stuff.  */
+   stuff.  Handles serial errors and EOF.  If TIMEOUT == 0, and no chars,
+   returns -1, else returns next char.  Discards chars > 127.  */
 
 static int
 readchar (timeout)
@@ -191,10 +190,13 @@ readchar (timeout)
       echo = 0;
       error ("Timeout reading from remote system.");
     }
+  else if (c < 0)
+    error ("Serial communication error");
+
   if (remote_debug) 
     {
-      putchar (c);
-      fflush (stdout);
+      putchar_unfiltered (c);
+      gdb_flush (gdb_stdout);
     }
 
   return normal (c);
@@ -238,6 +240,7 @@ expect (string)
   while (1)
     {
       c = readchar (timeout);
+#if 0
       notice_quit ();
       if (quit_flag == 1) 
        {
@@ -251,25 +254,22 @@ expect (string)
              quit ();
            }
        }
+#endif
       
-      if (c == SERIAL_ERROR)
-       {
-         error ("Serial communication error");
-       }
-      if (echo || remote_debug)
+      if (echo)
        {
          if (c == '\r' || c == '\n')
            {
              if (!nl)
-               putchar ('\n');
+               putchar_unfiltered ('\n');
              nl = 1;
            }
          else
            {
              nl = 0;
-             putchar (c);
+             putchar_unfiltered (c);
            }
-         fflush (stdout);
+         gdb_flush (gdb_stdout);
        }
       if (normal (c) == normal (*p++))
        {
@@ -458,7 +458,7 @@ e7000_login_command (args, from_tty)
       dir = next (&args);
       if (from_tty)
        {
-         printf ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
+         printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
        }
     }
   else
@@ -502,10 +502,9 @@ e7000_ftp_command (args, from_tty)
 }
 
 static int 
-e7000_parse_device(args,dev_name,serial_flag,baudrate) 
+e7000_parse_device (args, dev_name, baudrate) 
     char *args;
     char *dev_name;
-    int serial_flag;
     int baudrate;
 {
   char junk[128];
@@ -519,7 +518,7 @@ e7000_parse_device(args,dev_name,serial_flag,baudrate)
     {
       /* FIXME! temp hack to allow use with port master -
             target tcp_remote <device> */
-      if (args && strncmp (args, "tcp_remote", 10) == 0) 
+      if (args && strncmp (args, "tcp", 10) == 0) 
         {
          char com_type[128];
          n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
@@ -555,59 +554,45 @@ or \t\ttarget e7000 pc\n");
   return n;
 }
 
-static void
-e7000_open (args, from_tty)
-     char *args;
-     int from_tty;
+/* Stub for catch_errors.  */
+
+static int
+e7000_start_remote (dummy)
+     char *dummy;
 {
-  int n;
   int loop;
   int sync;
-  int serial_flag;
-  int try=0;
-  int quit_trying=20;
-
-  target_preopen (from_tty);
-
-  n = e7000_parse_device(args,dev_name,serial_flag,baudrate);
-
-  push_target (&e7000_ops);
-
-  e7000_desc = SERIAL_OPEN (dev_name);
-
-  if (!e7000_desc)
-  {
-      error ("Unable to open target or file not found: %s\n", dev_name);
-  }
+  int try;
+  int quit_trying;
 
-  SERIAL_SETBAUDRATE (e7000_desc, baudrate);
-  SERIAL_RAW (e7000_desc);
+  immediate_quit = 1;          /* Allow user to interrupt it */
 
   /* Hello?  Are you there?  */
   sync = 0;
   loop =  0;
+  try = 0;
+  quit_trying = 20;
   putchar_e7000 (CTRLC);
   while (!sync && ++try <= quit_trying)
     {
       int c;
 
-      if (from_tty)
-       printf_unfiltered ("[waiting for e7000...]\n");
+      printf_unfiltered ("[waiting for e7000...]\n");
 
       write_e7000 ("\r");
-      c = SERIAL_READCHAR (e7000_desc, 1);
+      c = readchar (1);
 
       /* FIXME!  this didn't seem right->  while (c != SERIAL_TIMEOUT)
        * we get stuck in this loop ...
        * We may never timeout, and never sync up :-(
        */
-      while (!sync && c != SERIAL_TIMEOUT)
+      while (!sync && c != -1)
        {
          /* Dont echo cr's */
-         if (from_tty && c != '\r')
+         if (c != '\r')
            {
-             putchar (c);
-             fflush (stdout);
+             putchar_unfiltered (c);
+             gdb_flush (gdb_stdout);
            }
          /* Shouldn't we either break here, or check for sync in inner loop? */
          if (c == ':')
@@ -621,46 +606,80 @@ e7000_open (args, from_tty)
 
          QUIT ;
 
-
-         /* FIXME!  with this logic, you might never break out of this loop!
-          * Changed to count tries and treat reads as TIMEOUTS
-          * In windows version, you never timeout cuz always read 1 char!
-          */
          if (quit_flag)
            {
              putchar_e7000 (CTRLC);
              /* Was-> quit_flag = 0; */
-             c = SERIAL_TIMEOUT;
+             c = -1;
              quit_trying = try+1;  /* we don't want to try anymore */
            }
          else
-             c = SERIAL_READCHAR (e7000_desc, 1);
+           {
+             c = readchar (1);
+           }
        }
     }
 
   if (!sync)
-  {
-      if (from_tty)
-       printf_unfiltered ("Giving up after %d tries...\n",try);
+    {
+      fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n",try);
       error ("Unable to syncronize with target.\n");
-      return;
-  }
+    }
 
   puts_e7000debug ("\r");
-
+  expect_prompt ();
+  puts_e7000debug ("b -\r");   /* Clear breakpoints */
   expect_prompt ();
 
-  puts_e7000debug ("b -\r");
+  immediate_quit = 0;
 
-  expect_prompt ();
+/* This is really the job of start_remote however, that makes an assumption
+   that the target is about to print out a status message of some sort.  That
+   doesn't happen here. */
 
-  if (from_tty)
-    printf_filtered ("Remote target %s connected to %s\n", target_shortname,
-                    dev_name);
+  flush_cached_frames ();
+  registers_changed ();
+  stop_pc = read_pc ();
+  set_current_frame (create_new_frame (read_fp (), stop_pc));
+  select_frame (get_current_frame (), 0);
+  print_stack_frame (selected_frame, -1, 1);
+
+  return 1;
+}
+
+static void
+e7000_open (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int n;
+
+  target_preopen (from_tty);
+
+  n = e7000_parse_device (args, dev_name, baudrate);
+
+  push_target (&e7000_ops);
+
+  e7000_desc = SERIAL_OPEN (dev_name);
+
+  if (!e7000_desc)
+    perror_with_name (dev_name);
+
+  SERIAL_SETBAUDRATE (e7000_desc, baudrate);
+  SERIAL_RAW (e7000_desc);
 
 #ifdef GDB_TARGET_IS_H8300
   h8300hmode = 1;
 #endif
+
+  /* Start the remote connection; if error (0), discard this target.
+     In particular, if the user quits, be sure to discard it
+     (we'd be in an inconsistent state otherwise).  */
+  if (!catch_errors (e7000_start_remote, (char *)0, 
+                    "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
+  if (from_tty)
+    printf_filtered ("Remote target %s connected to %s\n", target_shortname,
+                    dev_name);
 }
 
 /* Close out all files and local state before this target loses control. */
@@ -685,7 +704,7 @@ e7000_detach (from_tty)
 {
   pop_target ();               /* calls e7000_close to do the real work */
   if (from_tty)
-    printf ("Ending remote %s debugging\n", target_shortname);
+    printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
 }
 
 /* Tell the remote machine to resume.  */
@@ -772,16 +791,7 @@ char *want_sh3_nopc = "%16 SR=%22\n\
 static int
 gch ()
 {
-  int c = readchar (timeout);
-
-  if (remote_debug)
-    {
-      if (c >= ' ')
-       printf ("%c", c);
-      else if (c == '\n')
-       printf ("\n");
-    }
-  return c;
+  return readchar (timeout);
 }
 
 static unsigned int
@@ -904,18 +914,29 @@ static void
 e7000_fetch_registers ()
 {
   int regno;
+  char *wanted;
 
   puts_e7000debug ("R\r");
 
 #ifdef GDB_TARGET_IS_SH
-  if  ((sh_processor_type != NULL) && (*(sh_processor_type+2) == '3')) 
-     fetch_regs_from_dump (gch, want_sh3);
-  else
-     fetch_regs_from_dump (gch, want);
+  wanted = want;
+  if (target_architecture->arch == bfd_arch_sh)
+    switch (target_architecture->mach)
+      {
+      case bfd_mach_sh3:
+      case bfd_mach_sh3e:
+       /* start-sanitize-sh4 */        
+      case bfd_mach_sh4:
+       /* end-sanitize-sh4 */  
+       wanted = want_sh3;
+      }
 #else
-  fetch_regs_from_dump (gch, h8300smode ? want_h8300s : want_h8300h);
+  if (h8300smode)
+    wanted = want_h8300s;
+  else
+    wanted = want_h8300h);
 #endif
-
+  fetch_regs_from_dump (gch, wanted);
 
   /* And supply the extra ones the simulator uses */
   for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
@@ -1045,7 +1066,7 @@ e7000_prepare_to_store ()
 static void
 e7000_files_info ()
 {
-  printf ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
+  printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
 }
 
 static int
@@ -1170,8 +1191,8 @@ write_large (memaddr, myaddr, len)
       compose[where++] = 0;
 
       SERIAL_WRITE (e7000_desc, compose, where);
-      j = SERIAL_READCHAR (e7000_desc, 0);
-      if (j == SERIAL_TIMEOUT)
+      j = readchar (0);
+      if (j == -1)
        {
          /* This is ok - nothing there */
        }
@@ -1183,10 +1204,10 @@ write_large (memaddr, myaddr, len)
        }
       else
        {
-         printf ("@%d}@", j);
-         while ((j = SERIAL_READCHAR(e7000_desc,0)) > 0) 
+         printf_unfiltered ("@%d}@", j);
+         while ((j = readchar (0)) > 0) 
            {
-             printf ("@{%d}@",j);
+             printf_unfiltered ("@{%d}@",j);
            }
        }
     }
@@ -1259,7 +1280,8 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
       c = gch ();
       if (c == '*') 
        {                       /* Some kind of error */
-         expect_prompt();
+         puts_e7000debug (".\r"); /* Some errors leave us in memory input mode */
+         expect_full_prompt();
          return -1;
        }
       while (c != ' ')
@@ -1496,7 +1518,6 @@ e7000_load (args, from_tty)
   asection *section;
   bfd *pbfd;
   bfd_vma entry;
-  int i;
 #define WRITESIZE 0x1000
   char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + <addr> + <len> + <data> */
   char *filename;
@@ -1702,7 +1723,9 @@ e7000_insert_breakpoint (addr, shadow)
 {
   int i;
   char buf[200];
+#if 0
   static char nop[2] = NOP;
+#endif
 
   for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
     if (breakaddr[i] == 0)
@@ -1828,7 +1851,7 @@ e7000_drain_command (args, fromtty)
   puts_e7000debug("end\r");
   putchar_e7000 (CTRLC);
 
-  while ((c = SERIAL_READCHAR (e7000_desc, 1) != SERIAL_TIMEOUT))
+  while ((c = readchar (1) != -1))
     {
       if (quit_flag)
        {
@@ -1836,9 +1859,9 @@ e7000_drain_command (args, fromtty)
          quit_flag = 0;
        }
       if (c > ' ' && c < 127)
-       printf ("%c", c & 0xff);
+       printf_unfiltered ("%c", c & 0xff);
       else
-       printf ("<%x>", c & 0xff);
+       printf_unfiltered ("<%x>", c & 0xff);
     }
 }
 
@@ -1909,8 +1932,8 @@ char **strings;
       int i;
       int gotone = 0;
 
-      c = SERIAL_READCHAR (e7000_desc, 1);
-      if (c == SERIAL_TIMEOUT)
+      c = readchar (1);
+      if (c == -1)
        {
          printf_unfiltered ("[waiting for e7000...]\n");
        }
@@ -1957,13 +1980,13 @@ char **strings;
          if (buffer != saveaway) 
            {
              *buffer++ = 0;
-             printf ("%s", buffer);
+             printf_unfiltered ("%s", buffer);
              buffer = saveaway;
            }
-         if (c != SERIAL_TIMEOUT)
+         if (c != -1)
            {
-             putchar (c);
-             fflush (stdout);
+             putchar_unfiltered (c);
+             gdb_flush (gdb_stdout);
            }
        }
     }
@@ -2013,6 +2036,7 @@ e7000_wait (pid, status)
   int running_count = 0;
   int had_sleep = 0;
   int loop = 1;
+  char *wanted_nopc;
 
   /* Then echo chars until PC= string seen */
   gch ();                      /* Drop cr */
@@ -2052,13 +2076,24 @@ e7000_wait (pid, status)
   expect ("=");
 
 #ifdef GDB_TARGET_IS_SH
-  if  ((sh_processor_type != NULL) && (*(sh_processor_type+2) == '3')) 
-     fetch_regs_from_dump (gch, want_sh3_nopc);
-  else
-     fetch_regs_from_dump (gch, want_nopc);
+  wanted_nopc = want_nopc;
+  if (target_architecture->arch == bfd_arch_sh)
+    switch (target_architecture->mach)
+      {
+      case bfd_mach_sh3:
+      case bfd_mach_sh3e:
+       /* start-sanitize-sh4 */        
+      case bfd_mach_sh4:
+       /* end-sanitize-sh4 */  
+       wanted_nopc = want_sh3_nopc;
+      }
 #else
-  fetch_regs_from_dump (gch, h8300smode ? want_nopc_h8300s : want_nopc_h8300h);
+  if (h8300smode)
+    wanted_nopc = want_nopc_h8300s;
+  else
+    wanted_nopc = want_nopc_h8300h);
 #endif
+  fetch_regs_from_dump (gch, wanted_nopc);
 
   /* And supply the extra ones the simulator uses */
   for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
@@ -2183,13 +2218,13 @@ _initialize_remote_e7000 ()
 {
   add_target (&e7000_ops);
 
-  add_com ("e7000 <command>", class_obscure, e7000_command,
+  add_com ("e7000", class_obscure, e7000_command,
           "Send a command to the e7000 monitor.");
 
-  add_com ("ftplogin <machine> <name> <passwd> <dir>", class_obscure, e7000_login_command,
+  add_com ("ftplogin", class_obscure, e7000_login_command,
           "Login to machine and change to directory.");
 
-  add_com ("ftpload <file>", class_obscure, e7000_ftp_command,
+  add_com ("ftpload", class_obscure, e7000_ftp_command,
           "Fetch and load a file from previously described place.");
 
   add_com ("drain", class_obscure, e7000_drain_command,
index 71a73d35aee8828b781dbb1c4809a3921a94c094..49e573fa187ff13668676ac600463040935689fc 100644 (file)
@@ -504,7 +504,11 @@ gdbsim_open (args, from_tty)
   if (gdbsim_desc != NULL)
     unpush_target (&gdbsim_ops);
 
-  len = 7 + 1 + (args ? strlen (args) : 0) + 50;
+  len = (7 + 1 /* gdbsim */
+        + strlen (" -E little")
+        + strlen (" --arch=xxxxxxxxxx")
+        + (args ? strlen (args) : 0)
+        + 50) /* slack */;
   arg_buf = (char *) alloca (len);
   strcpy (arg_buf, "gdbsim"); /* 7 */
   /* Specify the byte order for the target when it is both selectable
@@ -525,6 +529,13 @@ gdbsim_open (args, from_tty)
        }
     }
 #endif
+  /* Specify the architecture of the target when it has been
+     explicitly specified */
+  if (!target_architecture_auto)
+    {
+      strcat (arg_buf, " --arch=");
+      strcat (arg_buf, target_architecture->printable_name);
+    }
   /* finally, any explicit args */
   if (args)
     {
index c1db88c02655945cf1e62d4179180bda29c9b3a7..5dad65b37a671b0c7e25f0b31e6d4d656fe036f8 100644 (file)
@@ -37,16 +37,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 extern int remote_write_size;  /* in remote.c */
 
-/* Default to the original SH.  */
-
-#define DEFAULT_SH_TYPE "sh"
-
-/* This value is the model of SH in use.  */
-
-char *sh_processor_type;
-
-char *tmp_sh_processor_type;
-
 /* A set of original names, to be used when restoring back to generic
    registers from a specific set.  */
 
@@ -89,13 +79,16 @@ char *sh3e_reg_names[] = {
 };
 
 struct {
-  char *name;
   char **regnames;
+  int mach;
 } sh_processor_type_table[] = {
-  { "sh", sh_reg_names },
-  { "sh3", sh3_reg_names },
-  { "sh3e", sh3e_reg_names },
-  { NULL, NULL }
+  { sh_reg_names, bfd_mach_sh },
+  { sh3_reg_names, bfd_mach_sh3 },
+  { sh3e_reg_names, bfd_mach_sh3e },
+  /* start-sanitize-sh4 */
+  { sh3e_reg_names, bfd_mach_sh4 },
+  /* end-sanitize-sh4 */
+  { NULL, 0 }
 };
 
 /* Prologue looks like
@@ -589,74 +582,28 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
 }
 
 
-/* Command to set the processor type.  */
-
-void
-sh_set_processor_type_command (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  int i;
-  char *temp;
-
-  /* The `set' commands work by setting the value, then calling the hook,
-     so we let the general command modify a scratch location, then decide
-     here if we really want to modify the processor type.  */
-  if (tmp_sh_processor_type == NULL || *tmp_sh_processor_type == '\0')
-    {
-      printf_unfiltered ("The known SH processor types are as follows:\n\n");
-      for (i = 0; sh_processor_type_table[i].name != NULL; ++i)
-       printf_unfiltered ("%s\n", sh_processor_type_table[i].name);
-
-      /* Restore the value.  */
-      tmp_sh_processor_type = strsave (sh_processor_type);
-
-      return;
-    }
-  
-  if (!sh_set_processor_type (tmp_sh_processor_type))
-    {
-      /* Restore to a valid value before erroring out.  */
-      temp = tmp_sh_processor_type;
-      tmp_sh_processor_type = strsave (sh_processor_type);
-      error ("Unknown processor type `%s'.", temp);
-    }
-}
-
-/* This is a dummy not actually run.  */
-
-static void
-sh_show_processor_type_command (args, from_tty)
-     char *args;
-     int from_tty;
-{
-}
-
 /* Modify the actual processor type. */
 
 int
-sh_set_processor_type (str)
-     char *str;
+sh_target_architecture_hook (ap)
+     const bfd_arch_info_type *ap;
 {
   int i, j;
 
-  if (str == NULL)
+  if (ap->arch != bfd_arch_sh)
     return 0;
 
-  for (i = 0; sh_processor_type_table[i].name != NULL; ++i)
+  for (i = 0; sh_processor_type_table[i].regnames != NULL; i++)
     {
-      if (strcasecmp (str, sh_processor_type_table[i].name) == 0)
+      if (sh_processor_type_table[i].mach == ap->mach)
        {
-         sh_processor_type = str;
-
          for (j = 0; j < NUM_REGS; ++j)
            reg_names[j] = sh_processor_type_table[i].regnames[j];
-
          return 1;
        }
     }
 
-  return 0;
+  fatal ("Architecture `%s' unreconized", ap->printable_name);
 }
 
 /* Print the registers in a form similar to the E7000 */
@@ -666,12 +613,16 @@ sh_show_regs (args, from_tty)
      char *args;
      int from_tty;
 {
-  int cpu = 0;
-
-  if (strcmp (sh_processor_type, "sh3") == 0)
-    cpu = 1;
-  else if (strcmp (sh_processor_type, "sh3e") == 0)
-    cpu = 2;
+  int cpu;
+  if (target_architecture->arch == bfd_arch_sh)
+    cpu = target_architecture->mach;
+  else
+    cpu = 0;
+  /* start-sanitize-sh4 */
+  /* FIXME: sh4 has more registers */
+  if (cpu == bfd_mach_sh4)
+    cpu = bfd_mach_sh3;
+  /* end-sanitize-sh4 */
 
   printf_filtered ("PC=%08x SR=%08x PR=%08x MACH=%08x MACHL=%08x\n",
                   read_register (PC_REGNUM),
@@ -683,12 +634,12 @@ sh_show_regs (args, from_tty)
   printf_filtered ("GBR=%08x VBR=%08x",
                    read_register (GBR_REGNUM),
                    read_register (VBR_REGNUM));
-  if (cpu == 1 || cpu == 2)
+  if (cpu == bfd_mach_sh3 || cpu == bfd_mach_sh3e)
     {
       printf_filtered (" SSR=%08x SPC=%08x",
                        read_register (SSR_REGNUM),
                        read_register (SPC_REGNUM));
-      if (cpu ==2)
+      if (cpu == bfd_mach_sh3e)
         {
           printf_filtered (" FPUL=%08x FPSCR=%08x",
                            read_register (FPUL_REGNUM),
@@ -714,7 +665,7 @@ sh_show_regs (args, from_tty)
                   read_register (13),
                   read_register (14),
                   read_register (15));
-  if (cpu == 2)
+  if (cpu == bfd_mach_sh3e)
     {
       printf_filtered ("FP0-FP7  %08x %08x %08x %08x %08x %08x %08x %08x\n",
                        read_register (FP0_REGNUM + 0),
@@ -764,18 +715,7 @@ _initialize_sh_tdep ()
 
   tm_print_insn = gdb_print_insn_sh;
 
-  c = add_set_cmd ("processor", class_support, var_string_noescape,
-                  (char *) &tmp_sh_processor_type,
-                  "Set the type of SH processor in use.\n\
-Set this to be able to access processor-type-specific registers.\n\
-",
-                  &setlist);
-  c->function.cfunc = sh_set_processor_type_command;
-  c = add_show_from_set (c, &showlist);
-  c->function.cfunc = sh_show_processor_type_command;
-
-  tmp_sh_processor_type = strsave (DEFAULT_SH_TYPE);
-  sh_set_processor_type_command (strsave (DEFAULT_SH_TYPE), 0);
+  target_architecture_hook = sh_target_architecture_hook;
 
   add_com ("regs", class_vars, sh_show_regs, "Print all registers");
 }
index 92992607199f27e17f5c9b8f035fffcc42a63ca2..a4e3b7146aef0e6883ad3933244fc124ede2129f 100644 (file)
@@ -284,7 +284,7 @@ sh3_open (args, from_tty)
     }
 
   /* If we connected successfully, we know the processor is an SH3.  */
-  sh_set_processor_type ("sh3");
+  set_architecture ("sh3", 0);
 }
 
 
@@ -333,7 +333,7 @@ sh3e_open (args, from_tty)
     }
 
   /* If we connected successfully, we know the processor is an SH3E.  */
-  sh_set_processor_type ("sh3e");
+  set_architecture ("sh3e", 0);
 }
 
 static void
index 1c85374f0fed3f0869db4f957a936d6572bff214..0d951d9019dc1966dc7619158e6ffbcdf857bde5 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -118,6 +118,12 @@ static void set_endian_auto PARAMS ((char *, int));
 
 static void show_endian PARAMS ((char *, int));
 
+extern void set_architecture PARAMS ((char *, int));
+
+static void show_architecture PARAMS ((char *, int));
+
+static void info_architecture PARAMS ((char *, int));
+
 static void show_history PARAMS ((char *, int));
 
 static void set_history PARAMS ((char *, int));
@@ -3229,6 +3235,110 @@ set_endian_from_file (abfd)
 #endif /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
 }
 \f
+/* Functions to manipulate the architecture of the target */
+
+int target_architecture_auto = 1;
+extern const bfd_arch_info_type bfd_default_arch_struct;
+const bfd_arch_info_type *target_architecture = &bfd_default_arch_struct;
+int (*target_architecture_hook) PARAMS ((const bfd_arch_info_type *ap));
+
+/* Called if the user enters ``set architecture'' with or without an argument. */
+void
+set_architecture (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  if (args == NULL)
+    {
+      printf_unfiltered ("\"set architecture\" must be followed by \"auto\" or an architecture name.\n");
+    }
+  else if (strcmp (args, "auto") == 0)
+    {
+      target_architecture_auto = 1;
+    }
+  else
+    {
+      const bfd_arch_info_type *arch = bfd_scan_arch (args);
+      if (arch != NULL)
+       {
+         /* FIXME: Is it compatible with gdb? */
+         /* Check with the target on the setting */
+         if (target_architecture_hook != NULL
+             && !target_architecture_hook (arch))
+           printf_unfiltered ("Target does not support `%s' architecture.", args);
+         else
+           {
+             target_architecture_auto = 0;
+             target_architecture = arch;
+           }
+       }
+      else
+       {
+         printf_unfiltered ("Architecture `%s' not reconized.\n", args);
+       }
+    }
+}
+
+/* Called if the user enters ``show architecture'' without an argument. */
+static void
+show_architecture (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  const char *arch;
+  arch = target_architecture->printable_name;
+  if (target_architecture_auto)
+    printf_filtered ("The target architecture is set automatically (currently %s)\n", arch);
+  else
+    printf_filtered ("The target architecture is assumed to be %s\n", arch);
+}
+
+/* Called if the user enters ``info architecture'' without an argument. */
+static void
+info_architecture (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  enum bfd_architecture a;
+  printf_filtered ("Available architectures are:\n");
+  for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
+    {
+      const bfd_arch_info_type *ap = bfd_lookup_arch (a, 0);
+      if (ap != NULL)
+       {
+         do
+           {
+             printf_filtered (" %s", ap->printable_name);
+             ap = ap->next;
+           }
+         while (ap != NULL);
+         printf_filtered ("\n");
+       }
+    }
+}
+
+/* Set the architecture from a BFD */
+void
+set_architecture_from_file (abfd)
+     bfd *abfd;
+{
+  const bfd_arch_info_type *wanted = bfd_get_arch_info (abfd);
+  if (target_architecture_auto)
+    {
+      if (target_architecture_hook != NULL
+         && !target_architecture_hook (wanted))
+       warning ("Target may not support %s architecture",
+                wanted->printable_name);
+      target_architecture = wanted;
+    }
+  else if (wanted != target_architecture)
+    {
+      warning ("%s architecture file may be incompatible with %s target.",
+              wanted->printable_name,
+              target_architecture->printable_name);
+    }
+}
+\f
 /* Functions to manipulate command line editing control variables.  */
 
 /* Number of commands to print in each call to show_commands.  */
@@ -3461,6 +3571,14 @@ init_main ()
   add_cmd ("endian", class_support, show_endian,
           "Show endianness of target.", &showlist);
 
+  add_cmd ("architecture", class_support, set_architecture,
+          "Set architecture of target.", &setlist);
+  add_cmd ("architecture", class_support, show_architecture,
+          "Show architecture of target.", &showlist);
+  add_cmd ("architecture", class_support, info_architecture,
+          "List supported target architectures", &infolist);
+
+
 #ifdef DEFAULT_PROMPT
   prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
 #else