67 lines
2.2 KiB
Diff
67 lines
2.2 KiB
Diff
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
|
Date: Mon, 26 Sep 2011 19:37:57 +0000
|
|
Subject: [PATCH] powerpc/ptrace: Fix build with gcc 4.6
|
|
|
|
commit e69b742a6793dc5bf16f6eedca534d4bc10d68b2 upstream.
|
|
|
|
gcc (rightfully) complains that we are accessing beyond the
|
|
end of the fpr array (we do, to access the fpscr).
|
|
|
|
The only sane thing to do (whether anything in that code can be
|
|
called remotely sane is debatable) is to special case fpscr and
|
|
handle it as a separate statement.
|
|
|
|
I initially tried to do it it by making the array access conditional
|
|
to index < PT_FPSCR and using a 3rd else leg but for some reason gcc
|
|
was unable to understand it and still spewed the warning.
|
|
|
|
So I ended up with something a tad more intricated but it seems to
|
|
build on 32-bit and on 64-bit with and without VSX.
|
|
|
|
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
|
---
|
|
arch/powerpc/kernel/ptrace.c | 18 ++++++++++++++----
|
|
1 files changed, 14 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
|
|
index 05b7dd2..18447c4 100644
|
|
--- a/arch/powerpc/kernel/ptrace.c
|
|
+++ b/arch/powerpc/kernel/ptrace.c
|
|
@@ -1497,9 +1497,14 @@ long arch_ptrace(struct task_struct *child, long request,
|
|
if (index < PT_FPR0) {
|
|
tmp = ptrace_get_reg(child, (int) index);
|
|
} else {
|
|
+ unsigned int fpidx = index - PT_FPR0;
|
|
+
|
|
flush_fp_to_thread(child);
|
|
- tmp = ((unsigned long *)child->thread.fpr)
|
|
- [TS_FPRWIDTH * (index - PT_FPR0)];
|
|
+ if (fpidx < (PT_FPSCR - PT_FPR0))
|
|
+ tmp = ((unsigned long *)child->thread.fpr)
|
|
+ [fpidx * TS_FPRWIDTH];
|
|
+ else
|
|
+ tmp = child->thread.fpscr.val;
|
|
}
|
|
ret = put_user(tmp, datalp);
|
|
break;
|
|
@@ -1525,9 +1530,14 @@ long arch_ptrace(struct task_struct *child, long request,
|
|
if (index < PT_FPR0) {
|
|
ret = ptrace_put_reg(child, index, data);
|
|
} else {
|
|
+ unsigned int fpidx = index - PT_FPR0;
|
|
+
|
|
flush_fp_to_thread(child);
|
|
- ((unsigned long *)child->thread.fpr)
|
|
- [TS_FPRWIDTH * (index - PT_FPR0)] = data;
|
|
+ if (fpidx < (PT_FPSCR - PT_FPR0))
|
|
+ ((unsigned long *)child->thread.fpr)
|
|
+ [fpidx * TS_FPRWIDTH] = data;
|
|
+ else
|
|
+ child->thread.fpscr.val = data;
|
|
ret = 0;
|
|
}
|
|
break;
|
|
--
|
|
1.7.7.2
|
|
|