1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License, Version 1.0 only 6*5d9d9091SRichard Lowe * (the "License"). You may not use this file except in compliance 7*5d9d9091SRichard Lowe * with the License. 8*5d9d9091SRichard Lowe * 9*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 11*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 12*5d9d9091SRichard Lowe * and limitations under the License. 13*5d9d9091SRichard Lowe * 14*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 15*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 17*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 18*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 19*5d9d9091SRichard Lowe * 20*5d9d9091SRichard Lowe * CDDL HEADER END 21*5d9d9091SRichard Lowe */ 22*5d9d9091SRichard Lowe/* 23*5d9d9091SRichard Lowe * Copyright (c) 1988 AT&T 24*5d9d9091SRichard Lowe * All Rights Reserved 25*5d9d9091SRichard Lowe * 26*5d9d9091SRichard Lowe * 27*5d9d9091SRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28*5d9d9091SRichard Lowe * Use is subject to license terms. 29*5d9d9091SRichard Lowe */ 30*5d9d9091SRichard Lowe 31*5d9d9091SRichard Lowe/* 32*5d9d9091SRichard Lowe * Bootstrap routine for run-time linker. 33*5d9d9091SRichard Lowe * We get control from exec which has loaded our text and 34*5d9d9091SRichard Lowe * data into the process' address space and created the process 35*5d9d9091SRichard Lowe * stack. 36*5d9d9091SRichard Lowe * 37*5d9d9091SRichard Lowe * On entry, the process stack looks like this: 38*5d9d9091SRichard Lowe * 39*5d9d9091SRichard Lowe * # # <- %rsp 40*5d9d9091SRichard Lowe * #_______________________# high addresses 41*5d9d9091SRichard Lowe * # strings # 42*5d9d9091SRichard Lowe * #_______________________# 43*5d9d9091SRichard Lowe * # 0 word # 44*5d9d9091SRichard Lowe * #_______________________# 45*5d9d9091SRichard Lowe * # Auxiliary # 46*5d9d9091SRichard Lowe * # entries # 47*5d9d9091SRichard Lowe * # ... # 48*5d9d9091SRichard Lowe * # (size varies) # 49*5d9d9091SRichard Lowe * #_______________________# 50*5d9d9091SRichard Lowe * # 0 word # 51*5d9d9091SRichard Lowe * #_______________________# 52*5d9d9091SRichard Lowe * # Environment # 53*5d9d9091SRichard Lowe * # pointers # 54*5d9d9091SRichard Lowe * # ... # 55*5d9d9091SRichard Lowe * # (one word each) # 56*5d9d9091SRichard Lowe * #_______________________# 57*5d9d9091SRichard Lowe * # 0 word # 58*5d9d9091SRichard Lowe * #_______________________# 59*5d9d9091SRichard Lowe * # Argument # low addresses 60*5d9d9091SRichard Lowe * # pointers # 61*5d9d9091SRichard Lowe * # Argc words # 62*5d9d9091SRichard Lowe * #_______________________# 63*5d9d9091SRichard Lowe * # argc # 64*5d9d9091SRichard Lowe * #_______________________# <- %rbp 65*5d9d9091SRichard Lowe * 66*5d9d9091SRichard Lowe * 67*5d9d9091SRichard Lowe * We must calculate the address at which ld.so was loaded, 68*5d9d9091SRichard Lowe * find the addr of the dynamic section of ld.so, of argv[0], and of 69*5d9d9091SRichard Lowe * the process' environment pointers - and pass the thing to _setup 70*5d9d9091SRichard Lowe * to handle. We then call _rtld - on return we jump to the entry 71*5d9d9091SRichard Lowe * point for the executable. 72*5d9d9091SRichard Lowe */ 73*5d9d9091SRichard Lowe 74*5d9d9091SRichard Lowe#if defined(lint) 75*5d9d9091SRichard Lowe 76*5d9d9091SRichard Loweextern unsigned long _setup(); 77*5d9d9091SRichard Loweextern void atexit_fini(); 78*5d9d9091SRichard Lowevoid 79*5d9d9091SRichard Lowemain() 80*5d9d9091SRichard Lowe{ 81*5d9d9091SRichard Lowe (void) _setup(); 82*5d9d9091SRichard Lowe atexit_fini(); 83*5d9d9091SRichard Lowe} 84*5d9d9091SRichard Lowe 85*5d9d9091SRichard Lowe#else 86*5d9d9091SRichard Lowe 87*5d9d9091SRichard Lowe#include <link.h> 88*5d9d9091SRichard Lowe 89*5d9d9091SRichard Lowe .file "boot.s" 90*5d9d9091SRichard Lowe .text 91*5d9d9091SRichard Lowe .globl _rt_boot 92*5d9d9091SRichard Lowe .globl _setup 93*5d9d9091SRichard Lowe .globl _GLOBAL_OFFSET_TABLE_ 94*5d9d9091SRichard Lowe .type _rt_boot,@function 95*5d9d9091SRichard Lowe .align 4 96*5d9d9091SRichard Lowe 97*5d9d9091SRichard Lowe_rt_alias: 98*5d9d9091SRichard Lowe / in case we were invoked from libc.so 99*5d9d9091SRichard Lowe jmp .get_got 100*5d9d9091SRichard Lowe_rt_boot: 101*5d9d9091SRichard Lowe / save for referencing args 102*5d9d9091SRichard Lowe movq %rsp,%rbp 103*5d9d9091SRichard Lowe / make room for a max sized boot vector 104*5d9d9091SRichard Lowe subq $EB_MAX_SIZE64,%rsp 105*5d9d9091SRichard Lowe / use esi as a pointer to &eb[0] 106*5d9d9091SRichard Lowe movq %rsp,%rsi 107*5d9d9091SRichard Lowe / set up tag for argv 108*5d9d9091SRichard Lowe movq $EB_ARGV,0(%rsi) 109*5d9d9091SRichard Lowe / get address of argv 110*5d9d9091SRichard Lowe leaq 8(%rbp),%rax 111*5d9d9091SRichard Lowe / put after tag 112*5d9d9091SRichard Lowe movq %rax,8(%rsi) 113*5d9d9091SRichard Lowe / set up tag for envp 114*5d9d9091SRichard Lowe movq $EB_ENVP,16(%rsi) 115*5d9d9091SRichard Lowe / get # of args 116*5d9d9091SRichard Lowe movq (%rbp),%rax 117*5d9d9091SRichard Lowe / one for the zero & one for argc 118*5d9d9091SRichard Lowe addq $2,%rax 119*5d9d9091SRichard Lowe / now points past args & @ envp 120*5d9d9091SRichard Lowe leaq (%rbp,%rax,8),%rdi 121*5d9d9091SRichard Lowe / set envp 122*5d9d9091SRichard Lowe movq %rdi,24(%rsi) 123*5d9d9091SRichard Lowe / next 124*5d9d9091SRichard Lowe.L0: addq $8,%rdi 125*5d9d9091SRichard Lowe / search for 0 at end of env 126*5d9d9091SRichard Lowe cmpq $0,-8(%rdi) 127*5d9d9091SRichard Lowe jne .L0 128*5d9d9091SRichard Lowe / set up tag for auxv 129*5d9d9091SRichard Lowe movq $EB_AUXV,32(%rsi) 130*5d9d9091SRichard Lowe / point to auxv 131*5d9d9091SRichard Lowe movq %rdi,40(%rsi) 132*5d9d9091SRichard Lowe / set up NULL tag 133*5d9d9091SRichard Lowe movq $EB_NULL,48(%rsi) 134*5d9d9091SRichard Lowe 135*5d9d9091SRichard Lowe / arg1 - address of &eb[0] 136*5d9d9091SRichard Lowe movq %rsi, %rdi 137*5d9d9091SRichard Lowe.get_got: 138*5d9d9091SRichard Lowe leaq _GLOBAL_OFFSET_TABLE_(%rip), %rbx 139*5d9d9091SRichard Lowe / addq $_GLOBAL_OFFSET_TABLE_, %rbx 140*5d9d9091SRichard Lowe movq %rbx,%r9 141*5d9d9091SRichard Lowe // addq $[.L2-.L1], %rbx 142*5d9d9091SRichard Lowe movq %rbx,%r10 143*5d9d9091SRichard Lowe 144*5d9d9091SRichard Lowe movq (%rbx),%rsi 145*5d9d9091SRichard Lowe 146*5d9d9091SRichard Lowe / _setup(&eb[0], _DYNAMIC) 147*5d9d9091SRichard Lowe call _setup@PLT 148*5d9d9091SRichard Lowe / release stack frame 149*5d9d9091SRichard Lowe movq %rbp,%rsp 150*5d9d9091SRichard Lowe 151*5d9d9091SRichard Lowe movq atexit_fini@GOTPCREL(%rip), %rdx 152*5d9d9091SRichard Lowe / transfer control to the executable 153*5d9d9091SRichard Lowe jmp *%rax 154*5d9d9091SRichard Lowe .size _rt_boot,.-_rt_boot 155*5d9d9091SRichard Lowe#endif 156