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