diff --git a/configure.in b/configure.in index e5d4ac28..dec0fea3 100644 --- a/configure.in +++ b/configure.in @@ -73,6 +73,13 @@ AC_CHECK_DECLS(PT_IO, [], [], #endif #include ]) +AC_CHECK_DECLS(PT_GETREGS, [], [], +[$ac_includes_default +#if HAVE_SYS_TYPES_H +#include +#endif +#include +]) AC_CHECK_DECLS(PT_GETFPREGS, [], [], [$ac_includes_default #if HAVE_SYS_TYPES_H diff --git a/src/ptrace/_UPT_access_reg.c b/src/ptrace/_UPT_access_reg.c index 60e006b9..a85b900f 100644 --- a/src/ptrace/_UPT_access_reg.c +++ b/src/ptrace/_UPT_access_reg.c @@ -33,6 +33,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # include "tdep-ia64/rse.h" #endif +#if 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) @@ -252,3 +253,40 @@ _UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, Debug (1, "bad register number %u (error: %s)\n", reg, strerror (errno)); return -UNW_EBADREG; } +#elif HAVE_DECL_PT_GETREGS +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; + char *r; + +#if UNW_DEBUG + if (write) + Debug (16, "%s <- %lx\n", unw_regname (reg), (long) *val); +#endif + if ((unsigned) reg >= sizeof (_UPT_reg_offset) / sizeof (_UPT_reg_offset[0])) + { + errno = EINVAL; + goto badreg; + } + r = (char *)®s + _UPT_reg_offset[reg]; + if (ptrace(PT_GETREGS, pid, (caddr_t)®s, 0) == -1) + goto badreg; + if (write) { + memcpy(r, val, sizeof(unw_word_t)); + if (ptrace(PT_SETREGS, pid, (caddr_t)®s, 0) == -1) + goto badreg; + } else + memcpy(val, r, sizeof(unw_word_t)); + return 0; + + badreg: + Debug (1, "bad register number %u (error: %s)\n", reg, strerror (errno)); + return -UNW_EBADREG; +} +#else +#error Port me +#endif diff --git a/src/ptrace/_UPT_reg_offset.c b/src/ptrace/_UPT_reg_offset.c index f586fb72..83dbcc31 100644 --- a/src/ptrace/_UPT_reg_offset.c +++ b/src/ptrace/_UPT_reg_offset.c @@ -25,6 +25,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UPT_internal.h" +#include + #ifdef HAVE_ASM_PTRACE_OFFSETS_H # include #endif @@ -265,6 +267,31 @@ int _UPT_reg_offset[UNW_REG_LAST + 1] = /* EFLAGS = 0x38, */ /* SS = 0x40 */ #elif defined(UNW_TARGET_X86_64) +#if defined(__FreeBSD__) +#define UNW_R_OFF(R, r) \ + [UNW_X86_64_##R] = offsetof(gregset_t, r_##r), + UNW_R_OFF(RAX, rax) + UNW_R_OFF(RDX, rdx) + UNW_R_OFF(RCX, rcx) + UNW_R_OFF(RBX, rbx) + UNW_R_OFF(RSI, rsi) + UNW_R_OFF(RDI, rdi) + UNW_R_OFF(RBP, rbp) + UNW_R_OFF(RSP, rsp) + UNW_R_OFF(R8, r8) + UNW_R_OFF(R9, r9) + UNW_R_OFF(R10, r10) + UNW_R_OFF(R11, r11) + UNW_R_OFF(R12, r12) + UNW_R_OFF(R13, r13) + UNW_R_OFF(R14, r14) + UNW_R_OFF(R15, r15) + UNW_R_OFF(RIP, rip) +// UNW_R_OFF(CS, cs) +// UNW_R_OFF(EFLAGS, rflags) +// UNW_R_OFF(SS, ss) +#undef UNW_R_OFF +#else [UNW_X86_64_RAX] = 0x50, [UNW_X86_64_RDX] = 0x60, [UNW_X86_64_RCX] = 0x58, @@ -286,6 +313,7 @@ int _UPT_reg_offset[UNW_REG_LAST + 1] = // [UNW_X86_64_EFLAGS] = 0x90, // [UNW_X86_64_RSP] = 0x98, // [UNW_X86_64_SS] = 0xa0 +#endif #elif defined(UNW_TARGET_PPC32) #elif defined(UNW_TARGET_PPC64) #elif defined(UNW_TARGET_ARM)