Fix libcontext on PPC64 ELFv2

libcontext currently restores and saves the FPSCR register
on ppc64. This behavior is fine (though unnecessary) on the
ELFv1 ABI which designates the register as volatile, but has
been observed to cause crashes on ELFv2 systems.

The ELFv2 ABI designates the FPSCR register as Limited-access
and specifies specific conditions that must be met to clobber
it. It does not seem that a context swap function meets these
conditions (and indeed, the save/restore register example in the
ABI document does not modify FPSCR).

This patch fixes ELFv2 ABI compliance by removing the FPSCR
save/restore code in libcontext entirely. This fixes observed
crashes on the platform and should have no consequence for
ELFv1 support.

Fixes: lp:1840088
* https://bugs.launchpad.net/kicad/+bug/1840088
This commit is contained in:
Shawn Anastasio 2019-08-14 08:06:52 -05:00 committed by Seth Hillbrand
parent 6fb96891b1
commit 3e22b75948
1 changed files with 51 additions and 55 deletions

View File

@ -1042,36 +1042,36 @@ __asm (
# endif # endif
#endif #endif
" # reserve space on stack\n" " # reserve space on stack\n"
" subi %r1, %r1, 328\n" " subi %r1, %r1, 320\n"
#if _CALL_ELF != 2 #if _CALL_ELF != 2
" std %r2, 152(%r1) # save TOC\n" " std %r2, 144(%r1) # save TOC\n"
#endif #endif
" std %r14, 160(%r1) # save R14\n" " std %r14, 152(%r1) # save R14\n"
" std %r15, 168(%r1) # save R15\n" " std %r15, 160(%r1) # save R15\n"
" std %r16, 176(%r1) # save R16\n" " std %r16, 168(%r1) # save R16\n"
" std %r17, 184(%r1) # save R17\n" " std %r17, 176(%r1) # save R17\n"
" std %r18, 192(%r1) # save R18\n" " std %r18, 184(%r1) # save R18\n"
" std %r19, 200(%r1) # save R19\n" " std %r19, 192(%r1) # save R19\n"
" std %r20, 208(%r1) # save R20\n" " std %r20, 200(%r1) # save R20\n"
" std %r21, 216(%r1) # save R21\n" " std %r21, 208(%r1) # save R21\n"
" std %r22, 224(%r1) # save R22\n" " std %r22, 216(%r1) # save R22\n"
" std %r23, 232(%r1) # save R23\n" " std %r23, 224(%r1) # save R23\n"
" std %r24, 240(%r1) # save R24\n" " std %r24, 232(%r1) # save R24\n"
" std %r25, 248(%r1) # save R25\n" " std %r25, 240(%r1) # save R25\n"
" std %r26, 256(%r1) # save R26\n" " std %r26, 248(%r1) # save R26\n"
" std %r27, 264(%r1) # save R27\n" " std %r27, 256(%r1) # save R27\n"
" std %r28, 272(%r1) # save R28\n" " std %r28, 264(%r1) # save R28\n"
" std %r29, 280(%r1) # save R29\n" " std %r29, 272(%r1) # save R29\n"
" std %r30, 288(%r1) # save R30\n" " std %r30, 280(%r1) # save R30\n"
" std %r31, 296(%r1) # save R31\n" " std %r31, 288(%r1) # save R31\n"
" # save CR\n" " # save CR\n"
" mfcr %r0\n" " mfcr %r0\n"
" std %r0, 304(%r1)\n" " std %r0, 296(%r1)\n"
" # save LR\n" " # save LR\n"
" mflr %r0\n" " mflr %r0\n"
" std %r0, 312(%r1)\n" " std %r0, 304(%r1)\n"
" # save LR as PC\n" " # save LR as PC\n"
" std %r0, 320(%r1)\n" " std %r0, 312(%r1)\n"
" # test if fpu env should be preserved\n" " # test if fpu env should be preserved\n"
" cmpwi cr7, %r6, 0\n" " cmpwi cr7, %r6, 0\n"
" beq cr7, 1f\n" " beq cr7, 1f\n"
@ -1093,8 +1093,6 @@ __asm (
" stfd %f29, 120(%r1) # save F29\n" " stfd %f29, 120(%r1) # save F29\n"
" stfd %f30, 128(%r1) # save F30\n" " stfd %f30, 128(%r1) # save F30\n"
" stfd %f31, 136(%r1) # save F31\n" " stfd %f31, 136(%r1) # save F31\n"
" mffs %f0 # load FPSCR\n"
" stfd %f0, 144(%r1) # save FPSCR\n"
"1:\n" "1:\n"
" # store RSP (pointing to context-data) in R3\n" " # store RSP (pointing to context-data) in R3\n"
" std %r1, 0(%r3)\n" " std %r1, 0(%r3)\n"
@ -1121,42 +1119,40 @@ __asm (
" lfd %f29, 120(%r1) # restore F29\n" " lfd %f29, 120(%r1) # restore F29\n"
" lfd %f30, 128(%r1) # restore F30\n" " lfd %f30, 128(%r1) # restore F30\n"
" lfd %f31, 136(%r1) # restore F31\n" " lfd %f31, 136(%r1) # restore F31\n"
" lfd %f0, 144(%r1) # load FPSCR\n"
" mtfsf 0xff, %f0 # restore FPSCR\n"
"2:\n" "2:\n"
#if _CALL_ELF != 2 #if _CALL_ELF != 2
" ld %r2, 152(%r1) # restore TOC\n" " ld %r2, 144(%r1) # restore TOC\n"
#endif #endif
" ld %r14, 160(%r1) # restore R14\n" " ld %r14, 152(%r1) # restore R14\n"
" ld %r15, 168(%r1) # restore R15\n" " ld %r15, 160(%r1) # restore R15\n"
" ld %r16, 176(%r1) # restore R16\n" " ld %r16, 168(%r1) # restore R16\n"
" ld %r17, 184(%r1) # restore R17\n" " ld %r17, 176(%r1) # restore R17\n"
" ld %r18, 192(%r1) # restore R18\n" " ld %r18, 184(%r1) # restore R18\n"
" ld %r19, 200(%r1) # restore R19\n" " ld %r19, 192(%r1) # restore R19\n"
" ld %r20, 208(%r1) # restore R20\n" " ld %r20, 200(%r1) # restore R20\n"
" ld %r21, 216(%r1) # restore R21\n" " ld %r21, 208(%r1) # restore R21\n"
" ld %r22, 224(%r1) # restore R22\n" " ld %r22, 216(%r1) # restore R22\n"
" ld %r23, 232(%r1) # restore R23\n" " ld %r23, 224(%r1) # restore R23\n"
" ld %r24, 240(%r1) # restore R24\n" " ld %r24, 232(%r1) # restore R24\n"
" ld %r25, 248(%r1) # restore R25\n" " ld %r25, 240(%r1) # restore R25\n"
" ld %r26, 256(%r1) # restore R26\n" " ld %r26, 248(%r1) # restore R26\n"
" ld %r27, 264(%r1) # restore R27\n" " ld %r27, 256(%r1) # restore R27\n"
" ld %r28, 272(%r1) # restore R28\n" " ld %r28, 264(%r1) # restore R28\n"
" ld %r29, 280(%r1) # restore R29\n" " ld %r29, 272(%r1) # restore R29\n"
" ld %r30, 288(%r1) # restore R30\n" " ld %r30, 280(%r1) # restore R30\n"
" ld %r31, 296(%r1) # restore R31\n" " ld %r31, 288(%r1) # restore R31\n"
" # restore CR\n" " # restore CR\n"
" ld %r0, 304(%r1)\n" " ld %r0, 296(%r1)\n"
" mtcr %r0\n" " mtcr %r0\n"
" # restore LR\n" " # restore LR\n"
" ld %r0, 312(%r1)\n" " ld %r0, 304(%r1)\n"
" mtlr %r0\n" " mtlr %r0\n"
" # load PC\n" " # load PC\n"
" ld %r12, 320(%r1)\n" " ld %r12, 312(%r1)\n"
" # restore CTR\n" " # restore CTR\n"
" mtctr %r12\n" " mtctr %r12\n"
" # adjust stack\n" " # adjust stack\n"
" addi %r1, %r1, 328\n" " addi %r1, %r1, 320\n"
" # use third arg as return value after jump\n" " # use third arg as return value after jump\n"
" # use third arg as first arg in context function\n" " # use third arg as first arg in context function\n"
" mr %r3, %r5\n" " mr %r3, %r5\n"
@ -1214,19 +1210,19 @@ __asm (
" clrrdi %r3, %r3, 4\n" " clrrdi %r3, %r3, 4\n"
" # reserve space for context-data on context-stack\n" " # reserve space for context-data on context-stack\n"
" # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n" " # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n"
" subi %r3, %r3, 392\n" " subi %r3, %r3, 384\n"
" # third arg of make_fcontext() == address of context-function\n" " # third arg of make_fcontext() == address of context-function\n"
" # entry point (ELFv2) or descriptor (ELFv1)\n" " # entry point (ELFv2) or descriptor (ELFv1)\n"
#if _CALL_ELF == 2 #if _CALL_ELF == 2
" # save address of context-function entry point\n" " # save address of context-function entry point\n"
" std %r5, 320(%r3)\n" " std %r5, 312(%r3)\n"
#else #else
" # save address of context-function entry point\n" " # save address of context-function entry point\n"
" ld %r4, 0(%r5)\n" " ld %r4, 0(%r5)\n"
" std %r4, 320(%r3)\n" " std %r4, 312(%r3)\n"
" # save TOC of context-function\n" " # save TOC of context-function\n"
" ld %r4, 8(%r5)\n" " ld %r4, 8(%r5)\n"
" std %r4, 152(%r3)\n" " std %r4, 144(%r3)\n"
#endif #endif
" # load LR\n" " # load LR\n"
" mflr %r0\n" " mflr %r0\n"
@ -1241,7 +1237,7 @@ __asm (
" mtlr %r0\n" " mtlr %r0\n"
" # save address of finish as return-address for context-function\n" " # save address of finish as return-address for context-function\n"
" # will be entered after context-function returns\n" " # will be entered after context-function returns\n"
" std %r4, 312(%r3)\n" " std %r4, 304(%r3)\n"
" # restore return address from R6\n" " # restore return address from R6\n"
" mtlr %r6\n" " mtlr %r6\n"
" blr # return pointer to context-data\n" " blr # return pointer to context-data\n"