From: H.J. Lu Date: Sat, 1 Feb 2020 13:44:55 +0000 (-0800) Subject: i386: Don't unnecessarily save and restore EAX, ECX and EDX [BZ# 25262] X-Git-Tag: glibc-2.32~768 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=15eab1e3e89129ab3ed03f5bdc3415b26e9caeb9;p=thirdparty%2Fglibc.git i386: Don't unnecessarily save and restore EAX, ECX and EDX [BZ# 25262] On i386, since EAX, ECX and EDX are caller-saved, there are no need to save and restore EAX, ECX and EDX in getcontext, setcontext and swapcontext. They just need to clear EAX on success. The extra scratch registers are needed to enable CET. Tested on i386. Reviewed-by: Adhemerval Zanella --- diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S index f86df4d5552..9c1df9a2aa5 100644 --- a/sysdeps/unix/sysv/linux/i386/getcontext.S +++ b/sysdeps/unix/sysv/linux/i386/getcontext.S @@ -26,13 +26,7 @@ ENTRY(__getcontext) /* Load address of the context data structure. */ movl 4(%esp), %eax - /* 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) + /* Save the preserved register values and the return address. */ 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 b4b5c0298c5..f042d80bf40 100644 --- a/sysdeps/unix/sysv/linux/i386/setcontext.S +++ b/sysdeps/unix/sysv/linux/i386/setcontext.S @@ -65,22 +65,19 @@ 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 32-bit registers (except ESP). - Since we are loading from EAX, it must be last. */ + /* Load the values of all the preserved registers (except ESP). */ movl oEDI(%eax), %edi movl oESI(%eax), %esi movl oEBP(%eax), %ebp movl oEBX(%eax), %ebx - movl oEDX(%eax), %edx - movl oECX(%eax), %ecx - movl oEAX(%eax), %eax + + /* All done, return 0 for success. */ + xorl %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 792bfdf7e6d..090c2d8c3ef 100644 --- a/sysdeps/unix/sysv/linux/i386/swapcontext.S +++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S @@ -26,13 +26,7 @@ ENTRY(__swapcontext) /* Load address of the context data structure we save in. */ movl 4(%esp), %eax - /* 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) + /* Save the preserved register values and the return address. */ movl %edi, oEDI(%eax) movl %esi, oESI(%eax) movl %ebp, oEBP(%eax) @@ -91,15 +85,14 @@ ENTRY(__swapcontext) /* Push the return address on the new stack so we can return there. */ pushl %ecx - /* Load the values of all the 32-bit registers (except ESP). - Since we are loading from EAX, it must be last. */ + /* Load the values of all the preserved registers (except ESP). */ movl oEDI(%eax), %edi movl oESI(%eax), %esi movl oEBP(%eax), %ebp movl oEBX(%eax), %ebx - movl oEDX(%eax), %edx - movl oECX(%eax), %ecx - movl oEAX(%eax), %eax + + /* All done, return 0 for success. */ + xorl %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 b11a5509cd4..1dfe03d2cc5 100644 --- a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym +++ b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym @@ -21,9 +21,6 @@ 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)