Blob Blame History Raw
From f6a42a36d6841ccf31f7490c7a872529d93ca7c1 Mon Sep 17 00:00:00 2001
From: Shawn Anastasio <shawn@anastas.io>
Date: Wed, 14 Aug 2019 08:06:52 -0500
Subject: 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

(cherry picked from commit 3e22b75948e01aec0382f26ee0c3d1b32d5aae30)

diff --git a/common/system/libcontext.cpp b/common/system/libcontext.cpp
index f6f83ce..e17fade 100644
--- a/common/system/libcontext.cpp
+++ b/common/system/libcontext.cpp
@@ -1040,36 +1040,36 @@ __asm (
 # endif
 #endif
 "    # reserve space on stack\n"
-"    subi  %r1, %r1, 328\n"
+"    subi  %r1, %r1, 320\n"
 #if _CALL_ELF != 2
-"    std  %r2,  152(%r1)  # save TOC\n"
+"    std  %r2,  144(%r1)  # save TOC\n"
 #endif
-"    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"
+"    std  %r14, 152(%r1)  # save R14\n"
+"    std  %r15, 160(%r1)  # save R15\n"
+"    std  %r16, 168(%r1)  # save R16\n"
+"    std  %r17, 176(%r1)  # save R17\n"
+"    std  %r18, 184(%r1)  # save R18\n"
+"    std  %r19, 192(%r1)  # save R19\n"
+"    std  %r20, 200(%r1)  # save R20\n"
+"    std  %r21, 208(%r1)  # save R21\n"
+"    std  %r22, 216(%r1)  # save R22\n"
+"    std  %r23, 224(%r1)  # save R23\n"
+"    std  %r24, 232(%r1)  # save R24\n"
+"    std  %r25, 240(%r1)  # save R25\n"
+"    std  %r26, 248(%r1)  # save R26\n"
+"    std  %r27, 256(%r1)  # save R27\n"
+"    std  %r28, 264(%r1)  # save R28\n"
+"    std  %r29, 272(%r1)  # save R29\n"
+"    std  %r30, 280(%r1)  # save R30\n"
+"    std  %r31, 288(%r1)  # save R31\n"
 "    # save CR\n"
 "    mfcr  %r0\n"
-"    std  %r0, 304(%r1)\n"
+"    std  %r0, 296(%r1)\n"
 "    # save LR\n"
 "    mflr  %r0\n"
-"    std  %r0, 312(%r1)\n"
+"    std  %r0, 304(%r1)\n"
 "    # save LR as PC\n"
-"    std  %r0, 320(%r1)\n"
+"    std  %r0, 312(%r1)\n"
 "    # test if fpu env should be preserved\n"
 "    cmpwi  cr7, %r6, 0\n"
 "    beq  cr7, 1f\n"
@@ -1091,8 +1091,6 @@ __asm (
 "    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"
@@ -1119,42 +1117,40 @@ __asm (
 "    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
-"    ld  %r2,  152(%r1)  # restore TOC\n"
+"    ld  %r2,  144(%r1)  # restore TOC\n"
 #endif
-"    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"
+"    ld  %r14, 152(%r1)  # restore R14\n"
+"    ld  %r15, 160(%r1)  # restore R15\n"
+"    ld  %r16, 168(%r1)  # restore R16\n"
+"    ld  %r17, 176(%r1)  # restore R17\n"
+"    ld  %r18, 184(%r1)  # restore R18\n"
+"    ld  %r19, 192(%r1)  # restore R19\n"
+"    ld  %r20, 200(%r1)  # restore R20\n"
+"    ld  %r21, 208(%r1)  # restore R21\n"
+"    ld  %r22, 216(%r1)  # restore R22\n"
+"    ld  %r23, 224(%r1)  # restore R23\n"
+"    ld  %r24, 232(%r1)  # restore R24\n"
+"    ld  %r25, 240(%r1)  # restore R25\n"
+"    ld  %r26, 248(%r1)  # restore R26\n"
+"    ld  %r27, 256(%r1)  # restore R27\n"
+"    ld  %r28, 264(%r1)  # restore R28\n"
+"    ld  %r29, 272(%r1)  # restore R29\n"
+"    ld  %r30, 280(%r1)  # restore R30\n"
+"    ld  %r31, 288(%r1)  # restore R31\n"
 "    # restore CR\n"
-"    ld  %r0, 304(%r1)\n"
+"    ld  %r0, 296(%r1)\n"
 "    mtcr  %r0\n"
 "    # restore LR\n"
-"    ld  %r0, 312(%r1)\n"
+"    ld  %r0, 304(%r1)\n"
 "    mtlr  %r0\n"
 "    # load PC\n"
-"    ld  %r12, 320(%r1)\n"
+"    ld  %r12, 312(%r1)\n"
 "    # restore CTR\n"
 "    mtctr  %r12\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 first arg in context function\n"
 "    mr  %r3, %r5\n"
@@ -1212,19 +1208,19 @@ __asm (
 "    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"
+"    subi  %r3, %r3, 384\n"
 "    # third arg of make_fcontext() == address of context-function\n"
 "    # entry point (ELFv2) or descriptor (ELFv1)\n"
 #if _CALL_ELF == 2
 "    # save address of context-function entry point\n"
-"    std  %r5, 320(%r3)\n"
+"    std  %r5, 312(%r3)\n"
 #else
 "    # save address of context-function entry point\n"
 "    ld   %r4, 0(%r5)\n"
-"    std  %r4, 320(%r3)\n"
+"    std  %r4, 312(%r3)\n"
 "    # save TOC of context-function\n"
 "    ld   %r4, 8(%r5)\n"
-"    std  %r4, 152(%r3)\n"
+"    std  %r4, 144(%r3)\n"
 #endif
 "    # load LR\n"
 "    mflr  %r0\n"
@@ -1239,7 +1235,7 @@ __asm (
 "    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"
+"    std  %r4, 304(%r3)\n"
 "    # restore return address from R6\n"
 "    mtlr  %r6\n"
 "    blr  # return pointer to context-data\n"
-- 
cgit v0.10.2