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