From a336e31785fa54c586724dc272f5d5da073e51ff Mon Sep 17 00:00:00 2001 From: GNU Libc Maintainers Date: Sat, 1 Jun 2024 23:16:35 +0200 Subject: [PATCH] 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 --- sysdeps/unix/sysv/linux/i386/getcontext.S | 8 +++++++- sysdeps/unix/sysv/linux/i386/setcontext.S | 11 +++++++---- sysdeps/unix/sysv/linux/i386/swapcontext.S | 17 ++++++++++++----- sysdeps/unix/sysv/linux/i386/ucontext_i.sym | 3 +++ 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S index b69a73847..f583fe05e 100644 --- a/sysdeps/unix/sysv/linux/i386/getcontext.S +++ b/sysdeps/unix/sysv/linux/i386/getcontext.S @@ -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) diff --git a/sysdeps/unix/sysv/linux/i386/setcontext.S b/sysdeps/unix/sysv/linux/i386/setcontext.S index ccd79906f..ac1de8be1 100644 --- a/sysdeps/unix/sysv/linux/i386/setcontext.S +++ b/sysdeps/unix/sysv/linux/i386/setcontext.S @@ -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 diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S index 551df10c9..8ee9f6c1f 100644 --- a/sysdeps/unix/sysv/linux/i386/swapcontext.S +++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S @@ -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. */ diff --git a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym index 1d8608eaf..058ccd9c8 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) oSCRATCH1 mreg (EAX) oSCRATCH2 mreg (ECX) -- 2.30.2