e354a5
commit 15eab1e3e89129ab3ed03f5bdc3415b26e9caeb9
e354a5
Author: H.J. Lu <hjl.tools@gmail.com>
e354a5
Date:   Sat Feb 1 05:44:55 2020 -0800
e354a5
e354a5
    i386: Don't unnecessarily save and restore EAX, ECX and EDX [BZ# 25262]
e354a5
    
e354a5
    On i386, since EAX, ECX and EDX are caller-saved, there are no need
e354a5
    to save and restore EAX, ECX and EDX in getcontext, setcontext and
e354a5
    swapcontext.  They just need to clear EAX on success.  The extra
e354a5
    scratch registers are needed to enable CET.
e354a5
    
e354a5
    Tested on i386.
e354a5
    
e354a5
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
e354a5
---
e354a5
e354a5
diff --git a/sysdeps/unix/sysv/linux/i386/getcontext.S b/sysdeps/unix/sysv/linux/i386/getcontext.S
e354a5
index 26ca08a..6637596 100644
e354a5
--- a/sysdeps/unix/sysv/linux/i386/getcontext.S
e354a5
+++ b/sysdeps/unix/sysv/linux/i386/getcontext.S
e354a5
@@ -26,13 +26,7 @@ ENTRY(__getcontext)
e354a5
 	/* Load address of the context data structure.  */
e354a5
 	movl	4(%esp), %eax
e354a5
 
e354a5
-	/* Return value of getcontext.  EAX is the only register whose
e354a5
-	   value is not preserved.  */
e354a5
-	movl	$0, oEAX(%eax)
e354a5
-
e354a5
-	/* Save the 32-bit register values and the return address.  */
e354a5
-	movl	%ecx, oECX(%eax)
e354a5
-	movl	%edx, oEDX(%eax)
e354a5
+	/* Save the preserved register values and the return address.  */
e354a5
 	movl	%edi, oEDI(%eax)
e354a5
 	movl	%esi, oESI(%eax)
e354a5
 	movl	%ebp, oEBP(%eax)
e354a5
diff --git a/sysdeps/unix/sysv/linux/i386/setcontext.S b/sysdeps/unix/sysv/linux/i386/setcontext.S
e354a5
index a604fca..7565d7d 100644
e354a5
--- a/sysdeps/unix/sysv/linux/i386/setcontext.S
e354a5
+++ b/sysdeps/unix/sysv/linux/i386/setcontext.S
e354a5
@@ -65,22 +65,19 @@ ENTRY(__setcontext)
e354a5
 	cfi_offset (esi, oESI)
e354a5
 	cfi_offset (ebp, oEBP)
e354a5
 	cfi_offset (ebx, oEBX)
e354a5
-	cfi_offset (edx, oEDX)
e354a5
-	cfi_offset (ecx, oECX)
e354a5
 	movl	oESP(%eax), %esp
e354a5
 
e354a5
 	/* Push the return address on the new stack so we can return there.  */
e354a5
 	pushl	%ecx
e354a5
 
e354a5
-	/* Load the values of all the 32-bit registers (except ESP).
e354a5
-	   Since we are loading from EAX, it must be last.  */
e354a5
+	/* Load the values of all the preserved registers (except ESP).  */
e354a5
 	movl	oEDI(%eax), %edi
e354a5
 	movl	oESI(%eax), %esi
e354a5
 	movl	oEBP(%eax), %ebp
e354a5
 	movl	oEBX(%eax), %ebx
e354a5
-	movl	oEDX(%eax), %edx
e354a5
-	movl	oECX(%eax), %ecx
e354a5
-	movl	oEAX(%eax), %eax
e354a5
+
e354a5
+	/* All done, return 0 for success.  */
e354a5
+	xorl	%eax, %eax
e354a5
 
e354a5
 	/* End FDE here, we fall into another context.  */
e354a5
 	cfi_endproc
e354a5
diff --git a/sysdeps/unix/sysv/linux/i386/swapcontext.S b/sysdeps/unix/sysv/linux/i386/swapcontext.S
e354a5
index 431f22c..ce27d51 100644
e354a5
--- a/sysdeps/unix/sysv/linux/i386/swapcontext.S
e354a5
+++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S
e354a5
@@ -26,13 +26,7 @@ ENTRY(__swapcontext)
e354a5
 	/* Load address of the context data structure we save in.  */
e354a5
 	movl	4(%esp), %eax
e354a5
 
e354a5
-	/* Return value of swapcontext.  EAX is the only register whose
e354a5
-	   value is not preserved.  */
e354a5
-	movl	$0, oEAX(%eax)
e354a5
-
e354a5
-	/* Save the 32-bit register values and the return address.  */
e354a5
-	movl	%ecx, oECX(%eax)
e354a5
-	movl	%edx, oEDX(%eax)
e354a5
+	/* Save the preserved register values and the return address.  */
e354a5
 	movl	%edi, oEDI(%eax)
e354a5
 	movl	%esi, oESI(%eax)
e354a5
 	movl	%ebp, oEBP(%eax)
e354a5
@@ -91,15 +85,14 @@ ENTRY(__swapcontext)
e354a5
 	/* Push the return address on the new stack so we can return there.  */
e354a5
 	pushl	%ecx
e354a5
 
e354a5
-	/* Load the values of all the 32-bit registers (except ESP).
e354a5
-	   Since we are loading from EAX, it must be last.  */
e354a5
+	/* Load the values of all the preserved registers (except ESP).  */
e354a5
 	movl	oEDI(%eax), %edi
e354a5
 	movl	oESI(%eax), %esi
e354a5
 	movl	oEBP(%eax), %ebp
e354a5
 	movl	oEBX(%eax), %ebx
e354a5
-	movl	oEDX(%eax), %edx
e354a5
-	movl	oECX(%eax), %ecx
e354a5
-	movl	oEAX(%eax), %eax
e354a5
+
e354a5
+	/* All done, return 0 for success.  */
e354a5
+	xorl	%eax, %eax
e354a5
 
e354a5
 	/* The following 'ret' will pop the address of the code and jump
e354a5
 	   to it.  */
e354a5
diff --git a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
e354a5
index b11a550..1dfe03d 100644
e354a5
--- a/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
e354a5
+++ b/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
e354a5
@@ -21,9 +21,6 @@ oESI		mreg (ESI)
e354a5
 oEBP		mreg (EBP)
e354a5
 oESP		mreg (ESP)
e354a5
 oEBX		mreg (EBX)
e354a5
-oEDX		mreg (EDX)
e354a5
-oECX		mreg (ECX)
e354a5
-oEAX		mreg (EAX)
e354a5
 oEIP		mreg (EIP)
e354a5
 oFPREGS		mcontext (fpregs)
e354a5
 oSIGMASK	ucontext (uc_sigmask)
e354a5