From 4a4ee8e1c9463ddeca610bb92203102df5b27be1 Mon Sep 17 00:00:00 2001 From: GNU Libc Maintainers Date: Sat, 27 Aug 2022 12:38:11 +0100 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 95e8d06dd..ea04f6ec5 100644 --- a/sysdeps/unix/sysv/linux/i386/getcontext.S +++ b/sysdeps/unix/sysv/linux/i386/getcontext.S @@ -27,7 +27,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 4be3d0598..e57caf0a2 100644 --- a/sysdeps/unix/sysv/linux/i386/setcontext.S +++ b/sysdeps/unix/sysv/linux/i386/setcontext.S @@ -63,6 +63,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 @@ -165,14 +167,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 369c22f7f..5505586d3 100644 --- a/sysdeps/unix/sysv/linux/i386/swapcontext.S +++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S @@ -27,7 +27,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) @@ -224,14 +230,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