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

Re: [RFC] Register sets


FYI, given a request for REGNUM (>= 0) the code must supply at least
that register (but is free to supply others).


That's where I'd like things more clearly specified.  The difference
between Mark's statement and Andrew's is whether the other register
data in the regset is considered precious, or is clobbered from the
copy in the regcache.  I believe not all our architectures agree on
that now.

Here data is moving moving from the regset buffer to the regcache. The problems you mention don't occure.


There's a more general problem here (JeffJ pointed it out to me). At
present "gcore" obtains the registers being saved using regcache collect. Unfortunatly, there's a missing target_fetch_registers(-1) call, and, as a consequence, the registers written out can be invalid :-( There are several issues here: should "gcore" use regcache collect directly (bypassing the register fetch mechanism); if not, should this regset methods be parameterized with the function that should be used when collecting the registers (see regcache_cooked_read_ftype)?


I've run into this problem also.  There's a target_fetch_registers in
linux-proc.c with a FIXME; that's in the threaded case.  In the
non-threaded case the call is missing.  Personally, I believe that the
call shouldn't be necessary, and that fill_gregset should use the
collect mechanism (which implicitly calls fetch).  But I'm not sure if
that will work.

I agree that the target_fetch_registers call shouldn't be needed. I think the correct way to avoid it though is to have the "gcore" code pull register values from the high (regcache_raw_read) and not the low (collect_register) side of the regcache. That way the target gets a chance to on-demand pull in the registers it needs.


That's exactly what I'm aiming at :-). The "mapping" needs to be a
>function though, since in some cases it might need to do some
>arithmetic on the buffer contents in order to convert them to the
>format used by GDB's register cache.


Yes. Functions will work better.


OK.  I'd like to add a function in common code which does the mapping
based on a table though, since for many cases that's enough - cuts down
on duplication.  What do you think?

I think transforming something like:


void
mipsnbsd_supply_reg (char *regs, int regno)
{
  int i;

  for (i = 0; i <= PC_REGNUM; i++)
    {
      if (regno == i || regno == -1)
        {
          if (CANNOT_FETCH_REGISTER (i))
            supply_register (i, NULL);
          else
            supply_register (i, regs + (i * MIPS_REGSIZE));
        }
    }
}

into an equivalent function like:


> void
> mipsnbsd_xfer_reg (void *cache, int regno, void (xfer*) (void *cache, int regnum, int offset))
> {
> int i;
>
> for (i = 0; i <= PC_REGNUM; i++)
> {
> if (regno == i || regno == -1)
> {
> if (CANNOT_FETCH_REGISTER (i))
> xfer (cache, i, -1);
> else
> xfer (cache, i, (i * MIPS_REGSIZE));
> }
> }
> }


is far lower risk and less complex then trying to replace this with a table.

The key thing to remember is that the code is write once, fix, forget. Any duplication isn't an issue as, once working, it won't be touched.
Yes.

Need to figure out how to relate these regsets back to ptrace/proc requests in some sort of generic way. Doing the same for remote would hopefully then fall out.


I'm not sure that it's possible to relate them back in any generic way;
ptrace is just too quirky.  The closest I can picture is the way I did
it in gdbserver, which is really more of a common-code thing than a
generic-interface thing:

struct regset_info target_regsets[] = {
  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
    GENERAL_REGS,
    i386_fill_gregset, i386_store_gregset },
  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
    FP_REGS,
    i386_fill_fpregset, i386_store_fpregset },
  { 0, 0, -1, -1, NULL, NULL }
};

Right. It needs a method to perform an arbitrary map from a REGNUM to a regset descriptor vis:
REGNUM -> regset descriptor
But what does a regset descriptor consist of?
- the buffer <-> cache method[s]
- the ptrace number (is this constant for an OS?)
- the /proc field (is this constant for an OS?)
- the size of the buffer


Recall an earlier suggestion that GDB be given access to /proc in the remote target? This would let GDB initiate remote ptrace and remote /proc requests.

Andrew


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