diff options
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/ia64-linux-tdep.c | 18 | ||||
-rw-r--r-- | gdb/ia64-tdep.c | 7 | ||||
-rw-r--r-- | gdb/ia64-tdep.h | 2 |
4 files changed, 37 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3f8b904..01e8152b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2004-02-23 David Mosberger <davidm@hpl.hp.com> + + Committed by Kevin Buettner <kevinb@redhat.com>. + + * 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. + 2004-02-23 Roland McGrath <roland@redhat.com> * auxv.c (info_auxv_command): Fix typos in error messages. @@ -59,6 +70,7 @@ * breakpoint.c (print_one_breakpoint): Do not output spaces after printing <PENDING> for a pending breakpoint. +>>>>>>> 1.5456 2004-02-23 Jeff Johnston <jjohnstn@redhat.com> * printcmd.c (print_scalar_formatted): Initialize val_long diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c index 12f0c18..c3fa443 100644 --- a/gdb/ia64-linux-tdep.c +++ b/gdb/ia64-linux-tdep.c @@ -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 @@ -94,3 +95,20 @@ ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno) 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); +} diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index caeaf2d..278538c 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -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 info, struct gdbarch_list *arches) 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); diff --git a/gdb/ia64-tdep.h b/gdb/ia64-tdep.h index 32364d2..e153eed 100644 --- a/gdb/ia64-tdep.h +++ b/gdb/ia64-tdep.h @@ -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 */ |