===================================================================
@@ -190,43 +190,6 @@
// From linux-2.6.8.1/include/asm-i386/sigcontext.h
//----------------------------------------------------------------------
-struct _vki_fpreg {
- unsigned short significand[4];
- unsigned short exponent;
-};
-
-struct _vki_fpxreg {
- unsigned short significand[4];
- unsigned short exponent;
- unsigned short padding[3];
-};
-
-struct _vki_xmmreg {
- unsigned long element[4];
-};
-
-struct _vki_fpstate {
- /* Regular FPU environment */
- unsigned long cw;
- unsigned long sw;
- unsigned long tag;
- unsigned long ipoff;
- unsigned long cssel;
- unsigned long dataoff;
- unsigned long datasel;
- struct _vki_fpreg _st[8];
- unsigned short status;
- unsigned short magic; /* 0xffff = regular FPU data only */
-
- /* FXSR FPU environment */
- unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */
- unsigned long mxcsr;
- unsigned long reserved;
- struct _vki_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
- struct _vki_xmmreg _xmm[8];
- unsigned long padding[56];
-};
-
struct vki_sigcontext {
unsigned long trap_no;
unsigned long error_code;
@@ -546,33 +509,41 @@
// From linux-2.6.8.1/include/asm-i386/user.h
//----------------------------------------------------------------------
-struct vki_user_i387_struct {
- long cwd;
- long swd;
- long twd;
- long fip;
- long fcs;
- long foo;
- long fos;
- long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
+struct vki_user_fp {
+ struct vki_fp_reg {
+ unsigned int sign1:1;
+ unsigned int unused:15;
+ unsigned int sign2:1;
+ unsigned int exponent:14;
+ unsigned int j:1;
+ unsigned int mantissa1:31;
+ unsigned int mantissa0:32;
+ } fpregs[8];
+ unsigned int fpsr:32;
+ unsigned int fpcr:32;
+ unsigned char ftype[8];
+ unsigned int init_flag;
};
-struct vki_user_fxsr_struct {
- unsigned short cwd;
- unsigned short swd;
- unsigned short twd;
- unsigned short fop;
- long fip;
- long fcs;
- long foo;
- long fos;
- long mxcsr;
- long reserved;
- long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
- long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
- long padding[56];
+struct vki_user_vfp {
+ unsigned long long fpregs[32];
+ unsigned long fpscr;
};
+#define VKI_IWMMXT_SIZE 0x98
+
+struct vki_iwmmxt_struct {
+ unsigned int save[VKI_IWMMXT_SIZE / sizeof(unsigned int)];
+};
+
+struct vki_crunch_state {
+ unsigned int mvdx[16][2];
+ unsigned int mvax[4][3];
+ unsigned int dspsc[2];
+};
+
+#define VKI_CRUNCH_SIZE sizeof(struct vki_crunch_state)
+
struct vki_user_regs_struct {
long uregs[18];
};
@@ -603,8 +574,7 @@
#define VKI_ELF_NGREG (sizeof (struct vki_user_regs_struct) / sizeof(vki_elf_greg_t))
typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG];
-typedef struct vki_user_i387_struct vki_elf_fpregset_t;
-typedef struct vki_user_fxsr_struct vki_elf_fpxregset_t;
+typedef struct vki_user_fp vki_elf_fpregset_t;
#define VKI_AT_SYSINFO 32
@@ -799,8 +769,16 @@
#define VKI_PTRACE_SETREGS 13
#define VKI_PTRACE_GETFPREGS 14
#define VKI_PTRACE_SETFPREGS 15
-#define VKI_PTRACE_GETFPXREGS 18
-#define VKI_PTRACE_SETFPXREGS 19
+#define VKI_PTRACE_GETWMMXREGS 18
+#define VKI_PTRACE_SETWMMXREGS 19
+#define VKI_PTRACE_GET_THREAD_AREA 22
+#define VKI_PTRACE_SET_SYSCALL 23
+#define VKI_PTRACE_GETCRUNCHREGS 25
+#define VKI_PTRACE_SETCRUNCHREGS 26
+#define VKI_PTRACE_GETVFPREGS 27
+#define VKI_PTRACE_SETVFPREGS 28
+#define VKI_PTRACE_GETHBPREGS 29
+#define VKI_PTRACE_SETHBPREGS 30
//----------------------------------------------------------------------
// From linux-2.6.15.4/include/asm-i386/vm86.h
===================================================================
@@ -342,6 +342,7 @@
DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
DECL_TEMPLATE(arm_linux, sys_set_tls);
DECL_TEMPLATE(arm_linux, sys_cacheflush);
+DECL_TEMPLATE(arm_linux, sys_ptrace);
PRE(sys_socketcall)
{
@@ -1205,7 +1206,125 @@
SET_STATUS_Success(0);
}
+// ARG3 is only used for pointers into the traced process's address
+// space and for offsets into the traced process's struct
+// user_regs_struct. It is never a pointer into this process's memory
+// space, and we should therefore not check anything it points to.
+PRE(sys_ptrace)
+{
+ PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
+ PRE_REG_READ4(int, "ptrace",
+ long, request, long, pid, long, addr, long, data);
+ switch (ARG1) {
+ case VKI_PTRACE_PEEKTEXT:
+ case VKI_PTRACE_PEEKDATA:
+ case VKI_PTRACE_PEEKUSR:
+ PRE_MEM_WRITE( "ptrace(peek)", ARG4,
+ sizeof (long));
+ break;
+ case VKI_PTRACE_GETREGS:
+ PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
+ sizeof (struct vki_user_regs_struct));
+ break;
+ case VKI_PTRACE_GETFPREGS:
+ PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
+ sizeof (struct vki_user_fp));
+ break;
+ case VKI_PTRACE_GETWMMXREGS:
+ PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4,
+ VKI_IWMMXT_SIZE);
+ break;
+ case VKI_PTRACE_GETCRUNCHREGS:
+ PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4,
+ VKI_CRUNCH_SIZE);
+ break;
+ case VKI_PTRACE_GETVFPREGS:
+ PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4,
+ sizeof (struct vki_user_vfp) );
+ break;
+ case VKI_PTRACE_GETHBPREGS:
+ PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4,
+ sizeof (unsigned long) );
+ break;
+ case VKI_PTRACE_SETREGS:
+ PRE_MEM_READ( "ptrace(setregs)", ARG4,
+ sizeof (struct vki_user_regs_struct));
+ break;
+ case VKI_PTRACE_SETFPREGS:
+ PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
+ sizeof (struct vki_user_fp));
+ break;
+ case VKI_PTRACE_SETWMMXREGS:
+ PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4,
+ VKI_IWMMXT_SIZE);
+ break;
+ case VKI_PTRACE_SETCRUNCHREGS:
+ PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4,
+ VKI_CRUNCH_SIZE);
+ break;
+ case VKI_PTRACE_SETVFPREGS:
+ PRE_MEM_READ( "ptrace(setvfpregs)", ARG4,
+ sizeof (struct vki_user_vfp));
+ break;
+ case VKI_PTRACE_SETHBPREGS:
+ PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long));
+ break;
+ case VKI_PTRACE_GET_THREAD_AREA:
+ PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long));
+ break;
+ case VKI_PTRACE_GETEVENTMSG:
+ PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
+ break;
+ case VKI_PTRACE_GETSIGINFO:
+ PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
+ break;
+ case VKI_PTRACE_SETSIGINFO:
+ PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
+ break;
+ default:
+ break;
+ }
+}
+POST(sys_ptrace)
+{
+ switch (ARG1) {
+ case VKI_PTRACE_PEEKTEXT:
+ case VKI_PTRACE_PEEKDATA:
+ case VKI_PTRACE_PEEKUSR:
+ POST_MEM_WRITE( ARG4, sizeof (long));
+ break;
+ case VKI_PTRACE_GETREGS:
+ POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
+ break;
+ case VKI_PTRACE_GETFPREGS:
+ POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp));
+ break;
+ case VKI_PTRACE_GETWMMXREGS:
+ POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE);
+ break;
+ case VKI_PTRACE_GETCRUNCHREGS:
+ POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE);
+ break;
+ case VKI_PTRACE_GETVFPREGS:
+ POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp));
+ break;
+ case VKI_PTRACE_GET_THREAD_AREA:
+ case VKI_PTRACE_GETHBPREGS:
+ case VKI_PTRACE_GETEVENTMSG:
+ POST_MEM_WRITE( ARG4, sizeof(unsigned long));
+ break;
+ case VKI_PTRACE_GETSIGINFO:
+ /* XXX: This is a simplification. Different parts of the
+ * siginfo_t are valid depending on the type of signal.
+ */
+ POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
+ break;
+ default:
+ break;
+ }
+}
+
#undef PRE
#undef POST
@@ -1262,7 +1381,7 @@
LINX_(__NR_getuid, sys_getuid16), // 24 ## P
//zz
//zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
-// PLAXY(__NR_ptrace, sys_ptrace), // 26
+ PLAXY(__NR_ptrace, sys_ptrace), // 26
GENX_(__NR_alarm, sys_alarm), // 27
//zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
GENX_(__NR_pause, sys_pause), // 29