10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*4832Srie * Common Development and Distribution License (the "License"). 6*4832Srie * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*4832Srie 220Sstevel@tonic-gate/* 230Sstevel@tonic-gate * Copyright (c) 1988 AT&T 240Sstevel@tonic-gate * All Rights Reserved 250Sstevel@tonic-gate * 26*4832Srie * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 27*4832Srie * Use is subject to license terms. 280Sstevel@tonic-gate */ 290Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate/* 320Sstevel@tonic-gate * Bootstrap routine for ld.so. Control arrives here directly from 330Sstevel@tonic-gate * exec() upon invocation of a dynamically linked program specifying ld.so 340Sstevel@tonic-gate * as its interpreter. 350Sstevel@tonic-gate * 360Sstevel@tonic-gate * On entry, the stack appears as: 370Sstevel@tonic-gate * 380Sstevel@tonic-gate * !_______________________! high addresses 390Sstevel@tonic-gate * ! 0 word ! 400Sstevel@tonic-gate * !_______________________! 410Sstevel@tonic-gate * ! ! 420Sstevel@tonic-gate * ! Information ! 430Sstevel@tonic-gate * ! Block ! 440Sstevel@tonic-gate * ! (size varies) ! 450Sstevel@tonic-gate * !_______________________! 460Sstevel@tonic-gate * ! Auxiliary ! 470Sstevel@tonic-gate * ! vector ! 480Sstevel@tonic-gate * ! 2 word entries ! 490Sstevel@tonic-gate * ! ! 500Sstevel@tonic-gate * !_______________________! 510Sstevel@tonic-gate * ! 0 word ! 520Sstevel@tonic-gate * !_______________________! 530Sstevel@tonic-gate * ! Environment ! 540Sstevel@tonic-gate * ! pointers ! 550Sstevel@tonic-gate * ! ... ! 560Sstevel@tonic-gate * ! (one word each) ! 570Sstevel@tonic-gate * !_______________________! 580Sstevel@tonic-gate * ! 0 word ! 590Sstevel@tonic-gate * !_______________________! 600Sstevel@tonic-gate * ! Argument ! low addresses 610Sstevel@tonic-gate * ! pointers ! 620Sstevel@tonic-gate * ! Argc words ! 630Sstevel@tonic-gate * !_______________________! 640Sstevel@tonic-gate * ! ! 650Sstevel@tonic-gate * ! Argc ! 660Sstevel@tonic-gate * !_______________________! <- %sp + STACK_BIAS + WINDOWSIZE 670Sstevel@tonic-gate * ! ! 680Sstevel@tonic-gate * ! Window save area ! 690Sstevel@tonic-gate * !_______________________! <- %sp + STACK_BIAS 700Sstevel@tonic-gate */ 710Sstevel@tonic-gate 720Sstevel@tonic-gate#if defined(lint) 730Sstevel@tonic-gate 740Sstevel@tonic-gateextern unsigned long _setup(); 750Sstevel@tonic-gateextern void atexit_fini(); 760Sstevel@tonic-gate 770Sstevel@tonic-gatevoid 780Sstevel@tonic-gatemain() 790Sstevel@tonic-gate{ 800Sstevel@tonic-gate (void) _setup(); 810Sstevel@tonic-gate atexit_fini(); 820Sstevel@tonic-gate} 830Sstevel@tonic-gate 840Sstevel@tonic-gate#else 850Sstevel@tonic-gate 860Sstevel@tonic-gate#include <sys/asm_linkage.h> 870Sstevel@tonic-gate#include <sys/param.h> 880Sstevel@tonic-gate#include <link.h> 890Sstevel@tonic-gate 90*4832Srie .file "boot.s" 910Sstevel@tonic-gate .seg ".text" 920Sstevel@tonic-gate .global _rt_boot, _setup, atexit_fini 930Sstevel@tonic-gate .type _rt_boot, #function 940Sstevel@tonic-gate .align 4 950Sstevel@tonic-gate 960Sstevel@tonic-gate! Entry vector 970Sstevel@tonic-gate! +0: normal start 980Sstevel@tonic-gate! +4: normal start 990Sstevel@tonic-gate! +8: alias start (frame exists) XX64 what's this for? 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate_rt_boot: 1020Sstevel@tonic-gate nop 1030Sstevel@tonic-gate ba,a _elf_start 1040Sstevel@tonic-gate ba,a _alias_start 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate! Start up routines 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate_elf_start: 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate! Create a stack frame, perform PIC set up. We have 1110Sstevel@tonic-gate! to determine a bunch of things from our "environment" and 1120Sstevel@tonic-gate! construct an Elf64_Boot attribute value vector. 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate save %sp, -SA(MINFRAME + (EB_MAX * 16)), %sp 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate_alias_start: 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate1: ! PIC prologue 1190Sstevel@tonic-gate call 2f 1200Sstevel@tonic-gate sethi %hh(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1 1210Sstevel@tonic-gate2: or %g1, %hm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1 1220Sstevel@tonic-gate sllx %g1, 32, %g5 1230Sstevel@tonic-gate sethi %lm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7 1240Sstevel@tonic-gate or %l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7 1250Sstevel@tonic-gate or %g5, %l7, %l7 1260Sstevel@tonic-gate add %l7, %o7, %l7 ! finish PIC prologue 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate! %fp points to the root of our ELF bootstrap vector, use it to construct 1290Sstevel@tonic-gate! the vector and send it to _setup. 1300Sstevel@tonic-gate! 1310Sstevel@tonic-gate! The resulting Elf64_Boot vector looks like this: 1320Sstevel@tonic-gate! 1330Sstevel@tonic-gate! Offset Contents 1340Sstevel@tonic-gate! +0x0 EB_ARGV 1350Sstevel@tonic-gate! +0x8 argv[] 1360Sstevel@tonic-gate! +0x10 EB_ENVP 1370Sstevel@tonic-gate! +0x18 envp[] 1380Sstevel@tonic-gate! +0x20 EB_AUXV 1390Sstevel@tonic-gate! +0x28 auxv[] 1400Sstevel@tonic-gate! +0x30 EB_NULL 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate add %sp, STACK_BIAS + SA(MINFRAME), %o0 1430Sstevel@tonic-gate ! &eb[0] == %sp + frame size 1440Sstevel@tonic-gate mov EB_ARGV, %l0 ! code for this entry 1450Sstevel@tonic-gate stx %l0, [%o0] ! store it 1460Sstevel@tonic-gate add %fp, WINDOWSIZE + 8 + STACK_BIAS, %l0 1470Sstevel@tonic-gate ! argument vector 1480Sstevel@tonic-gate stx %l0, [%o0 + 0x8] ! store that 1490Sstevel@tonic-gate ldx [%fp + WINDOWSIZE + STACK_BIAS], %l1 1500Sstevel@tonic-gate ! get argument count (argc) 1510Sstevel@tonic-gate inc %l1 ! account for last element of 0 1520Sstevel@tonic-gate sllx %l1, 3, %l1 ! multiply by 8 1530Sstevel@tonic-gate add %l0, %l1, %l0 ! and get address of first env ptr 1540Sstevel@tonic-gate stx %l0, [%o0 + 0x18] ! store it in the vector 1550Sstevel@tonic-gate mov EB_ENVP, %l1 ! code for environment base 1560Sstevel@tonic-gate stx %l1, [%o0 + 0x10] ! store it 1570Sstevel@tonic-gate mov EB_AUXV, %l1 ! get code for auxiliary vector 1580Sstevel@tonic-gate stx %l1, [%o0 + 0x20] ! store it 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate3: ldx [%l0], %l1 ! get an entry 1610Sstevel@tonic-gate brnz,pt %l1, 3b ! if not at end, go back and look again 1620Sstevel@tonic-gate add %l0, 8, %l0 ! incrementing pointer in delay 1630Sstevel@tonic-gate stx %l0, [%o0 + 0x28] ! store aux vector pointer 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate mov EB_NULL, %l0 ! set up for the last pointer 1660Sstevel@tonic-gate stx %l0, [%o0 + 0x30] ! and store it 1670Sstevel@tonic-gate mov %g0, %g2 ! clear globals 1680Sstevel@tonic-gate mov %g0, %g3 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate! Call _setup. Two arguments, the ELF bootstrap vector and our (unrelocated) 1710Sstevel@tonic-gate! _DYNAMIC address. The _DYNAMIC address is located in entry 0 of the GOT 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate call _setup ! call it 1750Sstevel@tonic-gate ldx [%l7], %o1 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate! On return, give callee the exit function in %g1, and jump to the 1780Sstevel@tonic-gate! target program, clearing out the reserved globals as we go. 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate ldx [%l7 + atexit_fini], %g1! get function address 1810Sstevel@tonic-gate restore %o0, %g0, %l1 ! release frame 1820Sstevel@tonic-gate jmpl %l1, %g0 ! call main program 1830Sstevel@tonic-gate mov %g0, %g4 ! clear one last global in delay 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate .size _rt_boot, . - _rt_boot 1860Sstevel@tonic-gate#endif 187