local-setcontext-revert-eax-ecx-edx
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Mon, 10 Jun 2024 20:25:19 +0000 (22:25 +0200)
committerSamuel Thibault <sthibault@debian.org>
Mon, 10 Jun 2024 20:25:19 +0000 (22:25 +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 b69a73847b6d15c24e8579e6026fae063f59aef4..f583fe05e6609c243cb3d4d86781ae453a7d80cd 100644 (file)
@@ -26,7 +26,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 ccd79906fd35f5e9c126e47ea349d780d7bed9d2..ac1de8be1be4be13e908230fc924c3c14261b56a 100644 (file)
@@ -62,6 +62,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
@@ -164,14 +166,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 551df10c91e972e8b07bec211ce8a5360a95bb84..8ee9f6c1fd5c2186198e7efae04830d55dd0714d 100644 (file)
@@ -26,7 +26,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)
@@ -223,14 +229,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)