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