Re: ia64-stub.c

Kevin Buettner
2002-01-23T02:27:59Z

[dropped binutils from the cc; these aren't issues that the folks on
that list generally care about...]

On Jan 22, 3:35pm, Piet/Pete Delaney wrote:
> Subject: Re: ia64-stub.c
> On Tue, Jan 22, 2002 at 02:57:03PM -0700, Kevin Buettner wrote:
> > On Jan 22, 12:51pm, Piet/Pete Delaney wrote:
> >
> > > I expected them to be offsets into the registers stored in memory in the
> > > order specified by the ia64_register_names[] array in gdb/ia64-tdep.c.
> >
> > See u_offsets[] in gdbserver/low-linux.c. These are the offsets
> > needed by the ptrace() operations PTRACE_PEEKUSER / PTRACE_POKEUSER.
> > I haven't tried it in a while, so these offsets may need some
> > updating. (They ought to match the offsets found in ia64-linux-nat.c.)
>
> So u_offsets are only used in the ptrace response for registers and not the
> associated with the offsets needed to access registers fetched with the 'g' request.
> Isn't that worthy of the comment just before the static int u_offsets decl:
>
> /* These must match the order of the register names.
>
> Some sort of lookup table is needed because the offsets associated
> with the registers are all over the board. */

Yeah. That would indeed be a good idea.

> I would think similar offsets are needed for accessing registers provided
> by the 'g' cmd for the gdb code to access a particular register. I would
> have thought the ptrace data would be copied to the memory based copy
> of the registers as layed out in ia64_register_names[] order.

To the best of my knowledge, that is correct. At the moment, IA-64's
"g" packet is obviously not laid out very well since there's a lot of
wasted space.

I haven't been closely following what has been going on with remote.c,
but I think it may (soon?) be possible for a stub to (re)define the
layout of the "g" packet. (Hopefully Andrew or Daniel J will jump
in here and set me straight if I've said something incorrect.)

(Hint: Take a look at struct remote_state in remote.c. It appears to
me that there's a little bit more work to do to be able to provide
something other than the default 1:1 mapping between g packet registers
and gdb register numbers, but the infrastructure is definitely there.)

> > Note that the
> > IA-64 target is multiarched and that the only definition that GDB uses
> > from config/ia64/tm-ia64.h is:
> >
> > #define GDB_MULTI_ARCH 1
> >
> > Anyway, REGISTER_RAW_SIZE is about a correct as it can be for gdbserver.
>
> 600 references to GDB_MULTI_ARCH. Lots of places to look. Does this
> GDB_MULTI_ARCH paradigm meam that gdb isn't keeping registers in the
> order defined by ia64_register_names[].

No. The reason that I pointed out that REGISTER_RAW_SIZE in
config/ia64/tm-ia64.h only pertains to those gdbserver is because
the REGISTER_RAW_SIZE definition for gdb resides in ia64-tdep.c.
(See ia64_register_raw_size() in ia64-tdep.c.)

If you look, you'll see that the macro and the function do the
same thing. (Which is a good thing or else the "g" packets
wouldn't match up.)

> I would expect that the registers available on the ia64 are
> archecture independant and the ia64_register_names[] concept and
> storage should/could be common for all archectures.

Yes. See above.

> > > I thought I read that the predict registers p0..p63 are 1 bit and packed into
> > > a single 64 bit chunk of memory.
> >
> > They're packed into the pr register. ia64-tdep.c knows how to unpack
> > this register to give you discreet p0..p63 registers. (Note that from
> > GDB's standpoint these registers are read-only. A bit of work still
> > needs to be done to make them writable too.)
>
> I get the impression that theses can't be fetched with the 'g' command.
> This seems to be insistant with the protocol.txt on the 'g' cmd:

As noted above, there are a number of registers which are included in
the "g" packet which the IA-64 port disregards. r32-r127 are retrieved
using an offset from BSP from the backing store (i.e, from memory).
The predicate registers are transferred in a single 64 bit word (the
pr register) and are split out to show individual 1-bit registers
by gdb. Something similar occurs for the NaT bits. Most of these
are indicated via a -1 in the u_offsets[] array. (Some of these,
however, are simply not retrievable via the ptrace interface and
are therefore marked with -1.)

> > > When
> > > I use the gdb info registers cmd it seems to know the values in first 31 registers from
> > > my response to the 'g' cmd but then tries to access memory for the rest.
> >
> > This is correct.
>
> Why? Why not accept any register in the ia64_register_names array?

This means that the stub will need to have the same logic in it for
accessing r32-r127. I felt it better to put it in only one place.

> The "GDB Remote Serial Protocol Specification" seems to say that the
> protocol should try to transfer as many registers as possible. Since
> the kernel trap handler may not store registers in the same order
> as the C compiler (SPARC for example on SunOS and Solaris) it would
> seem more flexable for the stub to be able to provide as many registers
> as possible with the 'g' response and then attempt to fill anyu unknown
> values from the stack.

On the IA-64, r32-r127 are written to predictable places in the register
backing store.

> > > The memory location
> > > it's trys to access is an offset from the values it receives for the first 31 registers.
> >
> > That's not right. It should be an offset from bsp.
>
> That's was the other possability I was considering, that it was expecting the registers to be
> comming from the stack. Since kdb isn't providing the %bsp register in the register dump I
> didn't provide it on my 1st shot at the response:
>
> Entering kdb (current=0xe0000000009a0000, pid 0) on processor 0 due to Keyboard Entry
> [0]kdb> rd
> psr: 0x0000101008026018 ifs: 0x8000000000000915 ip: 0xe002000000410c50
> unat: 0x0000000000000000 pfs: 0x0000000000000915 rsc: 0x0000000000000003
> rnat: 0x8000000000000012 bsps: 0x000000000001003e pr: 0x0000000000014a59
> ldrs: 0x0000000000000000 ccv: 0x0000000000000000 fpsr: 0x0009804c8a70433f
> b0: 0xe002000000410d50 b6: 0xe002000000678c60 b7: 0xe00200000040a1c0
> r1: 0xe002100000bb0000 r2: 0x0000000000000000 r3: 0xe000000001250000
> r8: 0x0000000000000000 r9: 0x60000000000451d0 r10: 0x0000000000000000
> r11: 0xc000000000000186 r12: 0xe0000000009a7e40 r13: 0xe0000000009a0000
> r14: 0x0000000000000000 r15: 0x0000000000000001 r16: 0xc0000b00100000c0
> r17: 0xe0000000009a0028 r18: 0xa000000000008320 r19: 0x0009804c8a70433f
> r20: 0x00000000009a0000 r21: 0xe0020000004b34d0 r22: 0x80000000ffd5eed0
> r23: 0x80000000ffd5ef10 r24: 0x80000000ffd5eec0 r25: 0x80000000ffd5ef20
> r26: 0x80000000ffd5eee0 r27: 0xe0000000009a1298 r28: 0x0000000000014a99
> r29: 0x0000000000000001 r30: 0x0000000000000000 r31: 0x0000000000000000
> &regs = e0000000009a7cb0
>
> [0]kdb> rd %bsp
> bsp = 0x000000000001003e
> [0]kdb>
>
> I'll update skdb to cancatinate a few kdb commands together to collect ALL of the registers.

That's fine. But you should understand that some of the registers that
you collect will be ignored by gdb.

> I'm not sure the %bsp will always provide access to the corect values of registers.
> On SPARC the trap hander stores registers in a different place than the C compiler
> uses. I assume the gdb stub is assuming C compiler offets for the registers it's
> fetching from the %bsp. Is there a include file that defines this? It might make it
> easier to sort this possability out.

The location of where a particular register lives in the backing store with
respect to bsp is defined by the IA-64 architecture. It is not compiler
dependent. GDB is using BSP, CFM, and (sometimes) PFS to figure out the
locations of r32-r127.

[...]
> BTW, I don't suppose there is an existing variable that I could set to have gdb spin till I have
> time to attach to it prior to sending the 'g' cmd?

Do you perhaps want to do ``set remotetimeout 600'' or some such from gdb?

Kevin