This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Fix to mips64 G/g/T/P packets
- To: gdb-patches@sourceware.cygnus.com
- Subject: Fix to mips64 G/g/T/P packets
- From: Andrew Cagney <ac131313@cygnus.com>
- Date: Mon, 12 Jul 1999 17:48:40 +1000
- DJ-Gateway: from newsgroup cygnus.patches.gdb
- Newsgroups: cygnus.patches.gdb
- Organization: Cygnus Solutions
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. */