@@ -59,20 +59,30 @@ struct ppc64_stub_entry
59
59
struct ppc64_opd_entry opd ;
60
60
};
61
61
62
- /* We use a stub to fix up r2 (TOC ptr) and to jump to the (external)
63
- function which may be more than 24-bits away. We could simply
64
- patch the new r2 value and function pointer into the stub, but it's
65
- significantly shorter to put these values at the end of the stub
66
- code, and patch the stub address (32-bits relative to the TOC ptr,
67
- r2) into the stub. */
62
+ /*
63
+ * PPC64 uses 24 bit jumps, but we need to jump into other modules or
64
+ * the kernel which may be further. So we jump to a stub.
65
+ *
66
+ * For ELFv1 we need to use this to set up the new r2 value (aka TOC
67
+ * pointer). For ELFv2 it's the callee's responsibility to set up the
68
+ * new r2, but for both we need to save the old r2.
69
+ *
70
+ * We could simply patch the new r2 value and function pointer into
71
+ * the stub, but it's significantly shorter to put these values at the
72
+ * end of the stub code, and patch the stub address (32-bits relative
73
+ * to the TOC ptr, r2) into the stub.
74
+ */
68
75
static struct ppc64_stub_entry ppc64_stub =
69
76
{ .jump = {
70
77
0x3d620000 , /* addis r11,r2, <high> */
71
78
0x396b0000 , /* addi r11,r11, <low> */
72
79
/* Save current r2 value in magic place on the stack. */
73
80
0xf8410000 |R2_STACK_OFFSET , /* std r2,R2_STACK_OFFSET(r1) */
74
81
0xe98b0020 , /* ld r12,32(r11) */
82
+ #if !defined (_CALL_ELF ) || _CALL_ELF != 2
83
+ /* Set up new r2 from function descriptor */
75
84
0xe84b0026 , /* ld r2,40(r11) */
85
+ #endif
76
86
0x7d8903a6 , /* mtctr r12 */
77
87
0x4e800420 /* bctr */
78
88
} };
0 commit comments