aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2008-07-27 20:52:42 +0000
committerDaniel Jacobowitz <drow@false.org>2008-07-27 20:52:42 +0000
commite38d4e1aae6fb86cfae320ae6ae9b2b48cd1ddb7 (patch)
treeac0abdedb377ac367e1d8496a86382aaf9bbeeba
parent0d600a79d88b480541093f06639eff6ea1c33ed6 (diff)
downloadfsf-binutils-gdb-e38d4e1aae6fb86cfae320ae6ae9b2b48cd1ddb7.zip
fsf-binutils-gdb-e38d4e1aae6fb86cfae320ae6ae9b2b48cd1ddb7.tar.gz
fsf-binutils-gdb-e38d4e1aae6fb86cfae320ae6ae9b2b48cd1ddb7.tar.bz2
* mips-linux-tdep.c (mips_linux_syscall_next_pc): New function.
(mips_linux_init_abi): Set tdep->syscall_next_pc. * mips-tdep.c (enum mips_fpu_type, struct gdbarch_tdep): Move to mips-tdep.h. (mips32_next_pc): Handle the syscall instruction. * mips-tdep.h (enum mips_fpu_type, struct gdbarch_tdep): New, from mips-tdep.c. Add syscall_next_pc to gdbarch_tdep.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/mips-linux-tdep.c22
-rw-r--r--gdb/mips-tdep.c52
-rw-r--r--gdb/mips-tdep.h45
4 files changed, 88 insertions, 41 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 99b8f54..e58b216 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2008-07-27 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * mips-linux-tdep.c (mips_linux_syscall_next_pc): New function.
+ (mips_linux_init_abi): Set tdep->syscall_next_pc.
+ * mips-tdep.c (enum mips_fpu_type, struct gdbarch_tdep): Move to
+ mips-tdep.h.
+ (mips32_next_pc): Handle the syscall instruction.
+ * mips-tdep.h (enum mips_fpu_type, struct gdbarch_tdep): New,
+ from mips-tdep.c. Add syscall_next_pc to gdbarch_tdep.
+
2008-07-26 Tom Tromey <tromey@redhat.com>
PR gdb/1158:
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index d631a7b..8f30aef 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -1101,6 +1101,26 @@ mips_linux_restart_reg_p (struct gdbarch *gdbarch)
return register_size (gdbarch, MIPS_RESTART_REGNUM) > 0;
}
+/* When FRAME is at a syscall instruction, return the PC of the next
+ instruction to be executed. */
+
+CORE_ADDR
+mips_linux_syscall_next_pc (struct frame_info *frame)
+{
+ CORE_ADDR pc = get_frame_pc (frame);
+ ULONGEST v0 = get_frame_register_unsigned (frame, MIPS_V0_REGNUM);
+
+ /* If we are about to make a sigreturn syscall, use the unwinder to
+ decode the signal frame. */
+ if (v0 == MIPS_NR_sigreturn
+ || v0 == MIPS_NR_rt_sigreturn
+ || v0 == MIPS_NR_N64_rt_sigreturn
+ || v0 == MIPS_NR_N32_rt_sigreturn)
+ return frame_pc_unwind (get_current_frame ());
+
+ return pc + 4;
+}
+
/* Initialize one of the GNU/Linux OS ABIs. */
static void
@@ -1175,6 +1195,8 @@ mips_linux_init_abi (struct gdbarch_info info,
set_gdbarch_core_read_description (gdbarch,
mips_linux_core_read_description);
+ tdep->syscall_next_pc = mips_linux_syscall_next_pc;
+
if (tdesc_data)
{
const struct tdesc_feature *feature;
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 98d033b..4469754 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -142,16 +142,6 @@ const struct register_alias mips_register_aliases[] = {
{ "fsr", MIPS_EMBED_FP0_REGNUM + 32 }
};
-/* Some MIPS boards don't support floating point while others only
- support single-precision floating-point operations. */
-
-enum mips_fpu_type
-{
- MIPS_FPU_DOUBLE, /* Full double precision floating point. */
- MIPS_FPU_SINGLE, /* Single precision floating point (R4650). */
- MIPS_FPU_NONE /* No floating point. */
-};
-
#ifndef MIPS_DEFAULT_FPU_TYPE
#define MIPS_DEFAULT_FPU_TYPE MIPS_FPU_DOUBLE
#endif
@@ -168,37 +158,6 @@ static int mips_debug = 0;
struct target_desc *mips_tdesc_gp32;
struct target_desc *mips_tdesc_gp64;
-/* MIPS specific per-architecture information */
-struct gdbarch_tdep
-{
- /* from the elf header */
- int elf_flags;
-
- /* mips options */
- enum mips_abi mips_abi;
- enum mips_abi found_abi;
- enum mips_fpu_type mips_fpu_type;
- int mips_last_arg_regnum;
- int mips_last_fp_arg_regnum;
- int default_mask_address_p;
- /* Is the target using 64-bit raw integer registers but only
- storing a left-aligned 32-bit value in each? */
- int mips64_transfers_32bit_regs_p;
- /* Indexes for various registers. IRIX and embedded have
- different values. This contains the "public" fields. Don't
- add any that do not need to be public. */
- const struct mips_regnum *regnum;
- /* Register names table for the current register set. */
- const char **mips_processor_reg_names;
-
- /* The size of register data available from the target, if known.
- This doesn't quite obsolete the manual
- mips64_transfers_32bit_regs_p, since that is documented to force
- left alignment even for big endian (very strange). */
- int register_size_valid_p;
- int register_size;
-};
-
const struct mips_regnum *
mips_regnum (struct gdbarch *gdbarch)
{
@@ -1018,6 +977,17 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
/* Set PC to that address */
pc = get_frame_register_signed (frame, rtype_rs (inst));
break;
+ case 12: /* SYSCALL */
+ {
+ struct gdbarch_tdep *tdep;
+
+ tdep = gdbarch_tdep (get_frame_arch (frame));
+ if (tdep->syscall_next_pc != NULL)
+ pc = tdep->syscall_next_pc (frame);
+ else
+ pc += 4;
+ }
+ break;
default:
pc += 4;
}
diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h
index 3917951..85c40d9 100644
--- a/gdb/mips-tdep.h
+++ b/gdb/mips-tdep.h
@@ -56,6 +56,51 @@ struct mips_regnum
};
extern const struct mips_regnum *mips_regnum (struct gdbarch *gdbarch);
+/* Some MIPS boards don't support floating point while others only
+ support single-precision floating-point operations. */
+
+enum mips_fpu_type
+{
+ MIPS_FPU_DOUBLE, /* Full double precision floating point. */
+ MIPS_FPU_SINGLE, /* Single precision floating point (R4650). */
+ MIPS_FPU_NONE /* No floating point. */
+};
+
+/* MIPS specific per-architecture information */
+struct gdbarch_tdep
+{
+ /* from the elf header */
+ int elf_flags;
+
+ /* mips options */
+ enum mips_abi mips_abi;
+ enum mips_abi found_abi;
+ enum mips_fpu_type mips_fpu_type;
+ int mips_last_arg_regnum;
+ int mips_last_fp_arg_regnum;
+ int default_mask_address_p;
+ /* Is the target using 64-bit raw integer registers but only
+ storing a left-aligned 32-bit value in each? */
+ int mips64_transfers_32bit_regs_p;
+ /* Indexes for various registers. IRIX and embedded have
+ different values. This contains the "public" fields. Don't
+ add any that do not need to be public. */
+ const struct mips_regnum *regnum;
+ /* Register names table for the current register set. */
+ const char **mips_processor_reg_names;
+
+ /* The size of register data available from the target, if known.
+ This doesn't quite obsolete the manual
+ mips64_transfers_32bit_regs_p, since that is documented to force
+ left alignment even for big endian (very strange). */
+ int register_size_valid_p;
+ int register_size;
+
+ /* Return the expected next PC if FRAME is stopped at a syscall
+ instruction. */
+ CORE_ADDR (*syscall_next_pc) (struct frame_info *frame);
+};
+
/* Register numbers of various important registers. */
enum