Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA] gdbserver fetch/store registers problem on s390x
@ 2005-05-10 19:48 Ulrich Weigand
  2005-05-15 19:39 ` Daniel Jacobowitz
  2005-07-13  1:35 ` Daniel Jacobowitz
  0 siblings, 2 replies; 4+ messages in thread
From: Ulrich Weigand @ 2005-05-10 19:48 UTC (permalink / raw)
  To: gdb-patches

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFA] gdbserver fetch/store registers problem on s390x
  2005-05-10 19:48 [RFA] gdbserver fetch/store registers problem on s390x Ulrich Weigand
@ 2005-05-15 19:39 ` Daniel Jacobowitz
  2005-07-13  1:35 ` Daniel Jacobowitz
  1 sibling, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2005-05-15 19:39 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

On Tue, May 10, 2005 at 06:54:28PM +0200, Ulrich Weigand wrote:
> 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?

This is OK.  Thank you!

-- 
Daniel Jacobowitz
CodeSourcery, LLC


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFA] gdbserver fetch/store registers problem on s390x
  2005-05-10 19:48 [RFA] gdbserver fetch/store registers problem on s390x Ulrich Weigand
  2005-05-15 19:39 ` Daniel Jacobowitz
@ 2005-07-13  1:35 ` Daniel Jacobowitz
  2005-07-13 12:03   ` Ulrich Weigand
  1 sibling, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2005-07-13  1:35 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

Hi Ulrich,

On Tue, May 10, 2005 at 06:54:28PM +0200, Ulrich Weigand wrote:
> 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.

While this patch was fine, it did make me take a closer look at what's
going on.  I've got a couple questions :-)  The kernel sources weren't
too enlightening, except that whoever maintains ptrace for s390 really
doesn't like GDB.

When you access the acrs, it looks like we are actually peeking/poking
two of them at once.  I didn't see any sign of the "rest must be
zeroed" you mentioned.  Is this in code not currently contributed to
kernel.org?

In the current code the ACR we want to be poking at is the
low-memory-address end of the buffer, i.e. leftmost in a big endian
system (which all supported s390 appears to be).  Is that right?

This is unfortunate... it means I need another target knob, since the
PPC64 FPSCR is definitively in the rightmost 32 bits of the ptrace
xfer.


-- 
Daniel Jacobowitz
CodeSourcery, LLC


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFA] gdbserver fetch/store registers problem on s390x
  2005-07-13  1:35 ` Daniel Jacobowitz
@ 2005-07-13 12:03   ` Ulrich Weigand
  0 siblings, 0 replies; 4+ messages in thread
From: Ulrich Weigand @ 2005-07-13 12:03 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

Hi Daniel,

> When you access the acrs, it looks like we are actually peeking/poking
> two of them at once.  I didn't see any sign of the "rest must be
> zeroed" you mentioned.  Is this in code not currently contributed to
> kernel.org?

OK, this only applies to the FPC register.  For the ACRs we're indeed
always transferring two at the same time, except when trying to read
the last one (%a15), in which case we get zeros in the low word on
peeking, and on poking the low word is ignored.

> In the current code the ACR we want to be poking at is the
> low-memory-address end of the buffer, i.e. leftmost in a big endian
> system (which all supported s390 appears to be).  Is that right?

Yes, that's correct.

> This is unfortunate... it means I need another target knob, since the
> PPC64 FPSCR is definitively in the rightmost 32 bits of the ptrace
> xfer.

Hmm ...


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-07-13 12:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-10 19:48 [RFA] gdbserver fetch/store registers problem on s390x Ulrich Weigand
2005-05-15 19:39 ` Daniel Jacobowitz
2005-07-13  1:35 ` Daniel Jacobowitz
2005-07-13 12:03   ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox