2004-05-07 Randolph Chung <tausq@debian.org>

* hppa-linux-tdep.c (hppa_linux_sigtramp_find_sigcontext): Pass in pc
	instead of sp, handle sigaltstack case.
	(hppa_linux_sigtramp_frame_unwind_cache): Adjust calls to
	hppa_linux_sigtramp_find_sigcontext, and set base to the frame of the
	signal handler and not that of the caller.
	(hppa_linux_sigtramp_unwind_sniffer): Adjust calls to
	hppa_linux_sigtramp_find_sigcontext.
This commit is contained in:
Randolph Chung 2004-05-08 03:45:44 +00:00
parent 959464ff2c
commit 2f0e8c7aff
2 changed files with 35 additions and 9 deletions

View File

@ -1,3 +1,13 @@
2004-05-07 Randolph Chung <tausq@debian.org>
* hppa-linux-tdep.c (hppa_linux_sigtramp_find_sigcontext): Pass in pc
instead of sp, handle sigaltstack case.
(hppa_linux_sigtramp_frame_unwind_cache): Adjust calls to
hppa_linux_sigtramp_find_sigcontext, and set base to the frame of the
signal handler and not that of the caller.
(hppa_linux_sigtramp_unwind_sniffer): Adjust calls to
hppa_linux_sigtramp_find_sigcontext.
2004-05-07 Randolph Chung <tausq@debian.org>
* Makefile.in (ALLDEPFILES): Add hppa-linux-tdep.c and

View File

@ -282,7 +282,7 @@ hppa_linux_skip_trampoline_code (CORE_ADDR pc)
Note that with a 2.4 64-bit kernel, the signal context is not properly
passed back to userspace so the unwind will not work correctly. */
static CORE_ADDR
hppa_linux_sigtramp_find_sigcontext (CORE_ADDR sp)
hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
{
unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
int offs = 0;
@ -291,6 +291,12 @@ hppa_linux_sigtramp_find_sigcontext (CORE_ADDR sp)
static int pcoffs[] = { 0, 4*4, 5*4 };
/* offsets to the rt_sigframe structure */
static int sfoffs[] = { 4*4, 10*4, 10*4 };
CORE_ADDR sp;
/* Most of the time, this will be correct. The one case when this will
fail is if the user defined an alternate stack, in which case the
beginning of the stack will not be align_down (pc, 64). */
sp = align_down (pc, 64);
/* rt_sigreturn trampoline:
3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2)
@ -308,7 +314,20 @@ hppa_linux_sigtramp_find_sigcontext (CORE_ADDR sp)
}
if (offs == 0)
return 0;
{
if (insns_match_pattern (pc, hppa_sigtramp, dummy))
{
/* sigaltstack case: we have no way of knowing which offset to
use in this case; default to new kernel handling. If this is
wrong the unwinding will fail. */
try = 2;
sp = pc - pcoffs[try];
}
else
{
return 0;
}
}
/* sp + sfoffs[try] points to a struct rt_sigframe, which contains
a struct siginfo and a struct ucontext. struct ucontext contains
@ -331,7 +350,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
{
struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct hppa_linux_sigtramp_unwind_cache *info;
CORE_ADDR sp, pc, scptr;
CORE_ADDR pc, scptr;
int i;
if (*this_cache)
@ -342,8 +361,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
pc = frame_pc_unwind (next_frame);
sp = (pc & ~63);
scptr = hppa_linux_sigtramp_find_sigcontext (sp);
scptr = hppa_linux_sigtramp_find_sigcontext (pc);
/* structure of struct sigcontext:
@ -393,8 +411,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
scptr += 4;
info->base = read_memory_unsigned_integer (
info->saved_regs[HPPA_SP_REGNUM].addr, 4);
info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
return info;
}
@ -439,9 +456,8 @@ static const struct frame_unwind *
hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
{
CORE_ADDR pc = frame_pc_unwind (next_frame);
CORE_ADDR sp = (pc & ~63);
if (hppa_linux_sigtramp_find_sigcontext (sp))
if (hppa_linux_sigtramp_find_sigcontext (pc))
return &hppa_linux_sigtramp_frame_unwind;
return NULL;