]> git.saurik.com Git - apple/dyld.git/blobdiff - src/stub_binding_helper.s
dyld-360.18.tar.gz
[apple/dyld.git] / src / stub_binding_helper.s
index af9c2d51b0bd89a675ff04bfa5d581f06cc6644a..de2d90be5109bcfcb6ad7b55e73ab4f75c28597a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -26,9 +26,8 @@
 #ifdef __i386__
 /*
  * This is the interface for the stub_binding_helper for i386:
- * The caller has pushed the address of the a lazy pointer to be filled in with
- * the value for the defined symbol and pushed the address of the the mach
- * header this pointer comes from.
+ * The caller has pushed the address of the a lazy pointer to be filled in 
+ * and pushed the address of the the mach header this pointer comes from.
  *
  * sp+4        address of lazy pointer
  * sp+0        address of mach header
  * Some inter-image function calls pass parameters in registers EAX, ECX, EDX, or XXM0-3,
  * Therefore those registers need to be preserved during the lazy binding.
  * 
- * After the symbol has been resolved and the pointer filled in this is to pop
- * these arguments off the stack and jump to the address of the defined symbol.
+ * After the symbol has been resolved and the lazy pointer filled in, this jumps
+ * to the target address.
  */
-#define MH_PARAM_BP                    4
-#define LP_PARAM_BP                    8
-#define RESULT_BP                      8    /* in order to trash no registers, the target is stored back on the stack then ret it done to it */
-
-#define MH_PARAM_OUT        0
-#define LP_PARAM_OUT        4
-#define EAX_SAVE                       8
-#define ECX_SAVE                       12
-#define EDX_SAVE                       16
-#define XMMM0_SAVE                     32    /* 16-byte align */
-#define XMMM1_SAVE                     48
-#define XMMM2_SAVE                     64
-#define XMMM3_SAVE                     80
-#define STACK_SIZE                     96 /*  (XMMM3_SAVE+16) must be 16 byte aligned too */
-
+#define MH_PARAM_OUT                   0
+#define LP_PARAM_OUT                   4
+#define XMMM0_SAVE                     16      /* 16-byte align */
+#define XMMM1_SAVE                     32
+#define XMMM2_SAVE                     48
+#define XMMM3_SAVE                     64
+#define EAX_SAVE                       84
+#define ECX_SAVE                       88
+#define EDX_SAVE                       92
+#define LP_LOCAL                       96
+#define MH_LOCAL                       100
+#define STACK_SIZE                     100     /* must be 4 mod 16 so that stack winds up 16-byte aliged  */
+#define LP_OLD_BP_SAVE                 104
 
     .text
     .align 4,0x90
-    .globl _stub_binding_helper_interface
-_stub_binding_helper_interface:
-       pushl           %ebp
-       movl            %esp,%ebp
-       subl            $STACK_SIZE,%esp                # at this point stack is 16-byte aligned because two meta-parameters where pushed
-       movl            %eax,EAX_SAVE(%esp)             # save registers that might be used as parameters
+       .globl _stub_binding_helper_i386_old
+_stub_binding_helper_i386_old:
+       pushl           $0
+    .globl _stub_binding_helper
+    .globl _misaligned_stack_error
+_stub_binding_helper:
+       subl            $STACK_SIZE,%esp            # makes stack 16-byte aligned
+       movl            %eax,EAX_SAVE(%esp)     
+       movl            LP_OLD_BP_SAVE(%esp),%eax   # get lazy-pointer meta-parameter
+       movl            %eax,LP_LOCAL(%esp)     
+       movl            %ebp,LP_OLD_BP_SAVE(%esp)   # store epb back chain
+       movl            %esp,%ebp                   # set epb to be this frame
+       add             $LP_OLD_BP_SAVE,%ebp
        movl            %ecx,ECX_SAVE(%esp)
        movl            %edx,EDX_SAVE(%esp)
-       movdqu          %xmm0,XMMM0_SAVE(%esp)
-       movdqu          %xmm1,XMMM1_SAVE(%esp)
-       movdqu          %xmm2,XMMM2_SAVE(%esp)
-       movdqu          %xmm3,XMMM3_SAVE(%esp)
-       movl            MH_PARAM_BP(%ebp),%eax  # call dyld::bindLazySymbol(mh, lazy_ptr)
+       .align 0,0x90
+_misaligned_stack_error:
+       movdqa          %xmm0,XMMM0_SAVE(%esp)
+       movdqa          %xmm1,XMMM1_SAVE(%esp)
+       movdqa          %xmm2,XMMM2_SAVE(%esp)
+       movdqa          %xmm3,XMMM3_SAVE(%esp)
+_stub_binding_helper_interface2:
+       movl            MH_LOCAL(%esp),%eax     # call dyld::bindLazySymbol(mh, lazy_ptr)
        movl            %eax,MH_PARAM_OUT(%esp)
-       movl            LP_PARAM_BP(%ebp),%eax
+       movl            LP_LOCAL(%esp),%eax
        movl            %eax,LP_PARAM_OUT(%esp)
        call            __ZN4dyld14bindLazySymbolEPK11mach_headerPm
-       movl            %eax,RESULT_BP(%ebp)    # store target for ret
-       movdqu          XMMM0_SAVE(%esp),%xmm0  # restore registers
-       movdqu          XMMM1_SAVE(%esp),%xmm1
-       movdqu          XMMM2_SAVE(%esp),%xmm2
-       movdqu          XMMM3_SAVE(%esp),%xmm3
-       movl            EAX_SAVE(%esp),%eax
+       movdqa          XMMM0_SAVE(%esp),%xmm0  # restore registers
+       movdqa          XMMM1_SAVE(%esp),%xmm1
+       movdqa          XMMM2_SAVE(%esp),%xmm2
+       movdqa          XMMM3_SAVE(%esp),%xmm3
        movl            ECX_SAVE(%esp),%ecx
        movl            EDX_SAVE(%esp),%edx
-       addl            $STACK_SIZE,%esp
-       popl            %ebp
-       addl            $4,%esp                                 # remove meta-parameter, other meta-parmaeter now holds target for ret
-       ret
+       movl            %eax,%ebp               # move target address to epb
+       movl            EAX_SAVE(%esp),%eax     # restore eaz
+       addl            $STACK_SIZE+4,%esp      # cut back stack
+       xchg            %ebp, (%esp)            # restore ebp and set target to top of stack
+       ret                                     # jump to target
+    
 #endif /* __i386__ */
 
 
-
-#if __ppc__ || __ppc64__
-#include <architecture/ppc/mode_independent_asm.h>
+#if __x86_64__
+/*
+ * This is the interface for the stub_binding_helper for x86_64:
+ * The caller has pushed the address of the a lazy pointer to be filled in with
+ * the value for the defined symbol and pushed the address of the the mach
+ * header this pointer comes from.
+ *
+ * sp+8        address of lazy pointer
+ * sp+0        address of mach header
+ *
+ * All parameters registers must be preserved.
+ * 
+ * After the symbol has been resolved and the pointer filled in this is to pop
+ * these arguments off the stack and jump to the address of the defined symbol.
+ */
+#define MH_PARAM_BP                    8
+#define LP_PARAM_BP                    16
+
+#define RDI_SAVE                       0
+#define RSI_SAVE                       8
+#define RDX_SAVE                       16
+#define RCX_SAVE                       24
+#define R8_SAVE                                32
+#define R9_SAVE                                40
+#define RAX_SAVE                       48
+#define XMMM0_SAVE                     64    /* 16-byte align */
+#define XMMM1_SAVE                     80
+#define XMMM2_SAVE                     96
+#define XMMM3_SAVE                     112
+#define XMMM4_SAVE                     128
+#define XMMM5_SAVE                     144
+#define XMMM6_SAVE                     160
+#define XMMM7_SAVE                     176
+#define STACK_SIZE                     192 /*  (XMMM7_SAVE+16) must be 16 byte aligned too */
+    
+    .text
+    .align 2,0x90
+    .globl _stub_binding_helper
+_stub_binding_helper:
+       pushq           %rbp
+       movq            %rsp,%rbp
+       subq            $STACK_SIZE,%rsp        # at this point stack is 16-byte aligned because two meta-parameters where pushed
+       movq            %rdi,RDI_SAVE(%rsp)     # save registers that might be used as parameters
+       movq            %rsi,RSI_SAVE(%rsp)
+       movq            %rdx,RDX_SAVE(%rsp)
+       movq            %rcx,RCX_SAVE(%rsp)
+       movq            %r8,R8_SAVE(%rsp)
+       movq            %r9,R9_SAVE(%rsp)
+       movq            %rax,RAX_SAVE(%rsp)
+       movdqa          %xmm0,XMMM0_SAVE(%rsp)
+       movdqa          %xmm1,XMMM1_SAVE(%rsp)
+       movdqa          %xmm2,XMMM2_SAVE(%rsp)
+       movdqa          %xmm3,XMMM3_SAVE(%rsp)
+       movdqa          %xmm4,XMMM4_SAVE(%rsp)
+       movdqa          %xmm5,XMMM5_SAVE(%rsp)
+       movdqa          %xmm6,XMMM6_SAVE(%rsp)
+       movdqa          %xmm7,XMMM7_SAVE(%rsp)
+       movq            MH_PARAM_BP(%rbp),%rdi  # call dyld::bindLazySymbol(mh, lazy_ptr)
+       movq            LP_PARAM_BP(%rbp),%rsi
+       call            __ZN4dyld14bindLazySymbolEPK11mach_headerPm
+       movq            %rax,%r11               # save target
+       movdqa          XMMM0_SAVE(%rsp),%xmm0  # restore registers
+       movdqa          XMMM1_SAVE(%rsp),%xmm1
+       movdqa          XMMM2_SAVE(%rsp),%xmm2
+       movdqa          XMMM3_SAVE(%rsp),%xmm3
+       movdqa          XMMM4_SAVE(%rsp),%xmm4
+       movdqa          XMMM5_SAVE(%rsp),%xmm5
+       movdqa          XMMM6_SAVE(%rsp),%xmm6
+       movdqa          XMMM7_SAVE(%rsp),%xmm7
+       movq            RDI_SAVE(%rsp),%rdi
+       movq            RSI_SAVE(%rsp),%rsi
+       movq            RDX_SAVE(%rsp),%rdx
+       movq            RCX_SAVE(%rsp),%rcx
+       movq            R8_SAVE(%rsp),%r8
+       movq            R9_SAVE(%rsp),%r9
+       movq            RAX_SAVE(%rsp),%rax
+       addq            $STACK_SIZE,%rsp
+       popq            %rbp
+       addq            $16,%rsp                # remove meta-parameters
+       jmp             *%r11                   # jmp to target
+
+#endif
+
+
+#if __arm__ && !__ARM_ARCH_7K__
 /*
- * This is the interface for the stub_binding_helper for the ppc:
- * The caller has placed in r11 the address of the a lazy pointer to be filled
- * in with the value for the defined symbol and placed in r12 the address of
- * the the mach header this pointer comes from.
+ * This is the interface for the old stub_binding_helper for ARM:
+ * The caller has pushed the address of the a lazy pointer to be filled in with
+ * the value for the defined symbol and pushed the address of the the mach
+ * header this pointer comes from.
  *
- * r11 address of lazy pointer
- * r12 address of mach header
+ * sp+4        address of lazy pointer
+ * sp+0        address of mach header
+ * 
+ * After the symbol has been resolved and the pointer filled in this is to pop
+ * these arguments off the stack and jump to the address of the defined symbol.
  */
-#define LRSAVE         MODE_CHOICE(8,16)
-#define STACK_SIZE     MODE_CHOICE(144,288)
-#define R3SAVE          MODE_CHOICE(56,112)
-#define R4SAVE          MODE_CHOICE(60,120)
-#define R5SAVE          MODE_CHOICE(64,128)
-#define R6SAVE          MODE_CHOICE(68,136)
-#define R7SAVE          MODE_CHOICE(72,144)
-#define R8SAVE          MODE_CHOICE(76,152)
-#define R9SAVE          MODE_CHOICE(80,160)
-#define R10SAVE         MODE_CHOICE(84,168)
-
   
        .text
        .align 2
-       .globl _stub_binding_helper_interface
-_stub_binding_helper_interface:
-       mflr    r0                  ; get link register value
-       stg     r0,LRSAVE(r1)       ; save link register value in the linkage area
-       stgu    r1,-STACK_SIZE(r1)  ; save stack pointer and update it
-
-       stg     r3,R3SAVE(r1)   ; save all registers that could contain
-       stg     r4,R4SAVE(r1)   ;  parameters to the routine that is being
-       stg     r5,R5SAVE(r1)   ;  bound.
-       stg     r6,R6SAVE(r1)
-       stg     r7,R7SAVE(r1)
-       stg     r8,R8SAVE(r1)
-       stg     r9,R9SAVE(r1)
-       stg     r10,R10SAVE(r1)
-
-       mr      r3,r12          ; move address of mach header to 1st parameter
-       mr      r4,r11          ; move address of lazy pointer to 2nd parameter
-       ; call dyld::bindLazySymbol(mh, lazy_symbol_pointer_address)
-       bl      __ZN4dyld14bindLazySymbolEPK11mach_headerPm
-       mr      r12,r3          ; move the symbol`s address into r12
-       mtctr   r12             ; move the symbol`s address into count register
-
-       lg      r0,STACK_SIZE+LRSAVE(r1)        ; get old link register value
+       .globl  _stub_binding_helper
+_stub_binding_helper:
+       stmfd   sp!, {r0,r1,r2,r3,r7,lr}        // save registers
+       add     r7, sp, #16                     // point FP to previous FP
 
-       lg      r3,R3SAVE(r1)   ; restore all registers that could contain
-       lg      r4,R4SAVE(r1)   ;  parameters to the routine that was bound.
-       lg      r5,R5SAVE(r1)
-       lg      r6,R6SAVE(r1)
-       lg      r7,R7SAVE(r1)
-       lg      r8,R8SAVE(r1)
-       lg      r9,R9SAVE(r1)
-       lg      r10,R10SAVE(r1)
+       ldr     r0, [sp, #24]                   // move address of mach header to 1st parameter
+       ldr     r1, [sp, #28]                   // move address of lazy pointer to 2nd parameter
 
-       addi    r1,r1,STACK_SIZE; restore old stack pointer
-       mtlr    r0              ; restore link register
+       // call dyld::bindLazySymbol(mh, lazy_symbol_pointer_address)
+       bl      __ZN4dyld14bindLazySymbolEPK11mach_headerPm
+       mov     ip, r0                          // move the symbol`s address into ip
 
-       bctr                    ; jump to the symbol`s address that was bound
+       ldmfd   sp!, {r0,r1,r2,r3,r7,lr}        // restore registers
+       add     sp, sp, #8                      // remove meta-parameters
 
-#endif /* __ppc__ */
+       bx      ip                              // jump to the symbol`s address that was bound
 
+#endif /* __arm__ */