]> Zhao Yanbai Git Server - minix.git/commitdiff
libc: make MINIX assembly code position-independent 16/716/4
authorAntoine Leca <Antoine.Leca.1@gmail.com>
Fri, 1 Feb 2013 09:39:47 +0000 (09:39 +0000)
committerGerrit Code Review <gerrit@gerrit>
Fri, 9 Aug 2013 09:09:51 +0000 (11:09 +0200)
While here, simplify ucontext.S

. makes libc link without the messy DT_TEXTREL warning.

Change-Id: I4656d9068eab5ed2fa1e391242883d5dd9d93644

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

index 01182b0580f74ff1a8df0ebdc38a7ae9f1b75d68..094440aee723e2a6552550185fffe0b57f930c1f 100644 (file)
@@ -6,4 +6,10 @@
 IMPORT(_sigreturn)
 ENTRY(__sigreturn)
        addl    $16, %esp
+#ifndef PIC
        jmp     _C_LABEL(_sigreturn)
+#else
+       PIC_PROLOGUE            /* push %ebx, but we do not care */
+       pop     %eax /* special knowledge of how PIC works: discard pushed EBX */
+       jmp     PIC_PLT(_C_LABEL(_sigreturn))
+#endif /* PIC */
index 3c73c0970b91b66f046eddd9534203abf27d18f0..48a6fff991f5852343e7ff8ec0e83d846f116765 100644 (file)
@@ -1,26 +1,11 @@
 #include <machine/asm.h>
 #include <ucontextoffsets.h>
 
-#ifdef __ACK__
-.text
-begtext:
-#ifdef __ACK__
-.rom
-#else
-.data
-#endif
-begrom:
-.data
-begdata:
-.bss
-begbss:
-#endif
-
-
 IMPORT(getuctx)
 IMPORT(setuctx)
 IMPORT(resumecontext)
 
+       .globl  _C_LABEL(__errno)
 
 /* MCF_MAGIC value from <mcontext.h> */
 #define MCF_MAGIC      0xc0ffee
@@ -43,59 +28,41 @@ ENTRY(getcontext)
         * saving its signal mask, then we can skip the context switch to
         * PM and kernel altogether and only save general-purpose registers. */
 
-       mov (%esp), %ecx        /* Save return address:
-                                * When setcontext or swapcontext is called,
-                                * we jump to this address and continue
-                                * running. */
-
        mov 4(%esp), %edx               /* edx = ucp */
        /* Check null pointer */
        cmp $0, %edx                    /* edx == NULL? */
        jne 3f                          /* Not null, continue */
-       movl $EFAULT, (_C_LABEL(errno))
+       PIC_PROLOGUE
+       call PIC_PLT(_C_LABEL(__errno))
+       PIC_EPILOGUE
+       movl $EFAULT, (%eax)
        xor %eax, %eax
        dec %eax                        /* return -1 */
        ret
        
 3:     /* Check flags */
-       push %ecx                       /* save ecx */
-       push %ebx                       /* save ebx */
-       lea UC_FLAGS(%edx), %ebx        /* ebx = &(ucp->uc_flags) */
-       mov (%ebx), %ecx                /* ecx = ucp->uc_flags */
-       mov $UCF_IGNFPU, %eax
-       or $UCF_IGNSIGM, %eax
-       cmp %eax, %ecx                  /* is UCF_IGNFPU or UCF_IGNSIGM set? */
-       pop %ebx                        /* restore ebx */
-       pop %ecx                        /* restore ecx */
-       jz 1f                           /* Both are set, skip getuctx */
-
-0:
-       push %ecx                       /* Save ecx */
+       mov UC_FLAGS(%edx), %eax        /* eax = ucp->uc_flags */
+       xor $[UCF_IGNFPU|UCF_IGNSIGM], %eax /* toggle both flags */
+       jz 5f                           /* Both were set, skip getuctx */
+       PIC_PROLOGUE
        push %edx                
-       call _C_LABEL(getuctx)          /* getuctx(ucp) */
+       call PIC_PLT(_C_LABEL(getuctx)) /* getuctx(ucp) */
        pop %edx                        /* clean up stack and restore edx */
-       pop %ecx                        /* Restore ecx */
+       PIC_EPILOGUE
 
-1: 
+5:
        /* Save the context */
-       mov 4(%esp), %edx               /* edx = ucp */
-       pop %eax                        /* retaddr */
-       mov %eax, PC(%edx)              /* Save real RTA in mcp struct */
+       pop PC(%edx)                    /* Save real RTA in mcp struct */
        mov %esp, SP(%edx)      /* Save stack pointer (now pointing to ucp) */
-       /* Save GP registers */
+       /* Save GP registers (except EAX and EDX) */
        mov %ebp, BP(%edx)              /* Save EBP */
        mov %esi, SI(%edx)              /* Save ESI */
        mov %edi, DI(%edx)              /* Save EDI */
        mov %ebx, BX(%edx)              /* Save EBX */
        mov %ecx, CX(%edx)              /* Save ECX */
        movl $MCF_MAGIC, MAGIC(%edx)    /* Set magic value */
-       push %eax                       /* Restore retaddr */
-
        xor %eax, %eax                  /* Return 0 */
-
-2:     
-       add $4, %esp                    /* Remove stale (setcontext) RTA */
-       jmp *%ecx                       /* Restore return address */
+       jmp *PC(%edx)                   /* Return return address */
        
 
 /* int setcontext(const ucontext_t *ucp)
@@ -115,52 +82,43 @@ ENTRY(setcontext)
        /* Check null pointer */
        cmp $0, %edx                    /* edx == NULL? */
        jnz 3f                          /* Not null, continue */
-       movl $EFAULT, (_C_LABEL(errno))
+       movl $EFAULT, %edx
+0:     push %edx                       /* preserve errno */
+       PIC_PROLOGUE
+       call    PIC_PLT(_C_LABEL(__errno))
+       PIC_EPILOGUE
+       pop %edx
+       movl %edx, (%eax)
        xor %eax, %eax
        dec %eax                        /* return -1 */
        ret
        
 3:     /* Check flags */
-       push %ebx                       /* save ebx */
-       lea MAGIC(%edx), %ebx           /* ebx = &(ucp->mc_context.mc_magic) */
-       mov (%ebx), %ecx                /* ecx = ucp->mc_context.mc_magic */
-       pop %ebx                        /* restore ebx */
-       cmp $MCF_MAGIC, %ecx    /* is the magic value set (is context valid)?*/
+       cmpl $MCF_MAGIC, MAGIC(%edx)    /* is the magic value set (is context valid)?*/
        jz 4f                           /* is set, proceed */
-       movl $EINVAL, (_C_LABEL(errno)) /* not set, return error code */
-       xor %eax, %eax
-       dec %eax                        /* return -1 */
-       ret     
+       movl $EINVAL, %edx              /* not set, return error code */
+       jmp 0b
 
 
-4:     push %ebx                       /* save ebx */
-       lea UC_FLAGS(%edx), %ebx        /* ebx = &(ucp->uc_flags) */
-       mov (%ebx), %ecx                /* ecx = ucp->uc_flags */
-       pop %ebx                        /* restore ebx */
-       mov $UCF_IGNFPU, %eax
-       or $UCF_IGNSIGM, %eax
-       cmp %eax, %ecx          /* Are UCF_IGNFPU and UCF_IGNSIGM flags set? */
-       jz 1f                   /* Both are set, so don't bother restoring FPU
+4:     mov UC_FLAGS(%edx), %eax        /* eax = ucp->uc_flags */
+       xor $[UCF_IGNFPU|UCF_IGNSIGM], %eax /* toggle both flags */
+       jz 5f                   /* Both are set, so don't bother restoring FPU
                                 * state and signal mask */
 
-0:     push %ecx                       /* Save ecx */
+       PIC_PROLOGUE
        push %edx                
-       call _C_LABEL(setuctx)          /* setuctx(ucp) */
+       call PIC_PLT(_C_LABEL(setuctx)) /* setuctx(ucp) */
        pop %edx                        /* Clean up stack and restore edx */
-       pop %ecx                        /* Restore ecx */
+       PIC_EPILOGUE
 
-1:     /* Restore the registers */
-       mov 4(%esp), %edx               /* edx = ucp */
+5:     /* Restore the registers (except EAX and EDX) */
        mov CX(%edx), %ecx              /* Restore ECX */
        mov BX(%edx), %ebx              /* Restore EBX */
        mov DI(%edx), %edi              /* Restore EDI */
        mov SI(%edx), %esi              /* Restore ESI */
        mov BP(%edx), %ebp              /* Restore EBP */
        mov SP(%edx), %esp              /* Restore stack pointer */
-
-2:
-       jmp *PC(%edx)   /* Push RTA onto stack so we can return to it */
-
+       jmp *PC(%edx)                   /* Return to RTA */
 
 /* void ctx_start((void *func)(int arg1, ..., argn), arg1, ..., argn,
  *               ucontext_t *ucp)
@@ -168,7 +126,11 @@ ENTRY(setcontext)
  *     to ucp on the stack. By setting ESP to ESI, we effectively 'remove' all
  *     arguments to `func' from the stack. Finally, a call to resumecontext
  *     will start the next context in the linked list (or exit the program if
- *     there is no context). */
+ *     there is no context).
+ *
+ * Since PIC needs the EBX register, which is pushed on the stack by
+ * PIC_PROLOGUE, we need an extra of salsa here.
+ */
 ENTRY(ctx_start)
        /* 0(esp) -> func
         * 4(esp) -> arg1
@@ -178,9 +140,10 @@ ENTRY(ctx_start)
 
        pop %eax                        /* eax = func */
        call *%eax                      /* func(arg1, ..., argn) */
-       mov %esi, %esp                  /* Clean up stack */
+       PIC_PROLOGUE            /* may push %ebx, but we do not care */
+       mov %esi, %esp          /* Clean up stack, keep %ebx = &GOT */
        /* ucp is now at the top of the stack again */
-       call _C_LABEL(resumecontext)    /* resumecontext(ucp) */
+       call PIC_PLT(_C_LABEL(resumecontext))   /* resumecontext(ucp) */
        ret                     /* never reached */