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