/* * Copyright (c) 2008-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include // simulator does not have full libdyld.dylib - just a small libdyld_sim.dylib #if ! TARGET_IPHONE_SIMULATOR #ifdef __i386__ #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 /* * sp+4 lazy binding info offset * sp+0 address of ImageLoader cache */ .text .align 4,0x90 .globl dyld_stub_binder .globl _misaligned_stack_error dyld_stub_binder: 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) dyld_stub_binder_: movl MH_LOCAL(%esp),%eax # call dyld::fastBindLazySymbol(loadercache, lazyinfo) movl %eax,MH_PARAM_OUT(%esp) movl LP_LOCAL(%esp),%eax movl %eax,LP_PARAM_OUT(%esp) call __Z21_dyld_fast_stub_entryPvl 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 eax 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__ #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 XMM0_SAVE 64 /* 16-byte align */ #define XMM1_SAVE 80 #define XMM2_SAVE 96 #define XMM3_SAVE 112 #define XMM4_SAVE 128 #define XMM5_SAVE 144 #define XMM6_SAVE 160 #define XMM7_SAVE 176 #define YMM0_SAVE 64 #define YMM1_SAVE 96 #define YMM2_SAVE 128 #define YMM3_SAVE 160 #define YMM4_SAVE 192 #define YMM5_SAVE 224 #define YMM6_SAVE 256 #define YMM7_SAVE 288 #define STACK_SIZE 320 /* * sp+4 lazy binding info offset * sp+0 address of ImageLoader cache */ .align 2,0x90 .globl dyld_stub_binder dyld_stub_binder: 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) misaligned_stack_error_entering_dyld_stub_binder: movq $(_COMM_PAGE_CPU_CAPABILITIES), %rax movl (%rax), %eax testl $kHasAVX1_0, %eax jne L2 movdqa %xmm0,XMM0_SAVE(%rsp) movdqa %xmm1,XMM1_SAVE(%rsp) movdqa %xmm2,XMM2_SAVE(%rsp) movdqa %xmm3,XMM3_SAVE(%rsp) movdqa %xmm4,XMM4_SAVE(%rsp) movdqa %xmm5,XMM5_SAVE(%rsp) movdqa %xmm6,XMM6_SAVE(%rsp) movdqa %xmm7,XMM7_SAVE(%rsp) jmp L3 L2: vmovdqu %ymm0,YMM0_SAVE(%rsp) # stack is only 16-byte aligned, so must use unaligned stores for avx registers vmovdqu %ymm1,YMM1_SAVE(%rsp) vmovdqu %ymm2,YMM2_SAVE(%rsp) vmovdqu %ymm3,YMM3_SAVE(%rsp) vmovdqu %ymm4,YMM4_SAVE(%rsp) vmovdqu %ymm5,YMM5_SAVE(%rsp) vmovdqu %ymm6,YMM6_SAVE(%rsp) vmovdqu %ymm7,YMM7_SAVE(%rsp) L3: dyld_stub_binder_: movq MH_PARAM_BP(%rbp),%rdi # call fastBindLazySymbol(loadercache, lazyinfo) movq LP_PARAM_BP(%rbp),%rsi call __Z21_dyld_fast_stub_entryPvl movq %rax,%r11 # save target movq $(_COMM_PAGE_CPU_CAPABILITIES), %rax movl (%rax), %eax testl $kHasAVX1_0, %eax jne L4 movdqa XMM0_SAVE(%rsp),%xmm0 movdqa XMM1_SAVE(%rsp),%xmm1 movdqa XMM2_SAVE(%rsp),%xmm2 movdqa XMM3_SAVE(%rsp),%xmm3 movdqa XMM4_SAVE(%rsp),%xmm4 movdqa XMM5_SAVE(%rsp),%xmm5 movdqa XMM6_SAVE(%rsp),%xmm6 movdqa XMM7_SAVE(%rsp),%xmm7 jmp L5 L4: vmovdqu YMM0_SAVE(%rsp),%ymm0 vmovdqu YMM1_SAVE(%rsp),%ymm1 vmovdqu YMM2_SAVE(%rsp),%ymm2 vmovdqu YMM3_SAVE(%rsp),%ymm3 vmovdqu YMM4_SAVE(%rsp),%ymm4 vmovdqu YMM5_SAVE(%rsp),%ymm5 vmovdqu YMM6_SAVE(%rsp),%ymm6 vmovdqu YMM7_SAVE(%rsp),%ymm7 L5: 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__ /* * sp+4 lazy binding info offset * sp+0 address of ImageLoader cache */ .text .align 2 .globl dyld_stub_binder dyld_stub_binder: stmfd sp!, {r0,r1,r2,r3,r7,lr} // save registers add r7, sp, #16 // point FP to previous FP ldr r0, [sp, #24] // move address ImageLoader cache to 1st parameter ldr r1, [sp, #28] // move lazy info offset 2nd parameter // call dyld::fastBindLazySymbol(loadercache, lazyinfo) bl __Z21_dyld_fast_stub_entryPvl mov ip, r0 // move the symbol`s address into ip ldmfd sp!, {r0,r1,r2,r3,r7,lr} // restore registers add sp, sp, #8 // remove meta-parameters bx ip // jump to the symbol`s address that was bound #endif /* __arm__ */ // simulator does not have full libdyld.dylib - just a small libdyld_sim.dylib #endif // ! TARGET_IPHONE_SIMULATOR