Home | History | Annotate | Line # | Download | only in alpha
rtld_start.S revision 1.5
      1 /*	$NetBSD: rtld_start.S,v 1.5 2001/12/13 20:30:48 thorpej 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 	.extern _GOT_END_
     34 
     35 /*
     36  * Note: we can call ourselves LEAF even though we use callee-saved
     37  * registers because we're the root of the call graph.
     38  */
     39 LEAF_NOPROFILE(_rtld_start, 0)
     40 	.set	noreorder
     41 	br	pv, L1
     42 L1:	LDGP(pv)
     43 
     44 	/* XXX Partially relocate ourself. */
     45 
     46 	/* Step 1 -- Figure out the displacement */
     47 
     48 	br	t2, L2		/* get our PC */
     49 L2:	ldiq	t3, L2		/* get where the linker thought we were */
     50 	subq	t2, t3, t8	/* calculate the displacement */
     51 
     52 
     53 	/* Step 2 -- Find bounds of global offset table */
     54 
     55 	lda	t5, _GLOBAL_OFFSET_TABLE_
     56 	addq	t8, t5, t9	/* add the displacement */
     57 #if defined(OLD_GOT)
     58 	ldq	t4, 0(t9)	/* Get the address of dynamic table */
     59 #else
     60 	lda	t4, _GOT_END_	/* Get the address of the end of the GOT */
     61 #endif
     62 	addq	t8, t4, t10	/* add the displacement */
     63 
     64 	/*
     65 	 * Step 3 -- Every entry in the global offset table needs to
     66 	 * modified for the displacement before any code will work.
     67 	 */
     68 
     69 L3:	ldq	t1, 0(t9)	/* load the value */
     70 	addq	t8, t1, t1	/* add the displacement */
     71 	stq	t1, 0(t9)	/* save the new value */
     72 	lda	t9, 8(t9)	/* point to next entry */
     73 	cmpult	t9, t10, t1	/* are we done? */
     74 	bne	t1, L3		/* no, do more */
     75 
     76 	/*
     77 	 * Ya!  Things are far enough so we can do some dynamic linking!
     78 	 */
     79 
     80 	/* Squirrel away ps_strings. */
     81 	mov	a3, s0
     82 
     83 	/*
     84 	 * Allocate space on the stack for the cleanup and obj_main
     85 	 * entries that _rtld() will provide for us.
     86 	 */
     87 	lda	sp, -16(sp)
     88 
     89 	mov	sp, a0		/* v0 = _rtld(sp); */
     90 	CALL(_rtld)
     91 
     92 	ldq	a1, 0(sp)	/* cleanup */
     93 	ldq	a2, 8(sp)	/* obj_main */
     94 	lda	sp, 16(sp)	/* pop stack */
     95 
     96 	mov	sp, a0		/* stack pointer */
     97 	mov	s0, a3		/* ps_strings */
     98 
     99 	mov	v0, pv		/* set up PV for entry point */
    100 
    101 	jsr	ra, (v0), 0	/* (*_start)(sp, cleanup, obj, ps_strings); */
    102 	ldgp	gp, 0(ra)
    103 
    104 	CALL(exit)
    105 	halt
    106 END(_rtld_start)
    107 
    108 /*
    109  * Lazy binding entry point, called via PLT.
    110  */
    111 NESTED_NOPROFILE(_rtld_bind_start, 0, 168, ra, 0, 0)
    112 	/* at_reg already used by PLT code. */
    113 	.set	noat
    114 
    115 	/*
    116 	 * Allocate stack frame and preserve all registers that the caller
    117 	 * would have normally saved themselves.
    118 	 */
    119 	lda	sp, -168(sp)
    120 	stq	ra, 0(sp)
    121 	stq	v0, 8(sp)
    122 	stq	t0, 16(sp)
    123 	stq	t1, 24(sp)
    124 	stq	t2, 32(sp)
    125 	stq	t3, 40(sp)
    126 	stq	t4, 48(sp)
    127 	stq	t5, 56(sp)
    128 	stq	t6, 64(sp)
    129 	stq	t7, 72(sp)
    130 	stq	a0, 80(sp)
    131 	stq	a1, 88(sp)
    132 	stq	a2, 96(sp)
    133 	stq	a3, 104(sp)
    134 	stq	a4, 112(sp)
    135 	stq	a5, 120(sp)
    136 	stq	t8, 128(sp)
    137 	stq	t9, 136(sp)
    138 	stq	t10, 144(sp)
    139 	stq	t11, 152(sp)
    140 	stq	gp, 160(sp)
    141 
    142 	/*
    143 	 * Load our global pointer.  Note, can't use pv, since it is
    144 	 * already used by the PLT code.
    145 	 */
    146 	br	t0, L100
    147 L100:	LDGP(t0)
    148 
    149 	/* Set up the arguments for _rtld_bind. */
    150 #ifdef NEW_PLT_FORMAT
    151 	subq	at_reg, pv, a1		/* calculate offset of reloc entry */
    152 	ldq	a0, 8(pv)		/* object structure */
    153 	subq	a1, 20, a1		/* = (at - pv - 20) / 12 * 24 */
    154 	addq	a1, a1, a1
    155 #else
    156 	ldq	a0, 8(pv)		/* object structure */
    157 	mov	at_reg, a1		/* offset of reloc entry */
    158 #endif /* NEW_PLT_FORMAT */
    159 	CALL(_rtld_bind)
    160 
    161 	/* Move the destination address into position. */
    162 	mov	v0, pv
    163 
    164 	/* Restore program registers. */
    165 	ldq	ra, 0(sp)
    166 	ldq	v0, 8(sp)
    167 	ldq	t0, 16(sp)
    168 	ldq	t1, 24(sp)
    169 	ldq	t2, 32(sp)
    170 	ldq	t3, 40(sp)
    171 	ldq	t4, 48(sp)
    172 	ldq	t5, 56(sp)
    173 	ldq	t6, 64(sp)
    174 	ldq	t7, 72(sp)
    175 	ldq	a0, 80(sp)
    176 	ldq	a1, 88(sp)
    177 	ldq	a2, 96(sp)
    178 	ldq	a3, 104(sp)
    179 	ldq	a4, 112(sp)
    180 	ldq	a5, 120(sp)
    181 	ldq	t8, 128(sp)
    182 	ldq	t9, 136(sp)
    183 	ldq	t10, 144(sp)
    184 	ldq	t11, 152(sp)
    185 	ldq	gp, 160(sp)
    186 	/* XXX LDGP? */
    187 
    188 	/*
    189 	 * We've patched the PLT; sync the I-stream.
    190 	 */
    191 	imb
    192 
    193 	/* Pop the stack frame and turn control to the destination. */
    194 	lda     sp, 168(sp)
    195 	jmp	zero, (pv)
    196 END(_rtld_bind_start)
    197