rtld_start.S revision 281453
193354Sphk/*- 293354Sphk * Copyright 1996-1998 John D. Polstra. 393354Sphk * All rights reserved. 493354Sphk * 593354Sphk * Redistribution and use in source and binary forms, with or without 693354Sphk * modification, are permitted provided that the following conditions 793354Sphk * are met: 893354Sphk * 1. Redistributions of source code must retain the above copyright 993354Sphk * notice, this list of conditions and the following disclaimer. 1093354Sphk * 2. Redistributions in binary form must reproduce the above copyright 1193354Sphk * notice, this list of conditions and the following disclaimer in the 1293354Sphk * documentation and/or other materials provided with the distribution. 1393354Sphk * 1493354Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1593354Sphk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1693354Sphk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1793354Sphk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1893354Sphk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1993354Sphk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2093354Sphk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2193354Sphk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2293354Sphk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2393354Sphk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2493354Sphk * 2593354Sphk * $FreeBSD: stable/10/libexec/rtld-elf/amd64/rtld_start.S 281453 2015-04-12 06:45:40Z kib $ 2693354Sphk */ 2793354Sphk 2893354Sphk .text 2993354Sphk .align 4 3093354Sphk .globl .rtld_start 3193354Sphk .type .rtld_start,@function 3293354Sphk.rtld_start: 33116196Sobrien xorq %rbp,%rbp # Clear frame pointer for good form 34116196Sobrien subq $24,%rsp # A place to store exit procedure addr 35116196Sobrien movq %rdi,%r12 3693354Sphk movq %rsp,%rsi # save address of exit proc 37113013Sphk movq %rsp,%rdx # construct address of obj_main 3893354Sphk addq $8,%rdx 39219029Snetchild call _rtld # Call rtld(sp); returns entry point 4093354Sphk popq %rsi # Get exit procedure address 41138732Sphk movq %r12,%rdi # *ap 42106559Snyan/* 4393354Sphk * At this point, %rax contains the entry point of the main program, and 4493354Sphk * %rdx contains a pointer to a termination function that should be 4593354Sphk * registered with atexit(). (crt1.o registers it.) 46235480Savg */ 47223921Sae.globl .rtld_goto_main 48106559Snyan.rtld_goto_main: # This symbol exists just to make debugging easier. 49106559Snyan jmp *%rax # Enter main program 5093354Sphk 5193354Sphk 5293354Sphk/* 53219029Snetchild * Binder entry point. Control is transferred to here by code in the PLT. 54219029Snetchild * On entry, there are two arguments on the stack. In ascending address 5597075Sphk * order, they are (1) "obj", a pointer to the calling object's Obj_Entry, 5693354Sphk * and (2) "reloff", the byte offset of the appropriate relocation entry 5793354Sphk * in the PLT relocation table. 58108591Snyan * 59108591Snyan * We are careful to preserve all registers, even the caller-save 60108591Snyan * registers. That is because this code may be invoked by low-level 6193354Sphk * assembly-language code that is not ABI-compliant. 6293354Sphk * 63108591Snyan * Stack map: 64108650Snyan * reloff 0x60 65108591Snyan * obj 0x58 66108591Snyan * spare 0x50 67108591Snyan * rflags 0x48 68108591Snyan * rax 0x40 69108591Snyan * rdx 0x38 70108591Snyan * rcx 0x30 71123215Sscottl * rsi 0x28 72108591Snyan * rdi 0x20 73108591Snyan * r8 0x18 74108591Snyan * r9 0x10 75108591Snyan * r10 0x8 76108591Snyan * r11 0x0 77108591Snyan */ 78108591Snyan .align 4 79148061Snyan .globl _rtld_bind_start 80148061Snyan .type _rtld_bind_start,@function 81148061Snyan_rtld_bind_start: 82148061Snyan .cfi_startproc 8393354Sphk .cfi_adjust_cfa_offset 16 84148061Snyan subq $8,%rsp 85108591Snyan .cfi_adjust_cfa_offset 8 86108591Snyan pushfq # Save rflags 87108591Snyan .cfi_adjust_cfa_offset 8 88108650Snyan pushq %rax # Save %rax 89108591Snyan .cfi_adjust_cfa_offset 8 90108591Snyan .cfi_offset %rax,-32 91108591Snyan pushq %rdx # Save %rdx 92108591Snyan .cfi_adjust_cfa_offset 8 93108591Snyan .cfi_offset %rdx,-40 94108591Snyan pushq %rcx # Save %rcx 95108591Snyan .cfi_adjust_cfa_offset 8 96108591Snyan .cfi_offset %rcx,-48 97138221Simp pushq %rsi # Save %rsi 98138221Simp .cfi_adjust_cfa_offset 8 99138221Simp .cfi_offset %rsi,-56 100138221Simp pushq %rdi # Save %rdi 101138221Simp .cfi_adjust_cfa_offset 8 102138221Simp .cfi_offset %rdi,-64 103138221Simp pushq %r8 # Save %r8 104138221Simp .cfi_adjust_cfa_offset 8 105138221Simp .cfi_offset %r8,-72 106138221Simp pushq %r9 # Save %r9 107138221Simp .cfi_adjust_cfa_offset 8 108138221Simp .cfi_offset %r9,-80 109138221Simp pushq %r10 # Save %r10 110138221Simp .cfi_adjust_cfa_offset 8 111138221Simp .cfi_offset %r10,-88 112108591Snyan pushq %r11 # Save %r11 113108591Snyan .cfi_adjust_cfa_offset 8 114108591Snyan .cfi_offset %r11,-96 115108591Snyan 116108591Snyan movq 0x58(%rsp),%rdi # Fetch obj argument 117108591Snyan movq 0x60(%rsp),%rsi # Fetch reloff argument 118114414Snyan leaq (%rsi,%rsi,2),%rsi # multiply by 3 119108650Snyan leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela) 120108591Snyan 121108591Snyan call _rtld_bind # Transfer control to the binder 122108591Snyan /* Now %rax contains the entry point of the function being called. */ 123108591Snyan 124108591Snyan movq %rax,0x60(%rsp) # Store target over reloff argument 125108591Snyan popq %r11 # Restore %r11 126108591Snyan .cfi_adjust_cfa_offset -8 127108591Snyan .cfi_restore %r11 128108591Snyan popq %r10 # Restore %r10 129108591Snyan .cfi_adjust_cfa_offset -8 130108591Snyan .cfi_restore %r10 131108591Snyan popq %r9 # Restore %r9 132108591Snyan .cfi_adjust_cfa_offset -8 133108591Snyan .cfi_restore %r9 134108591Snyan popq %r8 # Restore %r8 135108591Snyan .cfi_adjust_cfa_offset -8 136108591Snyan .cfi_restore %r8 137108591Snyan popq %rdi # Restore %rdi 138108591Snyan .cfi_adjust_cfa_offset -8 139113292Sphk .cfi_restore %rdi 140113292Sphk popq %rsi # Restore %rsi 141113292Sphk .cfi_adjust_cfa_offset -8 142113292Sphk .cfi_restore %rsi 143108591Snyan popq %rcx # Restore %rcx 144108591Snyan .cfi_adjust_cfa_offset -8 145108591Snyan .cfi_restore %rcx 146108591Snyan popq %rdx # Restore %rdx 147108591Snyan .cfi_adjust_cfa_offset -8 148108591Snyan .cfi_restore %rdx 149108591Snyan popq %rax # Restore %rax 150108591Snyan .cfi_adjust_cfa_offset -8 151108591Snyan .cfi_restore %rax 152108591Snyan popfq # Restore rflags 153108591Snyan .cfi_adjust_cfa_offset -8 154108591Snyan leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags 155108591Snyan ret # "Return" to target address 156108591Snyan .cfi_endproc 157108591Snyan .size _rtld_bind_start, . - _rtld_bind_start 158108591Snyan 159108591Snyan .section .note.GNU-stack,"",%progbits 160119660Sphk