This is the mail archive of the gdb-patches@sources.redhat.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]
Other format: [Raw text]

[RFA] gdbserver fetch/store registers problem on s390x


Hello,

this patch fixes another problem with gdbserver on s390x occurring
on recent kernels.  The problem is that some registers accessed by
ptrace (notably the access registers and the floating-point status
register) are still 32 bits wide, even though the PTRACE_PEEKUSER
and PTRACE_POKEUSER commands always transfer 64 bits.

This is a problem for two reasons: when fetching those registers,
a 4-byte buffer is allocated via alloca, but then 8 bytes are 
written to that buffer (which just happens to work because alloca
rounds the size up to the next multiple of 8 anyway).  The same
holds for storing the register; but in this case the second 4 bytes
have just random contents, and recent kernels won't allow the POKEUSER
command to succeed unless those extra bytes are zero.

The following patch fixes this problem by always allocating a buffer
that has multiple of sizeof (PTRACE_XFER_TYPE) as size, and by
zeroing out the excess bytes of the buffer when storing the register.

Tested on s390-ibm-linux and s390x-ibm-linux.
OK?

Bye,
Ulrich


ChangeLog:

	* linux-low.c (fetch_register): Ensure buffer size is a multiple
	of sizeof (PTRACE_XFER_TYPE).
	(usr_store_inferior_registers): Likewise.  Zero out excess bytes.

Index: gdb/gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.34
diff -c -p -r1.34 linux-low.c
*** gdb/gdbserver/linux-low.c	3 Mar 2005 16:56:53 -0000	1.34
--- gdb/gdbserver/linux-low.c	10 May 2005 11:53:40 -0000
*************** static void
*** 1095,1101 ****
  fetch_register (int regno)
  {
    CORE_ADDR regaddr;
!   register int i;
    char *buf;
  
    if (regno >= the_low_target.num_regs)
--- 1095,1101 ----
  fetch_register (int regno)
  {
    CORE_ADDR regaddr;
!   int i, size;
    char *buf;
  
    if (regno >= the_low_target.num_regs)
*************** fetch_register (int regno)
*** 1106,1113 ****
    regaddr = register_addr (regno);
    if (regaddr == -1)
      return;
!   buf = alloca (register_size (regno));
!   for (i = 0; i < register_size (regno); i += sizeof (PTRACE_XFER_TYPE))
      {
        errno = 0;
        *(PTRACE_XFER_TYPE *) (buf + i) =
--- 1106,1115 ----
    regaddr = register_addr (regno);
    if (regaddr == -1)
      return;
!   size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
!          & - sizeof (PTRACE_XFER_TYPE);
!   buf = alloca (size);
!   for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
      {
        errno = 0;
        *(PTRACE_XFER_TYPE *) (buf + i) =
*************** static void
*** 1147,1153 ****
  usr_store_inferior_registers (int regno)
  {
    CORE_ADDR regaddr;
!   int i;
    char *buf;
  
    if (regno >= 0)
--- 1149,1155 ----
  usr_store_inferior_registers (int regno)
  {
    CORE_ADDR regaddr;
!   int i, size;
    char *buf;
  
    if (regno >= 0)
*************** usr_store_inferior_registers (int regno)
*** 1162,1170 ****
        if (regaddr == -1)
  	return;
        errno = 0;
!       buf = alloca (register_size (regno));
        collect_register (regno, buf);
!       for (i = 0; i < register_size (regno); i += sizeof (PTRACE_XFER_TYPE))
  	{
  	  errno = 0;
  	  ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
--- 1164,1175 ----
        if (regaddr == -1)
  	return;
        errno = 0;
!       size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
! 	     & - sizeof (PTRACE_XFER_TYPE);
!       buf = alloca (size);
!       memset (buf, 0, size);
        collect_register (regno, buf);
!       for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
  	{
  	  errno = 0;
  	  ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  Ulrich.Weigand@de.ibm.com


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