head	1.17;
access;
symbols
	netbsd-11-0-RC5:1.17
	netbsd-11-0-RC4:1.17
	netbsd-11-0-RC3:1.17
	netbsd-11-0-RC2:1.17
	netbsd-11-0-RC1:1.17
	perseant-exfatfs-base-20250801:1.17
	netbsd-11:1.17.0.2
	netbsd-11-base:1.17
	netbsd-10-1-RELEASE:1.16
	perseant-exfatfs-base-20240630:1.16
	perseant-exfatfs:1.16.0.108
	perseant-exfatfs-base:1.16
	netbsd-8-3-RELEASE:1.16
	netbsd-9-4-RELEASE:1.16
	netbsd-10-0-RELEASE:1.16
	netbsd-10-0-RC6:1.16
	netbsd-10-0-RC5:1.16
	netbsd-10-0-RC4:1.16
	netbsd-10-0-RC3:1.16
	netbsd-10-0-RC2:1.16
	netbsd-10-0-RC1:1.16
	netbsd-10:1.16.0.106
	netbsd-10-base:1.16
	netbsd-9-3-RELEASE:1.16
	cjep_sun2x-base1:1.16
	cjep_sun2x:1.16.0.104
	cjep_sun2x-base:1.16
	cjep_staticlib_x-base1:1.16
	netbsd-9-2-RELEASE:1.16
	cjep_staticlib_x:1.16.0.102
	cjep_staticlib_x-base:1.16
	netbsd-9-1-RELEASE:1.16
	phil-wifi-20200421:1.16
	phil-wifi-20200411:1.16
	is-mlppp:1.16.0.100
	is-mlppp-base:1.16
	phil-wifi-20200406:1.16
	netbsd-8-2-RELEASE:1.16
	netbsd-9-0-RELEASE:1.16
	netbsd-9-0-RC2:1.16
	netbsd-9-0-RC1:1.16
	phil-wifi-20191119:1.16
	netbsd-9:1.16.0.98
	netbsd-9-base:1.16
	phil-wifi-20190609:1.16
	netbsd-8-1-RELEASE:1.16
	netbsd-8-1-RC1:1.16
	pgoyette-compat-merge-20190127:1.16
	pgoyette-compat-20190127:1.16
	pgoyette-compat-20190118:1.16
	pgoyette-compat-1226:1.16
	pgoyette-compat-1126:1.16
	pgoyette-compat-1020:1.16
	pgoyette-compat-0930:1.16
	pgoyette-compat-0906:1.16
	netbsd-7-2-RELEASE:1.16
	pgoyette-compat-0728:1.16
	netbsd-8-0-RELEASE:1.16
	phil-wifi:1.16.0.96
	phil-wifi-base:1.16
	pgoyette-compat-0625:1.16
	netbsd-8-0-RC2:1.16
	pgoyette-compat-0521:1.16
	pgoyette-compat-0502:1.16
	pgoyette-compat-0422:1.16
	netbsd-8-0-RC1:1.16
	pgoyette-compat-0415:1.16
	pgoyette-compat-0407:1.16
	pgoyette-compat-0330:1.16
	pgoyette-compat-0322:1.16
	pgoyette-compat-0315:1.16
	netbsd-7-1-2-RELEASE:1.16
	pgoyette-compat:1.16.0.94
	pgoyette-compat-base:1.16
	netbsd-7-1-1-RELEASE:1.16
	matt-nb8-mediatek:1.16.0.92
	matt-nb8-mediatek-base:1.16
	perseant-stdc-iso10646:1.16.0.90
	perseant-stdc-iso10646-base:1.16
	netbsd-8:1.16.0.88
	netbsd-8-base:1.16
	prg-localcount2-base3:1.16
	prg-localcount2-base2:1.16
	prg-localcount2-base1:1.16
	prg-localcount2:1.16.0.86
	prg-localcount2-base:1.16
	pgoyette-localcount-20170426:1.16
	bouyer-socketcan-base1:1.16
	pgoyette-localcount-20170320:1.16
	netbsd-7-1:1.16.0.84
	netbsd-7-1-RELEASE:1.16
	netbsd-7-1-RC2:1.16
	netbsd-7-nhusb-base-20170116:1.16
	bouyer-socketcan:1.16.0.82
	bouyer-socketcan-base:1.16
	pgoyette-localcount-20170107:1.16
	netbsd-7-1-RC1:1.16
	pgoyette-localcount-20161104:1.16
	netbsd-7-0-2-RELEASE:1.16
	localcount-20160914:1.16
	netbsd-7-nhusb:1.16.0.80
	netbsd-7-nhusb-base:1.16
	pgoyette-localcount-20160806:1.16
	pgoyette-localcount-20160726:1.16
	pgoyette-localcount:1.16.0.78
	pgoyette-localcount-base:1.16
	netbsd-7-0-1-RELEASE:1.16
	netbsd-7-0:1.16.0.76
	netbsd-7-0-RELEASE:1.16
	netbsd-7-0-RC3:1.16
	netbsd-7-0-RC2:1.16
	netbsd-7-0-RC1:1.16
	netbsd-5-2-3-RELEASE:1.16
	netbsd-5-1-5-RELEASE:1.16
	netbsd-6-0-6-RELEASE:1.16
	netbsd-6-1-5-RELEASE:1.16
	netbsd-7:1.16.0.74
	netbsd-7-base:1.16
	yamt-pagecache-base9:1.16
	yamt-pagecache-tag8:1.16
	netbsd-6-1-4-RELEASE:1.16
	netbsd-6-0-5-RELEASE:1.16
	tls-earlyentropy:1.16.0.72
	tls-earlyentropy-base:1.16
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.16
	riastradh-drm2-base3:1.16
	netbsd-6-1-3-RELEASE:1.16
	netbsd-6-0-4-RELEASE:1.16
	netbsd-5-2-2-RELEASE:1.16
	netbsd-5-1-4-RELEASE:1.16
	netbsd-6-1-2-RELEASE:1.16
	netbsd-6-0-3-RELEASE:1.16
	netbsd-5-2-1-RELEASE:1.16
	netbsd-5-1-3-RELEASE:1.16
	netbsd-6-1-1-RELEASE:1.16
	riastradh-drm2-base2:1.16
	riastradh-drm2-base1:1.16
	riastradh-drm2:1.16.0.66
	riastradh-drm2-base:1.16
	netbsd-6-1:1.16.0.70
	netbsd-6-0-2-RELEASE:1.16
	netbsd-6-1-RELEASE:1.16
	netbsd-6-1-RC4:1.16
	netbsd-6-1-RC3:1.16
	agc-symver:1.16.0.68
	agc-symver-base:1.16
	netbsd-6-1-RC2:1.16
	netbsd-6-1-RC1:1.16
	yamt-pagecache-base8:1.16
	netbsd-5-2:1.16.0.64
	netbsd-6-0-1-RELEASE:1.16
	yamt-pagecache-base7:1.16
	netbsd-5-2-RELEASE:1.16
	netbsd-5-2-RC1:1.16
	matt-nb6-plus-nbase:1.16
	yamt-pagecache-base6:1.16
	netbsd-6-0:1.16.0.62
	netbsd-6-0-RELEASE:1.16
	netbsd-6-0-RC2:1.16
	tls-maxphys:1.16.0.60
	tls-maxphys-base:1.16
	matt-nb6-plus:1.16.0.58
	matt-nb6-plus-base:1.16
	netbsd-6-0-RC1:1.16
	yamt-pagecache-base5:1.16
	yamt-pagecache-base4:1.16
	netbsd-6:1.16.0.56
	netbsd-6-base:1.16
	netbsd-5-1-2-RELEASE:1.16
	netbsd-5-1-1-RELEASE:1.16
	yamt-pagecache-base3:1.16
	yamt-pagecache-base2:1.16
	yamt-pagecache:1.16.0.54
	yamt-pagecache-base:1.16
	cherry-xenmp:1.16.0.52
	cherry-xenmp-base:1.16
	bouyer-quota2-nbase:1.16
	bouyer-quota2:1.16.0.50
	bouyer-quota2-base:1.16
	matt-mips64-premerge-20101231:1.16
	matt-nb5-mips64-premerge-20101231:1.16
	matt-nb5-pq3:1.16.0.48
	matt-nb5-pq3-base:1.16
	netbsd-5-1:1.16.0.46
	netbsd-5-1-RELEASE:1.16
	netbsd-5-1-RC4:1.16
	matt-nb5-mips64-k15:1.16
	netbsd-5-1-RC3:1.16
	netbsd-5-1-RC2:1.16
	netbsd-5-1-RC1:1.16
	netbsd-5-0-2-RELEASE:1.16
	matt-nb5-mips64-premerge-20091211:1.16
	matt-premerge-20091211:1.16
	matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.16
	matt-nb4-mips64-k7-u2a-k9b:1.16
	matt-nb5-mips64-u1-k1-k5:1.16
	matt-nb5-mips64:1.16.0.44
	netbsd-5-0-1-RELEASE:1.16
	jym-xensuspend-nbase:1.16
	netbsd-5-0:1.16.0.42
	netbsd-5-0-RELEASE:1.16
	netbsd-5-0-RC4:1.16
	netbsd-5-0-RC3:1.16
	netbsd-5-0-RC2:1.16
	jym-xensuspend:1.16.0.40
	jym-xensuspend-base:1.16
	netbsd-5-0-RC1:1.16
	netbsd-5:1.16.0.38
	netbsd-5-base:1.16
	matt-mips64-base2:1.16
	matt-mips64:1.16.0.36
	mjf-devfs2:1.16.0.34
	mjf-devfs2-base:1.16
	netbsd-4-0-1-RELEASE:1.16
	wrstuden-revivesa-base-3:1.16
	wrstuden-revivesa-base-2:1.16
	wrstuden-fixsa-newbase:1.16
	wrstuden-revivesa-base-1:1.16
	yamt-pf42-base4:1.16
	yamt-pf42-base3:1.16
	hpcarm-cleanup-nbase:1.16
	yamt-pf42-baseX:1.16
	yamt-pf42-base2:1.16
	wrstuden-revivesa:1.16.0.32
	wrstuden-revivesa-base:1.16
	yamt-pf42:1.16.0.30
	yamt-pf42-base:1.16
	keiichi-mipv6:1.16.0.28
	keiichi-mipv6-base:1.16
	matt-armv6-nbase:1.16
	matt-armv6-prevmlocking:1.16
	wrstuden-fixsa-base-1:1.16
	netbsd-4-0:1.16.0.26
	netbsd-4-0-RELEASE:1.16
	cube-autoconf:1.16.0.24
	cube-autoconf-base:1.16
	netbsd-4-0-RC5:1.16
	netbsd-4-0-RC4:1.16
	netbsd-4-0-RC3:1.16
	netbsd-4-0-RC2:1.16
	netbsd-4-0-RC1:1.16
	matt-armv6:1.16.0.22
	matt-armv6-base:1.16
	matt-mips64-base:1.16
	hpcarm-cleanup:1.16.0.20
	hpcarm-cleanup-base:1.16
	netbsd-3-1-1-RELEASE:1.16
	netbsd-3-0-3-RELEASE:1.16
	wrstuden-fixsa:1.16.0.18
	wrstuden-fixsa-base:1.16
	abandoned-netbsd-4-base:1.16
	abandoned-netbsd-4:1.16.0.12
	netbsd-3-1:1.16.0.14
	netbsd-3-1-RELEASE:1.16
	netbsd-3-0-2-RELEASE:1.16
	netbsd-3-1-RC4:1.16
	netbsd-3-1-RC3:1.16
	netbsd-3-1-RC2:1.16
	netbsd-3-1-RC1:1.16
	netbsd-4:1.16.0.16
	netbsd-4-base:1.16
	netbsd-3-0-1-RELEASE:1.16
	netbsd-3-0:1.16.0.10
	netbsd-3-0-RELEASE:1.16
	netbsd-3-0-RC6:1.16
	netbsd-3-0-RC5:1.16
	netbsd-3-0-RC4:1.16
	netbsd-3-0-RC3:1.16
	netbsd-3-0-RC2:1.16
	netbsd-3-0-RC1:1.16
	netbsd-2-0-3-RELEASE:1.16
	netbsd-2-1:1.16.0.8
	netbsd-2-1-RELEASE:1.16
	netbsd-2-1-RC6:1.16
	netbsd-2-1-RC5:1.16
	netbsd-2-1-RC4:1.16
	netbsd-2-1-RC3:1.16
	netbsd-2-1-RC2:1.16
	netbsd-2-1-RC1:1.16
	netbsd-2-0-2-RELEASE:1.16
	netbsd-3:1.16.0.6
	netbsd-3-base:1.16
	netbsd-2-0-1-RELEASE:1.16
	netbsd-2:1.16.0.4
	netbsd-2-base:1.16
	netbsd-2-0-RELEASE:1.16
	netbsd-2-0-RC5:1.16
	netbsd-2-0-RC4:1.16
	netbsd-2-0-RC3:1.16
	netbsd-2-0-RC2:1.16
	netbsd-2-0-RC1:1.16
	netbsd-2-0:1.16.0.2
	netbsd-2-0-base:1.16
	netbsd-1-6-PATCH002-RELEASE:1.8.2.1
	netbsd-1-6-PATCH002:1.8.2.1
	netbsd-1-6-PATCH002-RC4:1.8.2.1
	netbsd-1-6-PATCH002-RC3:1.8.2.1
	netbsd-1-6-PATCH002-RC2:1.8.2.1
	netbsd-1-6-PATCH002-RC1:1.8.2.1
	netbsd-1-6-PATCH001:1.8.2.1
	netbsd-1-6-PATCH001-RELEASE:1.8.2.1
	netbsd-1-6-PATCH001-RC3:1.8.2.1
	netbsd-1-6-PATCH001-RC2:1.8.2.1
	netbsd-1-6-PATCH001-RC1:1.8.2.1
	fvdl_fs64_base:1.15
	netbsd-1-6-RELEASE:1.8
	netbsd-1-6-RC3:1.8
	netbsd-1-6-RC2:1.8
	netbsd-1-6-RC1:1.8
	netbsd-1-6:1.8.0.2
	netbsd-1-6-base:1.8
	netbsd-1-5-PATCH003:1.3.8.1
	netbsd-1-5-PATCH002:1.3
	netbsd-1-5-PATCH001:1.3
	netbsd-1-5-RELEASE:1.3
	netbsd-1-5-BETA2:1.3
	netbsd-1-5-BETA:1.3
	netbsd-1-4-PATCH003:1.1
	netbsd-1-5-ALPHA2:1.3
	netbsd-1-5:1.3.0.8
	netbsd-1-5-base:1.3
	minoura-xpg4dl:1.3.0.6
	minoura-xpg4dl-base:1.3
	netbsd-1-4-PATCH002:1.1
	wrstuden-devbsize-19991221:1.3
	wrstuden-devbsize:1.3.0.4
	wrstuden-devbsize-base:1.3
	comdex-fall-1999:1.3.0.2
	comdex-fall-1999-base:1.3
	netbsd-1-4-PATCH001:1.1
	netbsd-1-4-RELEASE:1.1
	netbsd-1-4:1.1.0.2
	netbsd-1-4-base:1.1;
locks; strict;
comment	@# @;


1.17
date	2025.04.18.17.56.49;	author riastradh;	state Exp;
branches;
next	1.16;
commitid	MYywy6bialwNMyRF;

1.16
date	2004.02.18.23.04.49;	author enami;	state Exp;
branches
	1.16.108.1;
next	1.15;

1.15
date	2002.10.05.11.59.05;	author mycroft;	state Exp;
branches;
next	1.14;

1.14
date	2002.09.12.17.18.37;	author mycroft;	state Exp;
branches;
next	1.13;

1.13
date	2002.09.12.17.07.25;	author mycroft;	state Exp;
branches;
next	1.12;

1.12
date	2002.09.11.20.56.09;	author mycroft;	state Exp;
branches;
next	1.11;

1.11
date	2002.09.11.18.18.37;	author mycroft;	state Exp;
branches;
next	1.10;

1.10
date	2002.09.08.02.48.28;	author thorpej;	state Exp;
branches;
next	1.9;

1.9
date	2002.09.04.19.13.01;	author mycroft;	state Exp;
branches;
next	1.8;

1.8
date	2001.12.14.21.25.23;	author thorpej;	state Exp;
branches
	1.8.2.1;
next	1.7;

1.7
date	2001.12.13.22.34.52;	author thorpej;	state Exp;
branches;
next	1.6;

1.6
date	2001.12.13.21.34.04;	author thorpej;	state Exp;
branches;
next	1.5;

1.5
date	2001.12.13.20.30.48;	author thorpej;	state Exp;
branches;
next	1.4;

1.4
date	2001.05.28.06.10.20;	author nathanw;	state Exp;
branches;
next	1.3;

1.3
date	99.04.19.00.05.00;	author thorpej;	state Exp;
branches
	1.3.8.1;
next	1.2;

1.2
date	99.04.18.23.12.59;	author thorpej;	state Exp;
branches;
next	1.1;

1.1
date	96.12.16.20.38.09;	author cgd;	state Exp;
branches;
next	;

1.16.108.1
date	2025.08.02.05.55.01;	author perseant;	state Exp;
branches;
next	;
commitid	23j6GFaDws3O875G;

1.8.2.1
date	2002.11.30.14.22.19;	author he;	state Exp;
branches;
next	1.8.2.2;

1.8.2.2
date	2004.05.28.08.31.22;	author tron;	state Exp;
branches;
next	;

1.3.8.1
date	2001.12.09.17.23.30;	author he;	state Exp;
branches;
next	;


desc
@@


1.17
log
@ld.elf_so on alpha: Add support for secureplt.

ok thorpej

PR port-alpha/57511: ld.elf_so(1) does not support secure PLT for alpha
PR port-alpha/57717: Alpha linker generates LOAD segments (and
  generates warnings about them)
@
text
@/*	$NetBSD: rtld_start.S,v 1.16 2004/02/18 23:04:49 enami Exp $	*/

/*
 * Copyright 1996 Matt Thomas <matt@@3am-software.com>
 * Portions copyright 2002 Charles M. Hannum <root@@ihack.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <machine/asm.h>

/*
 * Note: we can call ourselves LEAF even though we use callee-saved
 * registers because we're the root of the call graph.
 */
LEAF_NOPROFILE(_rtld_start, 0)
	.set	noreorder
	br	pv, 1f
1:	LDGP(pv)

	/*
	 * Relocate ourself.
	 */
	br	s2, 2f		/* get our PC */
2:	ldiq	s3, 2b		/* get where the linker thought we were */

	subq	s2, s3, a1	/* relocbase */
	lda	t5, _DYNAMIC
	addq	a1, t5, a0	/* &_DYNAMIC */

	/* Squirrel away ps_strings. */
	mov	a3, s0

	bsr	ra, _rtld_relocate_nonplt_self
	LDGP(ra)

	/*
	 * Allocate space on the stack for the cleanup and obj_main
	 * entries that _rtld() will provide for us.
	 */
	lda	sp, -16(sp)

	subq	s2, s3, a1	/* relocbase */
	mov	sp, a0		/* sp */
	CALL(_rtld)		/* v0 = _rtld(sp, relocbase); */

	ldq	a1, 0(sp)	/* cleanup */
	ldq	a2, 8(sp)	/* obj_main */
	lda	sp, 16(sp)	/* pop stack */

	mov	sp, a0		/* stack pointer */
	mov	s0, a3		/* ps_strings */

	mov	v0, pv		/* set up PV for entry point */

	jsr	ra, (v0), 0	/* (*_start)(sp, cleanup, obj, ps_strings); */
	ldgp	gp, 0(ra)

	CALL(exit)
	halt
END(_rtld_start)

#define	RTLD_BIND_START_PROLOGUE					\
	/* at_reg already used by PLT code. */				\
	.set	noat						;	\
									\
	/*								\
	 * Allocate stack frame and preserve all registers that the	\
	 * caller would have normally saved themselves.			\
	 */								\
	lda	sp, -168(sp)					;	\
	stq	ra, 0(sp)					;	\
	stq	v0, 8(sp)					;	\
	stq	t0, 16(sp)	/* XXX t0-t7 necessary? */	;	\
	stq	t1, 24(sp)					;	\
	stq	t2, 32(sp)					;	\
	stq	t3, 40(sp)					;	\
	stq	t4, 48(sp)					;	\
	stq	t5, 56(sp)					;	\
	stq	t6, 64(sp)					;	\
	stq	t7, 72(sp)					;	\
	stq	a0, 80(sp)					;	\
	stq	a1, 88(sp)					;	\
	stq	a2, 96(sp)					;	\
	stq	a3, 104(sp)					;	\
	stq	a4, 112(sp)					;	\
	stq	a5, 120(sp)					;	\
	stq	t8, 128(sp)	/* XXX t8-t11 necessary? */	;	\
	stq	t9, 136(sp)					;	\
	stq	t10, 144(sp)					;	\
	stq	t11, 152(sp)					;	\
	stq	gp, 160(sp)					;	\
									\
	/*								\
	 * Load our global pointer.  Note, can't use pv, since it is	\
	 * already used by the PLT code.				\
	 */								\
	br	t0, 1f						;	\
1:	LDGP(t0)

#define	RTLD_BIND_START_EPILOGUE(imb)					\
	/* Move the destination address into position. */		\
	mov	v0, pv						;	\
									\
	/* Restore program registers. */				\
	ldq	ra, 0(sp)					;	\
	ldq	v0, 8(sp)					;	\
	ldq	t0, 16(sp)					;	\
	ldq	t1, 24(sp)					;	\
	ldq	t2, 32(sp)					;	\
	ldq	t3, 40(sp)					;	\
	ldq	t4, 48(sp)					;	\
	ldq	t5, 56(sp)					;	\
	ldq	t6, 64(sp)					;	\
	ldq	t7, 72(sp)					;	\
	ldq	a0, 80(sp)					;	\
	ldq	a1, 88(sp)					;	\
	ldq	a2, 96(sp)					;	\
	ldq	a3, 104(sp)					;	\
	ldq	a4, 112(sp)					;	\
	ldq	a5, 120(sp)					;	\
	ldq	t8, 128(sp)					;	\
	ldq	t9, 136(sp)					;	\
	ldq	t10, 144(sp)					;	\
	ldq	t11, 152(sp)					;	\
	ldq	gp, 160(sp)					;	\
	/* XXX LDGP? */							\
									\
	/*								\
	 * We've patched the PLT; sync the I-stream.			\
	 */								\
	imb							;	\
									\
	/* Pop the stack frame and turn control to the destination. */	\
	lda     sp, 168(sp)					;	\
	jmp	zero, (pv)

/*
 * _rtld_bind_start_secureplt(_rtld_bind_start_secureplt@@pv, obj@@at,
 *     (sizeof(Elf_Rela)*index)@@t11)
 *
 *	Lazy binding entry point, called via PLT with read-only
 *	secureplt, when DT_ALPHA_PLTRO is set.  The PLT itself looks
 *	something like this:
 *
 *	_PROCEDURE_LINKAGE_TABLE_:
 *		subq	pv, at, t11	// t11 := pv - ent0 = 4*index
 *		s4subq	t11, t11, t11	// t11 := 12*index
 *		addq	t11, t11, t11	// t11 := 24*index
 *					//      = sizeof(Elf_Rela)*index
 *		ldah	at, ...(at)	// at  := PLTGOT
 *		lda	at, ...(at)
 *		ldq	pv, 0(at)	// pv  := PLTGOT[0]
 *					//      = _rtld_bind_start_secureplt
 *		ldq	at, 8(at)	// at  := PLTGOT[1]
 *					//	= obj
 *		jmp	(pv)
 *	0:	br	at, _PROCEDURE_LINKAGE_TABLE_	// at := ent0
 *	ent0:	br	0b		// pv - ent0 = 0 = 4*index
 *	ent1:	br	0b		// pv - ent0 = 4 = 4*index
 *	ent2:	br	0b		// pv - ent0 = 8 = 4*index
 *	...
 */
NESTED_NOPROFILE(_rtld_bind_start_secureplt, 0, 168, ra, 0, 0)

	RTLD_BIND_START_PROLOGUE

	/* Set up the arguments for _rtld_bind. */
	mov	at_reg, a0
	mov	t11, a1

	CALL(_rtld_bind)

	RTLD_BIND_START_EPILOGUE(/* no text writes, so no imb */)

END(_rtld_bind_start_secureplt)

/*
 * _rtld_bind_start(_rtld_bind_start@@pv, &PLTGOT[2]@@pv,
 *     (ent0 + 4*(3*index + 1))@@at)
 *
 *	Lazy binding entry point, called via PLT with read/write
 *	non-secureplt, when DT_ALPHA_PLTRO is not set.  The PLT itself
 *	looks something like this at program startup, with PLTGOT (an
 *	array of 64-bit Elf_Addr) pointing at _PROCEDURE_LINKAGE_TABLE_
 *	and PLTGOT[2] and PLTGOT[3] initialized by _rtld_setup_pltgot:
 *
 *	_PROCEDURE_LINKAGE_TABLE_:
 *		br	pv, .Lref	// pv  := .Lref
 *	.Lref:	ldq	pv, 12(pv)	// pv  := PLTGOT[2]
 *					        = _rtld_bind_start
 *		unop			// no-op for alignment
 *		jmp	pv, (pv)	// pv  := &PLTGOT[2]
 *		.qword	(_rtld_bind_start)	// PLTGOT[2]
 *		.qword	(object pointer)	// PLTGOT[3]
 *	ent0:	br	at, _PROCEDURE_LINKAGE_TABLE_
 *		unop			// space for adjusted stub
 *		unop			// space for adjusted stub
 *	ent1:	br	at, _PROCEDURE_LINKAGE_TABLE_
 *		unop
 *		unop
 *	ent2:	br	at, _PROCEDURE_LINKAGE_TABLE_
 *		unop
 *		unop
 *	...
 *
 *	Note: Distance from &PLTGOT[2] (pv) to ent[0] + 4 (at) is 20
 *	bytes, and each ent[index] + 4 (at) after that is separated by
 *	3 instructions, i.e., 12 bytes.
 */
NESTED_NOPROFILE(_rtld_bind_start, 0, 168, ra, 0, 0)

	RTLD_BIND_START_PROLOGUE

	/* Set up the arguments for _rtld_bind. */
	subq	at_reg, pv, a1		/* calculate offset of reloc entry */
	ldq	a0, 8(pv)		/* object structure */
	subq	a1, 20, a1		/* = (at - pv - 20) / 12 * 24 */
	addq	a1, a1, a1

	CALL(_rtld_bind)

	RTLD_BIND_START_EPILOGUE(imb)

END(_rtld_bind_start)

/*
 * _rtld_bind_start_old(&PLTGOT[2]@@pv, (sizeof(Elf_Rela)*index)@@at)
 *
 *	Lazy binding entry point, called via PLT.  This version is for
 *	the old PLT entry format, for which the PLT looks something
 *	like this at program startup, with PLTGOT (an array of 64-bit
 *	Elf_Addr) pointing at _PROCEDURE_LINKAGE_TABLE_, and PLTGOT[2]
 *	and PLTGOT[3] initialized by _rtld_setup_pltgot:
 *
 *	_PROCEDURE_LINKAGE_TABLE_:
 *		br	pv, 1f		// pv  := .Lref
 *	.Lref:	ldq	pv, 12(pv)	// pv  := PLTGOT[2]
 *					        = _rtld_bind_start
 *		unop			// no-op for alignment
 *		jmp	pv, (pv)	// pv  := &PLTGOT[2]
 *		.qword	(_rtld_bind_start)	// PLTGOT[2]
 *		.qword	(object pointer)	// PLTGOT[3]
 *	ent0:	ldah	at, 0		// at  := 24*0
 *		lda	at, 0(at)	//      = sizeof(Elf_Rela)*index
 *		br	_PROCEDURE_LINKAGE_TABLE_
 *	ent1:	ldah	at, 0		// at  := 24*1
 *		lda	at, 24(at)	//      = sizeof(Elf_Rela)*index
 *		br	_PROCEDURE_LINKAGE_TABLE_
 *	ent3:	ldah	at, 0		// at  := 24*2
 *		lda	at, 48(at)	//      = sizeof(Elf_Rela)*index
 *		br	_PROCEDURE_LINKAGE_TABLE_
 *	...
 */
NESTED_NOPROFILE(_rtld_bind_start_old, 0, 168, ra, 0, 0)

	RTLD_BIND_START_PROLOGUE

	/* Set up the arguments for _rtld_bind. */
	ldq	a0, 8(pv)		/* object structure */
	mov	at_reg, a1		/* offset of reloc entry */

	CALL(_rtld_bind)

	RTLD_BIND_START_EPILOGUE(imb)

END(_rtld_bind_start_old)
@


1.16
log
@Salvage the instruction to save the pointer to ps_strings for later use
so that setproctitle() works again.  The problem reported by Naoki Fukaumi
on japanese mailing list.

Approved by: Ross Harvey
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.15 2002/10/05 11:59:05 mycroft Exp $	*/
d95 1
a95 1
	stq	t0, 16(sp)					;	\
d109 1
a109 1
	stq	t8, 128(sp)					;	\
d122 1
a122 1
#define	RTLD_BIND_START_EPILOGUE					\
d160 71
a230 1
 * Lazy binding entry point, called via PLT.
d244 1
a244 1
	RTLD_BIND_START_EPILOGUE
d249 26
a274 2
 * Lazy binding entry point, called via PLT.  This version is for the
 * old PLT entry format.
d286 1
a286 1
	RTLD_BIND_START_EPILOGUE
@


1.16.108.1
log
@Sync with HEAD
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.17 2025/04/18 17:56:49 riastradh Exp $	*/
d95 1
a95 1
	stq	t0, 16(sp)	/* XXX t0-t7 necessary? */	;	\
d109 1
a109 1
	stq	t8, 128(sp)	/* XXX t8-t11 necessary? */	;	\
d122 1
a122 1
#define	RTLD_BIND_START_EPILOGUE(imb)					\
d160 1
a160 71
 * _rtld_bind_start_secureplt(_rtld_bind_start_secureplt@@pv, obj@@at,
 *     (sizeof(Elf_Rela)*index)@@t11)
 *
 *	Lazy binding entry point, called via PLT with read-only
 *	secureplt, when DT_ALPHA_PLTRO is set.  The PLT itself looks
 *	something like this:
 *
 *	_PROCEDURE_LINKAGE_TABLE_:
 *		subq	pv, at, t11	// t11 := pv - ent0 = 4*index
 *		s4subq	t11, t11, t11	// t11 := 12*index
 *		addq	t11, t11, t11	// t11 := 24*index
 *					//      = sizeof(Elf_Rela)*index
 *		ldah	at, ...(at)	// at  := PLTGOT
 *		lda	at, ...(at)
 *		ldq	pv, 0(at)	// pv  := PLTGOT[0]
 *					//      = _rtld_bind_start_secureplt
 *		ldq	at, 8(at)	// at  := PLTGOT[1]
 *					//	= obj
 *		jmp	(pv)
 *	0:	br	at, _PROCEDURE_LINKAGE_TABLE_	// at := ent0
 *	ent0:	br	0b		// pv - ent0 = 0 = 4*index
 *	ent1:	br	0b		// pv - ent0 = 4 = 4*index
 *	ent2:	br	0b		// pv - ent0 = 8 = 4*index
 *	...
 */
NESTED_NOPROFILE(_rtld_bind_start_secureplt, 0, 168, ra, 0, 0)

	RTLD_BIND_START_PROLOGUE

	/* Set up the arguments for _rtld_bind. */
	mov	at_reg, a0
	mov	t11, a1

	CALL(_rtld_bind)

	RTLD_BIND_START_EPILOGUE(/* no text writes, so no imb */)

END(_rtld_bind_start_secureplt)

/*
 * _rtld_bind_start(_rtld_bind_start@@pv, &PLTGOT[2]@@pv,
 *     (ent0 + 4*(3*index + 1))@@at)
 *
 *	Lazy binding entry point, called via PLT with read/write
 *	non-secureplt, when DT_ALPHA_PLTRO is not set.  The PLT itself
 *	looks something like this at program startup, with PLTGOT (an
 *	array of 64-bit Elf_Addr) pointing at _PROCEDURE_LINKAGE_TABLE_
 *	and PLTGOT[2] and PLTGOT[3] initialized by _rtld_setup_pltgot:
 *
 *	_PROCEDURE_LINKAGE_TABLE_:
 *		br	pv, .Lref	// pv  := .Lref
 *	.Lref:	ldq	pv, 12(pv)	// pv  := PLTGOT[2]
 *					        = _rtld_bind_start
 *		unop			// no-op for alignment
 *		jmp	pv, (pv)	// pv  := &PLTGOT[2]
 *		.qword	(_rtld_bind_start)	// PLTGOT[2]
 *		.qword	(object pointer)	// PLTGOT[3]
 *	ent0:	br	at, _PROCEDURE_LINKAGE_TABLE_
 *		unop			// space for adjusted stub
 *		unop			// space for adjusted stub
 *	ent1:	br	at, _PROCEDURE_LINKAGE_TABLE_
 *		unop
 *		unop
 *	ent2:	br	at, _PROCEDURE_LINKAGE_TABLE_
 *		unop
 *		unop
 *	...
 *
 *	Note: Distance from &PLTGOT[2] (pv) to ent[0] + 4 (at) is 20
 *	bytes, and each ent[index] + 4 (at) after that is separated by
 *	3 instructions, i.e., 12 bytes.
d174 1
a174 1
	RTLD_BIND_START_EPILOGUE(imb)
d179 2
a180 26
 * _rtld_bind_start_old(&PLTGOT[2]@@pv, (sizeof(Elf_Rela)*index)@@at)
 *
 *	Lazy binding entry point, called via PLT.  This version is for
 *	the old PLT entry format, for which the PLT looks something
 *	like this at program startup, with PLTGOT (an array of 64-bit
 *	Elf_Addr) pointing at _PROCEDURE_LINKAGE_TABLE_, and PLTGOT[2]
 *	and PLTGOT[3] initialized by _rtld_setup_pltgot:
 *
 *	_PROCEDURE_LINKAGE_TABLE_:
 *		br	pv, 1f		// pv  := .Lref
 *	.Lref:	ldq	pv, 12(pv)	// pv  := PLTGOT[2]
 *					        = _rtld_bind_start
 *		unop			// no-op for alignment
 *		jmp	pv, (pv)	// pv  := &PLTGOT[2]
 *		.qword	(_rtld_bind_start)	// PLTGOT[2]
 *		.qword	(object pointer)	// PLTGOT[3]
 *	ent0:	ldah	at, 0		// at  := 24*0
 *		lda	at, 0(at)	//      = sizeof(Elf_Rela)*index
 *		br	_PROCEDURE_LINKAGE_TABLE_
 *	ent1:	ldah	at, 0		// at  := 24*1
 *		lda	at, 24(at)	//      = sizeof(Elf_Rela)*index
 *		br	_PROCEDURE_LINKAGE_TABLE_
 *	ent3:	ldah	at, 0		// at  := 24*2
 *		lda	at, 48(at)	//      = sizeof(Elf_Rela)*index
 *		br	_PROCEDURE_LINKAGE_TABLE_
 *	...
d192 1
a192 1
	RTLD_BIND_START_EPILOGUE(imb)
@


1.15
log
@Minor cleanup.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.14 2002/09/12 17:18:37 mycroft Exp $	*/
d52 3
@


1.14
log
@Update comments.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.13 2002/09/12 17:07:25 mycroft Exp $	*/
d5 1
a5 1
 * Portions copyright 2002 Charles M. Hannum.
@


1.13
log
@Pass the calculated relocation offset down to _rtld().
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.12 2002/09/11 20:56:09 mycroft Exp $	*/
d5 1
@


1.12
log
@We don't use _GLOBAL_OFFSET_TABLE_ any more, so don't .global it.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.11 2002/09/11 18:18:37 mycroft Exp $	*/
d44 2
a45 3
	br	t2, 2f		/* get our PC */
2:	ldiq	t3, 2b		/* get where the linker thought we were */
	subq	t2, t3, a1	/* calculate the displacement */
d47 1
d49 1
a49 1
	addq	a1, t5, a0	/* add the displacement */
d60 3
a62 2
	mov	sp, a0		/* v0 = _rtld(sp); */
	CALL(_rtld)
@


1.11
log
@Implement _rtld_relocate_nonplt_self() on Alpha.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.10 2002/09/08 02:48:28 thorpej Exp $	*/
a30 2

	.extern	_GLOBAL_OFFSET_TABLE_
@


1.10
log
@Fix a serious performance problem for large programs on the Alpha.

Large programs need multiple GOTs.  The lazy binding stub in the PLT
can be reached from any of these GOTs, but the dynamic linker only
has enough information to fix up the first GOT entry.  Thus, calls
through the other GOTs went through the time-consuming lazy binding
process on every call.

This fix rewrites the PLT entries themselves to bypass the lazy binding
for those GOT entries that the dynamic linker can't fixup.

Fix from FreeBSD.

Note that now that we patch up the PLT, we need to put back the "imb"
that was removed from the binder exit path.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.8 2001/12/14 21:25:23 thorpej Exp $	*/
a32 1
	.extern _GOT_END_
d43 3
a45 4
	/* XXX Partially relocate ourself. */

	/* Step 1 -- Figure out the displacement */

d48 1
a48 9
	subq	t2, t3, t8	/* calculate the displacement */


	/* Step 2 -- Find bounds of global offset table */

	lda	t5, _GLOBAL_OFFSET_TABLE_
	addq	t8, t5, t9	/* add the displacement */
	lda	t4, _GOT_END_	/* Get the address of the end of the GOT */
	addq	t8, t4, t10	/* add the displacement */
d50 2
a51 15
	/*
	 * Step 3 -- Every entry in the global offset table needs to
	 * modified for the displacement before any code will work.
	 */

3:	ldq	t1, 0(t9)	/* load the value */
	addq	t8, t1, t1	/* add the displacement */
	stq	t1, 0(t9)	/* save the new value */
	lda	t9, 8(t9)	/* point to next entry */
	cmpult	t9, t10, t1	/* are we done? */
	bne	t1, 3b		/* no, do more */

	/*
	 * Ya!  Things are far enough so we can do some dynamic linking!
	 */
d53 2
a54 2
	/* Squirrel away ps_strings. */
	mov	a3, s0
@


1.9
log
@There is no need to do an imb after each call to the binder, because we only
patch the GOT, not the PLT.  However, do an imb when setting up the PLT thunk,
just in case.
@
text
@d170 5
@


1.8
log
@Garbage-collect the OLD_GOT stuff.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.7 2001/12/13 22:34:52 thorpej Exp $	*/
a168 5
									\
	/*								\
	 * We've patched the PLT; sync the I-stream.			\
	 */								\
	imb							;	\
@


1.8.2.1
log
@Pull up revision 1.9 (requested by thorpej in ticket #774):
  There is no need to do an imb after each call to the binder,
  because we only patch the GOT, not the PLT.  However, do
  an imb when setting up the PLT thunk, just in case.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.8 2001/12/14 21:25:23 thorpej Exp $	*/
d169 5
@


1.8.2.2
log
@Apply patch (request by skrll in ticket #1702):
Bring "ld.elf_so" (mostly) in sync with NetBSD-current:
- MI and MD (e.g. under NetBSD-alpha) performance improvements
- RTLD_SELF, RTLD_NEXT, RTLD_DEFAULT support
- much better structured code
- closes PR bin/25464
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.8.2.1 2002/11/30 14:22:19 he Exp $	*/
a4 1
 * Portions copyright 2002 Charles M. Hannum <root@@ihack.net>
d32 3
d44 16
d61 2
a62 1
	 * Relocate ourself.
a63 2
	br	s2, 2f		/* get our PC */
2:	ldiq	s3, 2b		/* get where the linker thought we were */
d65 10
a74 3
	subq	s2, s3, a1	/* relocbase */
	lda	t5, _DYNAMIC
	addq	a1, t5, a0	/* &_DYNAMIC */
a78 3
	bsr	ra, _rtld_relocate_nonplt_self
	LDGP(ra)

d85 2
a86 3
	subq	s2, s3, a1	/* relocbase */
	mov	sp, a0		/* sp */
	CALL(_rtld)		/* v0 = _rtld(sp, relocbase); */
a169 5
	/*								\
	 * We've patched the PLT; sync the I-stream.			\
	 */								\
	imb							;	\
									\
@


1.7
log
@Supply two lazy binding routines for Alpha: one that works with the
old PLT format, and one that works with the new.

XXX We currently always use _rtld_bind_start_old() in
_rtld_setup_alpha_pltgot().  We need to add code to peek
into one of the PLT entries to see which format it's in
and pick the correct binding routine.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.6 2001/12/13 21:34:04 thorpej Exp $	*/
a56 3
#if defined(OLD_GOT)
	ldq	t4, 0(t9)	/* Get the address of dynamic table */
#else
a57 1
#endif
@


1.6
log
@Use numeric labels.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.5 2001/12/13 20:30:48 thorpej Exp $	*/
d108 75
a186 2
	/* at_reg already used by PLT code. */
	.set	noat
d188 1
a188 33
	/*
	 * Allocate stack frame and preserve all registers that the caller
	 * would have normally saved themselves.
	 */
	lda	sp, -168(sp)
	stq	ra, 0(sp)
	stq	v0, 8(sp)
	stq	t0, 16(sp)
	stq	t1, 24(sp)
	stq	t2, 32(sp)
	stq	t3, 40(sp)
	stq	t4, 48(sp)
	stq	t5, 56(sp)
	stq	t6, 64(sp)
	stq	t7, 72(sp)
	stq	a0, 80(sp)
	stq	a1, 88(sp)
	stq	a2, 96(sp)
	stq	a3, 104(sp)
	stq	a4, 112(sp)
	stq	a5, 120(sp)
	stq	t8, 128(sp)
	stq	t9, 136(sp)
	stq	t10, 144(sp)
	stq	t11, 152(sp)
	stq	gp, 160(sp)

	/*
	 * Load our global pointer.  Note, can't use pv, since it is
	 * already used by the PLT code.
	 */
	br	t0, 1f
1:	LDGP(t0)
a190 1
#ifdef NEW_PLT_FORMAT
d195 16
a210 1
#else
d213 1
a213 1
#endif /* NEW_PLT_FORMAT */
d216 1
a216 26
	/* Move the destination address into position. */
	mov	v0, pv

	/* Restore program registers. */
	ldq	ra, 0(sp)
	ldq	v0, 8(sp)
	ldq	t0, 16(sp)
	ldq	t1, 24(sp)
	ldq	t2, 32(sp)
	ldq	t3, 40(sp)
	ldq	t4, 48(sp)
	ldq	t5, 56(sp)
	ldq	t6, 64(sp)
	ldq	t7, 72(sp)
	ldq	a0, 80(sp)
	ldq	a1, 88(sp)
	ldq	a2, 96(sp)
	ldq	a3, 104(sp)
	ldq	a4, 112(sp)
	ldq	a5, 120(sp)
	ldq	t8, 128(sp)
	ldq	t9, 136(sp)
	ldq	t10, 144(sp)
	ldq	t11, 152(sp)
	ldq	gp, 160(sp)
	/* XXX LDGP? */
d218 1
a218 9
	/*
	 * We've patched the PLT; sync the I-stream.
	 */
	imb

	/* Pop the stack frame and turn control to the destination. */
	lda     sp, 168(sp)
	jmp	zero, (pv)
END(_rtld_bind_start)
@


1.5
log
@* Add a linker script which provides a _GOT_END_ symbol that we can
  use to find the end of the GOT, rather than relying on _DYNAMIC
  to immediately follow the GOT.  (A change in current binutils
  moved _DYNAMIC, and thus would have broken our Alpha ld.elf_so).
* Add #ifdef'd out code to deal with the new PLT format.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.4 2001/05/28 06:10:20 nathanw Exp $	*/
d41 2
a42 2
	br	pv, L1
L1:	LDGP(pv)
d48 2
a49 2
	br	t2, L2		/* get our PC */
L2:	ldiq	t3, L2		/* get where the linker thought we were */
d69 1
a69 1
L3:	ldq	t1, 0(t9)	/* load the value */
d74 1
a74 1
	bne	t1, L3		/* no, do more */
d146 2
a147 2
	br	t0, L100
L100:	LDGP(t0)
@


1.4
log
@Correct spelling in a comment.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.3 1999/04/19 00:05:00 thorpej Exp $	*/
d33 1
d60 1
a60 1
	lda	t4, _DYNAMIC
d150 6
d158 1
@


1.3
log
@Simplify _rtld_start() a little, and shave some cycles.  Spefically, there's
no need to save the stack pointer.  Just push the space for the cleanup
and obj_main pointers before calling _rtld(), and pop it after loading those
pointers into the appropriate argument registers for the program entry point.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.2 1999/04/18 23:12:59 thorpej Exp $	*/
d79 1
a79 1
	/* Sqirrel away ps_strings. */
@


1.3.8.1
log
@Pull up revision 1.4 (requested by skrll):
  Add init/fini section support in crtbegin and crtend, and introduce
  support for DWARF2 exception handling.  Fixes PR#12865, PR#13488,
  PR#13489, and PR#13491.  Also fix ld.elf_so to deal appropriately.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.3 1999/04/19 00:05:00 thorpej Exp $	*/
d79 1
a79 1
	/* Squirrel away ps_strings. */
@


1.2
log
@Tidy this up a little.
@
text
@d1 1
a1 1
/*	$NetBSD: rtld_start.S,v 1.1 1996/12/16 20:38:09 cgd Exp $	*/
a42 14
	/*
	 * Save the stack pointer.  This is what we will pass to _rtld().
	 */
	lda	s0, 0(sp)

	/*
	 * Make room for the atexit and cleanup vectors that _rtld() will
	 * provide to us.
	 */
	lda	sp, -16(sp)

	/* Save ps_strings pointer */
	mov	a3, s1

d76 1
a76 1
	 *  Ya!  Things are far enough so we can do some dynamic linking!
d79 20
a98 2
	lda	a0, -16(s0)
	CALL(_rtld)		/* v0 = _rtld(sp); */
a99 6
	ldq	a1, -16(s0)	/* our atexit function */
	ldq	a2, -8(s0)	/* obj_main entry */
	lda	sp, 16(sp)	/* readjust our stack */
	mov	s0, a0		/* stack pointer */
	mov	s1, a3		/* ps_strings pointer */
	mov	v0, t12
@


1.1
log
@First cut at an ELF shared loader.  Originally from John Polstra's FreeBSD elf
kit, then hacked on by Matt Thomas <matt@@3am-software.com>, then by me (to
make it work with new versions of the toolchain, etc.).  This runs, but it's
in serious need of cleaning and/or a fair bit of reworking.  See the README
file for more information, and a list of things to do.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d32 1
a32 1
.extern	_GLOBAL_OFFSET_TABLE_
d34 5
a38 1
LEAF(_rtld_start, 0)		/* XXX */
d40 2
a41 2
	br	pv, $33
$33:	LDGP(pv)
d43 4
a46 1
	/* save away the stack pointer */
d48 4
a51 1
	lda	s0, 0(sp)	/* get argc from stack */
d54 1
a54 1
	/* save ps_strings pointer */
d57 2
d61 2
a62 2
	br	t2, $34		/* get our PC */
$34:	ldiq	t3, $34		/* get where the linker thought we were */
d82 1
a82 1
$35:	ldq	t1, 0(t9)	/* load the value */
d87 1
a87 1
	bne	t1, $35		/* no, do more */
d102 1
a102 1
	jsr	ra, (v0), 0	/* (*_start)(sp, cleanup, obj); */
d109 5
d115 35
a149 33
	.globl	_rtld_bind_start
	.ent	_rtld_bind_start
_rtld_bind_start:

	lda     sp, -168(sp)
	.frame  sp, 168, $26
	/* Preserve all registers that C normally doesn't.  */
	stq     $26, 0(sp)
	stq     $0, 8(sp)
	stq     $1, 16(sp)
	stq     $2, 24(sp)
	stq     $3, 32(sp)
	stq     $4, 40(sp)
	stq     $5, 48(sp)
	stq     $6, 56(sp)
	stq     $7, 64(sp)
	stq     $8, 72(sp)
	stq     $16, 80(sp)
	stq     $17, 88(sp)
	stq     $18, 96(sp)
	stq     $19, 104(sp)
	stq     $20, 112(sp)
	stq     $21, 120(sp)
	stq     $22, 128(sp)
	stq     $23, 136(sp)
	stq     $24, 144(sp)
	stq     $25, 152(sp)
	stq     $29, 160(sp)
	.mask   0x27ff01ff, -168
	/* Set up our $gp */
	br      gp, $100
$100:	ldgp    gp, 0(gp)
	.prologue 1
d151 1
a151 1
	ldq     a0, 8(t12)		/* object structure */
d155 2
a156 31
	/* Move the destination address into position.  */
	mov     $0, $27
	/* Restore program registers.  */
	ldq     $26, 0(sp)
	ldq     $0, 8(sp)
	ldq     $1, 16(sp)
	ldq     $2, 24(sp)
	ldq     $3, 32(sp)
	ldq     $4, 40(sp)
	ldq     $5, 48(sp)
	ldq     $6, 56(sp)
	ldq     $7, 64(sp)
	ldq     $8, 72(sp)
	ldq     $16, 80(sp)
	ldq     $17, 88(sp)
	ldq     $18, 96(sp)
	ldq     $19, 104(sp)
	ldq     $20, 112(sp)
	ldq     $21, 120(sp)
	ldq     $22, 128(sp)
	ldq     $23, 136(sp)
	ldq     $24, 144(sp)
	ldq     $25, 152(sp)
	ldq     $29, 160(sp)
	/* Flush the Icache after having modified the .plt code.  */
	imb
	/* Clean up and turn control to the destination */
	lda     sp, 168(sp)
	jmp     $31, ($27)
	.end _rtld_bind_start
 
d158 23
d182 4
d187 4
@

