Re: ia64-stub.c

Piet/Pete Delaney
2002-01-23T12:44:37Z

On Wed, Jan 23, 2002 at 04:14:48AM -0700, Kevin Buettner wrote:
> On Jan 22, 11:47pm, Piet/Pete Delaney wrote:
>
> > > 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.)
> >
> > In the kernel the registers may not always flushed out the the backing store.
> > In a SPARC kernel a 2nd level trap is required for the kernel code to flush
> > the registers to the backing store. A similar case may apply to ia64. Like
> > in the even of a stack overflow (backing store isn't mapped).
>
> On IA-64, I think you will find that it's going to be *very* difficult
> for your debugging interface to learn the values of r32-r127 without
> using the backing store.
>
> > I would think it preferable for gdb to accept values in the 'g' packet
> > and if it doesn't receive a copy of the r32-r127 registers to then try
> > to fetch them using an offset from the BSP.
>
> I'm willing to work with you to make this possible if you convince me that
> it's worthwhile. (I.e, if you can show me how your stub is going to
> obtain these values without using the backing store.)

kdb seems to return %r1 ... %r52, the code appears to be using the stack,
so it seems your right; at least for now. The function show_cur_stack_frame()
is getting involved in unwind stuff and I still have to read HP's ABI and
runtime arch stuff and perhaps I'll understand enough of it to make out
what show_cur_stack_frame() is doing.

My background for the past few years is with SPARC, in this case I wrote
code that did produce the registers even when they didn't make it to the
backing store. I suspect the case is similar for ia64 but I'd only give
4:1 odds on it. On SPARC when we get a kernel stack overflow the registers
can't be pushed out to the stack because you hit a red zone. I added code
to map the redzone and flush the registers (if enabled). Even if not enabled
I had asm code to read the registers directly and store them in a register
save area for each register window. I got the impression that the ia64 hardware
is also defering the movement of the registers to memory like SPARC does as
so it would also have the same problem for regiter flushing bugs.

Anyway, it's not that important. Just seemed cleaner.

> > Isn't it possible to transfer predicate registers in the 'g' reply packet?
>
> You can if you wish, but at the moment they'll be ignored.
Fine.

>
> > There isn't a 'pr' register defined in the ia64_register_names[] array,
> > so the convention isn't clear.
>
> Please look again. It's there. (It comes just before "ip".)

Great, so my code should have worked. I wonder why the ip register had
the wrong value in it. I'll redo the experiment tomarrow. I recall the
ip register being way off.

>
> > If the REGISTER_RAW_SIZE macro indicates
> > they are 1 byte or perhaps 1 bit each, then the transfer is possible.
>
> They're eight bytes apiece. Why isn't the transfer possible with this
> size?

It's fine, that what I was assuming base on the REGISTER_RAW_SIZE macro.

>
> > The REGISTER_RAW_SIZE implies that the 'g' packet reply should provide
> > the predict registers at 8 byte offsets like all of the other registers
> > other than the floats.
>
> That's right.
good, the codes consistant.

> You might also want to take a look at REGISTER_BYTE which'll give the
> offsets more directly.
ok.

>
> BTW, I think it might be worthwhile spending time working with the
> maintainer of remote.c to make it possible to have a more abbreviated
> "g" packet for IA-64 in which certain registers computed by either
> means (r32-r127 from memory, p0-p63 from the bits of pr, etc) are
> omitted.
When I sent truncated packets the 'g' command seemed to be happy,
so it may not be that important. I do recall the gcc code as noting
that the packet is truncated and taking error recovery; so I don't
know why it appeared to be ok to sned just the first 31 registers.

Looking at the registers that arrive inside gdb would help.

I seem to have messed something up and I'm getting problems with
the thread code. I thought it compiled right out of the box last time.
-------------------------------------------------------------------------------------------------------------------------------------------
263 monica 04:34 ~/src/gdb/gdb-5.1/gdb> make
gcc -c -g -O2 -I. -I. -I./config -DHAVE_CONFIG_H -I./../include/opcode -I./../readline/.. -I../bfd -I./../bfd -I./../include -I../intl -I./../intl -DMI_OUT=1 -DUI_OUT=1 -Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith -Wuninitialized thread-db.c
In file included from /usr/include/thread_db.h:25,
from gdb_thread_db.h:2,
from thread-db.c:26:
/usr/include/pthread.h:163: parse error before `*'
/usr/include/pthread.h:165: `pthread_create' declared as function returning a function
/usr/include/pthread.h:166: parse error before `void'
/usr/include/pthread.h:169: parse error before `pthread_self'
/usr/include/pthread.h:169: warning: data definition has no type or storage class
/usr/include/pthread.h:172: parse error before `__thread1'
/usr/include/pthread.h:181: parse error before `__th'
/usr/include/pthread.h:187: parse error before `__th'
/usr/include/pthread.h:195: parse error before `*'
/usr/include/pthread.h:198: parse error before `*'
/usr/include/pthread.h:201: parse error before `*'
/usr/include/pthread.h:205: parse error before `*'
/usr/include/pthread.h:209: parse error before `*'
/usr/include/pthread.h:214: parse error before `*'
/usr/include/pthread.h:220: parse error before `*'
/usr/include/pthread.h:224: parse error before `*'
/usr/include/pthread.h:229: parse error before `*'
/usr/include/pthread.h:233: parse error before `*'
/usr/include/pthread.h:238: parse error before `*'
/usr/include/pthread.h:242: parse error before `*'
/usr/include/pthread.h:260: parse error before `*'
/usr/include/pthread.h:264: parse error before `*'
/usr/include/pthread.h:284: parse error before `*'
/usr/include/pthread.h:288: parse error before `*'
/usr/include/pthread.h:301: parse error before `__target_thread'
/usr/include/pthread.h:306: parse error before `__target_thread'
/usr/include/pthread.h:331: parse error before `*'
/usr/include/pthread.h:336: parse error before `*'
/usr/include/pthread.h:339: parse error before `*'
/usr/include/pthread.h:342: parse error before `*'
/usr/include/pthread.h:352: parse error before `*'
/usr/include/pthread.h:359: parse error before `*'
/usr/include/pthread.h:362: parse error before `*'
/usr/include/pthread.h:365: parse error before `*'
/usr/include/pthread.h:370: parse error before `*'
/usr/include/pthread.h:390: parse error before `*'
/usr/include/pthread.h:395: parse error before `*'
/usr/include/pthread.h:398: parse error before `*'
/usr/include/pthread.h:401: parse error before `*'
/usr/include/pthread.h:405: parse error before `*'
/usr/include/pthread.h:412: parse error before `*'
/usr/include/pthread.h:420: parse error before `*'
/usr/include/pthread.h:423: parse error before `*'
/usr/include/pthread.h:426: parse error before `*'
/usr/include/pthread.h:431: parse error before `*'
/usr/include/pthread.h:556: parse error before `*'
/usr/include/pthread.h:557: parse error before `)'
/usr/include/pthread.h:560: parse error before `__key'
/usr/include/pthread.h:563: parse error before `__key'
/usr/include/pthread.h:567: parse error before `__key'
/usr/include/pthread.h:576: parse error before `*'
/usr/include/pthread.h:577: parse error before `)'
/usr/include/pthread.h:591: parse error before `__thread'
In file included from gdb_thread_db.h:2,
from thread-db.c:26:
/usr/include/thread_db.h:234: parse error before `thread_t'
/usr/include/thread_db.h:234: warning: data definition has no type or storage class
/usr/include/thread_db.h:235: parse error before `thread_key_t'
/usr/include/thread_db.h:235: warning: data definition has no type or storage class
/usr/include/thread_db.h:242: parse error before `void'
/usr/include/thread_db.h:242: `td_key_iter_f' declared as function returning a function
/usr/include/thread_db.h:242: parse error before `void'
/usr/include/thread_db.h:255: parse error before `thread_t'
/usr/include/thread_db.h:255: warning: no semicolon at end of struct or union
/usr/include/thread_db.h:280: parse error before `}'
/usr/include/thread_db.h:280: warning: data definition has no type or storage class
/usr/include/thread_db.h:311: parse error before `pthread_t'
/usr/include/thread_db.h:370: parse error before `td_thrinfo_t'
/usr/include/thread_db.h:430: parse error before `__tk'
thread-db.c:81: parse error before `thread_t'
thread-db.c:99: parse error before `td_thrinfo_t'
thread-db.c: In function `thread_from_lwp':
thread-db.c:232: parse error before `ti'
thread-db.c:246: `ti' undeclared (first use in this function)
thread-db.c:246: (Each undeclared identifier is reported only once
thread-db.c:246: for each function it appears in.)
thread-db.c: In function `lwp_from_thread':
thread-db.c:256: parse error before `ti'
thread-db.c:268: `ti' undeclared (first use in this function)
thread-db.c: At top level:
thread-db.c:561: warning: type defaults to `int' in declaration of `td_thrinfo_t'
thread-db.c:561: parse error before `*'
thread-db.c: In function `attach_thread':
thread-db.c:568: `verbose' undeclared (first use in this function)
thread-db.c:569: `ptid' undeclared (first use in this function)
thread-db.c:574: `ti_p' undeclared (first use in this function)
thread-db.c:586: `th_p' undeclared (first use in this function)
thread-db.c: In function `check_event':
thread-db.c:655: parse error before `ti'
thread-db.c:673: `ti' undeclared (first use in this function)
thread-db.c: In function `thread_db_store_registers':
-------------------------------------------------------------------------------------------------------------------------------```
"/usr/include/pthread.h"
-------------------------------------------------------------------------------------------------------------------------------```
160 /* Create a thread with given attributes ATTR (or default attributes
161 if ATTR is NULL), and call function START_ROUTINE with given
162 arguments ARG. */
163 extern int pthread_create (pthread_t *__restrict __thread,
164 __const pthread_attr_t *__restrict __attr,
165 void *(*__start_routine) (void *),
166 void *__restrict __arg) __THROW;
167
-----------------------------------------------------------------------------------------------------------------------------------

Might have something to do with changing C compilers or trying out the latest libutils.

-piet

>
> Kevin