* 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:
Mark Kettenis 2006-01-22 20:07:38 +00:00
parent 0a8f48b9a8
commit c893be758b
6 changed files with 87 additions and 10 deletions

View File

@ -1,5 +1,22 @@
2006-01-22 Mark Kettenis <kettenis@gnu.org>
* 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.
* sparc-tdep.c (sparc32_return_value): Convert to use
RETURN_VALUE_ABI_PRESERVES_ADDRESS instead of
RETURN_VALUE_STRUCT_CONVENTION.

View File

@ -170,7 +170,7 @@ sparc_fetch_wcookie (void)
/* Return the contents if register REGNUM as an address. */
static CORE_ADDR
CORE_ADDR
sparc_address_from_register (int regnum)
{
ULONGEST addr;
@ -1000,7 +1000,8 @@ sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
software single-step mechanism. */
static CORE_ADDR
sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
sparc_analyze_control_transfer (struct gdbarch *arch,
CORE_ADDR pc, CORE_ADDR *npc)
{
unsigned long insn = sparc_fetch_instruction (pc);
int conditional_p = X_COND (insn) & 0x7;
@ -1038,11 +1039,14 @@ sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
branch_p = 1;
offset = 4 * X_DISP19 (insn);
}
else if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3a)
{
/* Trap instruction (TRAP). */
return gdbarch_tdep (arch)->step_trap (insn);
}
/* FIXME: Handle DONE and RETRY instructions. */
/* FIXME: Handle the Trap instruction. */
if (branch_p)
{
if (conditional_p)
@ -1070,10 +1074,17 @@ sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
return 0;
}
static CORE_ADDR
sparc_step_trap (unsigned long insn)
{
return 0;
}
void
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
struct gdbarch *arch = current_gdbarch;
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
static CORE_ADDR npc, nnpc;
static gdb_byte npc_save[4], nnpc_save[4];
@ -1085,7 +1096,7 @@ sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
/* Analyze the instruction at PC. */
nnpc = sparc_analyze_control_transfer (pc, &npc);
nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
if (npc != 0)
target_insert_breakpoint (npc, npc_save);
if (nnpc != 0)
@ -1188,6 +1199,7 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->fpregset = NULL;
tdep->sizeof_fpregset = 0;
tdep->plt_entry_size = 0;
tdep->step_trap = sparc_step_trap;
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, &floatformat_sparc_quad);

View File

@ -1,6 +1,6 @@
/* Target-dependent code for SPARC.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GDB.
@ -65,6 +65,9 @@ struct gdbarch_tdep
/* Size of an Procedure Linkage Table (PLT) entry, 0 if we shouldn't
treat the PLT special when doing prologue analysis. */
size_t plt_entry_size;
/* Alternative location for trap return. Used for single-stepping. */
CORE_ADDR (*step_trap) (unsigned long insn);
};
/* Register numbers of various important registers. */
@ -147,6 +150,9 @@ struct sparc_frame_cache
/* Fetch the instruction at PC. */
extern unsigned long sparc_fetch_instruction (CORE_ADDR pc);
/* Return the contents if register REGNUM as an address. */
extern CORE_ADDR sparc_address_from_register (int regnum);
/* Fetch StackGhost Per-Process XOR cookie. */
extern ULONGEST sparc_fetch_wcookie (void);
@ -198,6 +204,10 @@ extern void sparc32_sol2_init_abi (struct gdbarch_info info,
/* Register offsets for NetBSD. */
extern const struct sparc_gregset sparc32nbsd_gregset;
/* Return the address of a system call's alternative return
address. */
extern CORE_ADDR sparcnbsd_step_trap (unsigned long insn);
extern void sparc32nbsd_elf_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch);

View File

@ -1,6 +1,6 @@
/* Target-dependent code for NetBSD/sparc64.
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Based on code contributed by Wasabi Systems, Inc.
This file is part of GDB.
@ -249,6 +249,9 @@ sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->fpregset = regset_alloc (gdbarch, sparc64nbsd_supply_fpregset, NULL);
tdep->sizeof_fpregset = 272;
/* Make sure we can single-step "new" syscalls. */
tdep->step_trap = sparcnbsd_step_trap;
frame_unwind_append_sniffer (gdbarch, sparc64nbsd_sigtramp_frame_sniffer);
sparc64_init_abi (info, gdbarch);

View File

@ -1,6 +1,6 @@
/* Target-dependent code for OpenBSD/sparc64.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GDB.
@ -295,6 +295,9 @@ sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->gregset = regset_alloc (gdbarch, sparc64obsd_supply_gregset, NULL);
tdep->sizeof_gregset = 832;
/* Make sure we can single-step "new" syscalls. */
tdep->step_trap = sparcnbsd_step_trap;
frame_unwind_append_sniffer (gdbarch, sparc64obsd_sigtramp_frame_sniffer);
sparc64_init_abi (info, gdbarch);

View File

@ -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);
}