aboutsummaryrefslogtreecommitdiff
path: root/gdb/hppa-tdep.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1994-11-06 20:02:31 +0000
committerJeff Law <law@redhat.com>1994-11-06 20:02:31 +0000
commit54b2555b0cb8f52a811758758ec119c9941b070d (patch)
treefd87ba6444b89b56786cd26fe467554560e9826c /gdb/hppa-tdep.c
parent8deb5c5fd6618a8602634e449a5217dd307524bc (diff)
downloadgdb-54b2555b0cb8f52a811758758ec119c9941b070d.zip
gdb-54b2555b0cb8f52a811758758ec119c9941b070d.tar.gz
gdb-54b2555b0cb8f52a811758758ec119c9941b070d.tar.bz2
* 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.
Diffstat (limited to 'gdb/hppa-tdep.c')
-rw-r--r--gdb/hppa-tdep.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 384a67a..97bb9c8 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;
}