Skip to content

Commit 866c34e

Browse files
committed
libc: make MINIX assembly code position-independent
While here, simplify ucontext.S
1 parent 7a8811e commit 866c34e

File tree

2 files changed

+55
-78
lines changed

2 files changed

+55
-78
lines changed

lib/libc/arch/i386/sys-minix/__sigreturn.S

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,12 @@
55

66
IMPORT(_sigreturn)
77
ENTRY(__sigreturn)
8+
#ifndef PIC
89
addl $16, %esp
910
jmp _C_LABEL(_sigreturn)
11+
#else
12+
addl $16, %esp
13+
PIC_PROLOGUE /* push %ebx, but we do not care */
14+
pop %eax /* special knowledge of how PIC works: discard pushed EBX */
15+
jmp PIC_PLT(_C_LABEL(_sigreturn))
16+
#endif /* PIC */
Lines changed: 48 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
#include <machine/asm.h>
22
#include <ucontextoffsets.h>
33

4-
#ifdef __ACK__
5-
.text
6-
begtext:
7-
#ifdef __ACK__
8-
.rom
9-
#else
10-
.data
11-
#endif
12-
begrom:
13-
.data
14-
begdata:
15-
.bss
16-
begbss:
17-
#endif
18-
19-
204
IMPORT(getuctx)
215
IMPORT(setuctx)
226
IMPORT(resumecontext)
237

8+
.globl _C_LABEL(__errno)
249

2510
/* MCF_MAGIC value from <mcontext.h> */
2611
#define MCF_MAGIC 0xc0ffee
@@ -29,7 +14,6 @@ IMPORT(resumecontext)
2914
#define UCF_IGNFPU 0x002
3015
#define UCF_IGNSIGM 0x004
3116

32-
3317
/* EINVAL from errno.h */
3418
#define EFAULT 14
3519
#define EINVAL 22
@@ -43,59 +27,44 @@ ENTRY(getcontext)
4327
* saving its signal mask, then we can skip the context switch to
4428
* PM and kernel altogether and only save general-purpose registers. */
4529

46-
mov (%esp), %ecx /* Save return address:
47-
* When setcontext or swapcontext is called,
48-
* we jump to this address and continue
49-
* running. */
50-
5130
mov 4(%esp), %edx /* edx = ucp */
5231
/* Check null pointer */
5332
cmp $0, %edx /* edx == NULL? */
5433
jne 3f /* Not null, continue */
55-
movl $EFAULT, (_C_LABEL(errno))
34+
PIC_PROLOGUE
35+
call PIC_PLT(_C_LABEL(__errno))
36+
PIC_EPILOGUE
37+
movl $EFAULT, (%eax)
5638
xor %eax, %eax
5739
dec %eax /* return -1 */
5840
ret
5941

6042
3: /* Check flags */
61-
push %ecx /* save ecx */
62-
push %ebx /* save ebx */
63-
lea UC_FLAGS(%edx), %ebx /* ebx = &(ucp->uc_flags) */
64-
mov (%ebx), %ecx /* ecx = ucp->uc_flags */
65-
mov $UCF_IGNFPU, %eax
66-
or $UCF_IGNSIGM, %eax
67-
cmp %eax, %ecx /* is UCF_IGNFPU or UCF_IGNSIGM set? */
68-
pop %ebx /* restore ebx */
69-
pop %ecx /* restore ecx */
70-
jz 1f /* Both are set, skip getuctx */
71-
72-
0:
73-
push %ecx /* Save ecx */
43+
mov UC_FLAGS(%edx), %eax /* eax = ucp->uc_flags */
44+
#if 0
45+
and $~[UCF_IGNFPU|UCF_IGNSIGM], %eax /* check only those flags */
46+
#endif
47+
xor $[UCF_IGNFPU|UCF_IGNSIGM], %eax /* toggle both flags */
48+
jz 5f /* Both were set, skip getuctx */
49+
PIC_PROLOGUE
7450
push %edx
75-
call _C_LABEL(getuctx) /* getuctx(ucp) */
51+
call PIC_PLT(_C_LABEL(getuctx)) /* getuctx(ucp) */
7652
pop %edx /* clean up stack and restore edx */
77-
pop %ecx /* Restore ecx */
53+
PIC_EPILOGUE
7854

79-
1:
55+
5:
8056
/* Save the context */
81-
mov 4(%esp), %edx /* edx = ucp */
82-
pop %eax /* retaddr */
83-
mov %eax, PC(%edx) /* Save real RTA in mcp struct */
57+
pop PC(%edx) /* Save real RTA in mcp struct */
8458
mov %esp, SP(%edx) /* Save stack pointer (now pointing to ucp) */
85-
/* Save GP registers */
59+
/* Save GP registers (except EAX and EDX) */
8660
mov %ebp, BP(%edx) /* Save EBP */
8761
mov %esi, SI(%edx) /* Save ESI */
8862
mov %edi, DI(%edx) /* Save EDI */
8963
mov %ebx, BX(%edx) /* Save EBX */
9064
mov %ecx, CX(%edx) /* Save ECX */
9165
movl $MCF_MAGIC, MAGIC(%edx) /* Set magic value */
92-
push %eax /* Restore retaddr */
93-
9466
xor %eax, %eax /* Return 0 */
95-
96-
2:
97-
add $4, %esp /* Remove stale (setcontext) RTA */
98-
jmp *%ecx /* Restore return address */
67+
jmp *PC(%edx) /* Return return address */
9968

10069

10170
/* int setcontext(const ucontext_t *ucp)
@@ -115,60 +84,60 @@ ENTRY(setcontext)
11584
/* Check null pointer */
11685
cmp $0, %edx /* edx == NULL? */
11786
jnz 3f /* Not null, continue */
118-
movl $EFAULT, (_C_LABEL(errno))
87+
movl $EFAULT, %edx
88+
0: PIC_PROLOGUE
89+
call PIC_PLT(_C_LABEL(__errno))
90+
PIC_EPILOGUE
91+
movl %edx, (%eax)
11992
xor %eax, %eax
12093
dec %eax /* return -1 */
12194
ret
12295

12396
3: /* Check flags */
124-
push %ebx /* save ebx */
125-
lea MAGIC(%edx), %ebx /* ebx = &(ucp->mc_context.mc_magic) */
126-
mov (%ebx), %ecx /* ecx = ucp->mc_context.mc_magic */
127-
pop %ebx /* restore ebx */
128-
cmp $MCF_MAGIC, %ecx /* is the magic value set (is context valid)?*/
97+
cmpl $MCF_MAGIC, MAGIC(%edx) /* is the magic value set (is context valid)?*/
12998
jz 4f /* is set, proceed */
130-
movl $EINVAL, (_C_LABEL(errno)) /* not set, return error code */
131-
xor %eax, %eax
132-
dec %eax /* return -1 */
133-
ret
99+
movl $EINVAL, %edx /* not set, return error code */
100+
jmp 0b
134101

135102

136-
4: push %ebx /* save ebx */
137-
lea UC_FLAGS(%edx), %ebx /* ebx = &(ucp->uc_flags) */
138-
mov (%ebx), %ecx /* ecx = ucp->uc_flags */
139-
pop %ebx /* restore ebx */
140-
mov $UCF_IGNFPU, %eax
141-
or $UCF_IGNSIGM, %eax
142-
cmp %eax, %ecx /* Are UCF_IGNFPU and UCF_IGNSIGM flags set? */
143-
jz 1f /* Both are set, so don't bother restoring FPU
103+
4: mov UC_FLAGS(%edx), %eax /* eax = ucp->uc_flags */
104+
#if 0
105+
and $~[UCF_IGNFPU|UCF_IGNSIGM], %eax /* check only those flags */
106+
#endif
107+
xor $[UCF_IGNFPU|UCF_IGNSIGM], %eax /* toggle both flags */
108+
jz 5f /* Both are set, so don't bother restoring FPU
144109
* state and signal mask */
145110

146-
0: push %ecx /* Save ecx */
111+
PIC_PROLOGUE
147112
push %edx
148-
call _C_LABEL(setuctx) /* setuctx(ucp) */
113+
call PIC_PLT(_C_LABEL(setuctx)) /* setuctx(ucp) */
149114
pop %edx /* Clean up stack and restore edx */
150-
pop %ecx /* Restore ecx */
115+
PIC_EPILOGUE
151116

152-
1: /* Restore the registers */
153-
mov 4(%esp), %edx /* edx = ucp */
117+
5: /* Restore the registers (except EAX and EDX) */
154118
mov CX(%edx), %ecx /* Restore ECX */
155119
mov BX(%edx), %ebx /* Restore EBX */
156120
mov DI(%edx), %edi /* Restore EDI */
157121
mov SI(%edx), %esi /* Restore ESI */
158122
mov BP(%edx), %ebp /* Restore EBP */
159123
mov SP(%edx), %esp /* Restore stack pointer */
160-
161-
2:
124+
#if 0
162125
jmp *PC(%edx) /* Push RTA onto stack so we can return to it */
163-
126+
#else
127+
jmp *PC(%edx) /* Return to RTA */
128+
#endif
164129

165130
/* void ctx_start((void *func)(int arg1, ..., argn), arg1, ..., argn,
166131
* ucontext_t *ucp)
167132
* A wrapper to start function `func'. ESI register will contain a pointer
168133
* to ucp on the stack. By setting ESP to ESI, we effectively 'remove' all
169134
* arguments to `func' from the stack. Finally, a call to resumecontext
170135
* will start the next context in the linked list (or exit the program if
171-
* there is no context). */
136+
* there is no context).
137+
*
138+
* Since PIC needs the EBX register, which is pushed on the stack by
139+
* PIC_PROLOGUE, we need an extra of salsa here.
140+
*/
172141
ENTRY(ctx_start)
173142
/* 0(esp) -> func
174143
* 4(esp) -> arg1
@@ -178,9 +147,10 @@ ENTRY(ctx_start)
178147

179148
pop %eax /* eax = func */
180149
call *%eax /* func(arg1, ..., argn) */
181-
mov %esi, %esp /* Clean up stack */
150+
PIC_PROLOGUE /* may push %ebx, but we do not care */
151+
mov %esi, %esp /* Clean up stack, keep %ebx = &GOT */
182152
/* ucp is now at the top of the stack again */
183-
call _C_LABEL(resumecontext) /* resumecontext(ucp) */
153+
call PIC_PLT(_C_LABEL(resumecontext)) /* resumecontext(ucp) */
184154
ret /* never reached */
185155

186156

0 commit comments

Comments
 (0)