-/* Functions specific to running gdb native on IA-64 running Linux.
- Copyright 1999, 2000 Free Software Foundation, Inc.
+/* Functions specific to running gdb native on IA-64 running
+ GNU/Linux.
+
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
This file is part of GDB.
Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "gdb_string.h"
#include "inferior.h"
#include "target.h"
#include "gdbcore.h"
+#include "regcache.h"
+#include "ia64-tdep.h"
#include <signal.h>
#include <sys/ptrace.h>
-#include <sys/wait.h>
+#include "gdb_wait.h"
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif
+#include <sys/syscall.h>
#include <sys/user.h>
#include <asm/ptrace_offsets.h>
CORE_ADDR addr;
if (regno < 0 || regno >= NUM_REGS)
- error ("Invalid register number %d.", regno);
+ error (_("Invalid register number %d."), regno);
if (u_offsets[regno] == -1)
addr = 0;
to be changed by (roughly) N as well. (It could be N-1 or N+1
depending upon where the NaT collection bits fall.)
- OTOH, the linux kernel provides read/write access to bsp (and
+ OTOH, the Linux kernel provides read/write access to bsp (and
currently read/write access to bspstore as well). But it
is definitely the case that if you change one, the other
will change at the same time. It is more useful to gdb to
for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
{
- supply_register (regi, (char *) (regp + (regi - IA64_GR0_REGNUM)));
+ regcache_raw_supply (current_regcache, regi,
+ (char *) (regp + (regi - IA64_GR0_REGNUM)));
}
/* FIXME: NAT collection bits are at index 32; gotta deal with these
somehow... */
- supply_register (IA64_PR_REGNUM, (char *) (regp + 33));
+ regcache_raw_supply (current_regcache, IA64_PR_REGNUM, (char *) (regp + 33));
for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
{
- supply_register (regi, (char *) (regp + 34 + (regi - IA64_BR0_REGNUM)));
+ regcache_raw_supply (current_regcache, regi,
+ (char *) (regp + 34 + (regi - IA64_BR0_REGNUM)));
}
- supply_register (IA64_IP_REGNUM, (char *) (regp + 42));
- supply_register (IA64_CFM_REGNUM, (char *) (regp + 43));
- supply_register (IA64_PSR_REGNUM, (char *) (regp + 44));
- supply_register (IA64_RSC_REGNUM, (char *) (regp + 45));
- supply_register (IA64_BSP_REGNUM, (char *) (regp + 46));
- supply_register (IA64_BSPSTORE_REGNUM, (char *) (regp + 47));
- supply_register (IA64_RNAT_REGNUM, (char *) (regp + 48));
- supply_register (IA64_CCV_REGNUM, (char *) (regp + 49));
- supply_register (IA64_UNAT_REGNUM, (char *) (regp + 50));
- supply_register (IA64_FPSR_REGNUM, (char *) (regp + 51));
- supply_register (IA64_PFS_REGNUM, (char *) (regp + 52));
- supply_register (IA64_LC_REGNUM, (char *) (regp + 53));
- supply_register (IA64_EC_REGNUM, (char *) (regp + 54));
+ regcache_raw_supply (current_regcache, IA64_IP_REGNUM,
+ (char *) (regp + 42));
+ regcache_raw_supply (current_regcache, IA64_CFM_REGNUM,
+ (char *) (regp + 43));
+ regcache_raw_supply (current_regcache, IA64_PSR_REGNUM,
+ (char *) (regp + 44));
+ regcache_raw_supply (current_regcache, IA64_RSC_REGNUM,
+ (char *) (regp + 45));
+ regcache_raw_supply (current_regcache, IA64_BSP_REGNUM,
+ (char *) (regp + 46));
+ regcache_raw_supply (current_regcache, IA64_BSPSTORE_REGNUM,
+ (char *) (regp + 47));
+ regcache_raw_supply (current_regcache, IA64_RNAT_REGNUM,
+ (char *) (regp + 48));
+ regcache_raw_supply (current_regcache, IA64_CCV_REGNUM,
+ (char *) (regp + 49));
+ regcache_raw_supply (current_regcache, IA64_UNAT_REGNUM,
+ (char *) (regp + 50));
+ regcache_raw_supply (current_regcache, IA64_FPSR_REGNUM,
+ (char *) (regp + 51));
+ regcache_raw_supply (current_regcache, IA64_PFS_REGNUM,
+ (char *) (regp + 52));
+ regcache_raw_supply (current_regcache, IA64_LC_REGNUM,
+ (char *) (regp + 53));
+ regcache_raw_supply (current_regcache, IA64_EC_REGNUM,
+ (char *) (regp + 54));
}
void
#define COPY_REG(_idx_,_regi_) \
if ((regno == -1) || regno == _regi_) \
- memcpy (regp + _idx_, ®isters[REGISTER_BYTE (_regi_)], \
- REGISTER_RAW_SIZE (_regi_))
+ regcache_raw_collect (current_regcache, _regi_, regp + _idx_)
for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
{
void
supply_fpregset (fpregset_t *fpregsetp)
{
- register int regi;
+ int regi;
char *from;
for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
{
from = (char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
- supply_register (regi, from);
+ regcache_raw_supply (current_regcache, regi, from);
}
}
fill_fpregset (fpregset_t *fpregsetp, int regno)
{
int regi;
- char *to;
- char *from;
for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
{
if ((regno == -1) || (regno == regi))
- {
- from = (char *) ®isters[REGISTER_BYTE (regi)];
- to = (char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
- memcpy (to, from, REGISTER_RAW_SIZE (regi));
- }
+ regcache_raw_collect (current_regcache, regi,
+ &((*fpregsetp)[regi - IA64_FR0_REGNUM]));
}
}
#define IA64_PSR_DD (1UL << 39)
static void
-enable_watchpoints_in_psr (int pid)
+enable_watchpoints_in_psr (ptid_t ptid)
{
CORE_ADDR psr;
- psr = read_register_pid (IA64_PSR_REGNUM, pid);
+ psr = read_register_pid (IA64_PSR_REGNUM, ptid);
if (!(psr & IA64_PSR_DB))
{
psr |= IA64_PSR_DB; /* Set the db bit - this enables hardware
watchpoints and breakpoints. */
- write_register_pid (IA64_PSR_REGNUM, psr, pid);
+ write_register_pid (IA64_PSR_REGNUM, psr, ptid);
}
}
static long
-fetch_debug_register (int pid, int idx)
+fetch_debug_register (ptid_t ptid, int idx)
{
long val;
int tid;
- tid = TIDGET(pid);
+ tid = TIDGET (ptid);
if (tid == 0)
- tid = pid;
+ tid = PIDGET (ptid);
- val = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) (PT_DBR + 8 * idx), 0);
+ val = ptrace (PT_READ_U, tid, (PTRACE_TYPE_ARG3) (PT_DBR + 8 * idx), 0);
return val;
}
static void
-store_debug_register (int pid, int idx, long val)
+store_debug_register (ptid_t ptid, int idx, long val)
{
int tid;
- tid = TIDGET(pid);
+ tid = TIDGET (ptid);
if (tid == 0)
- tid = pid;
+ tid = PIDGET (ptid);
- (void) ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) (PT_DBR + 8 * idx), val);
+ (void) ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) (PT_DBR + 8 * idx), val);
}
static void
-fetch_debug_register_pair (int pid, int idx, long *dbr_addr, long *dbr_mask)
+fetch_debug_register_pair (ptid_t ptid, int idx, long *dbr_addr, long *dbr_mask)
{
if (dbr_addr)
- *dbr_addr = fetch_debug_register (pid, 2 * idx);
+ *dbr_addr = fetch_debug_register (ptid, 2 * idx);
if (dbr_mask)
- *dbr_mask = fetch_debug_register (pid, 2 * idx + 1);
+ *dbr_mask = fetch_debug_register (ptid, 2 * idx + 1);
}
static void
-store_debug_register_pair (int pid, int idx, long *dbr_addr, long *dbr_mask)
+store_debug_register_pair (ptid_t ptid, int idx, long *dbr_addr, long *dbr_mask)
{
if (dbr_addr)
- store_debug_register (pid, 2 * idx, *dbr_addr);
+ store_debug_register (ptid, 2 * idx, *dbr_addr);
if (dbr_mask)
- store_debug_register (pid, 2 * idx + 1, *dbr_mask);
+ store_debug_register (ptid, 2 * idx + 1, *dbr_mask);
}
static int
}
int
-ia64_linux_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
+ia64_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rw)
{
int idx;
long dbr_addr, dbr_mask;
for (idx = 0; idx < max_watchpoints; idx++)
{
- fetch_debug_register_pair (pid, idx, NULL, &dbr_mask);
+ fetch_debug_register_pair (ptid, idx, NULL, &dbr_mask);
if ((dbr_mask & (0x3UL << 62)) == 0)
{
/* Exit loop if both r and w bits clear */
return -1;
}
- store_debug_register_pair (pid, idx, &dbr_addr, &dbr_mask);
- enable_watchpoints_in_psr (pid);
+ store_debug_register_pair (ptid, idx, &dbr_addr, &dbr_mask);
+ enable_watchpoints_in_psr (ptid);
return 0;
}
int
-ia64_linux_remove_watchpoint (int pid, CORE_ADDR addr, int len)
+ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr, int len)
{
int idx;
long dbr_addr, dbr_mask;
for (idx = 0; idx < max_watchpoints; idx++)
{
- fetch_debug_register_pair (pid, idx, &dbr_addr, &dbr_mask);
+ fetch_debug_register_pair (ptid, idx, &dbr_addr, &dbr_mask);
if ((dbr_mask & (0x3UL << 62)) && addr == (CORE_ADDR) dbr_addr)
{
dbr_addr = 0;
dbr_mask = 0;
- store_debug_register_pair (pid, idx, &dbr_addr, &dbr_mask);
+ store_debug_register_pair (ptid, idx, &dbr_addr, &dbr_mask);
return 0;
}
}
return -1;
}
-CORE_ADDR
-ia64_linux_stopped_by_watchpoint (int pid)
+int
+ia64_linux_stopped_data_address (CORE_ADDR *addr_p)
{
CORE_ADDR psr;
int tid;
struct siginfo siginfo;
+ ptid_t ptid = inferior_ptid;
- tid = TIDGET(pid);
+ tid = TIDGET(ptid);
if (tid == 0)
- tid = pid;
+ tid = PIDGET (ptid);
errno = 0;
- ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_ARG3_TYPE) 0, &siginfo);
+ ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_TYPE_ARG3) 0, &siginfo);
- if (errno != 0 || siginfo.si_code != 4 /* TRAP_HWBKPT */)
+ if (errno != 0 || siginfo.si_signo != SIGTRAP ||
+ (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
return 0;
- psr = read_register_pid (IA64_PSR_REGNUM, pid);
+ psr = read_register_pid (IA64_PSR_REGNUM, ptid);
psr |= IA64_PSR_DD; /* Set the dd bit - this will disable the watchpoint
for the next instruction */
- write_register_pid (IA64_PSR_REGNUM, psr, pid);
+ write_register_pid (IA64_PSR_REGNUM, psr, ptid);
- return (CORE_ADDR) siginfo.si_addr;
+ *addr_p = (CORE_ADDR)siginfo.si_addr;
+ return 1;
+}
+
+int
+ia64_linux_stopped_by_watchpoint (void)
+{
+ CORE_ADDR addr;
+ return ia64_linux_stopped_data_address (&addr);
+}
+
+LONGEST
+ia64_linux_xfer_unwind_table (struct target_ops *ops,
+ enum target_object object,
+ const char *annex,
+ void *readbuf, const void *writebuf,
+ ULONGEST offset, LONGEST len)
+{
+ return syscall (__NR_getunwind, readbuf, len);
}