This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: make inferior calls work on ia64 even when syscall is pending
On Fri, 13 Feb 2004 14:06:54 -0800
David Mosberger <davidm@napali.hpl.hp.com> wrote:
> 2004-02-12 David Mosberger <davidm@hpl.hp.com>
>
> * ia64-tdep.c (ia64_linux_write_pc): Declare as extern.
> (ia64_write_pc): Make it a global function.
> (ia64_gdbarch_init): For Linux targets, use ia64_linux_write_pc()
> instead of ia64_write_pc().
>
> * ia64-linux-tdep.c (ia64_write_pc): Declare as extern.
> (ia64_linux_write_pc): New function. Works like ia64_write_pc(),
> except that it also clears r10 afterwards to prevent the kernel
> from attempting to restart an interrupt system call.
I've committed the above via the following patch. Please let me know
if I've missed anything.
* ia64-tdep.h (ia64_write_pc, ia64_linux_write_pc): Declare.
* ia64-tdep.c (ia64_write_pc): Make it a global function.
(ia64_gdbarch_init): For Linux targets, use ia64_linux_write_pc()
instead of ia64_write_pc().
* ia64-linux-tdep.c (regcache.h): Include.
(ia64_linux_write_pc): New function.
Index: ia64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-linux-tdep.c,v
retrieving revision 1.6
diff -u -p -r1.6 ia64-linux-tdep.c
--- ia64-linux-tdep.c 17 Feb 2004 16:23:23 -0000 1.6
+++ ia64-linux-tdep.c 23 Feb 2004 21:06:43 -0000
@@ -23,6 +23,7 @@
#include "ia64-tdep.h"
#include "arch-utils.h"
#include "gdbcore.h"
+#include "regcache.h"
/* The sigtramp code is in a non-readable (executable-only) region
of memory called the ``gate page''. The addresses in question
@@ -93,4 +94,21 @@ ia64_linux_sigcontext_register_address (
default :
return 0;
}
+}
+
+void
+ia64_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+ ia64_write_pc (pc, ptid);
+
+ /* We must be careful with modifying the instruction-pointer: if we
+ just interrupt a system call, the kernel would ordinarily try to
+ restart it when we resume the inferior, which typically results
+ in SIGSEGV or SIGILL. We prevent this by clearing r10, which
+ will tell the kernel that r8 does NOT contain a valid error code
+ and hence it will skip system-call restart.
+
+ The clearing of r10 is safe as long as ia64_write_pc() is only
+ called as part of setting up an inferior call. */
+ write_register_pid (IA64_GR10_REGNUM, 0, ptid);
}
Index: ia64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
retrieving revision 1.116
diff -u -p -r1.116 ia64-tdep.c
--- ia64-tdep.c 17 Feb 2004 16:23:23 -0000 1.116
+++ ia64-tdep.c 23 Feb 2004 21:06:44 -0000
@@ -628,7 +628,7 @@ ia64_read_pc (ptid_t ptid)
return pc_value | (slot_num * SLOT_MULTIPLIER);
}
-static void
+void
ia64_write_pc (CORE_ADDR new_pc, ptid_t ptid)
{
int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
@@ -3338,7 +3338,10 @@ ia64_gdbarch_init (struct gdbarch_info i
set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);
set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
set_gdbarch_read_pc (gdbarch, ia64_read_pc);
- set_gdbarch_write_pc (gdbarch, ia64_write_pc);
+ if (info.osabi == GDB_OSABI_LINUX)
+ set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
+ else
+ set_gdbarch_write_pc (gdbarch, ia64_write_pc);
/* Settings for calling functions in the inferior. */
set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
Index: ia64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.h,v
retrieving revision 1.1
diff -u -p -r1.1 ia64-tdep.h
--- ia64-tdep.h 17 Feb 2004 16:23:23 -0000 1.1
+++ ia64-tdep.h 23 Feb 2004 21:06:44 -0000
@@ -25,5 +25,7 @@
extern CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR, int);
extern CORE_ADDR ia64_aix_sigcontext_register_address (CORE_ADDR, int);
extern unsigned long ia64_linux_getunwind_table (void *, size_t);
+extern void ia64_write_pc (CORE_ADDR, ptid_t);
+extern void ia64_linux_write_pc (CORE_ADDR, ptid_t);
#endif /* IA64_TDEP_H */