1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
Revert upstream commit 15eab1e3e891 ("i386: Don't unnecessarily save and
restore EAX, ECX and EDX [BZ# 25262]"). It breaks libunwind8.
--- a/sysdeps/unix/sysv/linux/i386/getcontext.S
+++ b/sysdeps/unix/sysv/linux/i386/getcontext.S
@@ -25,7 +25,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)
--- a/sysdeps/unix/sysv/linux/i386/setcontext.S
+++ b/sysdeps/unix/sysv/linux/i386/setcontext.S
@@ -64,19 +64,22 @@ 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 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
--- a/sysdeps/unix/sysv/linux/i386/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/i386/swapcontext.S
@@ -25,7 +25,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)
@@ -84,14 +90,15 @@ ENTRY(__swapcontext)
/* 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. */
--- 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)
oFPREGS mcontext (fpregs)
oSIGMASK ucontext (uc_sigmask)
|