local-setcontext-revert-eax-ecx-edx
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Wed, 18 Jun 2025 04:49:31 +0000 (06:49 +0200)
committerAurelien Jarno <aurel32@debian.org>
Wed, 18 Jun 2025 04:49:31 +0000 (06:49 +0200)
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 799cdd3640f0b0dd76a7c6db34dac245380dc3da..d07adb62fb4b646a104260e5e1aff1c87ed21ef5 100644 (file)
@@ -25,7 +25,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 b9b5258c0e5424d9ff83f60f95aef6fab0086736..8dab90c8e1f0cfc4bfe06356d39776108931684d 100644 (file)
@@ -64,19 +64,22 @@ 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
 
        /* 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 18446be7d49c6e74f1e5ca9f76dbcbdd2a40bd69..e7dbf65a99b2e441886167387563bb02e8b21483 100644 (file)
@@ -25,7 +25,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)
@@ -84,14 +90,15 @@ ENTRY(__swapcontext)
        /* 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 1dfe03d2cc5e8642b1f91295d115b9fc2724814a..b11a5509cd469b320b4c92bdcb429b6e2470c756 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)
 oFPREGS                mcontext (fpregs)
 oSIGMASK       ucontext (uc_sigmask)