+
+/*
+ * This should match arch/i386/kernel/ptrace.c:native_regsets.
+ * XXX ioperm? vm86?
+ */
+static const struct utrace_regset ia32_regsets[] = {
+ {
+ .n = sizeof(struct user_regs_struct32)/4,
+ .size = 4, .align = 4,
+ .get = ia32_genregs_get, .set = ia32_genregs_set
+ },
+ {
+ .n = sizeof(struct user_i387_ia32_struct) / 4,
+ .size = 4, .align = 4,
+ .active = ia32_fpregs_active,
+ .get = ia32_fpregs_get, .set = ia32_fpregs_set
+ },
+ {
+ .n = sizeof(struct user32_fxsr_struct) / 4,
+ .size = 4, .align = 4,
+ .active = ia32_fpxregs_active,
+ .get = ia32_fpxregs_get, .set = ia32_fpxregs_set
+ },
+ {
+ .n = GDT_ENTRY_TLS_ENTRIES,
+ .bias = GDT_ENTRY_TLS_MIN,
+ .size = sizeof(struct user_desc),
+ .align = sizeof(struct user_desc),
+ .active = ia32_tls_active,
+ .get = ia32_tls_get, .set = ia32_tls_set
+ },
+ {
+ .n = 8, .size = 4, .align = 4,
+ .active = ia32_dbregs_active,
+ .get = ia32_dbregs_get, .set = ia32_dbregs_set
+ },
+};
+
+const struct utrace_regset_view utrace_ia32_view = {
+ .name = "i386", .e_machine = EM_386,
+ .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_ia32_view);
+
+
+#ifdef CONFIG_PTRACE
+/*
+ * This matches the arch/i386/kernel/ptrace.c definitions.
+ */
+
+static const struct ptrace_layout_segment ia32_uarea[] = {
+ {0, sizeof(struct user_regs_struct32), 0, 0},
+ {sizeof(struct user_regs_struct32),
+ offsetof(struct user32, u_debugreg[0]), -1, 0},
+ {offsetof(struct user32, u_debugreg[0]),
+ offsetof(struct user32, u_debugreg[8]), 4, 0},
+ {0, 0, -1, 0}
+};
+
+int arch_compat_ptrace(compat_long_t *req, struct task_struct *child,
+ struct utrace_attached_engine *engine,
+ compat_ulong_t addr, compat_ulong_t data,
+ compat_long_t *val)
+{
+ switch (*req) {
+ case PTRACE_PEEKUSR:
+ return ptrace_compat_peekusr(child, engine, ia32_uarea,
+ addr, data);
+ case PTRACE_POKEUSR:
+ return ptrace_compat_pokeusr(child, engine, ia32_uarea,
+ addr, data);
+ case PTRACE_GETREGS:
+ return ptrace_whole_regset(child, engine, data, 0, 0);
+ case PTRACE_SETREGS:
+ return ptrace_whole_regset(child, engine, data, 0, 1);
+ case PTRACE_GETFPREGS:
+ return ptrace_whole_regset(child, engine, data, 1, 0);
+ case PTRACE_SETFPREGS:
+ return ptrace_whole_regset(child, engine, data, 1, 1);
+ case PTRACE_GETFPXREGS:
+ return ptrace_whole_regset(child, engine, data, 2, 0);
+ case PTRACE_SETFPXREGS:
+ return ptrace_whole_regset(child, engine, data, 2, 1);
+ case PTRACE_GET_THREAD_AREA:
+ case PTRACE_SET_THREAD_AREA:
+ return ptrace_onereg_access(child, engine,
+ &utrace_ia32_view, 3,
+ addr,
+ (void __user *)(unsigned long)data,
+ *req == PTRACE_SET_THREAD_AREA);
+ }
+ return -ENOSYS;
+}
+#endif /* CONFIG_PTRACE */