Fix TOC pointer value on ffi callback handling

This commit is contained in:
Gustavo Serra Scalet 2017-08-30 11:03:20 -03:00
parent 6d4d7f3ec1
commit 36237e70e1
2 changed files with 12 additions and 9 deletions

View File

@ -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;

View File

@ -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