33 #include <elf/common.h>
35 #include <sys/ptrace.h>
36 #include <sys/utsname.h>
37 #include <sys/procfs.h>
47 #ifndef PTRACE_GET_THREAD_AREA
48 #define PTRACE_GET_THREAD_AREA 22
51 #ifndef PTRACE_GETWMMXREGS
52 #define PTRACE_GETWMMXREGS 18
53 #define PTRACE_SETWMMXREGS 19
56 #ifndef PTRACE_GETVFPREGS
57 #define PTRACE_GETVFPREGS 27
58 #define PTRACE_SETVFPREGS 28
61 #ifndef PTRACE_GETHBPREGS
62 #define PTRACE_GETHBPREGS 29
63 #define PTRACE_SETHBPREGS 30
83 #define GET_THREAD_ID(PTID) get_thread_id (PTID)
108 ret =
ptrace (PT_GETFPREGS, tid, 0, fp);
112 warning (
_(
"Unable to fetch floating point register."));
149 ret =
ptrace (PT_GETFPREGS, tid, 0, fp);
153 warning (
_(
"Unable to fetch the floating point registers."));
189 ret =
ptrace (PT_GETFPREGS, tid, 0, fp);
193 warning (
_(
"Unable to fetch the floating point registers."));
220 warning (
_(
"Unable to store floating point register."));
240 elf_fpregset_t fpregs;
243 iov.iov_base = &fpregs;
244 iov.iov_len =
sizeof (fpregs);
249 ret =
ptrace (PT_GETFPREGS, tid, 0, fp);
253 warning (
_(
"Unable to fetch the floating point registers."));
280 warning (
_(
"Unable to store floating point registers."));
301 iov.iov_base = ®s;
302 iov.iov_len =
sizeof (regs);
311 warning (
_(
"Unable to fetch general register."));
334 (
char *) ®s[ARM_PC_REGNUM]);
354 iov.iov_base = ®s;
355 iov.iov_len =
sizeof (regs);
364 warning (
_(
"Unable to fetch general registers."));
376 (
char *) ®s[ARM_PC_REGNUM]);
381 (
char *) ®s[ARM_PC_REGNUM]);
404 iov.iov_base = ®s;
405 iov.iov_len =
sizeof (regs);
414 warning (
_(
"Unable to fetch general registers."));
431 iov.iov_base = ®s;
432 iov.iov_len =
sizeof (regs);
441 warning (
_(
"Unable to store general register."));
460 iov.iov_base = ®s;
461 iov.iov_len =
sizeof (regs);
470 warning (
_(
"Unable to fetch general registers."));
488 iov.iov_base = ®s;
489 iov.iov_len =
sizeof (regs);
498 warning (
_(
"Unable to store general registers."));
506 #define IWMMXT_REGS_SIZE (16 * 8 + 6 * 4)
520 warning (
_(
"Unable to fetch WMMX registers."));
524 for (regno = 0; regno < 16; regno++)
528 for (regno = 0; regno < 2; regno++)
530 ®buf[16 * 8 + regno * 4]);
532 for (regno = 0; regno < 4; regno++)
534 ®buf[16 * 8 + 2 * 4 + regno * 4]);
549 warning (
_(
"Unable to fetch WMMX registers."));
553 for (regno = 0; regno < 16; regno++)
559 for (regno = 0; regno < 2; regno++)
563 ®buf[16 * 8 + regno * 4]);
565 for (regno = 0; regno < 4; regno++)
569 ®buf[16 * 8 + 2 * 4 + regno * 4]);
575 warning (
_(
"Unable to store WMMX registers."));
583 #define VFP_REGS_SIZE (32 * 8 + 4)
600 iov.iov_base = regbuf;
609 warning (
_(
"Unable to fetch VFP registers."));
615 (
char *) regbuf + regno * 8);
618 (
char *) regbuf + 32 * 8);
636 iov.iov_base = regbuf;
645 warning (
_(
"Unable to fetch VFP registers (for update)."));
651 (
char *) regbuf + regno * 8);
654 (
char *) regbuf + 32 * 8);
660 iov.iov_base = regbuf;
669 warning (
_(
"Unable to store VFP registers."));
782 lwpid_t lwpid,
int idx,
void **base)
790 *base = (
void *) ((
char *)*base - idx);
802 elf_gregset_t gpregs;
806 iov.iov_base = &gpregs;
807 iov.iov_len =
sizeof (gpregs);
899 warning (
_(
"arm-linux-gdb supports %d hardware watchpoints but target \
906 warning (
_(
"arm-linux-gdb supports %d hardware breakpoints but target \
910 available = (info.
arch != 0);
914 return available == 1 ? &info : NULL;
922 return cap != NULL ? cap->
bp_count : 0;
930 return cap != NULL ? cap->
wp_count : 0;
937 int type,
int cnt,
int ot)
946 else if (cnt + ot > count)
955 else if (cnt > count)
1043 for (proc = arm_linux_process_list; proc; proc = proc->
next)
1044 if (proc->
pid == pid)
1058 proc =
xcalloc (1,
sizeof (*proc));
1062 arm_linux_process_list = proc;
1093 while (proc != NULL)
1095 if (proc->
pid == pid)
1097 *proc_link = proc->
next;
1103 proc_link = &proc->
next;
1125 gdb_assert ((byte_address_select & ~0xffU) == 0);
1127 || ((byte_address_select & 0xfU) != 0));
1129 return (byte_address_select << 5) | (hwbp_type << 3) | (3 << 1) |
enable;
1136 return control & 0x1;
1143 return control & ~0x1;
1198 mask = (1 <<
len) - 1;
1271 for (i = 0; i < count; ++i)
1274 data.
watch = watchpoint;
1310 for (i = 0; i < count; ++i)
1313 data.
watch = watchpoint;
1375 if (cap == NULL || cap->
wp_count == 0)
1381 aligned_addr = addr & ~(max_wp_length - 1);
1383 if (aligned_addr + max_wp_length < addr + len)
1388 if ((len & (len - 1)) != 0)
1444 if (siginfo.si_signo != SIGTRAP
1445 || (siginfo.si_code & 0xffff) != 0x0004 )
1452 slot = siginfo.si_errno;
1459 *addr_p = (
CORE_ADDR) (uintptr_t) siginfo.si_addr;
1476 return start <= addr && start + length - 1 >= addr;
1516 if (arm_lwp_info == NULL)
1528 if (bpts[i].control != 0)
1545 if (wpts[i].control != 0)
1577 *child_state = *parent_state;
struct arch_lwp_info * arch_private
#define PTRACE_SETHBPREGS
static int update_registers_callback(struct lwp_info *lwp, void *arg)
struct target_desc * tdesc_arm_with_iwmmxt
#define PTRACE_SETVFPREGS
static const struct arm_linux_hwbp_cap * arm_linux_get_hwbp_cap(void)
const struct target_desc *(* to_read_description)(struct target_ops *ops) TARGET_DEFAULT_RETURN(NULL)
void arm_linux_supply_nwfpe(const struct regset *regset, struct regcache *regcache, int regnum, const void *regs_buf, size_t len)
static void store_fpregs(const struct regcache *regcache)
void linux_stop_lwp(struct lwp_info *lwp)
struct arm_linux_hw_breakpoint wpts[MAX_WPTS]
static void store_wmmx_regs(const struct regcache *regcache)
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
static struct arm_linux_process_info * arm_linux_find_process_pid(pid_t pid)
void linux_nat_set_new_thread(struct target_ops *t, void(*new_thread)(struct lwp_info *))
struct target_desc * tdesc_arm_with_vfpv2
void warning(const char *fmt,...)
#define PTRACE_GET_THREAD_AREA
#define NWFPE_FPSR_OFFSET
static int arm_linux_get_hw_watchpoint_count(void)
static void store_fpregister(const struct regcache *regcache, int regno)
static void arm_linux_hw_breakpoint_initialize(struct gdbarch *gdbarch, struct bp_target_info *bp_tgt, struct arm_linux_hw_breakpoint *p)
void collect_nwfpe_register(const struct regcache *regcache, int regno, gdb_byte *regs)
static void store_regs(const struct regcache *regcache)
#define PTRACE_GETWMMXREGS
static void fetch_regs(struct regcache *regcache)
static void fetch_wmmx_regs(struct regcache *regcache)
static int arm_hwbp_control_is_enabled(arm_hwbp_control_t control)
static int arm_linux_insert_watchpoint(struct target_ops *self, CORE_ADDR addr, int len, int rw, struct expression *cond)
static struct arm_linux_debug_reg_state * arm_linux_get_debug_reg_state(pid_t pid)
static arm_hwbp_control_t arm_hwbp_control_disable(arm_hwbp_control_t control)
static void fetch_vfp_regs(struct regcache *regcache)
int(* to_region_ok_for_hw_watchpoint)(struct target_ops *, CORE_ADDR, int) TARGET_DEFAULT_FUNC(default_region_ok_for_hw_watchpoint)
int linux_nat_get_siginfo(ptid_t ptid, siginfo_t *siginfo)
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
void linux_nat_set_new_fork(struct target_ops *t, linux_nat_new_fork_ftype *new_fork)
#define PTRACE_GETVFPREGS
static void arm_linux_forget_process(pid_t pid)
static void arm_linux_prepare_to_resume(struct lwp_info *lwp)
#define PTRACE_GETHBPREGS
unsigned int arm_hwbp_control_t
static arm_hwbp_type arm_linux_get_hwbp_type(int rw)
static void arm_linux_new_thread(struct lwp_info *lp)
int(* to_insert_watchpoint)(struct target_ops *, CORE_ADDR, int, int, struct expression *) TARGET_DEFAULT_RETURN(-1)
struct arm_linux_process_info * next
static void arm_linux_store_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regno)
enum tribool have_ptrace_getregset
CORE_ADDR gdbarch_addr_bits_remove(struct gdbarch *gdbarch, CORE_ADDR addr)
void fill_fpregset(const struct regcache *regcache, gdb_fpregset_t *fpregsetp, int regno)
arm_hwbp_control_t control
int(* to_watchpoint_addr_within_range)(struct target_ops *, CORE_ADDR, CORE_ADDR, int) TARGET_DEFAULT_FUNC(default_watchpoint_addr_within_range)
GDB_GREGSET_T gdb_gregset_t
static void arm_linux_fetch_inferior_registers(struct target_ops *ops, struct regcache *regcache, int regno)
static const struct target_desc * arm_linux_read_description(struct target_ops *ops)
void arm_linux_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs_buf, size_t len)
static void fetch_register(struct regcache *regcache, int regno)
int(* to_remove_watchpoint)(struct target_ops *, CORE_ADDR, int, int, struct expression *) TARGET_DEFAULT_RETURN(-1)
char bpts_changed[MAX_BPTS]
int target_auxv_search(struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
GDB_FPREGSET_T gdb_fpregset_t
ptid_t pid_to_ptid(int pid)
void linux_nat_set_prepare_to_resume(struct target_ops *t, void(*prepare_to_resume)(struct lwp_info *))
void supply_fpregset(struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
static void arm_linux_insert_hw_breakpoint1(const struct arm_linux_hw_breakpoint *bpt, int watchpoint)
static arm_hwbp_control_t arm_hwbp_control_initialize(unsigned byte_address_select, arm_hwbp_type hwbp_type, int enable)
static int arm_linux_can_use_hw_breakpoint(struct target_ops *self, int type, int cnt, int ot)
void linux_nat_add_target(struct target_ops *t)
static int arm_linux_region_ok_for_hw_watchpoint(struct target_ops *self, CORE_ADDR addr, int len)
struct target_ops * linux_target(void)
int arm_pc_is_thumb(struct gdbarch *gdbarch, CORE_ADDR memaddr)
int(* to_insert_hw_breakpoint)(struct target_ops *, struct gdbarch *, struct bp_target_info *) TARGET_DEFAULT_RETURN(-1)
static int arm_linux_insert_hw_breakpoint(struct target_ops *self, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
static struct arm_linux_process_info * arm_linux_process_info_get(pid_t pid)
static int arm_linux_remove_hw_breakpoint(struct target_ops *self, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
int ptid_get_pid(ptid_t ptid)
static void fetch_fpregs(struct regcache *regcache)
static int arm_linux_get_hw_breakpoint_count(void)
int(* to_remove_hw_breakpoint)(struct target_ops *, struct gdbarch *, struct bp_target_info *) TARGET_DEFAULT_RETURN(-1)
const char const char int
static int arm_linux_hw_breakpoint_equal(const struct arm_linux_hw_breakpoint *p1, const struct arm_linux_hw_breakpoint *p2)
void arm_linux_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs_buf, size_t len)
static void store_vfp_regs(const struct regcache *regcache)
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
void arm_linux_collect_nwfpe(const struct regset *regset, const struct regcache *regcache, int regnum, void *regs_buf, size_t len)
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
#define PTRACE_SETWMMXREGS
static int arm_linux_watchpoint_addr_within_range(struct target_ops *target, CORE_ADDR addr, CORE_ADDR start, int length)
enum register_status regcache_register_status(const struct regcache *regcache, int regnum)
int(* to_can_use_hw_breakpoint)(struct target_ops *, int, int, int) TARGET_DEFAULT_RETURN(0)
static void fetch_fpregister(struct regcache *regcache, int regno)
struct arm_linux_debug_reg_state state
void supply_nwfpe_register(struct regcache *regcache, int regno, const gdb_byte *regs)
static int arm_linux_stopped_by_watchpoint(struct target_ops *ops)
ps_err_e ps_get_thread_area(const struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base)
static struct arm_linux_process_info * arm_linux_add_process(pid_t pid)
void _initialize_arm_linux_nat(void)
static void store_register(const struct regcache *regcache, int regno)
void fill_gregset(const struct regcache *regcache, gdb_gregset_t *gregsetp, int regno)
int(* to_stopped_by_watchpoint)(struct target_ops *) TARGET_DEFAULT_RETURN(0)
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
void supply_gregset(struct regcache *regcache, const gdb_gregset_t *gregsetp)
static void arm_linux_hw_watchpoint_initialize(CORE_ADDR addr, int len, int rw, struct arm_linux_hw_breakpoint *p)
long ptid_get_lwp(ptid_t ptid)
static struct arm_linux_process_info * arm_linux_process_list
static int arm_linux_remove_watchpoint(struct target_ops *self, CORE_ADDR addr, int len, int rw, struct expression *cond)
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
void linux_nat_set_forget_process(struct target_ops *t, linux_nat_forget_process_ftype *fn)
static int get_thread_id(ptid_t ptid)
#define GET_THREAD_ID(PTID)
int(* to_stopped_data_address)(struct target_ops *, CORE_ADDR *) TARGET_DEFAULT_RETURN(0)
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
struct lwp_info * iterate_over_lwps(ptid_t filter, iterate_over_lwps_ftype callback, void *data)
PTR xcalloc(size_t number, size_t size)
struct target_desc * tdesc_arm_with_vfpv3
static void arm_linux_remove_hw_breakpoint1(const struct arm_linux_hw_breakpoint *bpt, int watchpoint)
static int arm_linux_stopped_data_address(struct target_ops *target, CORE_ADDR *addr_p)
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int int rusage_t pid_t pid
#define ARM_LINUX_SIZEOF_NWFPE
struct target_ops * beneath
char wpts_changed[MAX_WPTS]
struct target_desc * tdesc_arm_with_neon
static void arm_linux_new_fork(struct lwp_info *parent, pid_t child_pid)
struct arm_linux_hw_breakpoint bpts[MAX_BPTS]
const ULONGEST const LONGEST len