From 8c69c81393b7b207092178ef7a08d6ec934eed15 Mon Sep 17 00:00:00 2001 From: Jean-Samuel Reynaud Date: Mon, 11 Feb 2019 16:33:28 +0100 Subject: [PATCH] Adding support for PPC32 and PPC64. Modification proposed by Gianluca Renzi. --- common/system/libcontext.cpp | 441 +++++++++++++++++++++++++++++++++++ include/system/libcontext.h | 9 + 2 files changed, 450 insertions(+) diff --git a/common/system/libcontext.cpp b/common/system/libcontext.cpp index 84f97c0f95..17f656e7af 100644 --- a/common/system/libcontext.cpp +++ b/common/system/libcontext.cpp @@ -827,3 +827,444 @@ __asm ( #endif +#if defined(LIBCONTEXT_PLATFORM_linux_ppc32) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".text\n" +".globl jump_fcontext\n" +".align 2\n" +".type jump_fcontext,@function\n" +"jump_fcontext:\n" +" # reserve space on stack\n" +" subi %r1, %r1, 240\n" +" stw %r13, 152(%r1) # save R13\n" +" stw %r14, 156(%r1) # save R14\n" +" stw %r15, 160(%r1) # save R15\n" +" stw %r16, 164(%r1) # save R16\n" +" stw %r17, 168(%r1) # save R17\n" +" stw %r18, 172(%r1) # save R18\n" +" stw %r19, 176(%r1) # save R19\n" +" stw %r20, 180(%r1) # save R20\n" +" stw %r21, 184(%r1) # save R21\n" +" stw %r22, 188(%r1) # save R22\n" +" stw %r23, 192(%r1) # save R23\n" +" stw %r24, 196(%r1) # save R24\n" +" stw %r25, 200(%r1) # save R25\n" +" stw %r26, 204(%r1) # save R26\n" +" stw %r27, 208(%r1) # save R27\n" +" stw %r28, 212(%r1) # save R28\n" +" stw %r29, 216(%r1) # save R29\n" +" stw %r30, 220(%r1) # save R30\n" +" stw %r31, 224(%r1) # save R31\n" +" # save CR\n" +" mfcr %r0\n" +" stw %r0, 228(%r1)\n" +" # save LR\n" +" mflr %r0\n" +" stw %r0, 232(%r1)\n" +" # save LR as PC\n" +" stw %r0, 236(%r1)\n" +" # test if fpu env should be preserved\n" +" cmpwi cr7, %r6, 0\n" +" beq cr7, 1f\n" +" stfd %f14, 0(%r1) # save F14\n" +" stfd %f15, 8(%r1) # save F15\n" +" stfd %f16, 16(%r1) # save F16\n" +" stfd %f17, 24(%r1) # save F17\n" +" stfd %f18, 32(%r1) # save F18\n" +" stfd %f19, 40(%r1) # save F19\n" +" stfd %f20, 48(%r1) # save F20\n" +" stfd %f21, 56(%r1) # save F21\n" +" stfd %f22, 64(%r1) # save F22\n" +" stfd %f23, 72(%r1) # save F23\n" +" stfd %f24, 80(%r1) # save F24\n" +" stfd %f25, 88(%r1) # save F25\n" +" stfd %f26, 96(%r1) # save F26\n" +" stfd %f27, 104(%r1) # save F27\n" +" stfd %f28, 112(%r1) # save F28\n" +" stfd %f29, 120(%r1) # save F29\n" +" stfd %f30, 128(%r1) # save F30\n" +" stfd %f31, 136(%r1) # save F31\n" +" mffs %f0 # load FPSCR\n" +" stfd %f0, 144(%r1) # save FPSCR\n" +"1:\n" +" # store RSP (pointing to context-data) in R3\n" +" stw %r1, 0(%r3)\n" +" # restore RSP (pointing to context-data) from R4\n" +" mr %r1, %r4\n" +" # test if fpu env should be preserved\n" +" cmpwi cr7, %r6, 0\n" +" beq cr7, 2f\n" +" lfd %f14, 0(%r1) # restore F14\n" +" lfd %f15, 8(%r1) # restore F15\n" +" lfd %f16, 16(%r1) # restore F16\n" +" lfd %f17, 24(%r1) # restore F17\n" +" lfd %f18, 32(%r1) # restore F18\n" +" lfd %f19, 40(%r1) # restore F19\n" +" lfd %f20, 48(%r1) # restore F20\n" +" lfd %f21, 56(%r1) # restore F21\n" +" lfd %f22, 64(%r1) # restore F22\n" +" lfd %f23, 72(%r1) # restore F23\n" +" lfd %f24, 80(%r1) # restore F24\n" +" lfd %f25, 88(%r1) # restore F25\n" +" lfd %f26, 96(%r1) # restore F26\n" +" lfd %f27, 104(%r1) # restore F27\n" +" lfd %f28, 112(%r1) # restore F28\n" +" lfd %f29, 120(%r1) # restore F29\n" +" lfd %f30, 128(%r1) # restore F30\n" +" lfd %f31, 136(%r1) # restore F31\n" +" lfd %f0, 144(%r1) # load FPSCR\n" +" mtfsf 0xff, %f0 # restore FPSCR\n" +"2:\n" +" lwz %r13, 152(%r1) # restore R13\n" +" lwz %r14, 156(%r1) # restore R14\n" +" lwz %r15, 160(%r1) # restore R15\n" +" lwz %r16, 164(%r1) # restore R16\n" +" lwz %r17, 168(%r1) # restore R17\n" +" lwz %r18, 172(%r1) # restore R18\n" +" lwz %r19, 176(%r1) # restore R19\n" +" lwz %r20, 180(%r1) # restore R20\n" +" lwz %r21, 184(%r1) # restore R21\n" +" lwz %r22, 188(%r1) # restore R22\n" +" lwz %r23, 192(%r1) # restore R23\n" +" lwz %r24, 196(%r1) # restore R24\n" +" lwz %r25, 200(%r1) # restore R25\n" +" lwz %r26, 204(%r1) # restore R26\n" +" lwz %r27, 208(%r1) # restore R27\n" +" lwz %r28, 212(%r1) # restore R28\n" +" lwz %r29, 216(%r1) # restore R29\n" +" lwz %r30, 220(%r1) # restore R30\n" +" lwz %r31, 224(%r1) # restore R31\n" +" # restore CR\n" +" lwz %r0, 228(%r1)\n" +" mtcr %r0\n" +" # restore LR\n" +" lwz %r0, 232(%r1)\n" +" mtlr %r0\n" +" # load PC\n" +" lwz %r0, 236(%r1)\n" +" # restore CTR\n" +" mtctr %r0\n" +" # adjust stack\n" +" addi %r1, %r1, 240\n" +" # use third arg as return value after jump\n" +" # use third arg as first arg in context function\n" +" mr %r3, %r5\n" +" # jump to context\n" +" bctr\n" +".size jump_fcontext, .-jump_fcontext\n" +".section .note.GNU-stack,\"\",%progbits\n" +); + +#endif + +#if defined(LIBCONTEXT_PLATFORM_linux_ppc32) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".text\n" +".globl make_fcontext\n" +".align 2\n" +".type make_fcontext,@function\n" +"make_fcontext:\n" +" # save return address into R6\n" +" mflr %r6\n" +" # first arg of make_fcontext() == top address of context-function\n" +" # shift address in R3 to lower 16 byte boundary\n" +" clrrwi %r3, %r3, 4\n" +" # reserve space for context-data on context-stack\n" +" # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n" +" subi %r3, %r3, 304\n" +" # third arg of make_fcontext() == address of context-function\n" +" stw %r5, 236(%r3)\n" +" # load LR\n" +" mflr %r0\n" +" # jump to label 1\n" +" bl 1f\n" +"1:\n" +" # load LR into R4\n" +" mflr %r4\n" +" # compute abs address of label finish\n" +" addi %r4, %r4, finish - 1b\n" +" # restore LR\n" +" mtlr %r0\n" +" # save address of finish as return-address for context-function\n" +" # will be entered after context-function returns\n" +" stw %r4, 232(%r3)\n" +" # restore return address from R6\n" +" mtlr %r6\n" +" blr # return pointer to context-data\n" +"finish:\n" +" # save return address into R0\n" +" mflr %r0\n" +" # save return address on stack, set up stack frame\n" +" stw %r0, 4(%r1)\n" +" # allocate stack space, R1 % 16 == 0\n" +" stwu %r1, -16(%r1)\n" +" # exit code is zero\n" +" li %r3, 0\n" +" # exit application\n" +" bl _exit@plt\n" +".size make_fcontext, .-make_fcontext\n" +".section .note.GNU-stack,\"\",%progbits\n" +); + +#endif + +#if defined(LIBCONTEXT_PLATFORM_linux_ppc64) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".globl jump_fcontext\n" +"#if _CALL_ELF == 2\n" +" .text\n" +" .align 2\n" +"jump_fcontext:\n" +" addis %r2, %r12, .TOC.-jump_fcontext@ha\n" +" addi %r2, %r2, .TOC.-jump_fcontext@l\n" +" .localentry jump_fcontext, . - jump_fcontext\n" +"#else\n" +" .section \".opd\",\"aw\"\n" +" .align 3\n" +"jump_fcontext:\n" +"# ifdef _CALL_LINUX\n" +" .quad .L.jump_fcontext,.TOC.@tocbase,0\n" +" .type jump_fcontext,@function\n" +" .text\n" +" .align 2\n" +".L.jump_fcontext:\n" +"# else\n" +" .hidden .jump_fcontext\n" +" .globl .jump_fcontext\n" +" .quad .jump_fcontext,.TOC.@tocbase,0\n" +" .size jump_fcontext,24\n" +" .type .jump_fcontext,@function\n" +" .text\n" +" .align 2\n" +".jump_fcontext:\n" +"# endif\n" +"#endif\n" +" # reserve space on stack\n" +" subi %r1, %r1, 328\n" +"#if _CALL_ELF != 2\n" +" std %r2, 152(%r1) # save TOC\n" +"#endif\n" +" std %r14, 160(%r1) # save R14\n" +" std %r15, 168(%r1) # save R15\n" +" std %r16, 176(%r1) # save R16\n" +" std %r17, 184(%r1) # save R17\n" +" std %r18, 192(%r1) # save R18\n" +" std %r19, 200(%r1) # save R19\n" +" std %r20, 208(%r1) # save R20\n" +" std %r21, 216(%r1) # save R21\n" +" std %r22, 224(%r1) # save R22\n" +" std %r23, 232(%r1) # save R23\n" +" std %r24, 240(%r1) # save R24\n" +" std %r25, 248(%r1) # save R25\n" +" std %r26, 256(%r1) # save R26\n" +" std %r27, 264(%r1) # save R27\n" +" std %r28, 272(%r1) # save R28\n" +" std %r29, 280(%r1) # save R29\n" +" std %r30, 288(%r1) # save R30\n" +" std %r31, 296(%r1) # save R31\n" +" # save CR\n" +" mfcr %r0\n" +" std %r0, 304(%r1)\n" +" # save LR\n" +" mflr %r0\n" +" std %r0, 312(%r1)\n" +" # save LR as PC\n" +" std %r0, 320(%r1)\n" +" # test if fpu env should be preserved\n" +" cmpwi cr7, %r6, 0\n" +" beq cr7, 1f\n" +" stfd %f14, 0(%r1) # save F14\n" +" stfd %f15, 8(%r1) # save F15\n" +" stfd %f16, 16(%r1) # save F16\n" +" stfd %f17, 24(%r1) # save F17\n" +" stfd %f18, 32(%r1) # save F18\n" +" stfd %f19, 40(%r1) # save F19\n" +" stfd %f20, 48(%r1) # save F20\n" +" stfd %f21, 56(%r1) # save F21\n" +" stfd %f22, 64(%r1) # save F22\n" +" stfd %f23, 72(%r1) # save F23\n" +" stfd %f24, 80(%r1) # save F24\n" +" stfd %f25, 88(%r1) # save F25\n" +" stfd %f26, 96(%r1) # save F26\n" +" stfd %f27, 104(%r1) # save F27\n" +" stfd %f28, 112(%r1) # save F28\n" +" stfd %f29, 120(%r1) # save F29\n" +" stfd %f30, 128(%r1) # save F30\n" +" stfd %f31, 136(%r1) # save F31\n" +" mffs %f0 # load FPSCR\n" +" stfd %f0, 144(%r1) # save FPSCR\n" +"1:\n" +" # store RSP (pointing to context-data) in R3\n" +" std %r1, 0(%r3)\n" +" # restore RSP (pointing to context-data) from R4\n" +" mr %r1, %r4\n" +" # test if fpu env should be preserved\n" +" cmpwi cr7, %r6, 0\n" +" beq cr7, 2f\n" +" lfd %f14, 0(%r1) # restore F14\n" +" lfd %f15, 8(%r1) # restore F15\n" +" lfd %f16, 16(%r1) # restore F16\n" +" lfd %f17, 24(%r1) # restore F17\n" +" lfd %f18, 32(%r1) # restore F18\n" +" lfd %f19, 40(%r1) # restore F19\n" +" lfd %f20, 48(%r1) # restore F20\n" +" lfd %f21, 56(%r1) # restore F21\n" +" lfd %f22, 64(%r1) # restore F22\n" +" lfd %f23, 72(%r1) # restore F23\n" +" lfd %f24, 80(%r1) # restore F24\n" +" lfd %f25, 88(%r1) # restore F25\n" +" lfd %f26, 96(%r1) # restore F26\n" +" lfd %f27, 104(%r1) # restore F27\n" +" lfd %f28, 112(%r1) # restore F28\n" +" lfd %f29, 120(%r1) # restore F29\n" +" lfd %f30, 128(%r1) # restore F30\n" +" lfd %f31, 136(%r1) # restore F31\n" +" lfd %f0, 144(%r1) # load FPSCR\n" +" mtfsf 0xff, %f0 # restore FPSCR\n" +"2:\n" +"#if _CALL_ELF != 2\n" +" ld %r2, 152(%r1) # restore TOC\n" +"#endif\n" +" ld %r14, 160(%r1) # restore R14\n" +" ld %r15, 168(%r1) # restore R15\n" +" ld %r16, 176(%r1) # restore R16\n" +" ld %r17, 184(%r1) # restore R17\n" +" ld %r18, 192(%r1) # restore R18\n" +" ld %r19, 200(%r1) # restore R19\n" +" ld %r20, 208(%r1) # restore R20\n" +" ld %r21, 216(%r1) # restore R21\n" +" ld %r22, 224(%r1) # restore R22\n" +" ld %r23, 232(%r1) # restore R23\n" +" ld %r24, 240(%r1) # restore R24\n" +" ld %r25, 248(%r1) # restore R25\n" +" ld %r26, 256(%r1) # restore R26\n" +" ld %r27, 264(%r1) # restore R27\n" +" ld %r28, 272(%r1) # restore R28\n" +" ld %r29, 280(%r1) # restore R29\n" +" ld %r30, 288(%r1) # restore R30\n" +" ld %r31, 296(%r1) # restore R31\n" +" # restore CR\n" +" ld %r0, 304(%r1)\n" +" mtcr %r0\n" +" # restore LR\n" +" ld %r0, 312(%r1)\n" +" mtlr %r0\n" +" # load PC\n" +" ld %r12, 320(%r1)\n" +" # restore CTR\n" +" mtctr %r12\n" +" # adjust stack\n" +" addi %r1, %r1, 328\n" +" # use third arg as return value after jump\n" +" # use third arg as first arg in context function\n" +" mr %r3, %r5\n" +" # jump to context\n" +" bctr\n" +"#if _CALL_ELF == 2\n" +" .size jump_fcontext, .-jump_fcontext\n" +"#else\n" +"# ifdef _CALL_LINUX\n" +" .size .jump_fcontext, .-.L.jump_fcontext\n" +"# else\n" +" .size .jump_fcontext, .-.jump_fcontext\n" +"# endif\n" +"#endif\n" +".section .note.GNU-stack,\"\",%progbits\n" +); + +#endif + +#if defined(LIBCONTEXT_PLATFORM_linux_ppc64) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".globl make_fcontext\n" +"#if _CALL_ELF == 2\n" +" .text\n" +" .align 2\n" +"make_fcontext:\n" +" addis %r2, %r12, .TOC.-make_fcontext@ha\n" +" addi %r2, %r2, .TOC.-make_fcontext@l\n" +" .localentry make_fcontext, . - make_fcontext\n" +"#else\n" +" .section \".opd\",\"aw\"\n" +" .align 3\n" +"make_fcontext:\n" +"# ifdef _CALL_LINUX\n" +" .quad .L.make_fcontext,.TOC.@tocbase,0\n" +" .type make_fcontext,@function\n" +" .text\n" +" .align 2\n" +".L.make_fcontext:\n" +"# else\n" +" .hidden .make_fcontext\n" +" .globl .make_fcontext\n" +" .quad .make_fcontext,.TOC.@tocbase,0\n" +" .size make_fcontext,24\n" +" .type .make_fcontext,@function\n" +" .text\n" +" .align 2\n" +".make_fcontext:\n" +"# endif\n" +"#endif\n" +" # save return address into R6\n" +" mflr %r6\n" +" # first arg of make_fcontext() == top address of context-stack\n" +" # shift address in R3 to lower 16 byte boundary\n" +" clrrdi %r3, %r3, 4\n" +" # reserve space for context-data on context-stack\n" +" # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n" +" subi %r3, %r3, 392\n" +" # third arg of make_fcontext() == address of context-function\n" +" # entry point (ELFv2) or descriptor (ELFv1)\n" +"#if _CALL_ELF == 2\n" +" # save address of context-function entry point\n" +" std %r5, 320(%r3)\n" +"#else\n" +" # save address of context-function entry point\n" +" ld %r4, 0(%r5)\n" +" std %r4, 320(%r3)\n" +" # save TOC of context-function\n" +" ld %r4, 8(%r5)\n" +" std %r4, 152(%r3)\n" +"#endif\n" +" # load LR\n" +" mflr %r0\n" +" # jump to label 1\n" +" bl 1f\n" +"1:\n" +" # load LR into R4\n" +" mflr %r4\n" +" # compute abs address of label finish\n" +" addi %r4, %r4, finish - 1b\n" +" # restore LR\n" +" mtlr %r0\n" +" # save address of finish as return-address for context-function\n" +" # will be entered after context-function returns\n" +" std %r4, 312(%r3)\n" +" # restore return address from R6\n" +" mtlr %r6\n" +" blr # return pointer to context-data\n" +"finish:\n" +" # save return address into R0\n" +" mflr %r0\n" +" # save return address on stack, set up stack frame\n" +" std %r0, 8(%r1)\n" +" # allocate stack space, R1 % 16 == 0\n" +" stdu %r1, -32(%r1)\n" +" # exit code is zero\n" +" li %r3, 0\n" +" # exit application\n" +" bl _exit\n" +" nop\n" +"#if _CALL_ELF == 2\n" +" .size make_fcontext, .-make_fcontext\n" +"#else\n" +"# ifdef _CALL_LINUX\n" +" .size .make_fcontext, .-.L.make_fcontext\n" +"# else\n" +" .size .make_fcontext, .-.make_fcontext\n" +"# endif\n" +"#endif\n" +".section .note.GNU-stack,\"\",%progbits\n" +); + +#endif diff --git a/include/system/libcontext.h b/include/system/libcontext.h index 3226353f5c..2cd0482838 100644 --- a/include/system/libcontext.h +++ b/include/system/libcontext.h @@ -42,6 +42,15 @@ #elif (__mips__ && _MIPS_SIM == _ABI64) #define LIBCONTEXT_PLATFORM_linux_mips_n64 #define LIBCONTEXT_CALL_CONVENTION + #elif __powerpc__ + #ifdef _ARCH_PPC64 + #define LIBCONTEXT_PLATFORM_linux_ppc64 + #define LIBCONTEXT_CALL_CONVENTION + #endif + #ifdef _ARCH_PPC + #define LIBCONTEXT_PLATFORM_linux_ppc32 + #define LIBCONTEXT_CALL_CONVENTION + #endif #endif #elif defined(__MINGW32__) || defined(__MINGW64__)