File 0013-Fix-TOC-pointer-value-on-ffi-callback-handling.patch of Package lua51-luajit

From f286f26af6368947ad975753de77a4f8c7d105e0 Mon Sep 17 00:00:00 2001
From: Gustavo Serra Scalet <gustavo.scalet@eldorado.org.br>
Date: Wed, 30 Aug 2017 11:03:20 -0300
Subject: [PATCH 13/15] Fix TOC pointer value on ffi callback handling

---
 src/lj_ccallback.c | 18 ++++++++++--------
 src/vm_ppc64.dasc  |  3 ++-
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c
index e44d077d4345..edb8736539d8 100644
--- a/src/lj_ccallback.c
+++ b/src/lj_ccallback.c
@@ -198,21 +198,23 @@ static void callback_mcode_init(global_State *g, uint32_t *page)
   void *target = (void *)lj_vm_ffi_callback;
   MSize slot;
 #if LJ_ARCH_PPC64
-  *p++ = PPCI_LI | PPCF_T(RID_TMP) | ((((intptr_t)target) >> 32) & 0xffff);
-  *p++ = PPCI_LI | PPCF_T(RID_R12) | ((((intptr_t)g) >> 32) & 0xffff);
-  *p++ = PPCI_RLDICR | PPCF_T(RID_TMP) | PPCF_A(RID_TMP) | PPCF_SH(32) | PPCF_M6(63-32);  /* sldi */
+  // Store on R0 the global state and point R12 to the function so TOC is calculated correctly.
+  *p++ = PPCI_LI | PPCF_T(RID_R12) | ((((intptr_t)target) >> 32) & 0xffff);
+  *p++ = PPCI_LI | PPCF_T(RID_TMP) | ((((intptr_t)g) >> 32) & 0xffff);
   *p++ = PPCI_RLDICR | PPCF_T(RID_R12) | PPCF_A(RID_R12) | PPCF_SH(32) | PPCF_M6(63-32);  /* sldi */
-  *p++ = PPCI_ORIS | PPCF_A(RID_TMP) | PPCF_T(RID_TMP) | ((((intptr_t)target) >> 16) & 0xffff);
-  *p++ = PPCI_ORIS | PPCF_A(RID_R12) | PPCF_T(RID_R12) | ((((intptr_t)g) >> 16) & 0xffff);
-  *p++ = PPCI_ORI | PPCF_A(RID_TMP) | PPCF_T(RID_TMP) | (((intptr_t)target) & 0xffff);
-  *p++ = PPCI_ORI | PPCF_A(RID_R12) | PPCF_T(RID_R12) | (((intptr_t)g) & 0xffff);
+  *p++ = PPCI_RLDICR | PPCF_T(RID_TMP) | PPCF_A(RID_TMP) | PPCF_SH(32) | PPCF_M6(63-32);  /* sldi */
+  *p++ = PPCI_ORIS | PPCF_A(RID_R12) | PPCF_T(RID_R12) | ((((intptr_t)target) >> 16) & 0xffff);
+  *p++ = PPCI_ORIS | PPCF_A(RID_TMP) | PPCF_T(RID_TMP) | ((((intptr_t)g) >> 16) & 0xffff);
+  *p++ = PPCI_ORI | PPCF_A(RID_R12) | PPCF_T(RID_R12) | (((intptr_t)target) & 0xffff);
+  *p++ = PPCI_ORI | PPCF_A(RID_TMP) | PPCF_T(RID_TMP) | (((intptr_t)g) & 0xffff);
+  *p++ = PPCI_MTCTR | PPCF_T(RID_R12);
 #else  /* PPC 32bits */
   *p++ = PPCI_LIS | PPCF_T(RID_TMP) | (u32ptr(target) >> 16);
   *p++ = PPCI_LIS | PPCF_T(RID_R12) | (u32ptr(g) >> 16);
   *p++ = PPCI_ORI | PPCF_A(RID_TMP)|PPCF_T(RID_TMP) | (u32ptr(target) & 0xffff);
   *p++ = PPCI_ORI | PPCF_A(RID_R12)|PPCF_T(RID_R12) | (u32ptr(g) & 0xffff);
-#endif
   *p++ = PPCI_MTCTR | PPCF_T(RID_TMP);
+#endif
   *p++ = PPCI_BCTR;
   for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
     *p++ = PPCI_LI | PPCF_T(RID_R11) | slot;
diff --git a/src/vm_ppc64.dasc b/src/vm_ppc64.dasc
index 5d15d01ac820..cd38d544b673 100644
--- a/src/vm_ppc64.dasc
+++ b/src/vm_ppc64.dasc
@@ -2286,11 +2286,12 @@ static void build_subroutines(BuildCtx *ctx)
   |//-- FFI helper functions -----------------------------------------------
   |//-----------------------------------------------------------------------
   |
-  |// Handler for callback functions. Callback slot number in r11, g in r12.
+  |// Handler for callback functions. Callback slot number in r11, g in r0.
   |->vm_ffi_callback:
   |.if FFI
   |.type CTSTATE, CTState, PC
   |  pic_code_setup vm_ffi_callback
+  |  mr r12, r0 // Use r12 as saveregs overwrites r0
   |  saveregs
   |  ld CTSTATE, GL:r12->ctype_state
   |   addi DISPATCH, r12, GG_G2DISP
-- 
2.20.1