local-setcontext-revert-eax-ecx-edx
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Sun, 19 Sep 2021 18:46:59 +0000 (19:46 +0100)
committerAurelien Jarno <aurel32@debian.org>
Sun, 19 Sep 2021 18:46:59 +0000 (19:46 +0100)
Revert upstream commit 15eab1e3e891 ("i386: Don't unnecessarily save and

Revert upstream commit 15eab1e3e891 ("i386: Don't unnecessarily save and
restore EAX, ECX and EDX [BZ# 25262]"). It breaks libunwind8.

Gbp-Pq: Topic i386
Gbp-Pq: Name local-setcontext-revert-eax-ecx-edx.patch

sysdeps/unix/sysv/linux/i386/getcontext.S
sysdeps/unix/sysv/linux/i386/setcontext.S
sysdeps/unix/sysv/linux/i386/swapcontext.S
sysdeps/unix/sysv/linux/i386/ucontext_i.sym

index d91cfe4b1d64c06c3e63443a2d698b558ddf139e..ad8b13934f69069615035dc8e7f55d0ce1171348 100644 (file)
@@ -27,7 +27,13 @@ ENTRY(__getcontext)
        /* Load address of the context data structure.  */
        movl    4(%esp), %eax
 
-       /* Save the preserved register values and the return address.  */
+       /* Return value of getcontext.  EAX is the only register whose
+          value is not preserved.  */
+       movl    $0, oEAX(%eax)
+
+       /* Save the 32-bit register values and the return address.  */
+       movl    %ecx, oECX(%eax)
+       movl    %edx, oEDX(%eax)
        movl    %edi, oEDI(%eax)
        movl    %esi, oESI(%eax)
        movl    %ebp, oEBP(%eax)
index 332b5147bcd42e6d83f97e8e4f9abab6ea09e666..453d4f079ab8d1fa4f54123710b40746ff403dd8 100644 (file)
@@ -63,6 +63,8 @@ ENTRY(__setcontext)
        cfi_offset (esi, oESI)
        cfi_offset (ebp, oEBP)
        cfi_offset (ebx, oEBX)
+       cfi_offset (edx, oEDX)
+       cfi_offset (ecx, oECX)
        movl    oESP(%eax), %esp
 
 #if SHSTK_ENABLED
@@ -165,14 +167,15 @@ L(no_shstk):
        /* Push the return address on the new stack so we can return there.  */
        pushl   %ecx
 
-       /* Load the values of all the preserved registers (except ESP).  */
+       /* Load the values of all the 32-bit registers (except ESP).
+          Since we are loading from EAX, it must be last.  */
        movl    oEDI(%eax), %edi
        movl    oESI(%eax), %esi
        movl    oEBP(%eax), %ebp
        movl    oEBX(%eax), %ebx
-
-       /* All done, return 0 for success.  */
-       xorl    %eax, %eax
+       movl    oEDX(%eax), %edx
+       movl    oECX(%eax), %ecx
+       movl    oEAX(%eax), %eax
 
        /* End FDE here, we fall into another context.  */
        cfi_endproc
index 203eafa2e7c160381a36432ba5ecb37deb7b4edd..14d367dc8eb409e26e360f7b20f0495017a48b77 100644 (file)
@@ -27,7 +27,13 @@ ENTRY(__swapcontext)
        /* Load address of the context data structure we save in.  */
        movl    4(%esp), %eax
 
-       /* Save the preserved register values and the return address.  */
+       /* Return value of swapcontext.  EAX is the only register whose
+          value is not preserved.  */
+       movl    $0, oEAX(%eax)
+
+       /* Save the 32-bit register values and the return address.  */
+       movl    %ecx, oECX(%eax)
+       movl    %edx, oEDX(%eax)
        movl    %edi, oEDI(%eax)
        movl    %esi, oESI(%eax)
        movl    %ebp, oEBP(%eax)
@@ -224,14 +230,15 @@ L(no_shstk):
        /* Push the return address on the new stack so we can return there.  */
        pushl   %ecx
 
-       /* Load the values of all the preserved registers (except ESP).  */
+       /* Load the values of all the 32-bit registers (except ESP).
+          Since we are loading from EAX, it must be last.  */
        movl    oEDI(%eax), %edi
        movl    oESI(%eax), %esi
        movl    oEBP(%eax), %ebp
        movl    oEBX(%eax), %ebx
-
-       /* All done, return 0 for success.  */
-       xorl    %eax, %eax
+       movl    oEDX(%eax), %edx
+       movl    oECX(%eax), %ecx
+       movl    oEAX(%eax), %eax
 
        /* The following 'ret' will pop the address of the code and jump
           to it.  */
index 1d8608eafc3f2a676f63b310dbb5eeba2c80c6be..058ccd9c885cdc94b2e51241b5336352d26604ee 100644 (file)
@@ -21,6 +21,9 @@ oESI          mreg (ESI)
 oEBP           mreg (EBP)
 oESP           mreg (ESP)
 oEBX           mreg (EBX)
+oEDX           mreg (EDX)
+oECX           mreg (ECX)
+oEAX           mreg (EAX)
 oEIP           mreg (EIP)
 oSCRATCH1      mreg (EAX)
 oSCRATCH2      mreg (ECX)