X-Git-Url: https://git.saurik.com/apple/dyld.git/blobdiff_plain/0959b6d4289bd106fddb7fe7d84a346159895fdd..4a1021af038d99f6d416c0003e1a3f2c6027faac:/src/stub_binding_helper.s?ds=sidebyside diff --git a/src/stub_binding_helper.s b/src/stub_binding_helper.s index e2a6d87..de2d90b 100644 --- a/src/stub_binding_helper.s +++ b/src/stub_binding_helper.s @@ -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,91 +26,194 @@ #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. * - * sp+4 address of lazy pointer + * 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. */ - .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 +#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__ */