From 54b2555b0cb8f52a811758758ec119c9941b070d Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sun, 6 Nov 1994 20:02:31 +0000 Subject: [PATCH] * hppa-tdep.c (frame_saved_pc): Mask off low two bits when retrieving the PC from a signal handler caller. Fix thinko in Stan's last change ("frame", should have been "frame->next"). If the next frame is a signal handler caller and it's a system call which has entered the kernel ((PSW & 0x2) != 0), then the saved pc is in %r2 instead of %r31. --- gdb/ChangeLog | 9 +++++++++ gdb/hppa-tdep.c | 26 ++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index edcdf69486..090092b98d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +Sun Nov 6 12:54:54 1994 Jeff Law (law@snake.cs.utah.edu) + + * hppa-tdep.c (frame_saved_pc): Mask off low two bits when + retrieving the PC from a signal handler caller. Fix thinko + in Stan's last change ("frame", should have been "frame->next"). + If the next frame is a signal handler caller and it's a system + call which has entered the kernel ((PSW & 0x2) != 0), then the + saved pc is in %r2 instead of %r31. + Fri Nov 4 23:47:07 1994 Jeff Law (law@snake.cs.utah.edu) * hppa-tdep.c (hppa_frame_find_saved_regs): Change "frame" to diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 384a67a398..97bb9c8db0 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -766,7 +766,7 @@ frame_saved_pc (frame) { CORE_ADDR rp; FRAME_SAVED_PC_IN_SIGTRAMP (frame, &rp); - return rp; + return rp & ~0x3; } if (frameless_function_invocation (frame)) @@ -785,9 +785,18 @@ frame_saved_pc (frame) { struct frame_saved_regs saved_regs; - get_frame_saved_regs (frame, &saved_regs); + get_frame_saved_regs (frame->next, &saved_regs); if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2) - pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3; + { + pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3; + + /* Syscalls are really two frames. The syscall stub itself + with a return pointer in %rp and the kernel call with + a return pointer in %r31. We return the %rp variant + if %r31 is the same as frame->pc. */ + if (pc == frame->pc) + pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; + } else pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; } @@ -812,7 +821,16 @@ restart: get_frame_saved_regs (frame->next, &saved_regs); if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2) - pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3; + { + pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3; + + /* Syscalls are really two frames. The syscall stub itself + with a return pointer in %rp and the kernel call with + a return pointer in %r31. We return the %rp variant + if %r31 is the same as frame->pc. */ + if (pc == frame->pc) + pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; + } else pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; }