134192Sjdp/*- 234192Sjdp * Copyright 1996-1998 John D. Polstra. 334192Sjdp * All rights reserved. 434192Sjdp * 534192Sjdp * Redistribution and use in source and binary forms, with or without 634192Sjdp * modification, are permitted provided that the following conditions 734192Sjdp * are met: 834192Sjdp * 1. Redistributions of source code must retain the above copyright 934192Sjdp * notice, this list of conditions and the following disclaimer. 1034192Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1134192Sjdp * notice, this list of conditions and the following disclaimer in the 1234192Sjdp * documentation and/or other materials provided with the distribution. 1334192Sjdp * 1434192Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1534192Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1634192Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1734192Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1834192Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1934192Sjdp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2034192Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2134192Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2234192Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2334192Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2434192Sjdp * 2550476Speter * $FreeBSD$ 2634192Sjdp */ 2734192Sjdp 2834192Sjdp .text 2934192Sjdp .align 4 3034192Sjdp .globl .rtld_start 3134192Sjdp .type .rtld_start,@function 3234192Sjdp.rtld_start: 33115280Speter xorq %rbp,%rbp # Clear frame pointer for good form 34127254Speter subq $24,%rsp # A place to store exit procedure addr 35115280Speter movq %rdi,%r12 36115280Speter movq %rsp,%rsi # save address of exit proc 37115280Speter movq %rsp,%rdx # construct address of obj_main 38115280Speter addq $8,%rdx 3934192Sjdp call _rtld@PLT # Call rtld(sp); returns entry point 40115280Speter popq %rsi # Get exit procedure address 41115280Speter movq %r12,%rdi # *ap 4234192Sjdp/* 43115280Speter * At this point, %rax contains the entry point of the main program, and 44115280Speter * %rdx contains a pointer to a termination function that should be 4534192Sjdp * registered with atexit(). (crt1.o registers it.) 4634192Sjdp */ 4734192Sjdp.globl .rtld_goto_main 4834192Sjdp.rtld_goto_main: # This symbol exists just to make debugging easier. 49115280Speter jmp *%rax # Enter main program 5034192Sjdp 5134192Sjdp 5234192Sjdp/* 5334192Sjdp * Binder entry point. Control is transferred to here by code in the PLT. 5434192Sjdp * On entry, there are two arguments on the stack. In ascending address 5534192Sjdp * order, they are (1) "obj", a pointer to the calling object's Obj_Entry, 5634192Sjdp * and (2) "reloff", the byte offset of the appropriate relocation entry 5734192Sjdp * in the PLT relocation table. 5834192Sjdp * 59226436Seadler * We are careful to preserve all registers, even the caller-save 6034192Sjdp * registers. That is because this code may be invoked by low-level 6134192Sjdp * assembly-language code that is not ABI-compliant. 62115280Speter * 63115280Speter * Stack map: 64127254Speter * reloff 0x60 65127254Speter * obj 0x58 66127254Speter * spare 0x50 67115280Speter * rflags 0x48 68115280Speter * rax 0x40 69115280Speter * rdx 0x38 70115280Speter * rcx 0x30 71115280Speter * rsi 0x28 72115280Speter * rdi 0x20 73115280Speter * r8 0x18 74115280Speter * r9 0x10 75115280Speter * r10 0x8 76115280Speter * r11 0x0 7734192Sjdp */ 7834192Sjdp .align 4 7934192Sjdp .globl _rtld_bind_start 8034192Sjdp .type _rtld_bind_start,@function 8134192Sjdp_rtld_bind_start: 82127254Speter subq $8,%rsp 83115280Speter pushfq # Save rflags 84115280Speter pushq %rax # Save %rax 85115280Speter pushq %rdx # Save %rdx 86115280Speter pushq %rcx # Save %rcx 87115280Speter pushq %rsi # Save %rsi 88115280Speter pushq %rdi # Save %rdi 89115280Speter pushq %r8 # Save %r8 90115280Speter pushq %r9 # Save %r9 91115280Speter pushq %r10 # Save %r10 92115280Speter pushq %r11 # Save %r11 9334192Sjdp 94127254Speter movq 0x58(%rsp),%rdi # Fetch obj argument 95127254Speter movq 0x60(%rsp),%rsi # Fetch reloff argument 96115280Speter leaq (%rsi,%rsi,2),%rsi # multiply by 3 97115280Speter leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela) 98115280Speter 9934192Sjdp call _rtld_bind@PLT # Transfer control to the binder 100115280Speter /* Now %rax contains the entry point of the function being called. */ 10134192Sjdp 102127254Speter movq %rax,0x60(%rsp) # Store target over reloff argument 103115280Speter popq %r11 # Restore %r11 104115280Speter popq %r10 # Restore %r10 105115280Speter popq %r9 # Restore %r9 106115280Speter popq %r8 # Restore %r8 107115280Speter popq %rdi # Restore %rdi 108115280Speter popq %rsi # Restore %rsi 109115280Speter popq %rcx # Restore %rcx 110115280Speter popq %rdx # Restore %rdx 111115280Speter popq %rax # Restore %rax 112115280Speter popfq # Restore rflags 113127254Speter leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags 11434192Sjdp ret # "Return" to target address 115217103Skib 116217103Skib .section .note.GNU-stack,"",%progbits 117