* sparc-tdep.h (struct gdbarch_tdep): Add step_trap member.
(sparc_address_from_register): New prototype. (sparcnbsd_step_trap): New prototype. * sparc-tdep.c (sparc_address_from_register): Make globally visible. (sparc_analyze_control_transfer): Change prototype to accept `struct gdbarch *' as first argument. Allow for optional hnadling for trap instructions. (sparc_step_trap): New function. (sparc_software_single_step): Adjust call to sparc_analyze_control_trabsfer. (sparc32_gdbarch_init): Initialize TDEP->step_trap. * sparcnbsd-tdep.c (sparcnbsd_step_trap): New function. (sparc32nbsd_init_abi): Set TDEP->step_trap. * sparc64obsd-tdep.c (sparc64obsd_init_abi): Set TDEP->step_trap. * sparc64nbsd-tdep.c (sparc64nbsd_init_abi): Set TDEP->step_trap.
This commit is contained in:
parent
0a8f48b9a8
commit
c893be758b
6 changed files with 87 additions and 10 deletions
|
@ -1,6 +1,6 @@
|
|||
/* Target-dependent code for NetBSD/sparc.
|
||||
|
||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||
Contributed by Wasabi Systems, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
@ -38,6 +38,11 @@
|
|||
#include "sparc-tdep.h"
|
||||
#include "nbsd-tdep.h"
|
||||
|
||||
/* Macros to extract fields from SPARC instructions. */
|
||||
#define X_RS1(i) (((i) >> 14) & 0x1f)
|
||||
#define X_RS2(i) ((i) & 0x1f)
|
||||
#define X_I(i) (((i) >> 13) & 1)
|
||||
|
||||
const struct sparc_gregset sparc32nbsd_gregset =
|
||||
{
|
||||
0 * 4, /* %psr */
|
||||
|
@ -256,6 +261,30 @@ sparc32nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the address of a system call's alternative return
|
||||
address. */
|
||||
|
||||
CORE_ADDR
|
||||
sparcnbsd_step_trap (unsigned long insn)
|
||||
{
|
||||
if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
|
||||
|| (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
|
||||
{
|
||||
/* "New" system call. */
|
||||
ULONGEST number;
|
||||
|
||||
regcache_cooked_read_unsigned (current_regcache,
|
||||
SPARC_G1_REGNUM, &number);
|
||||
|
||||
if (number & 0x400)
|
||||
return sparc_address_from_register (SPARC_G2_REGNUM);
|
||||
if (number & 0x800)
|
||||
return sparc_address_from_register (SPARC_G7_REGNUM);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
|
@ -272,6 +301,9 @@ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
tdep->fpregset = regset_alloc (gdbarch, sparc32nbsd_supply_fpregset, NULL);
|
||||
tdep->sizeof_fpregset = 33 * 4;
|
||||
|
||||
/* Make sure we can single-step "new" syscalls. */
|
||||
tdep->step_trap = sparcnbsd_step_trap;
|
||||
|
||||
frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue