Home | History | Annotate | Line # | Download | only in alpha
rtld_start.S revision 1.4
      1 /*	$NetBSD: rtld_start.S,v 1.4 2001/05/28 06:10:20 nathanw Exp $	*/
      2 
      3 /*
      4  * Copyright 1996 Matt Thomas <matt (at) 3am-software.com>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <machine/asm.h>
     31 
     32 	.extern	_GLOBAL_OFFSET_TABLE_
     33 
     34 /*
     35  * Note: we can call ourselves LEAF even though we use callee-saved
     36  * registers because we're the root of the call graph.
     37  */
     38 LEAF_NOPROFILE(_rtld_start, 0)
     39 	.set	noreorder
     40 	br	pv, L1
     41 L1:	LDGP(pv)
     42 
     43 	/* XXX Partially relocate ourself. */
     44 
     45 	/* Step 1 -- Figure out the displacement */
     46 
     47 	br	t2, L2		/* get our PC */
     48 L2:	ldiq	t3, L2		/* get where the linker thought we were */
     49 	subq	t2, t3, t8	/* calculate the displacement */
     50 
     51 
     52 	/* Step 2 -- Find bounds of global offset table */
     53 
     54 	lda	t5, _GLOBAL_OFFSET_TABLE_
     55 	addq	t8, t5, t9	/* add the displacement */
     56 #if defined(OLD_GOT)
     57 	ldq	t4, 0(t9)	/* Get the address of dynamic table */
     58 #else
     59 	lda	t4, _DYNAMIC
     60 #endif
     61 	addq	t8, t4, t10	/* add the displacement */
     62 
     63 	/*
     64 	 * Step 3 -- Every entry in the global offset table needs to
     65 	 * modified for the displacement before any code will work.
     66 	 */
     67 
     68 L3:	ldq	t1, 0(t9)	/* load the value */
     69 	addq	t8, t1, t1	/* add the displacement */
     70 	stq	t1, 0(t9)	/* save the new value */
     71 	lda	t9, 8(t9)	/* point to next entry */
     72 	cmpult	t9, t10, t1	/* are we done? */
     73 	bne	t1, L3		/* no, do more */
     74 
     75 	/*
     76 	 * Ya!  Things are far enough so we can do some dynamic linking!
     77 	 */
     78 
     79 	/* Squirrel away ps_strings. */
     80 	mov	a3, s0
     81 
     82 	/*
     83 	 * Allocate space on the stack for the cleanup and obj_main
     84 	 * entries that _rtld() will provide for us.
     85 	 */
     86 	lda	sp, -16(sp)
     87 
     88 	mov	sp, a0		/* v0 = _rtld(sp); */
     89 	CALL(_rtld)
     90 
     91 	ldq	a1, 0(sp)	/* cleanup */
     92 	ldq	a2, 8(sp)	/* obj_main */
     93 	lda	sp, 16(sp)	/* pop stack */
     94 
     95 	mov	sp, a0		/* stack pointer */
     96 	mov	s0, a3		/* ps_strings */
     97 
     98 	mov	v0, pv		/* set up PV for entry point */
     99 
    100 	jsr	ra, (v0), 0	/* (*_start)(sp, cleanup, obj, ps_strings); */
    101 	ldgp	gp, 0(ra)
    102 
    103 	CALL(exit)
    104 	halt
    105 END(_rtld_start)
    106 
    107 /*
    108  * Lazy binding entry point, called via PLT.
    109  */
    110 NESTED_NOPROFILE(_rtld_bind_start, 0, 168, ra, 0, 0)
    111 	/* at_reg already used by PLT code. */
    112 	.set	noat
    113 
    114 	/*
    115 	 * Allocate stack frame and preserve all registers that the caller
    116 	 * would have normally saved themselves.
    117 	 */
    118 	lda	sp, -168(sp)
    119 	stq	ra, 0(sp)
    120 	stq	v0, 8(sp)
    121 	stq	t0, 16(sp)
    122 	stq	t1, 24(sp)
    123 	stq	t2, 32(sp)
    124 	stq	t3, 40(sp)
    125 	stq	t4, 48(sp)
    126 	stq	t5, 56(sp)
    127 	stq	t6, 64(sp)
    128 	stq	t7, 72(sp)
    129 	stq	a0, 80(sp)
    130 	stq	a1, 88(sp)
    131 	stq	a2, 96(sp)
    132 	stq	a3, 104(sp)
    133 	stq	a4, 112(sp)
    134 	stq	a5, 120(sp)
    135 	stq	t8, 128(sp)
    136 	stq	t9, 136(sp)
    137 	stq	t10, 144(sp)
    138 	stq	t11, 152(sp)
    139 	stq	gp, 160(sp)
    140 
    141 	/*
    142 	 * Load our global pointer.  Note, can't use pv, since it is
    143 	 * already used by the PLT code.
    144 	 */
    145 	br	t0, L100
    146 L100:	LDGP(t0)
    147 
    148 	/* Set up the arguments for _rtld_bind. */
    149 	ldq	a0, 8(pv)		/* object structure */
    150 	mov	at_reg, a1		/* offset of reloc entry */
    151 	CALL(_rtld_bind)
    152 
    153 	/* Move the destination address into position. */
    154 	mov	v0, pv
    155 
    156 	/* Restore program registers. */
    157 	ldq	ra, 0(sp)
    158 	ldq	v0, 8(sp)
    159 	ldq	t0, 16(sp)
    160 	ldq	t1, 24(sp)
    161 	ldq	t2, 32(sp)
    162 	ldq	t3, 40(sp)
    163 	ldq	t4, 48(sp)
    164 	ldq	t5, 56(sp)
    165 	ldq	t6, 64(sp)
    166 	ldq	t7, 72(sp)
    167 	ldq	a0, 80(sp)
    168 	ldq	a1, 88(sp)
    169 	ldq	a2, 96(sp)
    170 	ldq	a3, 104(sp)
    171 	ldq	a4, 112(sp)
    172 	ldq	a5, 120(sp)
    173 	ldq	t8, 128(sp)
    174 	ldq	t9, 136(sp)
    175 	ldq	t10, 144(sp)
    176 	ldq	t11, 152(sp)
    177 	ldq	gp, 160(sp)
    178 	/* XXX LDGP? */
    179 
    180 	/*
    181 	 * We've patched the PLT; sync the I-stream.
    182 	 */
    183 	imb
    184 
    185 	/* Pop the stack frame and turn control to the destination. */
    186 	lda     sp, 168(sp)
    187 	jmp	zero, (pv)
    188 END(_rtld_bind_start)
    189