* Bringing over SKY PKE disassembler feature from sky branch.
[deliverable/binutils-gdb.git] / gdb / remote.c
index 02b31ccd0d34c76c912bdfe42f11bb8d763b6927..ca1a8a406a79b8a92c4bb3a082fdf35fe5bd5af3 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
-   Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -275,109 +275,20 @@ static int remote_remove_breakpoint PARAMS ((CORE_ADDR, char *));
 
 static int hexnumlen PARAMS ((ULONGEST num));
 
+static void init_remote_ops PARAMS ((void));
+
+static void init_extended_remote_ops PARAMS ((void));
+
 /* exported functions */
 
 extern int fromhex PARAMS ((int a));
 extern void getpkt PARAMS ((char *buf, int forever));
 extern int putpkt PARAMS ((char *buf));
 
-/* Define the target subroutine names */
-
 static struct target_ops remote_ops ;
 
-static void init_remote_ops(void)
-{
-  remote_ops.to_shortname =   "remote";                
-  remote_ops.to_longname =   "Remote serial target in gdb-specific protocol";
-  remote_ops.to_doc =   "Use a remote computer via a serial line; using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya)." ;  
-  remote_ops.to_open =   remote_open;          
-  remote_ops.to_close =   remote_close;                
-  remote_ops.to_attach =   NULL;               
-  remote_ops.to_detach =   remote_detach;      
-  remote_ops.to_resume =   remote_resume;      
-  remote_ops.to_wait  =   remote_wait;         
-  remote_ops.to_fetch_registers  =   remote_fetch_registers;
-  remote_ops.to_store_registers  =   remote_store_registers;
-  remote_ops.to_prepare_to_store =   remote_prepare_to_store;
-  remote_ops.to_xfer_memory  =   remote_xfer_memory;   
-  remote_ops.to_files_info  =   remote_files_info;     
-  remote_ops.to_insert_breakpoint =   remote_insert_breakpoint;
-  remote_ops.to_remove_breakpoint =   remote_remove_breakpoint;
-  remote_ops.to_terminal_init  =   NULL;               
-  remote_ops.to_terminal_inferior =   NULL;            
-  remote_ops.to_terminal_ours_for_output =   NULL;
-  remote_ops.to_terminal_ours  =   NULL;       
-  remote_ops.to_terminal_info  =   NULL;       
-  remote_ops.to_kill  =   remote_kill;         
-  remote_ops.to_load  =   generic_load;                
-  remote_ops.to_lookup_symbol =   NULL;                
-  remote_ops.to_create_inferior =   NULL;      
-  remote_ops.to_mourn_inferior =   remote_mourn;
-  remote_ops.to_can_run  =   0;                        
-  remote_ops.to_notice_signals =   0;          
-  remote_ops.to_thread_alive  =   remote_thread_alive;
-  remote_ops.to_stop  =   0;           
-  remote_ops.to_stratum =   process_stratum;
-  remote_ops.DONT_USE =   NULL;                
-  remote_ops.to_has_all_memory =   1;  
-  remote_ops.to_has_memory =   1;      
-  remote_ops.to_has_stack =   1;       
-  remote_ops.to_has_registers =   1;   
-  remote_ops.to_has_execution =   1;   
-  remote_ops.to_sections =   NULL;     
-  remote_ops.to_sections_end =   NULL; 
-  remote_ops.to_magic =   OPS_MAGIC ;  
-} /* init_remote_ops */
-
 static struct target_ops extended_remote_ops ;
 
-static void init_extended_remote_ops(void) 
-{
-  extended_remote_ops.to_shortname =   "extended-remote";      
-  extended_remote_ops.to_longname =   "Extended remote serial target in gdb-specific protocol";
-  extended_remote_ops.to_doc =   "Use a remote computer via a serial line; using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
-    extended_remote_ops.to_open =   extended_remote_open;      
-  extended_remote_ops.to_close =   remote_close;       
-  extended_remote_ops.to_attach =   NULL;              
-  extended_remote_ops.to_detach =   remote_detach;     
-  extended_remote_ops.to_resume =   remote_resume;     
-  extended_remote_ops.to_wait  =   remote_wait;                
-  extended_remote_ops.to_fetch_registers  =   remote_fetch_registers;
-  extended_remote_ops.to_store_registers  =   remote_store_registers;  
-  extended_remote_ops.to_prepare_to_store =   remote_prepare_to_store;
-  extended_remote_ops.to_xfer_memory  =   remote_xfer_memory;  
-  extended_remote_ops.to_files_info  =   remote_files_info;    
-  extended_remote_ops.to_insert_breakpoint =   remote_insert_breakpoint;
-  extended_remote_ops.to_remove_breakpoint =   remote_remove_breakpoint;
-  extended_remote_ops.to_terminal_init  =   NULL;              
-  extended_remote_ops.to_terminal_inferior =   NULL;           
-  extended_remote_ops.to_terminal_ours_for_output =   NULL;
-  extended_remote_ops.to_terminal_ours  =   NULL;      
-  extended_remote_ops.to_terminal_info  =   NULL;      
-  extended_remote_ops.to_kill  =   remote_kill;                
-  extended_remote_ops.to_load  =   generic_load;       
-  extended_remote_ops.to_lookup_symbol =   NULL;       
-  extended_remote_ops.to_create_inferior =   extended_remote_create_inferior;
-  extended_remote_ops.to_mourn_inferior =   extended_remote_mourn;
-  extended_remote_ops.to_can_run  =   0;                       
-  extended_remote_ops.to_notice_signals =   0;                 
-  extended_remote_ops.to_thread_alive  =   remote_thread_alive;
-  extended_remote_ops.to_stop  =   0;                  
-  extended_remote_ops.to_stratum =   process_stratum;
-  extended_remote_ops.DONT_USE =   NULL;       
-  extended_remote_ops.to_has_all_memory =   1; 
-  extended_remote_ops.to_has_memory =   1;     
-  extended_remote_ops.to_has_stack =   1;      
-  extended_remote_ops.to_has_registers =   1;  
-  extended_remote_ops.to_has_execution =   1;  
-  extended_remote_ops.to_sections =   NULL;    
-  extended_remote_ops.to_sections_end =   NULL;
-  extended_remote_ops.to_magic =   OPS_MAGIC ;
-} 
-
-
 /* This was 5 seconds, which is a long time to sit and wait.
    Unless this is going though some terminal server or multiplexer or
    other form of hairy serial connection, I would think 2 seconds would
@@ -725,8 +636,10 @@ device is attached to the remote system (e.g. /dev/ttya).");
      (we'd be in an inconsistent state otherwise).  */
   if (!catch_errors (remote_start_remote, (char *)0, 
                     "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
-    pop_target();
-
+    {
+      pop_target();
+      return;
+    }
 
   if (extended_p)
     {
@@ -1540,6 +1453,18 @@ remote_send (buf)
     error ("Remote failure reply: %s", buf);
 }
 
+/* Display a null-terminated packet on stdout, for debugging, using C
+   string notation.  */
+static void
+print_packet (char *buf)
+{
+  puts_filtered ("\"");
+  while (*buf)
+    gdb_printchar (*buf++, gdb_stdout, '"');
+  puts_filtered ("\"");
+}
+
+
 /* Send a packet to the remote machine, with error checking.
    The data of the packet is in BUF.  */
 
@@ -2020,15 +1945,208 @@ open_remote_target (name, from_tty, target, extended_p)
   remote_open_1 (name, from_tty, target, extended_p);
 }
 
+/* Table used by the crc32 function to calcuate the checksum. */
+static unsigned long crc32_table[256] = {0, 0};
+
+static unsigned long
+crc32 (buf, len, crc)
+     unsigned char *buf;
+     int len;
+     unsigned int crc;
+{
+  if (! crc32_table[1])
+    {
+      /* Initialize the CRC table and the decoding table. */
+      int i, j;
+      unsigned int c;
+
+      for (i = 0; i < 256; i++)
+        {
+          for (c = i << 24, j = 8; j > 0; --j)
+            c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+          crc32_table[i] = c;
+        }
+    }
+
+  while (len--)
+    {
+      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+      buf++;
+    }
+  return crc;
+}
+
+static void
+compare_sections_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  asection *s;
+  unsigned long host_crc, target_crc;
+  extern bfd *exec_bfd;
+  struct cleanup *old_chain;
+  char *tmp, *sectdata, *sectname, buf[PBUFSIZ];
+  bfd_size_type size;
+  bfd_vma lma;
+  int matched = 0;
+  int mismatched = 0;
+
+  if (!exec_bfd)
+    error ("command cannot be used without an exec file");
+  if (!current_target.to_shortname ||
+      strcmp (current_target.to_shortname, "remote") != 0)
+    error ("command can only be used with remote target");
+
+  for (s = exec_bfd->sections; s; s = s->next) 
+    {
+      if (!(s->flags & SEC_LOAD))
+       continue;       /* skip non-loadable section */
+
+      size = bfd_get_section_size_before_reloc (s);
+      if (size == 0)
+       continue;       /* skip zero-length section */
+
+      sectname = (char *) bfd_get_section_name (exec_bfd, s);
+      if (args && strcmp (args, sectname) != 0)
+       continue;       /* not the section selected by user */
+
+      matched = 1;     /* do this section */
+      lma = s->lma;
+      /* FIXME: assumes lma can fit into long */
+      sprintf (buf, "qCRC:%lx,%lx", (long) lma, (long) size);
+      putpkt (buf);
+
+      /* be clever; compute the host_crc before waiting for target reply */
+      sectdata = xmalloc (size);
+      old_chain = make_cleanup (free, sectdata);
+      bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
+      host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
+
+      getpkt (buf, 0);
+      if (buf[0] == 'E')
+       error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
+              sectname, lma, lma + size);
+      if (buf[0] != 'C')
+       error ("remote target does not support this operation");
+
+      for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
+       target_crc = target_crc * 16 + fromhex (*tmp);
+
+      printf_filtered ("Section %s, range 0x%08x -- 0x%08x: ",
+                      sectname, lma, lma + size);
+      if (host_crc == target_crc)
+       printf_filtered ("matched.\n");
+      else
+       {
+       printf_filtered ("MIS-MATCHED!\n");
+        mismatched++;
+       }
+
+      do_cleanups (old_chain);
+    }
+  if (mismatched > 0)
+     warning ("One or more sections of the remote executable does not match\nthe loaded file\n");
+  if (args && !matched)
+    printf_filtered ("No loaded section named '%s'.\n", args);
+}
+
+static void
+packet_command (args, from_tty)
+     char *args;
+     int from_tty;
+
+
+{
+  char buf[PBUFSIZ];
+
+  if (!current_target.to_shortname ||
+      strcmp (current_target.to_shortname, "remote") != 0)
+    error ("command can only be used with remote target");
+
+  if (! args)
+    error ("remote-packet command requires packet text as argument");
+
+  puts_filtered ("sending: ");
+  print_packet (args);
+  puts_filtered ("\n");
+  putpkt (args);
+
+  getpkt (buf, 0);
+  puts_filtered ("received: ");
+  print_packet (buf);
+  puts_filtered ("\n");
+}
+
+static void
+init_remote_ops ()
+{
+  remote_ops.to_shortname = "remote";          
+  remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
+  remote_ops.to_doc = "Use a remote computer via a serial line; using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";  
+  remote_ops.to_open = remote_open;            
+  remote_ops.to_close = remote_close;          
+  remote_ops.to_detach = remote_detach;        
+  remote_ops.to_resume = remote_resume;        
+  remote_ops.to_wait = remote_wait;            
+  remote_ops.to_fetch_registers = remote_fetch_registers;
+  remote_ops.to_store_registers = remote_store_registers;
+  remote_ops.to_prepare_to_store = remote_prepare_to_store;
+  remote_ops.to_xfer_memory = remote_xfer_memory;      
+  remote_ops.to_files_info = remote_files_info;        
+  remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
+  remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+  remote_ops.to_kill = remote_kill;            
+  remote_ops.to_load = generic_load;           
+  remote_ops.to_mourn_inferior = remote_mourn;
+  remote_ops.to_thread_alive = remote_thread_alive;
+  remote_ops.to_stratum = process_stratum;
+  remote_ops.to_has_all_memory = 1;    
+  remote_ops.to_has_memory = 1;        
+  remote_ops.to_has_stack = 1; 
+  remote_ops.to_has_registers = 1;     
+  remote_ops.to_has_execution = 1;     
+  remote_ops.to_magic = OPS_MAGIC;     
+}
+
+static void
+init_extended_remote_ops () 
+{
+  extended_remote_ops = remote_ops;
+
+  extended_remote_ops.to_shortname = "extended-remote";        
+  extended_remote_ops.to_longname = "Extended remote serial target in gdb-specific protocol";
+  extended_remote_ops.to_doc = "Use a remote computer via a serial line; using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+  extended_remote_ops.to_open = extended_remote_open;  
+  extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
+  extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
+} 
 
 void
 _initialize_remote ()
 {
-  init_remote_ops() ;
-  init_extended_remote_ops() ;
+  init_remote_ops ();
   add_target (&remote_ops);
+
+  init_extended_remote_ops ();
   add_target (&extended_remote_ops);
 
+  add_cmd ("compare-sections", class_obscure, compare_sections_command, 
+          "Compare section data on target to the exec file.\n\
+Argument is a single section name (default: all loaded sections).", 
+          &cmdlist);
+
+  add_cmd ("packet", class_maintenance, packet_command,
+          "Send an arbitrary packet to a remote target.\n\
+   maintenance packet TEXT\n\
+If GDB is talking to an inferior via the GDB serial protocol, then\n\
+this command sends the string TEXT to the inferior, and displays the\n\
+response packet.  GDB supplies the initial `$' character, and the\n\
+terminating `#' character and checksum.  This command was originally\n\
+provided for use by the gdb.emc test suite.",
+          &maintenancelist);
+
   add_show_from_set (add_set_cmd ("remotetimeout", no_class,
                                  var_integer, (char *)&remote_timeout,
                                  "Set timeout value for remote read.\n", &setlist),
@@ -2044,3 +2162,16 @@ _initialize_remote ()
                                  "Set the maximum number of bytes in each memory write packet.\n", &setlist),
                     &showlist);
 }
+
+
+
+
+
+
+
+
+
+
+
+
+
This page took 0.030395 seconds and 4 git commands to generate.