Re: parcelling up struct gdbarch

Andrew Cagney
2001-07-14T08:33:00Z

> Indeed. The current errors on one typical target - powerpc-linux -
> are:
>
> undefined reference to `current_gdbarch'
> undefined reference to `gdbarch_cannot_store_register'
> undefined reference to `gdbarch_fp_regnum'
> undefined reference to `gdbarch_npc_regnum'
> undefined reference to `gdbarch_pc_regnum'
> undefined reference to `gdbarch_register_byte'
> undefined reference to `gdbarch_register_bytes'
> undefined reference to `gdbarch_register_raw_size'
> undefined reference to `gdbarch_sp_regnum'

Live dangerously, try linking against libgdb.a :-)

> REGISTER_BYTES, KERNEL_U_ADDR, PC_REGNUM, SP_REGNUM, FP_REGNUM

REGISTER_BYTES is hard, I'll ignore it for the moment :-)
KERNEL_U_ADDR lives in nm.h so that one is probably ok.

As for PC_REGNUM, NPC_REGNUM, ... SP_REGNUM and FP_REGNUM, I think we
need to study a little history.

~'70: Wirth introduces pascal. By now everyone is convinced that
procedural languages need a program-counter, stack-pointer, dynamic-link
and static-link. Life was good.

~'79: The VAX appears, like everyone else they follow the DL/SL/SP
mantra and hence the VAX has a stack-pointer and a frame-pointer (DL).
I don't remember what was done with the static-link but, regardless,
life was good.

~'84: RMS writes GDB 0.0. It assumes FP, PC and SP are all raw
registers. Live was good.

Unfortunatly, from here on in, things started to go wrong: NPC_REGNUM,
then NNPC_REGNUM get added, DECR_PC_AFTER_BREAK was added, the MIPS gets
a bogus FP register and then proceeds to assume it is real, the arm gets
two FP registers, and finally GDB gets PSEUDO registers. Things are no
longer so good. In fact, thanks to DECR_PC_AFTER_BREAK, things are down
right miserable.

So we turn to now. Refering to figure ``1'':

> nat-register layout
> |
> |(*-nat.c)
> |
> raw register layout
> |
> |(*frame*)
> |
> cooked register layout

While it's taken 15 years to figure out, I think this is a register
model that works. As far as core GDB is concerned PC_REGNUM, FP_REGNUM,
SP_REGNUM et.al. are all cooked registers. While for many targets,
RAW_FP_REGNUM == COOKED_FP_REGNUM, might be true, they are separate.

The gdbserver code that refers to those macros has, has a result of the
above revalation, become wrong. The nat code, in general, should refer
to nat, raw or G register numbering and not cooked registers. When it
comes to the registers to pass back with the T packet, I think it should
be given an explicit list.

--

Looking to the future, PC_REGNUM, will get more interesting. Core GDB
has the idea of a stop-address and a continuation-address.
{read,write}_pc() control this. If someone ever tries to implement more
complex operations in gdbserver then they are going to need those
functions, or similar, to determine the ``cooked'' PC.

Andrew