xref: /netbsd-src/libexec/ld.elf_so/arch/powerpc/rtld_start.S (revision b7e0bd366214f5156bb40bf9f35475686410607f)
1*b7e0bd36Smrg/*	$NetBSD: rtld_start.S,v 1.17 2011/09/26 01:52:22 mrg Exp $	*/
2775e7035Stsubai
3775e7035Stsubai/*-
4775e7035Stsubai * Copyright (C) 1998	Tsubai Masanari
5ad8ccd62Smycroft * Portions copyright 2002 Charles M. Hannum <root@ihack.net>
6775e7035Stsubai * All rights reserved.
7775e7035Stsubai *
8775e7035Stsubai * Redistribution and use in source and binary forms, with or without
9775e7035Stsubai * modification, are permitted provided that the following conditions
10775e7035Stsubai * are met:
11775e7035Stsubai * 1. Redistributions of source code must retain the above copyright
12775e7035Stsubai *    notice, this list of conditions and the following disclaimer.
13775e7035Stsubai * 2. Redistributions in binary form must reproduce the above copyright
14775e7035Stsubai *    notice, this list of conditions and the following disclaimer in the
15775e7035Stsubai *    documentation and/or other materials provided with the distribution.
16775e7035Stsubai * 3. The name of the author may not be used to endorse or promote products
17775e7035Stsubai *    derived from this software without specific prior written permission.
18775e7035Stsubai *
19775e7035Stsubai * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20775e7035Stsubai * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21775e7035Stsubai * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22775e7035Stsubai * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23775e7035Stsubai * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24775e7035Stsubai * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25775e7035Stsubai * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26775e7035Stsubai * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27775e7035Stsubai * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28775e7035Stsubai * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29775e7035Stsubai */
30775e7035Stsubai
31775e7035Stsubai#include <machine/asm.h>
32775e7035Stsubai
33775e7035Stsubai	.globl	_rtld_start
34775e7035Stsubai	.globl	_rtld
35775e7035Stsubai
36775e7035Stsubai	.text
37775e7035Stsubai
38775e7035Stsubai_rtld_start:
3901ba93bcSmatt	stwu	%r1,-48(%r1)
4001ba93bcSmatt	stw	%r3,12(%r1)		# argc
4101ba93bcSmatt	stw	%r4,16(%r1)		# argv
4201ba93bcSmatt	stw	%r5,20(%r1)		# envp
4301ba93bcSmatt/*	stw	%r6,24(%r1)		# obj		(always 0) */
4401ba93bcSmatt/*	stw	%r7,28(%r1)		# cleanup	(always 0) */
4501ba93bcSmatt	stw	%r8,32(%r1)		# ps_strings
46775e7035Stsubai
47d31dbd75Smatt	bcl	20,31,1f
48d31dbd75Smatt1:	mflr	%r30
49d31dbd75Smatt	mr	%r3,%r30		# save for _DYNAMIC
50d31dbd75Smatt	addis	%r30,%r30,_GLOBAL_OFFSET_TABLE_-1b@ha
51d31dbd75Smatt	addi	%r30,%r30,_GLOBAL_OFFSET_TABLE_-1b@l
52d31dbd75Smatt	addis	%r3,%r3,_DYNAMIC-1b@ha	# get _DYNAMIC actual address
53d31dbd75Smatt	addi	%r3,%r3,_DYNAMIC-1b@l
54d31dbd75Smatt	lwz	%r28,0(%r30)		# get base-relative &_DYNAMIC
55d31dbd75Smatt	sub	%r28,%r3,%r28		# r28 = relocbase
56044aeabaSthorpej	mr	%r4,%r28		# r4 = relocbase
57d31dbd75Smatt	bl	_rtld_relocate_nonplt_self
58775e7035Stsubai
5901ba93bcSmatt	lwz	%r3,16(%r1)
6001ba93bcSmatt	addi	%r3,%r3,-12		# sp = &argv[-3]	/* XXX */
61044aeabaSthorpej	mr	%r4,%r28		# r4 = relocbase
62d31dbd75Smatt	bl	_rtld			# _start = _rtld(sp, relocbase)
6301ba93bcSmatt	mtlr	%r3
64775e7035Stsubai
6501ba93bcSmatt	lwz	%r3,12(%r1)		# argc
6601ba93bcSmatt	lwz	%r4,16(%r1)		# argv
6701ba93bcSmatt	lwz	%r5,20(%r1)		# envp
6801ba93bcSmatt	lwz	%r6,-8(%r4)		# obj = sp[1] (== argv[-2])
6901ba93bcSmatt	lwz	%r7,-12(%r4)		# cleanup = sp[0] (== argv[-3])
7001ba93bcSmatt	lwz	%r8,32(%r1)		# ps_strings
71775e7035Stsubai
7201ba93bcSmatt	addi	%r1,%r1,48
73775e7035Stsubai	blrl		# _start(argc, argv, envp, obj, cleanup, ps_strings)
74775e7035Stsubai
7501ba93bcSmatt	li	%r0,1			# _exit()
76775e7035Stsubai	sc
77775e7035Stsubai
78d31dbd75SmattEND(_rtld_start)
79775e7035Stsubai
80729925dfSmycroft	.globl	_rtld_bind
81775e7035Stsubai
82d31dbd75Smatt/*
83d31dbd75Smatt * secure-plt expects %r11 to be the offset to the rela entry.
84d31dbd75Smatt * bss-plt expects %r11 to be index of the rela entry.
85d31dbd75Smatt * So for bss-plt, we multiply the index by 12 to get the offset.
86d31dbd75Smatt */
87d31dbd75SmattENTRY_NOPROFILE(_rtld_bind_secureplt_start)
8801ba93bcSmatt	stwu	%r1,-160(%r1)
89483a1c95Smatt	stw	%r0,20(%r1)
90483a1c95Smatt
91483a1c95Smatt	/*
92483a1c95Smatt	 * Instead of division which is costly we will use multiplicative
93483a1c95Smatt	 * inverse.  a / n = ((a * inv(n)) >> 32)
94483a1c95Smatt	 * where inv(n) = (0x100000000 + n - 1) / n
95483a1c95Smatt	 */
96483a1c95Smatt	mr	%r0,%r11
974fee4fe7Smatt	lis	%r11,0x15555556@h	# load multiplicative inverse of 12
984fee4fe7Smatt	ori	%r11,%r11,0x15555556@l
99483a1c95Smatt	mulhwu	%r11,%r11,%r0		# get high half of multiplication
100483a1c95Smatt
101483a1c95Smatt	b	1f
102483a1c95SmattENTRY_NOPROFILE(_rtld_bind_bssplt_start)
103483a1c95Smatt	stwu	%r1,-160(%r1)
104cf4aca11Smycroft
10501ba93bcSmatt	stw	%r0,20(%r1)
106483a1c95Smatt1:
10701ba93bcSmatt	mflr	%r0
10801ba93bcSmatt	stw	%r0,16(%r1)		# save lr
10901ba93bcSmatt	mfcr	%r0
11001ba93bcSmatt	stw	%r0,12(%r1)		# save cr
11101ba93bcSmatt	stmw	%r3,24(%r1)		# save r3-r31
112775e7035Stsubai
11301ba93bcSmatt	mr	%r3,%r12		# obj
11401ba93bcSmatt	mr	%r4,%r11		# reloff
115d31dbd75Smatt	bl	_rtld_bind		# _rtld_bind(obj, reloff)
11601ba93bcSmatt	mtctr	%r3
117775e7035Stsubai
11801ba93bcSmatt	lmw	%r3,24(%r1)		# load r3-r31
11901ba93bcSmatt	lwz	%r0,12(%r1)		# restore cr
12001ba93bcSmatt	mtcr	%r0
12101ba93bcSmatt	lwz	%r0,16(%r1)		# restore lr
12201ba93bcSmatt	mtlr	%r0
12301ba93bcSmatt	lwz	%r0,20(%r1)
124cf4aca11Smycroft
12501ba93bcSmatt	addi	%r1,%r1,160
126775e7035Stsubai	bctr
127*b7e0bd36SmrgEND(_rtld_bind_secureplt_start)
128775e7035Stsubai
129775e7035Stsubai	.globl	_rtld_powerpc_pltcall
130775e7035Stsubai	.globl	_rtld_powerpc_pltresolve
131775e7035Stsubai
132775e7035Stsubai_rtld_powerpc_pltcall:
13301ba93bcSmatt	slwi	%r11,%r11,2
13401ba93bcSmatt	addis	%r11,%r11,0		# addis	11,11,jmptab@ha
13501ba93bcSmatt	lwz	%r11,0(%r11)		# lwz	11,jmptab@l(11)
13601ba93bcSmatt	mtctr	%r11
137775e7035Stsubai	bctr
138775e7035Stsubai
139775e7035Stsubai_rtld_powerpc_pltresolve:
140d31dbd75Smatt	lis	%r12,0			# lis	12,_rtld_bind_bssplt_start@ha
141d31dbd75Smatt	addi	%r12,%r12,0		# addi	12,12,_rtld_bind_bssplt_start@l
14201ba93bcSmatt	mtctr	%r12
14301ba93bcSmatt	lis	%r12,0			# lis	12,obj@ha
14401ba93bcSmatt	addi	%r12,%r12,0		# addi	12,12,obj@l
145775e7035Stsubai	bctr
146