diff options
author | Jeff Law <law@redhat.com> | 1994-11-06 20:02:31 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1994-11-06 20:02:31 +0000 |
commit | 54b2555b0cb8f52a811758758ec119c9941b070d (patch) | |
tree | fd87ba6444b89b56786cd26fe467554560e9826c /gdb/hppa-tdep.c | |
parent | 8deb5c5fd6618a8602634e449a5217dd307524bc (diff) | |
download | gdb-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.c | 26 |
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; } |