rtld_start.S revision 92195
192195Sjake/*	$NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $	*/
292195Sjake
392195Sjake/*-
492195Sjake * Copyright (c) 2001 Jake Burkholder.
592195Sjake * Copyright (c) 2000 Eduardo Horvath.
692195Sjake * Copyright (c) 1999 The NetBSD Foundation, Inc.
792195Sjake * All rights reserved.
892195Sjake *
992195Sjake * This code is derived from software contributed to The NetBSD Foundation
1092195Sjake * by Christos Zoulas and Paul Kranenburg.
1192195Sjake *
1292195Sjake * Redistribution and use in source and binary forms, with or without
1392195Sjake * modification, are permitted provided that the following conditions
1492195Sjake * are met:
1592195Sjake * 1. Redistributions of source code must retain the above copyright
1692195Sjake *    notice, this list of conditions and the following disclaimer.
1792195Sjake * 2. Redistributions in binary form must reproduce the above copyright
1892195Sjake *    notice, this list of conditions and the following disclaimer in the
1992195Sjake *    documentation and/or other materials provided with the distribution.
2092195Sjake * 3. All advertising materials mentioning features or use of this software
2192195Sjake *    must display the following acknowledgement:
2292195Sjake *        This product includes software developed by the NetBSD
2392195Sjake *        Foundation, Inc. and its contributors.
2492195Sjake * 4. Neither the name of The NetBSD Foundation nor the names of its
2592195Sjake *    contributors may be used to endorse or promote products derived
2692195Sjake *    from this software without specific prior written permission.
2792195Sjake *
2892195Sjake * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2992195Sjake * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
3092195Sjake * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3192195Sjake * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3292195Sjake * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3392195Sjake * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3492195Sjake * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3592195Sjake * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3692195Sjake * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3792195Sjake * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3892195Sjake * POSSIBILITY OF SUCH DAMAGE.
3992195Sjake *
4092195Sjake * $FreeBSD: head/libexec/rtld-elf/sparc64/rtld_start.S 92195 2002-03-13 02:40:39Z jake $
4192195Sjake */
4292195Sjake
4392195Sjake#include <machine/asm.h>
4492195Sjake
4592195Sjake/*
4692195Sjake * ELF:
4792195Sjake *	On startup the stack should contain 16 extended word register save
4892195Sjake *	area, followed by the arg count, etc.
4992195Sjake */
5092195Sjake
5192195SjakeENTRY(.rtld_start)
5292195Sjake	clr	%fp
5392195Sjake	mov	%o0, %l0
5492195Sjake	mov	%o3, %l1
5592195Sjake
5692195Sjake	sub	%sp, 16, %sp
5792195Sjake	add	%sp, SPOFF + CCFSZ + 0x0, %o1
5892195Sjake	call	_rtld
5992195Sjake	 add	%sp, SPOFF + CCFSZ + 0x8, %o2
6092195Sjake
6192195Sjake	ldx	[%sp + SPOFF + CCFSZ + 0x0], %o1
6292195Sjake	ldx	[%sp + SPOFF + CCFSZ + 0x8], %o2
6392195Sjake	add	%sp, 16, %sp
6492195Sjake
6592195Sjake	mov	%l1, %o3
6692195Sjake	jmp	%o0
6792195Sjake	 mov	%l0, %o0
6892195Sjake
6992195Sjake	/*
7092195Sjake	 * We have two separate entry points to the runtime linker.
7192195Sjake	 * I'm implementing this following the SPARC v9 ABI spec.
7292195Sjake	 *
7392195Sjake	 * _rtld_bind_start_0(x, y) is called from .PLT0, and is used for
7492195Sjake	 * PLT entries above 32768.
7592195Sjake	 *
7692195Sjake	 * _rtld_bind_start_1(x, y) is called from .PLT1, and is used for
7792195Sjake	 * PLT entries below 32768.
7892195Sjake	 *
7992195Sjake	 * The first two entries of PLT2 contain the xword object pointer.
8092195Sjake	 *
8192195Sjake	 * These routines are called with two longword arguments,
8292195Sjake	 * x and y.  To calculate the address of the entry,
8392195Sjake	 * _rtld_bind_start_1(x, y) does:
8492195Sjake	 *
8592195Sjake	 *	n = x >> 15;
8692195Sjake	 *
8792195Sjake	 * and _rtld_bind_start_0(x, y) does:
8892195Sjake	 *
8992195Sjake	 *	i = x - y + 1048596;
9092195Sjake	 *	n = 32768 + (i/5120)*160 + (i%5120)/24;
9192195Sjake	 *
9292195Sjake	 * Neither routine needs to issue a save since it's already been
9392195Sjake	 * done in the PLT entry.
9492195Sjake	 */
9592195Sjake
9692195SjakeENTRY(_rtld_bind_start_0)
9792195Sjake	sethi	%hi(1048596), %l1
9892195Sjake	sub	%o0, %o1, %l0		/* x - y */
9992195Sjake	or	%l1, %lo(1048596), %l1
10092195Sjake	add	%l0, %l1, %l0		/* x - y + 1048596 */
10192195Sjake
10292195Sjake	sdivx	%l0, 5120, %l1		/* Calculate i/5120 */
10392195Sjake	ldx	[%o1 + (10*4)], %o0	/* Load object pointer from PLT2 */
10492195Sjake	sub	%l0, %l1, %l2		/* And i%5120 */
10592195Sjake
10692195Sjake	/* Let the division churn for a bit. */
10792195Sjake	sdivx	%l2, 14, %l4		/* (i%5120)/24 */
10892195Sjake
10992195Sjake	/* 160 is (32 * 5) or (32 * (4 + 1)) */
11092195Sjake	sllx	%l1, 2, %l3		/* 4 * (i/5120) */
11192195Sjake	add	%l1, %l3, %l3		/* 5 * (i/5120) */
11292195Sjake	sllx	%l3, 5, %l3		/* 32 * 5 * (i/5120) */
11392195Sjake
11492195Sjake	sethi	%hi(32768), %l6
11592195Sjake	add	%l3, %l4, %l5		/* %l5 = (i/5120)*160 + (i%5120)/24; */
11692195Sjake	add	%l5, %l6, %l5
11792195Sjake
11892195Sjake	sllx	%l5, 1, %l6		/* Each element is an Elf_Rela which */
11992195Sjake	add	%l6, %l5, %l5		/*  is 3 longwords or 24 bytes. */
12092195Sjake	sllx	%l5, 3, %l5		/*  So multiply by 24. */
12192195Sjake
12292195Sjake	call	_rtld_bind		/* Call _rtld_bind(obj, offset) */
12392195Sjake	 mov	%l5, %o1
12492195Sjake
12592195Sjake	jmp	%o0			/* return value == function address */
12692195Sjake	 restore			/* Dump our stack frame */
12792195Sjake
12892195SjakeENTRY(_rtld_bind_start_1)
12992195Sjake	srax	%o0, 15, %o2		/* %o0 is the index to our PLT slot */
13092195Sjake	sub	%o2, 4, %o2		/* XXX:	4 entries are reserved */
13192195Sjake
13292195Sjake	sllx	%o2, 1, %o3		/* Each element is an Elf_Rela which */
13392195Sjake	add	%o3, %o2, %o2		/*  is 3 longwords or 24 bytes. */
13492195Sjake	sllx	%o2, 3, %o2		/*  So multiply by 24. */
13592195Sjake
13692195Sjake	ldx	[%o1 + 8], %o0		/* The object pointer is at [%o1 + 8] */
13792195Sjake
13892195Sjake	call	_rtld_bind		/* Call _rtld_bind(obj, offset) */
13992195Sjake	 mov	%o2, %o1
14092195Sjake
14192195Sjake	jmp	%o0			/* return value == function address */
14292195Sjake	 restore			/* Dump our stack frame */
14392195Sjake
144