From: GNU Libc Maintainers Date: Sat, 17 May 2025 15:15:43 +0000 (+0200) Subject: local-setcontext-revert-eax-ecx-edx X-Git-Tag: archive/raspbian/2.41-8+rpi1^2~26 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f045d9bc74488666b2aecc1323b447c9f7809883;p=glibc.git local-setcontext-revert-eax-ecx-edx 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 --- diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S index 799cdd364..d07adb62f 100644 --- a/sysdeps/unix/sysv/linux/i386/getcontext.S +++ b/sysdeps/unix/sysv/linux/i386/getcontext.S @@ -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) diff --git a/sysdeps/unix/sysv/linux/i386/setcontext.S b/sysdeps/unix/sysv/linux/i386/setcontext.S index b9b5258c0..8dab90c8e 100644 --- a/sysdeps/unix/sysv/linux/i386/setcontext.S +++ b/sysdeps/unix/sysv/linux/i386/setcontext.S @@ -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 diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S index 18446be7d..e7dbf65a9 100644 --- a/sysdeps/unix/sysv/linux/i386/swapcontext.S +++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S @@ -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. */ diff --git a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym index 1dfe03d2c..b11a5509c 100644 --- a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym +++ b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym @@ -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)