/* Native-dependent code for GNU/Linux i386.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "i386-nat.h"
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
val = ptrace (PTRACE_PEEKUSER, tid, 4 * regmap[regno], 0);
if (errno != 0)
error (_("Couldn't read register %s (#%d): %s."),
- gdbarch_register_name (current_gdbarch, regno),
+ gdbarch_register_name (get_regcache_arch (regcache), regno),
regno, safe_strerror (errno));
regcache_raw_supply (regcache, regno, &val);
ptrace (PTRACE_POKEUSER, tid, 4 * regmap[regno], val);
if (errno != 0)
error (_("Couldn't write register %s (#%d): %s."),
- gdbarch_register_name (current_gdbarch, regno),
+ gdbarch_register_name (get_regcache_arch (regcache), regno),
regno, safe_strerror (errno));
}
\f
for (i = 0; i < I386_NUM_GREGS; i++)
regcache_raw_supply (regcache, i, regp + regmap[i]);
- if (I386_LINUX_ORIG_EAX_REGNUM < gdbarch_num_regs (current_gdbarch))
+ if (I386_LINUX_ORIG_EAX_REGNUM
+ < gdbarch_num_regs (get_regcache_arch (regcache)))
regcache_raw_supply (regcache, I386_LINUX_ORIG_EAX_REGNUM,
regp + ORIG_EAX);
}
regcache_raw_collect (regcache, i, regp + regmap[i]);
if ((regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
- && I386_LINUX_ORIG_EAX_REGNUM < gdbarch_num_regs (current_gdbarch))
+ && I386_LINUX_ORIG_EAX_REGNUM
+ < gdbarch_num_regs (get_regcache_arch (regcache)))
regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM,
regp + ORIG_EAX);
}
registers). */
static void
-i386_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+i386_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
{
int i;
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
if (regno == -1 || regno == i)
fetch_register (regcache, i);
/* The call above might reset `have_ptrace_getregs'. */
if (!have_ptrace_getregs)
{
- i386_linux_fetch_inferior_registers (regcache, regno);
+ i386_linux_fetch_inferior_registers (ops, regcache, regno);
return;
}
do this for all registers (including the floating point and SSE
registers). */
static void
-i386_linux_store_inferior_registers (struct regcache *regcache, int regno)
+i386_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
{
int i;
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
if (regno == -1 || regno == i)
store_register (regcache, i);
perror_with_name (_("Couldn't write debug register"));
}
-void
+static void
i386_linux_dr_set_control (unsigned long control)
{
struct lwp_info *lp;
i386_linux_dr_set (ptid, DR_CONTROL, control);
}
-void
+static void
i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
{
struct lwp_info *lp;
i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
}
-void
+static void
i386_linux_dr_reset_addr (int regnum)
{
i386_linux_dr_set_addr (regnum, 0);
}
-unsigned long
+static unsigned long
i386_linux_dr_get_status (void)
{
return i386_linux_dr_get (inferior_ptid, DR_STATUS);
If SIGNAL is nonzero, give it that signal. */
static void
-i386_linux_resume (ptid_t ptid, int step, enum target_signal signal)
+i386_linux_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
int pid = PIDGET (ptid);
if (step)
{
struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid));
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST pc;
gdb_byte buf[LINUX_SYSCALL_LEN];
request = PTRACE_SINGLESTEP;
regcache_cooked_read_unsigned (regcache,
- gdbarch_pc_regnum (current_gdbarch), &pc);
+ gdbarch_pc_regnum (gdbarch), &pc);
/* Returning from a signal trampoline is done by calling a
special system call (sigreturn or rt_sigreturn, see
that's about to be restored, and set the trace flag there. */
/* First check if PC is at a system call. */
- if (read_memory_nobpt (pc, buf, LINUX_SYSCALL_LEN) == 0
+ if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0
&& memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
{
ULONGEST syscall;
regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp);
if (syscall == SYS_rt_sigreturn)
- addr = read_memory_integer (sp + 8, 4) + 20;
+ addr = read_memory_integer (sp + 8, 4, byte_order) + 20;
else
addr = sp;
/* Fill in the generic GNU/Linux methods. */
t = linux_target ();
+ i386_use_watchpoints (t);
+
+ i386_dr_low.set_control = i386_linux_dr_set_control;
+ i386_dr_low.set_addr = i386_linux_dr_set_addr;
+ i386_dr_low.reset_addr = i386_linux_dr_reset_addr;
+ i386_dr_low.get_status = i386_linux_dr_get_status;
+ i386_set_debug_register_length (4);
+
/* Override the default ptrace resume method. */
t->to_resume = i386_linux_resume;