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 <adhemerval.zanella@linaro.org>
This commit is contained in:
H.J. Lu 2020-02-01 05:44:55 -08:00
parent 635d6fae03
commit 15eab1e3e8
4 changed files with 10 additions and 29 deletions

View File

@ -26,13 +26,7 @@ ENTRY(__getcontext)
/* Load address of the context data structure. */ /* Load address of the context data structure. */
movl 4(%esp), %eax movl 4(%esp), %eax
/* Return value of getcontext. EAX is the only register whose /* Save the preserved register values and the return address. */
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 %edi, oEDI(%eax)
movl %esi, oESI(%eax) movl %esi, oESI(%eax)
movl %ebp, oEBP(%eax) movl %ebp, oEBP(%eax)

View File

@ -65,22 +65,19 @@ ENTRY(__setcontext)
cfi_offset (esi, oESI) cfi_offset (esi, oESI)
cfi_offset (ebp, oEBP) cfi_offset (ebp, oEBP)
cfi_offset (ebx, oEBX) cfi_offset (ebx, oEBX)
cfi_offset (edx, oEDX)
cfi_offset (ecx, oECX)
movl oESP(%eax), %esp movl oESP(%eax), %esp
/* Push the return address on the new stack so we can return there. */ /* Push the return address on the new stack so we can return there. */
pushl %ecx pushl %ecx
/* Load the values of all the 32-bit registers (except ESP). /* Load the values of all the preserved registers (except ESP). */
Since we are loading from EAX, it must be last. */
movl oEDI(%eax), %edi movl oEDI(%eax), %edi
movl oESI(%eax), %esi movl oESI(%eax), %esi
movl oEBP(%eax), %ebp movl oEBP(%eax), %ebp
movl oEBX(%eax), %ebx movl oEBX(%eax), %ebx
movl oEDX(%eax), %edx
movl oECX(%eax), %ecx /* All done, return 0 for success. */
movl oEAX(%eax), %eax xorl %eax, %eax
/* End FDE here, we fall into another context. */ /* End FDE here, we fall into another context. */
cfi_endproc cfi_endproc

View File

@ -26,13 +26,7 @@ ENTRY(__swapcontext)
/* Load address of the context data structure we save in. */ /* Load address of the context data structure we save in. */
movl 4(%esp), %eax movl 4(%esp), %eax
/* Return value of swapcontext. EAX is the only register whose /* Save the preserved register values and the return address. */
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 %edi, oEDI(%eax)
movl %esi, oESI(%eax) movl %esi, oESI(%eax)
movl %ebp, oEBP(%eax) movl %ebp, oEBP(%eax)
@ -91,15 +85,14 @@ ENTRY(__swapcontext)
/* Push the return address on the new stack so we can return there. */ /* Push the return address on the new stack so we can return there. */
pushl %ecx pushl %ecx
/* Load the values of all the 32-bit registers (except ESP). /* Load the values of all the preserved registers (except ESP). */
Since we are loading from EAX, it must be last. */
movl oEDI(%eax), %edi movl oEDI(%eax), %edi
movl oESI(%eax), %esi movl oESI(%eax), %esi
movl oEBP(%eax), %ebp movl oEBP(%eax), %ebp
movl oEBX(%eax), %ebx movl oEBX(%eax), %ebx
movl oEDX(%eax), %edx
movl oECX(%eax), %ecx /* All done, return 0 for success. */
movl oEAX(%eax), %eax xorl %eax, %eax
/* The following 'ret' will pop the address of the code and jump /* The following 'ret' will pop the address of the code and jump
to it. */ to it. */

View File

@ -21,9 +21,6 @@ oESI mreg (ESI)
oEBP mreg (EBP) oEBP mreg (EBP)
oESP mreg (ESP) oESP mreg (ESP)
oEBX mreg (EBX) oEBX mreg (EBX)
oEDX mreg (EDX)
oECX mreg (ECX)
oEAX mreg (EAX)
oEIP mreg (EIP) oEIP mreg (EIP)
oFPREGS mcontext (fpregs) oFPREGS mcontext (fpregs)
oSIGMASK ucontext (uc_sigmask) oSIGMASK ucontext (uc_sigmask)