+#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