1/*	$NetBSD: rtld_start.S,v 1.16 2011/03/04 00:40:48 matt Exp $	*/
2
3/*-
4 * Copyright (C) 1998	Tsubai Masanari
5 * Portions copyright 2002 Charles M. Hannum <root@ihack.net>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <machine/asm.h>
32
33	.globl	_rtld_start
34	.globl	_rtld
35
36	.text
37
38_rtld_start:
39	stwu	%r1,-48(%r1)
40	stw	%r3,12(%r1)		# argc
41	stw	%r4,16(%r1)		# argv
42	stw	%r5,20(%r1)		# envp
43/*	stw	%r6,24(%r1)		# obj		(always 0) */
44/*	stw	%r7,28(%r1)		# cleanup	(always 0) */
45	stw	%r8,32(%r1)		# ps_strings
46
47	bcl	20,31,1f
481:	mflr	%r30
49	mr	%r3,%r30		# save for _DYNAMIC
50	addis	%r30,%r30,_GLOBAL_OFFSET_TABLE_-1b@ha
51	addi	%r30,%r30,_GLOBAL_OFFSET_TABLE_-1b@l
52	addis	%r3,%r3,_DYNAMIC-1b@ha	# get _DYNAMIC actual address
53	addi	%r3,%r3,_DYNAMIC-1b@l
54	lwz	%r28,0(%r30)		# get base-relative &_DYNAMIC
55	sub	%r28,%r3,%r28		# r28 = relocbase
56	mr	%r4,%r28		# r4 = relocbase
57	bl	_rtld_relocate_nonplt_self
58
59	lwz	%r3,16(%r1)
60	addi	%r3,%r3,-12		# sp = &argv[-3]	/* XXX */
61	mr	%r4,%r28		# r4 = relocbase
62	bl	_rtld			# _start = _rtld(sp, relocbase)
63	mtlr	%r3
64
65	lwz	%r3,12(%r1)		# argc
66	lwz	%r4,16(%r1)		# argv
67	lwz	%r5,20(%r1)		# envp
68	lwz	%r6,-8(%r4)		# obj = sp[1] (== argv[-2])
69	lwz	%r7,-12(%r4)		# cleanup = sp[0] (== argv[-3])
70	lwz	%r8,32(%r1)		# ps_strings
71
72	addi	%r1,%r1,48
73	blrl		# _start(argc, argv, envp, obj, cleanup, ps_strings)
74
75	li	%r0,1			# _exit()
76	sc
77
78END(_rtld_start)
79
80	.globl	_rtld_bind
81
82/*
83 * secure-plt expects %r11 to be the offset to the rela entry.
84 * bss-plt expects %r11 to be index of the rela entry.
85 * So for bss-plt, we multiply the index by 12 to get the offset.
86 */
87ENTRY_NOPROFILE(_rtld_bind_secureplt_start)
88	stwu	%r1,-160(%r1)
89	stw	%r0,20(%r1)
90
91	/*
92	 * Instead of division which is costly we will use multiplicative
93	 * inverse.  a / n = ((a * inv(n)) >> 32)
94	 * where inv(n) = (0x100000000 + n - 1) / n
95	 */
96	mr	%r0,%r11
97	lis	%r11,0x15555556@h	# load multiplicative inverse of 12
98	ori	%r11,%r11,0x15555556@l
99	mulhwu	%r11,%r11,%r0		# get high half of multiplication
100
101	b	1f
102ENTRY_NOPROFILE(_rtld_bind_bssplt_start)
103	stwu	%r1,-160(%r1)
104
105	stw	%r0,20(%r1)
1061:
107	mflr	%r0
108	stw	%r0,16(%r1)		# save lr
109	mfcr	%r0
110	stw	%r0,12(%r1)		# save cr
111	stmw	%r3,24(%r1)		# save r3-r31
112
113	mr	%r3,%r12		# obj
114	mr	%r4,%r11		# reloff
115	bl	_rtld_bind		# _rtld_bind(obj, reloff)
116	mtctr	%r3
117
118	lmw	%r3,24(%r1)		# load r3-r31
119	lwz	%r0,12(%r1)		# restore cr
120	mtcr	%r0
121	lwz	%r0,16(%r1)		# restore lr
122	mtlr	%r0
123	lwz	%r0,20(%r1)
124
125	addi	%r1,%r1,160
126	bctr
127END(_rtld_bind_secureplt_start)
128
129	.globl	_rtld_powerpc_pltcall
130	.globl	_rtld_powerpc_pltresolve
131
132_rtld_powerpc_pltcall:
133	slwi	%r11,%r11,2
134	addis	%r11,%r11,0		# addis	11,11,jmptab@ha
135	lwz	%r11,0(%r11)		# lwz	11,jmptab@l(11)
136	mtctr	%r11
137	bctr
138
139_rtld_powerpc_pltresolve:
140	lis	%r12,0			# lis	12,_rtld_bind_bssplt_start@ha
141	addi	%r12,%r12,0		# addi	12,12,_rtld_bind_bssplt_start@l
142	mtctr	%r12
143	lis	%r12,0			# lis	12,obj@ha
144	addi	%r12,%r12,0		# addi	12,12,obj@l
145	bctr
146