This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix to mips64 G/g/T/P packets


Hello,

The patch below addresses to long standing problems with GDB's support
for a remote 64 bit MIPS target.  Namely:

Wed Apr  1 23:13:23 1998  Andrew Cagney  <cagney@b1.cygnus.com>

        * config/mips/tm-mips.h (REGISTER_VIRTUAL_TYPE): Handle 32 bit
SR,
        FSR and FIR registers.
        (REGISTER_VIRTUAL_SIZE): Compute using REGISTER_VIRTUAL_TYPE.
        (REGISTER_RAW_SIZE): Define using REGISTER_VIRTUAL_SIZE.

        * config/mips/tm-mips64.h: Ditto.

This patch while fixing a problem of GDB displaying 64 bits of 32 bit
registers such as the FSR and SP at the same time broke the remote
protocol for MIPS64 targets in the field :-(

The attached patch, which should address this problem, makes the
following changes:

o       adds a new command:
          (gdb) set remote-mips64-transfers-32bit-regs {on,off}
        for compatibility with targets in the field.
 
 o      fixes the problem of GDB displaying 64 bits when
        the MIPS ISA only defines 32 bits for certain
        registers (ex SR, FSR)
 
 o      transfers all registers as 64 bits under the
        64bit ISA.
 

	Andrew


Mon Jul 12 11:15:09 1999  Andrew Cagney  <cagney@b1.cygnus.com>

        * config/mips/tm-mips.h (REGISTER_CONVERT_TO_RAW,
        REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERTIBLE): Define.
        (REGISTER_RAW_SIZE): Re-define as mips_register_convert_to_raw.
        * mips-tdep.c (mips_register_convert_to_raw,
        mips_register_convert_to_virtual, ): New functions.
        (mips_register_raw_size, mips_register_convertible): New
        functions.  Handle bug introduced by ``Wed Apr 1 23:13:23 1998
        Andrew Cagney <cagney@b1.cygnus.com>'' where remote mips64
target
        transfers SR as 64 bits yet GDB expected only 32 bits.
        (mips64_transfers_32bit_regs): New static variable.
        (_initialize_mips_tdep): Add obscure command ``set
        remote-mips64-transfers-32bit-regs'' that provides backward
        compatibility.
        (do_gp_register_row): Extract register values from raw buffer.

        * NEWS: Document protocol change.
Index: ./gdb/NEWS
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/NEWS,v
retrieving revision 2.64
diff -p -r2.64 NEWS
*** ./gdb/NEWS	1999/07/09 03:59:14	2.64
--- ./gdb/NEWS	1999/07/12 04:29:48
*************** ./gdb/NEWS					m68*-altos-*
*** 23,28 ****
--- 23,37 ----
  Convex						c1-*-*, c2-*-*
  Pyramid						pyramid-*-*
  
+ * MIPS 64 remote protocol
+ 
+ A long standing bug in the mips64 remote protocol where by GDB
+ expected certain 32 bit registers (ex SR) to be transfered as 32
+ instead of 64 bits has been fixed.
+ 
+ The command ``set remote-mips64-transfers-32bit-regs on'' has been
+ added to provide backward compatibility with older versions of GDB.
+ 
  *** Changes in GDB-4.18:
  
  * New native configurations
Index: ./gdb/mips-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/mips-tdep.c,v
retrieving revision 1.192
diff -p -r1.192 mips-tdep.c
*** ./gdb/mips-tdep.c	1999/07/07 23:51:39	1.192
--- ./gdb/mips-tdep.c	1999/07/12 04:29:58
*************** mips_print_extra_frame_info (fi)
*** 310,315 ****
--- 310,375 ----
  		     fi->extra_info->proc_desc->pdr.frameoffset);
  }
  
+ /* Convert between RAW and VIRTUAL registers.  The RAW register size
+    defines the remote-gdb packet. */
+ 
+ static int mips64_transfers_32bit_regs_p = 0;
+ 
+ int
+ mips_register_raw_size (reg_nr)
+      int reg_nr;
+ {
+   if (mips64_transfers_32bit_regs_p)
+     return REGISTER_VIRTUAL_SIZE (reg_nr);
+   else
+     return MIPS_REGSIZE;
+ }
+ 
+ int
+ mips_register_convertible (reg_nr)
+      int reg_nr;
+ {
+   if (mips64_transfers_32bit_regs_p)
+     return 0;
+   else
+     return (REGISTER_RAW_SIZE (reg_nr) > REGISTER_VIRTUAL_SIZE (reg_nr));
+ }
+ 
+ void
+ mips_register_convert_to_virtual (n, virtual_type, raw_buf, virt_buf)
+      int n;
+      struct type *virtual_type;
+      char *raw_buf;
+      char *virt_buf;
+ {
+   if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+     memcpy (virt_buf,
+ 	    raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
+ 	    TYPE_LENGTH (virtual_type));
+   else
+     memcpy (virt_buf,
+ 	    raw_buf,
+ 	    TYPE_LENGTH (virtual_type));
+ }
+ 
+ void
+ mips_register_convert_to_raw (virtual_type, n, virt_buf, raw_buf)
+      struct type *virtual_type;
+      int n;
+      char *virt_buf;
+      char *raw_buf;
+ {
+   memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
+   if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+     memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
+ 	    virt_buf,
+ 	    TYPE_LENGTH (virtual_type));
+   else
+     memcpy (raw_buf,
+ 	    virt_buf,
+ 	    TYPE_LENGTH (virtual_type));
+ }
+ 
  /* Should the upper word of 64-bit addresses be zeroed? */
  static int mask_address_p = 1;
  
*************** do_gp_register_row (regnum)
*** 2506,2519 ****
        if (read_relative_register_raw_bytes (regnum, raw_buffer))
  	error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
        /* pad small registers */
!       for (byte = 0; byte < (MIPS_REGSIZE - REGISTER_RAW_SIZE (regnum)); byte++)
  	printf_filtered ("  ");
        /* Now print the register value in hex, endian order. */
        if (TARGET_BYTE_ORDER == BIG_ENDIAN)
! 	for (byte = 0; byte < REGISTER_RAW_SIZE (regnum); byte++)
  	  printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
        else
! 	for (byte = REGISTER_RAW_SIZE (regnum) - 1; byte >= 0; byte--)
  	  printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
        printf_filtered (" ");
        col++;
--- 2566,2583 ----
        if (read_relative_register_raw_bytes (regnum, raw_buffer))
  	error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
        /* pad small registers */
!       for (byte = 0; byte < (MIPS_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
  	printf_filtered ("  ");
        /* Now print the register value in hex, endian order. */
        if (TARGET_BYTE_ORDER == BIG_ENDIAN)
! 	for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
! 	     byte < REGISTER_RAW_SIZE (regnum);
! 	     byte++)
  	  printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
        else
! 	for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
! 	     byte >= 0;
! 	     byte--)
  	  printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
        printf_filtered (" ");
        col++;
*************** search.  The only need to set it is when
*** 3938,3941 ****
--- 4002,4018 ----
  Use \"on\" to enable the masking, and \"off\" to disable it.\n\
  Without an argument, zeroing of upper address bits is enabled.", &setlist),
       &showlist);
+ 
+   /* Allow the user to control the size of 32 bit registers within the
+      raw remote packet.  */
+   add_show_from_set (add_set_cmd ("remote-mips64-transfers-32bit-regs",
+ 				  class_obscure,
+ 				  var_boolean,
+ 				  (char *)&mips64_transfers_32bit_regs_p, "\
+ Set compatibility with MIPS targets that transfers 32 and 64 bit quantities.\n\
+ Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
+ that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
+ 64 bits for others.  Use \"off\" to disable compatibility mode",
+ 				  &setlist),
+ 		     &showlist);
  }
Index: ./gdb/config/mips/tm-mips.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/config/mips/tm-mips.h,v
retrieving revision 1.83
diff -p -r1.83 tm-mips.h
*** ./gdb/config/mips/tm-mips.h	1999/07/07 23:52:32	1.83
--- ./gdb/config/mips/tm-mips.h	1999/07/12 04:30:11
*************** extern void mips_do_registers_info PARAM
*** 249,258 ****
  
  #define REGISTER_BYTE(N) ((N) * MIPS_REGSIZE)
  
! /* Number of bytes of storage in the actual machine representation
!    for register N. */
  
! #define REGISTER_RAW_SIZE(N) REGISTER_VIRTUAL_SIZE(N)
  
  /* Number of bytes of storage in the program's representation
     for register N. */
--- 249,279 ----
  
  #define REGISTER_BYTE(N) ((N) * MIPS_REGSIZE)
  
! /* Number of bytes of storage in the actual machine representation for
!    register N.  NOTE: This indirectly defines the register size
!    transfered by the GDB protocol. */
  
! extern int mips_register_raw_size PARAMS ((int reg_nr));
! #define REGISTER_RAW_SIZE(N) (mips_register_raw_size ((N)))
! 
! 
! /* Covert between the RAW and VIRTUAL registers.
! 
!    Some MIPS (SR, FSR, FIR) have a `raw' size of MIPS_REGSIZE but are
!    really 32 bit registers.  This is a legacy of the 64 bit MIPS GDB
!    protocol which transfers 64 bits for 32 bit registers. */
! 
! extern int mips_register_convertible PARAMS ((int reg_nr));
! #define REGISTER_CONVERTIBLE(N) (mips_register_convertible ((N)))
!      
! 
! void mips_register_convert_to_virtual PARAMS ((int reg_nr, struct type *virtual_type, char *raw_buf, char *virt_buf));
! #define REGISTER_CONVERT_TO_VIRTUAL(N,VIRTUAL_TYPE,RAW_BUF,VIRT_BUF) \
!   mips_register_convert_to_virtual (N,VIRTUAL_TYPE,RAW_BUF,VIRT_BUF)
! 
! void mips_register_convert_to_raw PARAMS ((struct type *virtual_type, int reg_nr, char *virt_buf, char *raw_buf));
! #define REGISTER_CONVERT_TO_RAW(VIRTUAL_TYPE,N,VIRT_BUF,RAW_BUF) \
!   mips_register_convert_to_raw (VIRTUAL_TYPE,N,VIRT_BUF,RAW_BUF)
  
  /* Number of bytes of storage in the program's representation
     for register N. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]