aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ptrace.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-01-30 07:31:52 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:31:52 -0500
commit91e7b707a4776185f91f03bd052aa53af820094e (patch)
treeb354543c109f1ae290e3222d8a3708c0f93e4872 /arch/x86/kernel/ptrace.c
parent4c79a2d8e5b7e0a2f987ace9b6af9e7a1655447b (diff)
x86: x86 user_regset general regs
This adds accessor functions in the user_regset style for the general registers (struct user_regs_struct). Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r--arch/x86/kernel/ptrace.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 084805ab7323..ef349ff170a7 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -13,6 +13,7 @@
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/ptrace.h> 15#include <linux/ptrace.h>
16#include <linux/regset.h>
16#include <linux/user.h> 17#include <linux/user.h>
17#include <linux/security.h> 18#include <linux/security.h>
18#include <linux/audit.h> 19#include <linux/audit.h>
@@ -368,6 +369,59 @@ static unsigned long getreg(struct task_struct *task, unsigned long offset)
368 return *pt_regs_access(task_pt_regs(task), offset); 369 return *pt_regs_access(task_pt_regs(task), offset);
369} 370}
370 371
372static int genregs_get(struct task_struct *target,
373 const struct user_regset *regset,
374 unsigned int pos, unsigned int count,
375 void *kbuf, void __user *ubuf)
376{
377 if (kbuf) {
378 unsigned long *k = kbuf;
379 while (count > 0) {
380 *k++ = getreg(target, pos);
381 count -= sizeof(*k);
382 pos += sizeof(*k);
383 }
384 } else {
385 unsigned long __user *u = ubuf;
386 while (count > 0) {
387 if (__put_user(getreg(target, pos), u++))
388 return -EFAULT;
389 count -= sizeof(*u);
390 pos += sizeof(*u);
391 }
392 }
393
394 return 0;
395}
396
397static int genregs_set(struct task_struct *target,
398 const struct user_regset *regset,
399 unsigned int pos, unsigned int count,
400 const void *kbuf, const void __user *ubuf)
401{
402 int ret = 0;
403 if (kbuf) {
404 const unsigned long *k = kbuf;
405 while (count > 0 && !ret) {
406 ret = putreg(target, pos, *k++);
407 count -= sizeof(*k);
408 pos += sizeof(*k);
409 }
410 } else {
411 const unsigned long __user *u = ubuf;
412 while (count > 0 && !ret) {
413 unsigned long word;
414 ret = __get_user(word, u++);
415 if (ret)
416 break;
417 ret = putreg(target, pos, word);
418 count -= sizeof(*u);
419 pos += sizeof(*u);
420 }
421 }
422 return ret;
423}
424
371/* 425/*
372 * This function is trivial and will be inlined by the compiler. 426 * This function is trivial and will be inlined by the compiler.
373 * Having it separates the implementation details of debug 427 * Having it separates the implementation details of debug
@@ -1008,6 +1062,61 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
1008#undef R32 1062#undef R32
1009#undef SEG32 1063#undef SEG32
1010 1064
1065static int genregs32_get(struct task_struct *target,
1066 const struct user_regset *regset,
1067 unsigned int pos, unsigned int count,
1068 void *kbuf, void __user *ubuf)
1069{
1070 if (kbuf) {
1071 compat_ulong_t *k = kbuf;
1072 while (count > 0) {
1073 getreg32(target, pos, k++);
1074 count -= sizeof(*k);
1075 pos += sizeof(*k);
1076 }
1077 } else {
1078 compat_ulong_t __user *u = ubuf;
1079 while (count > 0) {
1080 compat_ulong_t word;
1081 getreg32(target, pos, &word);
1082 if (__put_user(word, u++))
1083 return -EFAULT;
1084 count -= sizeof(*u);
1085 pos += sizeof(*u);
1086 }
1087 }
1088
1089 return 0;
1090}
1091
1092static int genregs32_set(struct task_struct *target,
1093 const struct user_regset *regset,
1094 unsigned int pos, unsigned int count,
1095 const void *kbuf, const void __user *ubuf)
1096{
1097 int ret = 0;
1098 if (kbuf) {
1099 const compat_ulong_t *k = kbuf;
1100 while (count > 0 && !ret) {
1101 ret = putreg(target, pos, *k++);
1102 count -= sizeof(*k);
1103 pos += sizeof(*k);
1104 }
1105 } else {
1106 const compat_ulong_t __user *u = ubuf;
1107 while (count > 0 && !ret) {
1108 compat_ulong_t word;
1109 ret = __get_user(word, u++);
1110 if (ret)
1111 break;
1112 ret = putreg(target, pos, word);
1113 count -= sizeof(*u);
1114 pos += sizeof(*u);
1115 }
1116 }
1117 return ret;
1118}
1119
1011static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) 1120static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
1012{ 1121{
1013 siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t)); 1122 siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t));