* hppa-tdep.c (frame_saved_pc): Mask off low two bits when
authorJeff Law <law@redhat.com>
Sun, 6 Nov 1994 20:02:31 +0000 (20:02 +0000)
committerJeff Law <law@redhat.com>
Sun, 6 Nov 1994 20:02:31 +0000 (20:02 +0000)
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
gdb/hppa-tdep.c

index edcdf69486f795b85483aac95201971f1a3a24b8..090092b98dfe968c807eda8f242f308b6c0c0959 100644 (file)
@@ -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
index 384a67a398970c287976d128729044c8de14d4b8..97bb9c8db02872fcaef1326a1687010c3c52bdaf 100644 (file)
@@ -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;
        }