From Jeffrey Law:
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 30 Jul 1993 20:49:52 +0000 (20:49 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 30 Jul 1993 20:49:52 +0000 (20:49 +0000)
* tm-hppa.h (TARGET_WRITE_PC): Define.
* hppa-tdep.c (hppa_fix_call_dummy): If in a syscall,
then return the address of the dummy itself rather than
the address of $$dyncall.
(target_write_pc): New function to store a new PC.

gdb/ChangeLog
gdb/hppa-tdep.c

index b0bbeae..0a771b4 100644 (file)
@@ -1,3 +1,12 @@
+Fri Jul 30 15:43:49 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+       From Jeffrey Law:
+       * tm-hppa.h (TARGET_WRITE_PC): Define.
+       * hppa-tdep.c (hppa_fix_call_dummy): If in a syscall,
+       then return the address of the dummy itself rather than
+       the address of $$dyncall.
+       (target_write_pc): New function to store a new PC.
+
 Fri Jul 30 12:51:27 1993  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
                          and Jim Kingdon (kingdon@cygnus.com)
 
index 24701b1..c3842cf 100644 (file)
@@ -817,6 +817,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
 {
   CORE_ADDR dyncall_addr, sr4export_addr;
   struct minimal_symbol *msymbol;
+  int flags = read_register (FLAGS_REGNUM);
 
   msymbol = lookup_minimal_symbol ("$$dyncall", (struct objfile *) NULL);
   if (msymbol == NULL)
@@ -837,7 +838,16 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
 
   write_register (22, pc);
 
-  return dyncall_addr;
+  /* If we are in a syscall, then we should call the stack dummy
+     directly.  $$dyncall is not needed as the kernel sets up the
+     space id registers properly based on the value in %r31.  In
+     fact calling $$dyncall will not work because the value in %r22
+     will be clobbered on the syscall exit path.  */
+  if (flags & 2)
+    return pc;
+  else
+    return dyncall_addr;
+
 }
 
 /* Get the PC from %r31 if currently in a syscall.  Also mask out privilege
@@ -852,6 +862,23 @@ target_read_pc ()
   return read_register (PC_REGNUM) & ~0x3;
 }
 
+/* Write out the PC.  If currently in a syscall, then also write the new
+   PC value into %r31.  */
+void
+target_write_pc (v)
+     CORE_ADDR v;
+{
+  int flags = read_register (FLAGS_REGNUM);
+
+  /* If in a syscall, then set %r31.  Also make sure to get the 
+     privilege bits set correctly.  */
+  if (flags & 2)
+    write_register (31, (long) (v | 0x3));
+
+  write_register (PC_REGNUM, (long) v);
+  write_register (NPC_REGNUM, (long) v + 4);
+}
+
 /* return the alignment of a type in bytes. Structures have the maximum
    alignment required by their fields. */