extern void ML_(linux_PRE_sys_getsockopt) ( TId, UW, UW, UW, UW, UW );
extern void ML_(linux_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW );
+// Linux-specific (but non-arch-specific) ptrace wrapper helpers
+extern void ML_(linux_PRE_getregset) ( ThreadId, long, long );
+extern void ML_(linux_PRE_setregset) ( ThreadId, long, long );
+extern void ML_(linux_POST_getregset)( ThreadId, long, long );
+
#undef TId
#undef UW
#undef SR
}
}
+/* ---------------------------------------------------------------------
+ ptrace wrapper helpers
+ ------------------------------------------------------------------ */
+
+void
+ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
+{
+ struct vki_iovec *iov = (struct vki_iovec *) arg4;
+
+ PRE_MEM_READ("ptrace(getregset iovec->iov_base)",
+ (unsigned long) &iov->iov_base, sizeof(iov->iov_base));
+ PRE_MEM_READ("ptrace(getregset iovec->iov_len)",
+ (unsigned long) &iov->iov_len, sizeof(iov->iov_len));
+ PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
+ (unsigned long) iov->iov_base, iov->iov_len);
+}
+
+void
+ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
+{
+ struct vki_iovec *iov = (struct vki_iovec *) arg4;
+
+ PRE_MEM_READ("ptrace(setregset iovec->iov_base)",
+ (unsigned long) &iov->iov_base, sizeof(iov->iov_base));
+ PRE_MEM_READ("ptrace(setregset iovec->iov_len)",
+ (unsigned long) &iov->iov_len, sizeof(iov->iov_len));
+ PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
+ (unsigned long) iov->iov_base, iov->iov_len);
+}
+
+void
+ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
+{
+ struct vki_iovec *iov = (struct vki_iovec *) arg4;
+
+ /* XXX: The actual amount of data written by the kernel might be
+ less than iov_len, depending on the regset (arg3). */
+ POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
+}
+
#undef PRE
#undef POST
DECL_TEMPLATE(s390x_linux, sys_rt_sigreturn);
DECL_TEMPLATE(s390x_linux, sys_fadvise64);
-// PEEK TEXT,DATA and USER are common to all architectures
-// PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
-// containing the real addr, data, and len field pointed to by ARG3
-// instead of ARG4
+/* PEEK TEXT,DATA and USER are common to all architectures.
+ PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
+ containing the real addr, data, and len field pointed to by ARG3
+ instead of ARG4.
+ GETREGSET and SETREGSET use a struct iovec (pointed to by ARG4) for
+ the address and size of the user buffer. */
+
PRE(sys_ptrace)
{
PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
pa->vki_process_addr, pa->vki_len);
break;
}
+ case VKI_PTRACE_GETREGSET:
+ ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+ break;
+ case VKI_PTRACE_SETREGSET:
+ ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+ break;
default:
break;
}
pa = (vki_ptrace_area *) ARG3;
POST_MEM_WRITE(pa->vki_process_addr, pa->vki_len);
+ break;
}
+ case VKI_PTRACE_GETREGSET:
+ ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+ break;
default:
break;
}
#define VKI_PTRACE_GETEVENTMSG 0x4201
#define VKI_PTRACE_GETSIGINFO 0x4202
#define VKI_PTRACE_SETSIGINFO 0x4203
+#define VKI_PTRACE_GETREGSET 0x4204
+#define VKI_PTRACE_SETREGSET 0x4205
//----------------------------------------------------------------------
// From linux-2.6.14/include/sound/asound.h
non_empty(const char *buf, size_t len)
{
size_t i;
- int c;
+ int c = 0;
volatile const char *p = buf;
for (i = 0; i != len; i++)