This is the mail archive of the
mailing list for the GDB project.
Re: [RFC] hppa/multiarch - PUSH_DUMMY_FRAME depends on inf_status
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: Joel Brobecker <brobecker at gnat dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Sat, 11 Jan 2003 15:35:22 -0500
- Subject: Re: [RFC] hppa/multiarch - PUSH_DUMMY_FRAME depends on inf_status
- References: <20030111102928.GM30359@gnat.com>
tm-hppa.h contains the following macro definition for PUSH_DUMMY_FRAME:
/* FIXME: brobecker 2002-12-26. This macro definition takes advantage
of the fact that PUSH_DUMMY_FRAME is called within a function where
a variable inf_status of type struct inferior_status * is defined.
Ugh! Until this is fixed, we will not be able to move to multiarch
#define PUSH_DUMMY_FRAME hppa_push_dummy_frame (inf_status)
extern void hppa_push_dummy_frame (struct inferior_status *);
As said in the comment, there is this nasty dependency of the fact that
there is a variable called inf_status in the scope where this macro is
"invoked". This dependency is getting in the way of the multiarch conversion,
so I'd like to remove it.
I looked at the only place where PUSH_DUMMY_FRAME is used, and found
the following code (function hand_function_call in valops.c):
/* A cleanup for the inferior status. Create this AFTER the retbuf
so that this can be discarded or applied without interfering with
the regbuf. */
inf_status = save_inferior_status (1);
inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
This makes a copy of the inferior's registers.
Hmm, this means that there are potentially two copies of the system
registers - inf_status and dummy-frame's (but HP doesn't yet use dummy
In fact, this means that all targets, even the ones that don't use
generic dummy frames, are restoring their registers from a regcache and
_not_ from the the register values pushed onto the stack!
/* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
(and POP_FRAME for restoring them). (At least on most machines)
they are saved on the stack in the inferior. */
So inf_status is obtained by a call to save_inferior_status. OK.
HP's push_dummy_frame uses it exclusively to hack in some of the
registers. A comment explains why this is necessary:
/* Oh, what a hack. If we're trying to perform an inferior call
while the inferior is asleep, we have to make sure to clear
the "in system call" bit in the flag register (the call will
start after the syscall returns, so we're no longer in the system
call!) This state is kept in "inf_status", change it there.
We also need a number of horrid hacks to deal with lossage in the
PC queue registers (apparently they're not valid when the in syscall
bit is set). */
They do it like this:
write_inferior_status_register (inf_status, 0, int_buffer);
write_inferior_status_register (inf_status, PCOQ_HEAD_REGNUM, pc + 0);
write_inferior_status_register (inf_status, PCOQ_TAIL_REGNUM, pc + 4);
I think I'm missing something pretty fundamental here. This shouldn't
work. I can't figure out why it doesn't end up trying to do a write to
a read-only copy of current_regcache?
- inf_status->registers is created using regcache_dup (current_regcache)
gdb_assert (inf_status->registers != current_registers) true?
gdb_assert (inf_status->registers->readonly_p) true?
- inf_status->registers->regcache_raw_write() is calling (you've got
legacy code :-) legacy_write_register_gen(), but first it checks:
gdb_assert (regcache == current_regcache);
- legacy_write_register_gen() is then both writing the value into the
current_regcache and direct to the target.
i.e., those writes are hitting the target directly.
Any idea what I'm missing?