|
|
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 |
|