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