This is the mail archive of the gdb-patches@sourceware.org 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]

Re: [PATCH] Linux/gdbserver: Correctly handle narrow big-endian register transfers


Maciej W. Rozycki wrote:

>  This fixes the problem for MIPS, however from my understanding of your 
> commit it will break s390x unless it is further adjusted in a 
> target-dependent manner.  So my question is: does `ptrace' indeed place 
> 32-bit quantities transferred in bits 63:32 of the 64-bit integer data 
> quantity passed?
> 
>  If so, then would wrapping this into `#ifndef __s390x__' be OK with you 
> as it's s390x that appears to be an oddball here by representing the 
> same 32-bit integer data quantity differently between 32-bit and 64-bit 
> systems (i.e. you can't just cast `long' to `int')?
> 
>  I have no access to an s390x to verify this change.  This has passed 
> regression testing with o32 and n64 targets with `gdbserver' strapped to 
> use PTRACE_PEEKUSR and PTRACE_POKEUSR requests across all registers.

Well, my understanding of PTRACE_PEEKUSR and PTRACE_POKEUSR is that they
are supposed to simulate access to a "user area", i.e. a data structure
that holds per-process status, in word sized chunks.  Now of course the
Linux kernel doesn't actually maintain such a "user area", but for the
purpose of those ptrace calls, it is supposed to pretend it does.

So if we e.g. have some word-sized floating-point registers and a halfword
size status register, the kernel would pretend they are stored in a struct
like this:

  struct user_area
  {
    long fpr[16];
    int  fpc;
  };

and if you access this with PTRACE_PEEKUSR at offset
   offsetof(struct user_area, fpc)
you get the 8 bytes at this offset.  On a big-endian system, those
correspond to getting the 4 bytes of fpc in the most-significant
bytes, and some padding in the least-significant bytes.

This is what gdbserver expects, and what the kernel ptrace logic
(at least on s390x, I cannot say about others) implements:

        } else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) {
                /*
                 * floating point control reg. is in the thread structure
                 */
                tmp = child->thread.fpu.fpc;
                tmp <<= BITS_PER_LONG - 32;

If this is implemented differently on mips, I guess gdbserver will
have to handle this, but I don't really like an #ifdef here.

Can't you move the special logic into platform-specific
the_low_target.collect_ptrace_register and
the_low_target.supply_ptrace_register calls instead?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  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]