+ * 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: