rtld_start.S revision 281453
1226586Sdim/*- 2226586Sdim * Copyright 1996-1998 John D. Polstra. 3226586Sdim * All rights reserved. 4226586Sdim * 5226586Sdim * Redistribution and use in source and binary forms, with or without 6226586Sdim * modification, are permitted provided that the following conditions 7226586Sdim * are met: 8226586Sdim * 1. Redistributions of source code must retain the above copyright 9226586Sdim * notice, this list of conditions and the following disclaimer. 10226586Sdim * 2. Redistributions in binary form must reproduce the above copyright 11226586Sdim * notice, this list of conditions and the following disclaimer in the 12226586Sdim * documentation and/or other materials provided with the distribution. 13226586Sdim * 14226586Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15239462Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16226586Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17226586Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18226586Sdim * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19234353Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20226586Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21226586Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22226586Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23226586Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24226586Sdim * 25226586Sdim * $FreeBSD: stable/10/libexec/rtld-elf/amd64/rtld_start.S 281453 2015-04-12 06:45:40Z kib $ 26226586Sdim */ 27226586Sdim 28226586Sdim .text 29234353Sdim .align 4 30234353Sdim .globl .rtld_start 31234353Sdim .type .rtld_start,@function 32234353Sdim.rtld_start: 33234353Sdim xorq %rbp,%rbp # Clear frame pointer for good form 34234353Sdim subq $24,%rsp # A place to store exit procedure addr 35234353Sdim movq %rdi,%r12 36234353Sdim movq %rsp,%rsi # save address of exit proc 37234353Sdim movq %rsp,%rdx # construct address of obj_main 38234353Sdim addq $8,%rdx 39234353Sdim call _rtld # Call rtld(sp); returns entry point 40234353Sdim popq %rsi # Get exit procedure address 41234353Sdim movq %r12,%rdi # *ap 42234353Sdim/* 43234353Sdim * At this point, %rax contains the entry point of the main program, and 44234353Sdim * %rdx contains a pointer to a termination function that should be 45234353Sdim * registered with atexit(). (crt1.o registers it.) 46234353Sdim */ 47234353Sdim.globl .rtld_goto_main 48234353Sdim.rtld_goto_main: # This symbol exists just to make debugging easier. 49226586Sdim jmp *%rax # Enter main program 50226586Sdim 51226586Sdim 52226586Sdim/* 53226586Sdim * Binder entry point. Control is transferred to here by code in the PLT. 54226586Sdim * On entry, there are two arguments on the stack. In ascending address 55226586Sdim * order, they are (1) "obj", a pointer to the calling object's Obj_Entry, 56226586Sdim * and (2) "reloff", the byte offset of the appropriate relocation entry 57226586Sdim * in the PLT relocation table. 58226586Sdim * 59226586Sdim * We are careful to preserve all registers, even the caller-save 60226586Sdim * registers. That is because this code may be invoked by low-level 61226586Sdim * assembly-language code that is not ABI-compliant. 62226586Sdim * 63226586Sdim * Stack map: 64226586Sdim * reloff 0x60 65226586Sdim * obj 0x58 66226586Sdim * spare 0x50 67226586Sdim * rflags 0x48 68226586Sdim * rax 0x40 69226586Sdim * rdx 0x38 70226586Sdim * rcx 0x30 71226586Sdim * rsi 0x28 72226586Sdim * rdi 0x20 73226586Sdim * r8 0x18 74239462Sdim * r9 0x10 75239462Sdim * r10 0x8 76239462Sdim * r11 0x0 77239462Sdim */ 78239462Sdim .align 4 79239462Sdim .globl _rtld_bind_start 80239462Sdim .type _rtld_bind_start,@function 81239462Sdim_rtld_bind_start: 82239462Sdim .cfi_startproc 83239462Sdim .cfi_adjust_cfa_offset 16 84239462Sdim subq $8,%rsp 85239462Sdim .cfi_adjust_cfa_offset 8 86239462Sdim pushfq # Save rflags 87226586Sdim .cfi_adjust_cfa_offset 8 88226586Sdim pushq %rax # Save %rax 89226586Sdim .cfi_adjust_cfa_offset 8 90226586Sdim .cfi_offset %rax,-32 91226586Sdim pushq %rdx # Save %rdx 92226586Sdim .cfi_adjust_cfa_offset 8 93234353Sdim .cfi_offset %rdx,-40 94234353Sdim pushq %rcx # Save %rcx 95226586Sdim .cfi_adjust_cfa_offset 8 96226586Sdim .cfi_offset %rcx,-48 97226586Sdim pushq %rsi # Save %rsi 98226586Sdim .cfi_adjust_cfa_offset 8 99226586Sdim .cfi_offset %rsi,-56 100226586Sdim pushq %rdi # Save %rdi 101226586Sdim .cfi_adjust_cfa_offset 8 102226586Sdim .cfi_offset %rdi,-64 103226586Sdim pushq %r8 # Save %r8 104226586Sdim .cfi_adjust_cfa_offset 8 105226586Sdim .cfi_offset %r8,-72 106226586Sdim pushq %r9 # Save %r9 107226586Sdim .cfi_adjust_cfa_offset 8 108226586Sdim .cfi_offset %r9,-80 109226586Sdim pushq %r10 # Save %r10 110226586Sdim .cfi_adjust_cfa_offset 8 111226586Sdim .cfi_offset %r10,-88 112226586Sdim pushq %r11 # Save %r11 113226586Sdim .cfi_adjust_cfa_offset 8 114226586Sdim .cfi_offset %r11,-96 115226586Sdim 116226586Sdim movq 0x58(%rsp),%rdi # Fetch obj argument 117234353Sdim movq 0x60(%rsp),%rsi # Fetch reloff argument 118226586Sdim leaq (%rsi,%rsi,2),%rsi # multiply by 3 119226586Sdim leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela) 120226586Sdim 121226586Sdim call _rtld_bind # Transfer control to the binder 122226586Sdim /* Now %rax contains the entry point of the function being called. */ 123226586Sdim 124226586Sdim movq %rax,0x60(%rsp) # Store target over reloff argument 125226586Sdim popq %r11 # Restore %r11 126226586Sdim .cfi_adjust_cfa_offset -8 127226586Sdim .cfi_restore %r11 128234353Sdim popq %r10 # Restore %r10 129226586Sdim .cfi_adjust_cfa_offset -8 130226586Sdim .cfi_restore %r10 131226586Sdim popq %r9 # Restore %r9 132226586Sdim .cfi_adjust_cfa_offset -8 133226586Sdim .cfi_restore %r9 134226586Sdim popq %r8 # Restore %r8 135226586Sdim .cfi_adjust_cfa_offset -8 136234353Sdim .cfi_restore %r8 137226586Sdim popq %rdi # Restore %rdi 138226586Sdim .cfi_adjust_cfa_offset -8 139226586Sdim .cfi_restore %rdi 140226586Sdim popq %rsi # Restore %rsi 141226586Sdim .cfi_adjust_cfa_offset -8 142234353Sdim .cfi_restore %rsi 143226586Sdim popq %rcx # Restore %rcx 144226586Sdim .cfi_adjust_cfa_offset -8 145226586Sdim .cfi_restore %rcx 146226586Sdim popq %rdx # Restore %rdx 147226586Sdim .cfi_adjust_cfa_offset -8 148234353Sdim .cfi_restore %rdx 149226586Sdim popq %rax # Restore %rax 150234353Sdim .cfi_adjust_cfa_offset -8 151226586Sdim .cfi_restore %rax 152226586Sdim popfq # Restore rflags 153226586Sdim .cfi_adjust_cfa_offset -8 154226586Sdim leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags 155226586Sdim ret # "Return" to target address 156226586Sdim .cfi_endproc 157226586Sdim .size _rtld_bind_start, . - _rtld_bind_start 158226586Sdim 159234353Sdim .section .note.GNU-stack,"",%progbits 160226586Sdim