Browse Source

powerpc: modules: change r2 save/restore offset for ELFv2 ABI.

ELFv2 uses a different stack offset (24 vs 40) to save r2.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 11 years ago
parent
commit
d2fae54803
1 changed files with 15 additions and 8 deletions
  1. 15 8
      arch/powerpc/kernel/module_64.c

+ 15 - 8
arch/powerpc/kernel/module_64.c

@@ -41,6 +41,12 @@
 #define DEBUGP(fmt , ...)
 #define DEBUGP(fmt , ...)
 #endif
 #endif
 
 
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define R2_STACK_OFFSET 24
+#else
+#define R2_STACK_OFFSET 40
+#endif
+
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
    the kernel itself).  But on PPC64, these need to be used for every
    the kernel itself).  But on PPC64, these need to be used for every
    jump, actually, to reset r2 (TOC+0x8000). */
    jump, actually, to reset r2 (TOC+0x8000). */
@@ -61,14 +67,14 @@ struct ppc64_stub_entry
    r2) into the stub. */
    r2) into the stub. */
 static struct ppc64_stub_entry ppc64_stub =
 static struct ppc64_stub_entry ppc64_stub =
 { .jump = {
 { .jump = {
-	0x3d820000, /* addis   r12,r2, <high> */
-	0x398c0000, /* addi    r12,r12, <low> */
+	0x3d820000,			/* addis   r12,r2, <high> */
+	0x398c0000,			/* addi    r12,r12, <low> */
 	/* Save current r2 value in magic place on the stack. */
 	/* Save current r2 value in magic place on the stack. */
-	0xf8410028, /* std     r2,40(r1) */
-	0xe96c0020, /* ld      r11,32(r12) */
-	0xe84c0028, /* ld      r2,40(r12) */
-	0x7d6903a6, /* mtctr   r11 */
-	0x4e800420  /* bctr */
+	0xf8410000|R2_STACK_OFFSET,	/* std     r2,R2_STACK_OFFSET(r1) */
+	0xe96c0020,			/* ld      r11,32(r12) */
+	0xe84c0028,			/* ld      r2,40(r12) */
+	0x7d6903a6,			/* mtctr   r11 */
+	0x4e800420			/* bctr */
 } };
 } };
 
 
 /* Count how many different 24-bit relocations (different symbol,
 /* Count how many different 24-bit relocations (different symbol,
@@ -338,7 +344,8 @@ static int restore_r2(u32 *instruction, struct module *me)
 		       me->name, *instruction);
 		       me->name, *instruction);
 		return 0;
 		return 0;
 	}
 	}
-	*instruction = 0xe8410028;	/* ld r2,40(r1) */
+	/* ld r2,R2_STACK_OFFSET(r1) */
+	*instruction = 0xe8410000 | R2_STACK_OFFSET;
 	return 1;
 	return 1;
 }
 }