local-setcontext-revert-eax-ecx-edx
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Sat, 30 Sep 2023 08:31:05 +0000 (09:31 +0100)
committerAurelien Jarno <aurel32@debian.org>
Sat, 30 Sep 2023 08:31:05 +0000 (09:31 +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 234cc107fd1d51451fb9e8aaa10c34200c3d1dcf..4c038995ebb2a70d0099575ea1848bf65da3ab94 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 5a1c0bdac49903f353c85b579c73ea2d2bbdb8a5..23a26d59da3345a42d87af08fc7fdcd71777fd05 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 8f19bf5115b646541bb4565a3355d53aa617727c..7a9f2ea68e6fdf12a5232aa7fb1485d006e63125 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)