PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP,
PTRACE_SYSCALL, PT_IO, PT_GETREGS,
PT_GETFPREGS, PT_CONTINUE, PT_TRACE_ME,
-PT_STEP, PT_SYSCALL], [], [],
+PT_STEP, PT_SYSCALL, PTRACE_GETREGSET], [], [],
[$ac_includes_default
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
+#define _UPT_get_fpreg(fpreg, reg) &fpreg.vregs[reg]
extern int unw_tdep_is_fpreg (int);
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int);
+#define _UPT_get_fpreg(fpreg, reg) &fpreg.fpregs[reg]
#if defined(__cplusplus) || defined(c_plusplus)
}
typedef ucontext_t unw_tdep_context_t;
#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 32)
+#define _UPT_get_fpreg(fpreg, reg) &fpreg.fp_dregs[reg]
#include "libunwind-dynamic.h"
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int);
+#define _UPT_get_fpreg(fpreg, reg) &fpreg->_st[reg]
#if defined(__cplusplus) || defined(c_plusplus)
}
#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext)
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
+#define _UPT_get_fpreg(fpreg, reg) &fpreg->_st[reg]
extern int unw_tdep_getcontext (unw_tdep_context_t *);
extern int unw_tdep_is_fpreg (int);
#include "_UPT_internal.h"
-#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
+/* Architecture specific ptrace helper must be implemented,
+ * else we fall back to the old - and deprecated - ABI implementation
+ */
+#if HAVE_DECL_PTRACE_GETREGSET && defined(_UPT_get_fpreg)
+int
+_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
+ int write, void *arg)
+{
+ struct UPT_info *ui = arg;
+ pid_t pid = ui->pid;
+ struct iovec iovec = { 0 };
+ fpregset_t fpreg = { 0 };
+
+ if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset))
+ return -UNW_EBADREG;
+
+ iovec.iov_base = &fpreg;
+ iovec.iov_len = sizeof(fpreg);
+
+ if (ptrace(PTRACE_GETREGSET, pid, NT_FPREGSET, &iovec) == -1)
+ return -UNW_EBADREG;
+
+ if (write)
+ {
+ memcpy(_UPT_get_fpreg(fpreg, reg), val, sizeof(unw_fpreg_t));
+
+ if (ptrace(PTRACE_SETREGSET, pid, NT_FPREGSET, &iovec) == -1)
+ return -UNW_EBADREG;
+ } else
+ memcpy(val, _UPT_get_fpreg(fpreg, reg), sizeof(unw_fpreg_t));
+
+ return 0;
+}
+#elif HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
int
_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg)
# include "tdep-ia64/rse.h"
#endif
-#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
+#if HAVE_DECL_PTRACE_GETREGSET
+int
+_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
+ int write, void *arg)
+{
+ struct UPT_info *ui = arg;
+ pid_t pid = ui->pid;
+ gregset_t regs = { 0 };
+ struct iovec iovec = { 0 };
+ char *r;
+
+ iovec.iov_base = ®s;
+ iovec.iov_len = sizeof(regs);
+
+ Debug(16, "using getregset: reg: %s [%u], val: %lx, write: %u\n",
+ unw_regname(reg), (unsigned int)reg, (unsigned long)*val, write);
+
+ if (write)
+ Debug(16, "%s [%u] <- %lx\n",
+ unw_regname (reg), (unsigned int)reg, (unsigned long)*val);
+
+ if ((unsigned int)reg >= ARRAY_SIZE (_UPT_reg_offset))
+ {
+ errno = EINVAL;
+ goto badreg;
+ }
+
+ r = (char *)®s + _UPT_reg_offset[reg];
+ if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iovec) == -1)
+ goto badreg;
+
+ if (write) {
+ memcpy(r, val, sizeof(unw_word_t));
+ if (ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iovec) == -1)
+ goto badreg;
+ } else
+ memcpy(val, r, sizeof(unw_word_t));
+
+ return 0;
+
+badreg:
+ Debug(1, "bad register %s [%u] (error: %s)\n",
+ unw_regname(reg), reg, strerror (errno));
+ return -UNW_EBADREG;
+}
+#elif HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
int
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
int write, void *arg)