AltiVec aware ptrace for Linux
Edwin Robert Tisdale
E.Robert.Tisdale at jpl.nasa.gov
Fri Sep 7 23:27:37 EST 2001
Paul Mackerras wrote:
> 1. Make a unified diff listing rather than the old-style diff.
>
> 2. Your diff is backwards, it shows your new stuff as being deleted.
> Do the diff as "diff -u old new".
>
> 3. Don't take out the "addr = addr >> 2;" lines.
> I know the comment says "temporary hack"
> but you don't want to believe everything you read. :)
> In fact, a lot of existing software relies on
> the argument to PTRACE_PEEK/POKEUSR
> being an offset into a notional structure rather than an index
> and your change would introduce a significant change
> to existing behaviour which would break applications.
> Note that >> 2 divides by 4, not 2
> as you seemed to think in a previous message.
>
> 4. Send the patch to me (paulus at samba.org, the PPC/Linux maintainer)
> and to the linuxppc-dev at lists.linuxppc.org list.
/usr/src/linux-2.2.19/arch/ppc/kernel$ diff -u ptrace.cold ptrace.c
--- ptrace.cold Sun Mar 25 08:31:49 2001
+++ ptrace.c Fri Sep 7 07:00:43 2001
@@ -415,19 +415,26 @@
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > (PT_FPSCR << 2))
+ if ((addr & 3))
goto out;
tmp = 0; /* Default return condition */
- addr = addr >> 2; /* temporary hack. */
- if (addr < PT_FPR0) {
+ addr >>= 2;
+ if (PT_R0 <= addr && addr <= PT_MQ) {
tmp = get_reg(child, addr);
}
- else if (addr >= PT_FPR0 && addr <= PT_FPSCR) {
+ else if (PT_FPR0 <= addr && addr <= PT_FPSCR) {
if (child->tss.regs->msr & MSR_FP)
giveup_fpu(child);
tmp = ((long *)child->tss.fpr)[addr - PT_FPR0];
}
+#ifdef CONFIG_ALTIVEC
+ else if (PT_VR0 <= addr && addr <= PT_VRSAVE) {
+ if (child->tss.regs->msr & MSR_VEC)
+ giveup_altivec(child);
+ tmp = ((long *)child->tss.vr)[addr - PT_VR0];
+ }
+#endif /* CONFIG_ALTIVEC */
else
goto out;
ret = put_user(tmp, (unsigned long *) data);
@@ -444,26 +451,29 @@
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr >= ((PT_FPR0 + 64) << 2))
+ if ((addr & 3) || PT_ORIG_R3 == addr)
goto out;
- addr = addr >> 2; /* temporary hack. */
-
- if (addr == PT_ORIG_R3)
- goto out;
- if (addr < PT_FPR0) {
+ addr >>= 2;
+ if (PT_FPR0 <= addr && addr <= PT_FPSCR) {
if (put_reg(child, addr, data))
goto out;
ret = 0;
- goto out;
}
- if (addr >= PT_FPR0 && addr < PT_FPR0 + 64) {
+ else if (PT_FPR0 <= addr && addr <= PT_FPSRC) {
if (child->tss.regs->msr & MSR_FP)
giveup_fpu(child);
((long *)child->tss.fpr)[addr - PT_FPR0] = data; ret = 0;
- goto out;
}
+#ifdef CONFIG_ALTIVEC
+ else if (PT_VR0 <= addr && addr <= PT_VRSAVE) {
+ if (child->tss.regs->msr & MSR_VEC)
+ giveup_altivec(child);
+ ((long *)child->tss.vr)[addr - PT_VR0] = data;
+ ret = 0;
+ }
+#endif /* CONFIG_ALTIVEC */
goto out;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
/usr/src/linux-2.2.19/include/asm$ diff -u ptrace.hold ptrace.h
--- ptrace.hold Sun Mar 25 08:31:08 2001
+++ ptrace.h Thu Sep 6 17:13:12 2001
@@ -97,5 +97,12 @@
#define PT_FPR31 (PT_FPR0 + 2*31)
#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
+#ifdef CONFIG_ALTIVEC
+#define PT_VR0 128
+#define PT_VR31 (PT_VR0 + 4*31)
+#define PT_VRCR (PT_VR0 + 4*32)
+#define PT_VRSAVE (PT_VR0 + 4*33 + 1)
+#endif /* CONFIG_ALTIVEC */
+
#endif
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list