]> 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 e2a6d87c247af95fb622847644010b11c46054e2..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@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #ifdef __i386__
 /*
  * This is the interface for the stub_binding_helper for i386:
 #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 
+ * 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 lazy pointer filled in, this jumps
+ * to the target address.
+ */
+#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_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)
+       .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_LOCAL(%esp),%eax
+       movl            %eax,LP_PARAM_OUT(%esp)
+       call            __ZN4dyld14bindLazySymbolEPK11mach_headerPm
+       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
+       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 __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.
  *
  * 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+4        address of lazy pointer
+ * sp+8        address of lazy pointer
  * sp+0        address of mach header
  *
  * 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.
  */
  * 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.
  */
-       .text
-       .align 4,0x90
-       .globl _stub_binding_helper_interface
-_stub_binding_helper_interface:
-       call    __ZN4dyld14bindLazySymbolEPK11mach_headerPm
-       addl    $8,%esp
-       jmpl    %eax
-#endif /* __i386__ */
-
-
-#if __ppc__ || __ppc64__
-#include <architecture/ppc/mode_independent_asm.h>
+#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
   
        .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__ */