* arch-utils.c (legacy_pc_in_sigtramp): Remove.

* arch-utils.h (legacy_pc_in_sigtramp): Remove.

	* config/ia64/linux.mt (DEPRECATED_TM_FILE): Remove.
	* config/ia64/tm-linux.h: Remove file.
	* ia64-tdep.h (struct gdbarch_tdep): Add pc_in_sigtramp callback.
	* ia64-tdep.c (ia64_sigtramp_frame_sniffer): Use it instead of
	legacy_pc_in_sigtramp.
	(ia64_gdbarch_init): Initialize tdep->pc_in_sigtramp.
	* ia64-linux-tdep.c (ia64_linux_pc_in_sigtramp): Make static.
	Remove func_name argument.
	(ia64_linux_init_abi): Install it as tdep->pc_in_sigtramp.

	* infrun.c (HAVE_STEPPABLE_WATCHPOINT): Do not redefine.
	* target.c (update_current_target): Add to_have_steppable_watchpoint.
	* target.h (struct target_ops):  Add to_have_steppable_watchpoint.
	(HAVE_STEPPABLE_WATCHPOINT): Define.

	* config/ia64/linux.mh (NATDEPFILES): Remove core-aout.o.
	* config/ia64/nm-linux.h (KERNEL_U_ADDR, U_REGS_OFFSET,
	CANNOT_FETCH_REGISTER, CANNOT_STORE_REGISTER,
	TARGET_CAN_USE_HARDWARE_WATCHPOINT, HAVE_STEPPABLE_WATCHPOINT,
	STOPPED_BY_WATCHPOINT, target_stopped_data_address,
	target_insert_watchpoint, target_remove_watchpoint): Remove.
	(FETCH_INFERIOR_REGISTERS): Define.
	* ia64-linux-nat.c (ia64_register_addr): Make static.
	(ia64_cannot_fetch_register, ia64_cannot_store_register): Likewise.
	(ia64_linux_insert_watchpoint): Make static.  Remove ptid_p argument.
	(ia64_linux_remove_watchpoint): Likewise.  Add type argument.
	(ia64_linux_stopped_data_address): Make static.  Add target_ops.
	(ia64_linux_stopped_by_watchpoint): Make static.
	(ia64_linux_can_use_hw_breakpoint): New function.
	(ia64_linux_fetch_register, ia64_linux_fetch_registers): Likewise.
	(ia64_linux_store_register, ia64_linux_store_registers): Likewise.
	(_initialize_ia64_linux_nat): Install register and watchpoint ops.
This commit is contained in:
Ulrich Weigand 2007-03-28 18:56:07 +00:00
parent c76308d222
commit 74174d2e39
14 changed files with 218 additions and 120 deletions

View File

@ -1,3 +1,41 @@
2007-03-28 Ulrich Weigand <uweigand@de.ibm.com>
* arch-utils.c (legacy_pc_in_sigtramp): Remove.
* arch-utils.h (legacy_pc_in_sigtramp): Remove.
* config/ia64/linux.mt (DEPRECATED_TM_FILE): Remove.
* config/ia64/tm-linux.h: Remove file.
* ia64-tdep.h (struct gdbarch_tdep): Add pc_in_sigtramp callback.
* ia64-tdep.c (ia64_sigtramp_frame_sniffer): Use it instead of
legacy_pc_in_sigtramp.
(ia64_gdbarch_init): Initialize tdep->pc_in_sigtramp.
* ia64-linux-tdep.c (ia64_linux_pc_in_sigtramp): Make static.
Remove func_name argument.
(ia64_linux_init_abi): Install it as tdep->pc_in_sigtramp.
* infrun.c (HAVE_STEPPABLE_WATCHPOINT): Do not redefine.
* target.c (update_current_target): Add to_have_steppable_watchpoint.
* target.h (struct target_ops): Add to_have_steppable_watchpoint.
(HAVE_STEPPABLE_WATCHPOINT): Define.
* config/ia64/linux.mh (NATDEPFILES): Remove core-aout.o.
* config/ia64/nm-linux.h (KERNEL_U_ADDR, U_REGS_OFFSET,
CANNOT_FETCH_REGISTER, CANNOT_STORE_REGISTER,
TARGET_CAN_USE_HARDWARE_WATCHPOINT, HAVE_STEPPABLE_WATCHPOINT,
STOPPED_BY_WATCHPOINT, target_stopped_data_address,
target_insert_watchpoint, target_remove_watchpoint): Remove.
(FETCH_INFERIOR_REGISTERS): Define.
* ia64-linux-nat.c (ia64_register_addr): Make static.
(ia64_cannot_fetch_register, ia64_cannot_store_register): Likewise.
(ia64_linux_insert_watchpoint): Make static. Remove ptid_p argument.
(ia64_linux_remove_watchpoint): Likewise. Add type argument.
(ia64_linux_stopped_data_address): Make static. Add target_ops.
(ia64_linux_stopped_by_watchpoint): Make static.
(ia64_linux_can_use_hw_breakpoint): New function.
(ia64_linux_fetch_register, ia64_linux_fetch_registers): Likewise.
(ia64_linux_store_register, ia64_linux_store_registers): Likewise.
(_initialize_ia64_linux_nat): Install register and watchpoint ops.
2007-03-28 Pedro Alves <pedro_alves@portugalmail.pt>
* linespec.c: Include language.h.

View File

@ -234,16 +234,6 @@ generic_register_byte (int regnum)
}
int
legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
{
#if defined (DEPRECATED_IN_SIGTRAMP)
return DEPRECATED_IN_SIGTRAMP (pc, name);
#else
return name && strcmp ("_sigtramp", name) == 0;
#endif
}
int
generic_convert_register_p (int regnum, struct type *type)
{

View File

@ -97,9 +97,6 @@ extern int generic_register_size (int regnum);
/* Assume that the world is sane, the registers are all adjacent. */
extern int generic_register_byte (int regnum);
/* Prop up old targets that use various sigtramp macros. */
extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name);
/* By default, registers are not convertible. */
extern int generic_convert_register_p (int regnum, struct type *type);

View File

@ -2,7 +2,7 @@
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o gcore.o \
core-aout.o core-regset.o ia64-linux-nat.o \
core-regset.o ia64-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
LOADLIBES = -ldl -rdynamic

View File

@ -1,4 +1,3 @@
# Target: Intel IA-64 running GNU/Linux
TDEPFILES= ia64-tdep.o ia64-linux-tdep.o \
solib.o solib-svr4.o solib-legacy.o symfile-mem.o
DEPRECATED_TM_FILE= tm-linux.h

View File

@ -22,56 +22,8 @@
#ifndef NM_LINUX_H
#define NM_LINUX_H
struct target_ops;
#include "config/nm-linux.h"
/* This is the amount to subtract from u.u_ar0
to get the offset in the core file of the register values. */
#define KERNEL_U_ADDR 0x0
/* Note: It seems likely that we'll have to eventually define
FETCH_INFERIOR_REGISTERS. But until that time, we'll make do
with the following. */
#define CANNOT_FETCH_REGISTER(regno) ia64_cannot_fetch_register(regno)
extern int ia64_cannot_fetch_register (int regno);
#define CANNOT_STORE_REGISTER(regno) ia64_cannot_store_register(regno)
extern int ia64_cannot_store_register (int regno);
#define U_REGS_OFFSET 0
/* Hardware watchpoints */
#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
/* The IA-64 architecture can step over a watch point (without triggering
it again) if the "dd" (data debug fault disable) bit in the processor
status word is set.
This PSR bit is set in ia64_linux_stopped_by_watchpoint when the
code there has determined that a hardware watchpoint has indeed
been hit. The CPU will then be able to execute one instruction
without triggering a watchpoint. */
#define HAVE_STEPPABLE_WATCHPOINT 1
#define STOPPED_BY_WATCHPOINT(W) \
ia64_linux_stopped_by_watchpoint ()
extern int ia64_linux_stopped_by_watchpoint ();
#define target_stopped_data_address(target, x) \
ia64_linux_stopped_data_address(x)
extern int ia64_linux_stopped_data_address (CORE_ADDR *addr_p);
#define target_insert_watchpoint(addr, len, type) \
ia64_linux_insert_watchpoint (inferior_ptid, addr, len, type)
extern int ia64_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr,
int len, int rw);
#define target_remove_watchpoint(addr, len, type) \
ia64_linux_remove_watchpoint (inferior_ptid, addr, len)
extern int ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr,
int len);
#define FETCH_INFERIOR_REGISTERS
#endif /* #ifndef NM_LINUX_H */

View File

@ -1,28 +0,0 @@
/* Definitions to target GDB to GNU/Linux on ia64.
Copyright 1992, 1993, 2000, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef TM_LINUX_H
#define TM_LINUX_H
extern int ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name);
#define DEPRECATED_IN_SIGTRAMP(pc,func_name) ia64_linux_in_sigtramp (pc, func_name)
#endif /* #ifndef TM_LINUX_H */

View File

@ -303,8 +303,8 @@ static int u_offsets[] =
-1, -1, -1, -1, -1, -1, -1, -1,
};
CORE_ADDR
register_addr (int regno, CORE_ADDR blockend)
static CORE_ADDR
ia64_register_addr (int regno)
{
CORE_ADDR addr;
@ -319,14 +319,14 @@ register_addr (int regno, CORE_ADDR blockend)
return addr;
}
int ia64_cannot_fetch_register (regno)
int regno;
static int
ia64_cannot_fetch_register (int regno)
{
return regno < 0 || regno >= NUM_REGS || u_offsets[regno] == -1;
}
int ia64_cannot_store_register (regno)
int regno;
static int
ia64_cannot_store_register (int regno)
{
/* Rationale behind not permitting stores to bspstore...
@ -561,9 +561,10 @@ is_power_of_2 (int val)
return onecount <= 1;
}
int
ia64_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rw)
static int
ia64_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
{
ptid_t ptid = inferior_ptid;
int idx;
long dbr_addr, dbr_mask;
int max_watchpoints = 4;
@ -608,9 +609,10 @@ ia64_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rw)
return 0;
}
int
ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr, int len)
static int
ia64_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
{
ptid_t ptid = inferior_ptid;
int idx;
long dbr_addr, dbr_mask;
int max_watchpoints = 4;
@ -632,8 +634,8 @@ ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr, int len)
return -1;
}
int
ia64_linux_stopped_data_address (CORE_ADDR *addr_p)
static int
ia64_linux_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
{
CORE_ADDR psr;
int tid;
@ -660,13 +662,130 @@ ia64_linux_stopped_data_address (CORE_ADDR *addr_p)
return 1;
}
int
static int
ia64_linux_stopped_by_watchpoint (void)
{
CORE_ADDR addr;
return ia64_linux_stopped_data_address (&addr);
return ia64_linux_stopped_data_address (&current_target, &addr);
}
static int
ia64_linux_can_use_hw_breakpoint (int type, int cnt, int othertype)
{
return 1;
}
/* Fetch register REGNUM from the inferior. */
static void
ia64_linux_fetch_register (int regnum)
{
CORE_ADDR addr;
size_t size;
PTRACE_TYPE_RET *buf;
int pid, i;
if (ia64_cannot_fetch_register (regnum))
{
regcache_raw_supply (current_regcache, regnum, NULL);
return;
}
/* Cater for systems like GNU/Linux, that implement threads as
separate processes. */
pid = ptid_get_lwp (inferior_ptid);
if (pid == 0)
pid = ptid_get_pid (inferior_ptid);
/* This isn't really an address, but ptrace thinks of it as one. */
addr = ia64_register_addr (regnum);
size = register_size (current_gdbarch, regnum);
gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
buf = alloca (size);
/* Read the register contents from the inferior a chunk at a time. */
for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
{
errno = 0;
buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)addr, 0);
if (errno != 0)
error (_("Couldn't read register %s (#%d): %s."),
REGISTER_NAME (regnum), regnum, safe_strerror (errno));
addr += sizeof (PTRACE_TYPE_RET);
}
regcache_raw_supply (current_regcache, regnum, buf);
}
/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
for all registers. */
static void
ia64_linux_fetch_registers (int regnum)
{
if (regnum == -1)
for (regnum = 0; regnum < NUM_REGS; regnum++)
ia64_linux_fetch_register (regnum);
else
ia64_linux_fetch_register (regnum);
}
/* Store register REGNUM into the inferior. */
static void
ia64_linux_store_register (int regnum)
{
CORE_ADDR addr;
size_t size;
PTRACE_TYPE_RET *buf;
int pid, i;
if (ia64_cannot_store_register (regnum))
return;
/* Cater for systems like GNU/Linux, that implement threads as
separate processes. */
pid = ptid_get_lwp (inferior_ptid);
if (pid == 0)
pid = ptid_get_pid (inferior_ptid);
/* This isn't really an address, but ptrace thinks of it as one. */
addr = ia64_register_addr (regnum);
size = register_size (current_gdbarch, regnum);
gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
buf = alloca (size);
/* Write the register contents into the inferior a chunk at a time. */
regcache_raw_collect (current_regcache, regnum, buf);
for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
{
errno = 0;
ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)addr, buf[i]);
if (errno != 0)
error (_("Couldn't write register %s (#%d): %s."),
REGISTER_NAME (regnum), regnum, safe_strerror (errno));
addr += sizeof (PTRACE_TYPE_RET);
}
}
/* Store register REGNUM back into the inferior. If REGNUM is -1, do
this for all registers. */
static void
ia64_linux_store_registers (int regnum)
{
if (regnum == -1)
for (regnum = 0; regnum < NUM_REGS; regnum++)
ia64_linux_store_register (regnum);
else
ia64_linux_store_register (regnum);
}
static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
const char *, gdb_byte *, const gdb_byte *,
ULONGEST, LONGEST);
@ -695,10 +814,32 @@ _initialize_ia64_linux_nat (void)
/* Fill in the generic GNU/Linux methods. */
t = linux_target ();
/* Override the default fetch/store register routines. */
t->to_fetch_registers = ia64_linux_fetch_registers;
t->to_store_registers = ia64_linux_store_registers;
/* Override the default to_xfer_partial. */
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = ia64_linux_xfer_partial;
/* Override watchpoint routines. */
/* The IA-64 architecture can step over a watch point (without triggering
it again) if the "dd" (data debug fault disable) bit in the processor
status word is set.
This PSR bit is set in ia64_linux_stopped_by_watchpoint when the
code there has determined that a hardware watchpoint has indeed
been hit. The CPU will then be able to execute one instruction
without triggering a watchpoint. */
t->to_have_steppable_watchpoint = 1;
t->to_can_use_hw_breakpoint = ia64_linux_can_use_hw_breakpoint;
t->to_stopped_by_watchpoint = ia64_linux_stopped_by_watchpoint;
t->to_stopped_data_address = ia64_linux_stopped_data_address;
t->to_insert_watchpoint = ia64_linux_insert_watchpoint;
t->to_remove_watchpoint = ia64_linux_remove_watchpoint;
/* Register the target. */
linux_nat_add_target (t);
}

View File

@ -39,8 +39,8 @@
/* Offset to sigcontext structure from frame of handler */
#define IA64_LINUX_SIGCONTEXT_OFFSET 192
int
ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
static int
ia64_linux_pc_in_sigtramp (CORE_ADDR pc)
{
return (pc >= (CORE_ADDR) GATE_AREA_START && pc < (CORE_ADDR) GATE_AREA_END);
}
@ -125,6 +125,9 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
registers are saved. */
tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
/* Set the pc_in_sigtramp method. */
tdep->pc_in_sigtramp = ia64_linux_pc_in_sigtramp;
set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);

View File

@ -2078,12 +2078,14 @@ static const struct frame_unwind ia64_sigtramp_frame_unwind =
static const struct frame_unwind *
ia64_sigtramp_frame_sniffer (struct frame_info *next_frame)
{
char *name;
CORE_ADDR pc = frame_pc_unwind (next_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
if (tdep->pc_in_sigtramp)
{
CORE_ADDR pc = frame_pc_unwind (next_frame);
find_pc_partial_function (pc, &name, NULL, NULL);
if (legacy_pc_in_sigtramp (pc, name))
return &ia64_sigtramp_frame_unwind;
if (tdep->pc_in_sigtramp (pc))
return &ia64_sigtramp_frame_unwind;
}
return NULL;
}
@ -3576,6 +3578,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
gdbarch = gdbarch_alloc (&info, tdep);
tdep->sigcontext_register_address = 0;
tdep->pc_in_sigtramp = 0;
/* Define the ia64 floating-point format to gdb. */
builtin_type_ia64_ext =

View File

@ -199,6 +199,7 @@
struct gdbarch_tdep
{
CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int);
int (*pc_in_sigtramp) (CORE_ADDR);
};
extern void ia64_write_pc (CORE_ADDR, ptid_t);

View File

@ -197,13 +197,6 @@ a command like `return' or `jump' to continue execution."));
/* Convert the #defines into values. This is temporary until wfi control
flow is completely sorted out. */
#ifndef HAVE_STEPPABLE_WATCHPOINT
#define HAVE_STEPPABLE_WATCHPOINT 0
#else
#undef HAVE_STEPPABLE_WATCHPOINT
#define HAVE_STEPPABLE_WATCHPOINT 1
#endif
#ifndef CANNOT_STEP_HW_WATCHPOINTS
#define CANNOT_STEP_HW_WATCHPOINTS 0
#else

View File

@ -413,6 +413,7 @@ update_current_target (void)
INHERIT (to_remove_watchpoint, t);
INHERIT (to_stopped_data_address, t);
INHERIT (to_stopped_by_watchpoint, t);
INHERIT (to_have_steppable_watchpoint, t);
INHERIT (to_have_continuable_watchpoint, t);
INHERIT (to_region_ok_for_hw_watchpoint, t);
INHERIT (to_terminal_init, t);

View File

@ -362,6 +362,7 @@ struct target_ops
int (*to_remove_watchpoint) (CORE_ADDR, int, int);
int (*to_insert_watchpoint) (CORE_ADDR, int, int);
int (*to_stopped_by_watchpoint) (void);
int to_have_steppable_watchpoint;
int to_have_continuable_watchpoint;
int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
int (*to_region_ok_for_hw_watchpoint) (CORE_ADDR, int);
@ -1128,6 +1129,13 @@ extern void (*deprecated_target_new_objfile_hook) (struct objfile *);
(*current_target.to_stopped_by_watchpoint) ()
#endif
/* Non-zero if we have steppable watchpoints */
#ifndef HAVE_STEPPABLE_WATCHPOINT
#define HAVE_STEPPABLE_WATCHPOINT \
(current_target.to_have_steppable_watchpoint)
#endif
/* Non-zero if we have continuable watchpoints */
#ifndef HAVE_CONTINUABLE_WATCHPOINT