]> git.karo-electronics.de Git - linux-beck.git/commitdiff
powerpc: modules: skip r2 setup for ELFv2
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 18 Mar 2014 09:43:03 +0000 (20:13 +1030)
committerAnton Blanchard <anton@samba.org>
Wed, 23 Apr 2014 00:05:31 +0000 (10:05 +1000)
ELFv2 doesn't need to set up r2 when calling a function.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
arch/powerpc/kernel/module_64.c

index f8b6d28784efecd9d01f6c550835096390cf5f52..d7222495e24c68439e19e088eb59048d72ab9e46 100644 (file)
@@ -59,12 +59,19 @@ struct ppc64_stub_entry
        struct ppc64_opd_entry opd;
 };
 
-/* We use a stub to fix up r2 (TOC ptr) and to jump to the (external)
-   function which may be more than 24-bits away.  We could simply
-   patch the new r2 value and function pointer into the stub, but it's
-   significantly shorter to put these values at the end of the stub
-   code, and patch the stub address (32-bits relative to the TOC ptr,
-   r2) into the stub. */
+/*
+ * PPC64 uses 24 bit jumps, but we need to jump into other modules or
+ * the kernel which may be further.  So we jump to a stub.
+ *
+ * For ELFv1 we need to use this to set up the new r2 value (aka TOC
+ * pointer).  For ELFv2 it's the callee's responsibility to set up the
+ * new r2, but for both we need to save the old r2.
+ *
+ * We could simply patch the new r2 value and function pointer into
+ * the stub, but it's significantly shorter to put these values at the
+ * end of the stub code, and patch the stub address (32-bits relative
+ * to the TOC ptr, r2) into the stub.
+ */
 static struct ppc64_stub_entry ppc64_stub =
 { .jump = {
        0x3d620000,                     /* addis   r11,r2, <high> */
@@ -72,7 +79,10 @@ static struct ppc64_stub_entry ppc64_stub =
        /* Save current r2 value in magic place on the stack. */
        0xf8410000|R2_STACK_OFFSET,     /* std     r2,R2_STACK_OFFSET(r1) */
        0xe98b0020,                     /* ld      r12,32(r11) */
+#if !defined(_CALL_ELF) || _CALL_ELF != 2
+       /* Set up new r2 from function descriptor */
        0xe84b0026,                     /* ld      r2,40(r11) */
+#endif
        0x7d8903a6,                     /* mtctr   r12 */
        0x4e800420                      /* bctr */
 } };