1b2b3ffcdSSimon Schubert/*- 2b2b3ffcdSSimon Schubert * Copyright 1996-1998 John D. Polstra. 3b2b3ffcdSSimon Schubert * All rights reserved. 4b2b3ffcdSSimon Schubert * 5b2b3ffcdSSimon Schubert * Redistribution and use in source and binary forms, with or without 6b2b3ffcdSSimon Schubert * modification, are permitted provided that the following conditions 7b2b3ffcdSSimon Schubert * are met: 8b2b3ffcdSSimon Schubert * 1. Redistributions of source code must retain the above copyright 9b2b3ffcdSSimon Schubert * notice, this list of conditions and the following disclaimer. 10b2b3ffcdSSimon Schubert * 2. Redistributions in binary form must reproduce the above copyright 11b2b3ffcdSSimon Schubert * notice, this list of conditions and the following disclaimer in the 12b2b3ffcdSSimon Schubert * documentation and/or other materials provided with the distribution. 13b2b3ffcdSSimon Schubert * 14b2b3ffcdSSimon Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15b2b3ffcdSSimon Schubert * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16b2b3ffcdSSimon Schubert * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17b2b3ffcdSSimon Schubert * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18b2b3ffcdSSimon Schubert * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19b2b3ffcdSSimon Schubert * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20b2b3ffcdSSimon Schubert * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21b2b3ffcdSSimon Schubert * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22b2b3ffcdSSimon Schubert * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23b2b3ffcdSSimon Schubert * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24b2b3ffcdSSimon Schubert * 25f4f4bfd5SJohn Marino * $FreeBSD$ 26b2b3ffcdSSimon Schubert */ 27b2b3ffcdSSimon Schubert 28b2b3ffcdSSimon Schubert/* 29b2b3ffcdSSimon Schubert * Dynamic program start. argv pointer is in %rdi. 30b2b3ffcdSSimon Schubert */ 31b2b3ffcdSSimon Schubert .text 32b2b3ffcdSSimon Schubert .align 4 33b2b3ffcdSSimon Schubert .globl resident_start 34b2b3ffcdSSimon Schubert .globl .rtld_start 35b2b3ffcdSSimon Schubert .type .rtld_start,@function 36b2b3ffcdSSimon Schubertresident_start: 37b2b3ffcdSSimon Schubert.rtld_start: 38b2b3ffcdSSimon Schubert xorq %rbp,%rbp # Clear frame pointer for good form 39b2b3ffcdSSimon Schubert subq $24,%rsp # A place to store exit procedure addr 40b2b3ffcdSSimon Schubert movq %rdi,%r12 41b2b3ffcdSSimon Schubert movq %rsp,%rsi # save address of exit proc 42b2b3ffcdSSimon Schubert movq %rsp,%rdx # construct address of obj_main 43b2b3ffcdSSimon Schubert addq $8,%rdx 44b2b3ffcdSSimon Schubert call _rtld@PLT # Call rtld(sp); returns entry point 45b2b3ffcdSSimon Schubert popq %rsi # Get exit procedure address 46b2b3ffcdSSimon Schubert movq %r12,%rdi # *ap 47b2b3ffcdSSimon Schubert/* 48b2b3ffcdSSimon Schubert * At this point, %rax contains the entry point of the main program, and 49b2b3ffcdSSimon Schubert * %rdx contains a pointer to a termination function that should be 50b2b3ffcdSSimon Schubert * registered with atexit(). (crt1.o registers it.) 51b2b3ffcdSSimon Schubert */ 52b2b3ffcdSSimon Schubert.globl .rtld_goto_main 53b2b3ffcdSSimon Schubert.rtld_goto_main: # This symbol exists just to make debugging easier. 54b2b3ffcdSSimon Schubert jmp *%rax # Enter main program 55b2b3ffcdSSimon Schubert 56b2b3ffcdSSimon Schubert 57b2b3ffcdSSimon Schubert/* 58b2b3ffcdSSimon Schubert * Binder entry point. Control is transferred to here by code in the PLT. 59b2b3ffcdSSimon Schubert * On entry, there are two arguments on the stack. In ascending address 60b2b3ffcdSSimon Schubert * order, they are (1) "obj", a pointer to the calling object's Obj_Entry, 61b2b3ffcdSSimon Schubert * and (2) "reloff", the byte offset of the appropriate relocation entry 62b2b3ffcdSSimon Schubert * in the PLT relocation table. 63b2b3ffcdSSimon Schubert * 6430aefd4fSJohn Marino * We are careful to preserve all registers, even the caller-save 65b2b3ffcdSSimon Schubert * registers. That is because this code may be invoked by low-level 66b2b3ffcdSSimon Schubert * assembly-language code that is not ABI-compliant. 67b2b3ffcdSSimon Schubert * 68b2b3ffcdSSimon Schubert * Stack map: 69b2b3ffcdSSimon Schubert * reloff 0x60 70b2b3ffcdSSimon Schubert * obj 0x58 71b2b3ffcdSSimon Schubert * spare 0x50 72b2b3ffcdSSimon Schubert * rflags 0x48 73b2b3ffcdSSimon Schubert * rax 0x40 74b2b3ffcdSSimon Schubert * rdx 0x38 75b2b3ffcdSSimon Schubert * rcx 0x30 76b2b3ffcdSSimon Schubert * rsi 0x28 77b2b3ffcdSSimon Schubert * rdi 0x20 78b2b3ffcdSSimon Schubert * r8 0x18 79b2b3ffcdSSimon Schubert * r9 0x10 80b2b3ffcdSSimon Schubert * r10 0x8 81b2b3ffcdSSimon Schubert * r11 0x0 82b2b3ffcdSSimon Schubert */ 83b2b3ffcdSSimon Schubert .align 4 84b2b3ffcdSSimon Schubert .globl _rtld_bind_start 85b2b3ffcdSSimon Schubert .type _rtld_bind_start,@function 86b2b3ffcdSSimon Schubert_rtld_bind_start: 87b2b3ffcdSSimon Schubert subq $8,%rsp 88b2b3ffcdSSimon Schubert pushfq # Save rflags 89b2b3ffcdSSimon Schubert pushq %rax # Save %rax 90b2b3ffcdSSimon Schubert pushq %rdx # Save %rdx 91b2b3ffcdSSimon Schubert pushq %rcx # Save %rcx 92b2b3ffcdSSimon Schubert pushq %rsi # Save %rsi 93b2b3ffcdSSimon Schubert pushq %rdi # Save %rdi 94b2b3ffcdSSimon Schubert pushq %r8 # Save %r8 95b2b3ffcdSSimon Schubert pushq %r9 # Save %r9 96b2b3ffcdSSimon Schubert pushq %r10 # Save %r10 97b2b3ffcdSSimon Schubert pushq %r11 # Save %r11 98*9631883eSMatthew Dillon subq $128,%rsp 99*9631883eSMatthew Dillon movups %xmm0,0(%rsp) # Save xmm regs that might be 100*9631883eSMatthew Dillon movups %xmm1,16(%rsp) # used for scratch. clang may 101*9631883eSMatthew Dillon movups %xmm2,32(%rsp) # use them for fast structural copies. 102*9631883eSMatthew Dillon movups %xmm3,48(%rsp) 103*9631883eSMatthew Dillon movups %xmm4,64(%rsp) 104*9631883eSMatthew Dillon movups %xmm5,80(%rsp) 105*9631883eSMatthew Dillon movups %xmm6,96(%rsp) 106*9631883eSMatthew Dillon movups %xmm7,112(%rsp) 107fcf53d9bSJohn Marino 108*9631883eSMatthew Dillon movq 128+0x58(%rsp),%rdi # Fetch obj argument (arg 1) 109*9631883eSMatthew Dillon movq 128+0x60(%rsp),%rsi # Fetch reloff argument (arg 2) 110*9631883eSMatthew Dillon leaq 128+0x68(%rsp),%rdx # Fetch original stack pointer (arg 3) 111b2b3ffcdSSimon Schubert leaq (%rsi,%rsi,2),%rsi # multiply by 3 112b2b3ffcdSSimon Schubert leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela) 113b2b3ffcdSSimon Schubert 114b2b3ffcdSSimon Schubert call _rtld_bind@PLT # Transfer control to the binder 115b2b3ffcdSSimon Schubert /* Now %rax contains the entry point of the function being called. */ 116b2b3ffcdSSimon Schubert 117*9631883eSMatthew Dillon movq %rax,128+0x60(%rsp) # Store target over reloff argument 118*9631883eSMatthew Dillon 119*9631883eSMatthew Dillon movups 0(%rsp),%xmm0 120*9631883eSMatthew Dillon movups 16(%rsp),%xmm1 121*9631883eSMatthew Dillon movups 32(%rsp),%xmm2 122*9631883eSMatthew Dillon movups 48(%rsp),%xmm3 123*9631883eSMatthew Dillon movups 64(%rsp),%xmm4 124*9631883eSMatthew Dillon movups 80(%rsp),%xmm5 125*9631883eSMatthew Dillon movups 96(%rsp),%xmm6 126*9631883eSMatthew Dillon movups 112(%rsp),%xmm7 127*9631883eSMatthew Dillon leaq 128(%rsp),%rsp 128*9631883eSMatthew Dillon 129b2b3ffcdSSimon Schubert popq %r11 # Restore %r11 130b2b3ffcdSSimon Schubert popq %r10 # Restore %r10 131b2b3ffcdSSimon Schubert popq %r9 # Restore %r9 132b2b3ffcdSSimon Schubert popq %r8 # Restore %r8 133b2b3ffcdSSimon Schubert popq %rdi # Restore %rdi 134b2b3ffcdSSimon Schubert popq %rsi # Restore %rsi 135b2b3ffcdSSimon Schubert popq %rcx # Restore %rcx 136b2b3ffcdSSimon Schubert popq %rdx # Restore %rdx 137b2b3ffcdSSimon Schubert popq %rax # Restore %rax 138b2b3ffcdSSimon Schubert popfq # Restore rflags 139*9631883eSMatthew Dillon leaq 16(%rsp),%rsp # Discard spare, obj, 140*9631883eSMatthew Dillon # do not change rflags 141b2b3ffcdSSimon Schubert ret # "Return" to target address 142fcf53d9bSJohn Marino 143fcf53d9bSJohn Marino .section .note.GNU-stack,"",%progbits 144