* 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,5 +1,22 @@
|
||||||
2006-01-22 Mark Kettenis <kettenis@gnu.org>
|
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
|
* sparc-tdep.c (sparc32_return_value): Convert to use
|
||||||
RETURN_VALUE_ABI_PRESERVES_ADDRESS instead of
|
RETURN_VALUE_ABI_PRESERVES_ADDRESS instead of
|
||||||
RETURN_VALUE_STRUCT_CONVENTION.
|
RETURN_VALUE_STRUCT_CONVENTION.
|
||||||
|
|
|
@ -170,7 +170,7 @@ sparc_fetch_wcookie (void)
|
||||||
|
|
||||||
/* Return the contents if register REGNUM as an address. */
|
/* Return the contents if register REGNUM as an address. */
|
||||||
|
|
||||||
static CORE_ADDR
|
CORE_ADDR
|
||||||
sparc_address_from_register (int regnum)
|
sparc_address_from_register (int regnum)
|
||||||
{
|
{
|
||||||
ULONGEST addr;
|
ULONGEST addr;
|
||||||
|
@ -1000,7 +1000,8 @@ sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
|
||||||
software single-step mechanism. */
|
software single-step mechanism. */
|
||||||
|
|
||||||
static CORE_ADDR
|
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);
|
unsigned long insn = sparc_fetch_instruction (pc);
|
||||||
int conditional_p = X_COND (insn) & 0x7;
|
int conditional_p = X_COND (insn) & 0x7;
|
||||||
|
@ -1038,11 +1039,14 @@ sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
|
||||||
branch_p = 1;
|
branch_p = 1;
|
||||||
offset = 4 * X_DISP19 (insn);
|
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 DONE and RETRY instructions. */
|
||||||
|
|
||||||
/* FIXME: Handle the Trap instruction. */
|
|
||||||
|
|
||||||
if (branch_p)
|
if (branch_p)
|
||||||
{
|
{
|
||||||
if (conditional_p)
|
if (conditional_p)
|
||||||
|
@ -1070,10 +1074,17 @@ sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
sparc_step_trap (unsigned long insn)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
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 CORE_ADDR npc, nnpc;
|
||||||
static gdb_byte npc_save[4], nnpc_save[4];
|
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);
|
orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
|
||||||
|
|
||||||
/* Analyze the instruction at PC. */
|
/* Analyze the instruction at PC. */
|
||||||
nnpc = sparc_analyze_control_transfer (pc, &npc);
|
nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
|
||||||
if (npc != 0)
|
if (npc != 0)
|
||||||
target_insert_breakpoint (npc, npc_save);
|
target_insert_breakpoint (npc, npc_save);
|
||||||
if (nnpc != 0)
|
if (nnpc != 0)
|
||||||
|
@ -1188,6 +1199,7 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
tdep->fpregset = NULL;
|
tdep->fpregset = NULL;
|
||||||
tdep->sizeof_fpregset = 0;
|
tdep->sizeof_fpregset = 0;
|
||||||
tdep->plt_entry_size = 0;
|
tdep->plt_entry_size = 0;
|
||||||
|
tdep->step_trap = sparc_step_trap;
|
||||||
|
|
||||||
set_gdbarch_long_double_bit (gdbarch, 128);
|
set_gdbarch_long_double_bit (gdbarch, 128);
|
||||||
set_gdbarch_long_double_format (gdbarch, &floatformat_sparc_quad);
|
set_gdbarch_long_double_format (gdbarch, &floatformat_sparc_quad);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Target-dependent code for SPARC.
|
/* 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.
|
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
|
/* Size of an Procedure Linkage Table (PLT) entry, 0 if we shouldn't
|
||||||
treat the PLT special when doing prologue analysis. */
|
treat the PLT special when doing prologue analysis. */
|
||||||
size_t plt_entry_size;
|
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. */
|
/* Register numbers of various important registers. */
|
||||||
|
@ -147,6 +150,9 @@ struct sparc_frame_cache
|
||||||
/* Fetch the instruction at PC. */
|
/* Fetch the instruction at PC. */
|
||||||
extern unsigned long sparc_fetch_instruction (CORE_ADDR 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. */
|
/* Fetch StackGhost Per-Process XOR cookie. */
|
||||||
extern ULONGEST sparc_fetch_wcookie (void);
|
extern ULONGEST sparc_fetch_wcookie (void);
|
||||||
|
|
||||||
|
@ -198,6 +204,10 @@ extern void sparc32_sol2_init_abi (struct gdbarch_info info,
|
||||||
/* Register offsets for NetBSD. */
|
/* Register offsets for NetBSD. */
|
||||||
extern const struct sparc_gregset sparc32nbsd_gregset;
|
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,
|
extern void sparc32nbsd_elf_init_abi (struct gdbarch_info info,
|
||||||
struct gdbarch *gdbarch);
|
struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Target-dependent code for NetBSD/sparc64.
|
/* 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.
|
Based on code contributed by Wasabi Systems, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
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->fpregset = regset_alloc (gdbarch, sparc64nbsd_supply_fpregset, NULL);
|
||||||
tdep->sizeof_fpregset = 272;
|
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);
|
frame_unwind_append_sniffer (gdbarch, sparc64nbsd_sigtramp_frame_sniffer);
|
||||||
|
|
||||||
sparc64_init_abi (info, gdbarch);
|
sparc64_init_abi (info, gdbarch);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Target-dependent code for OpenBSD/sparc64.
|
/* 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.
|
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->gregset = regset_alloc (gdbarch, sparc64obsd_supply_gregset, NULL);
|
||||||
tdep->sizeof_gregset = 832;
|
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);
|
frame_unwind_append_sniffer (gdbarch, sparc64obsd_sigtramp_frame_sniffer);
|
||||||
|
|
||||||
sparc64_init_abi (info, gdbarch);
|
sparc64_init_abi (info, gdbarch);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Target-dependent code for NetBSD/sparc.
|
/* 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.
|
Contributed by Wasabi Systems, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
@ -38,6 +38,11 @@
|
||||||
#include "sparc-tdep.h"
|
#include "sparc-tdep.h"
|
||||||
#include "nbsd-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 =
|
const struct sparc_gregset sparc32nbsd_gregset =
|
||||||
{
|
{
|
||||||
0 * 4, /* %psr */
|
0 * 4, /* %psr */
|
||||||
|
@ -256,6 +261,30 @@ sparc32nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
|
||||||
return NULL;
|
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
|
static void
|
||||||
sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
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->fpregset = regset_alloc (gdbarch, sparc32nbsd_supply_fpregset, NULL);
|
||||||
tdep->sizeof_fpregset = 33 * 4;
|
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);
|
frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue