* 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 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.
}
\f
-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)
{
/* 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);
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
# 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
#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 */
+++ /dev/null
-/* 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 */
-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;
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...
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;
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;
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;
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 (¤t_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);
/* 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);
}
/* 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);
}
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);
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;
}
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 =
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);
/* 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
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);
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);
(*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