xref: /minix3/libexec/ld.elf_so/arch/arm/rtld_start.S (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc/*	$NetBSD: rtld_start.S,v 1.12 2013/12/03 00:19:56 matt Exp $	*/
2e83f7ba2SBen Gras
3e83f7ba2SBen Gras/*-
4e83f7ba2SBen Gras * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
5e83f7ba2SBen Gras * All rights reserved.
6e83f7ba2SBen Gras *
7e83f7ba2SBen Gras * This code is derived from software contributed to The NetBSD Foundation
8e83f7ba2SBen Gras * by Matt Thomas and by Charles M. Hannum.
9e83f7ba2SBen Gras *
10e83f7ba2SBen Gras * Redistribution and use in source and binary forms, with or without
11e83f7ba2SBen Gras * modification, are permitted provided that the following conditions
12e83f7ba2SBen Gras * are met:
13e83f7ba2SBen Gras * 1. Redistributions of source code must retain the above copyright
14e83f7ba2SBen Gras *    notice, this list of conditions and the following disclaimer.
15e83f7ba2SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
16e83f7ba2SBen Gras *    notice, this list of conditions and the following disclaimer in the
17e83f7ba2SBen Gras *    documentation and/or other materials provided with the distribution.
18e83f7ba2SBen Gras *
19e83f7ba2SBen Gras * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20e83f7ba2SBen Gras * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21e83f7ba2SBen Gras * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22e83f7ba2SBen Gras * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23e83f7ba2SBen Gras * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24e83f7ba2SBen Gras * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25e83f7ba2SBen Gras * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26e83f7ba2SBen Gras * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27e83f7ba2SBen Gras * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28e83f7ba2SBen Gras * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29e83f7ba2SBen Gras * POSSIBILITY OF SUCH DAMAGE.
30e83f7ba2SBen Gras */
31e83f7ba2SBen Gras
32e83f7ba2SBen Gras#include <machine/asm.h>
33e83f7ba2SBen Gras
34*0a6a1f1dSLionel SambucRCSID("$NetBSD: rtld_start.S,v 1.12 2013/12/03 00:19:56 matt Exp $")
35e83f7ba2SBen Gras
36*0a6a1f1dSLionel SambucENTRY_NP(_rtld_start)
37e83f7ba2SBen Gras	sub	sp, sp, #8		/* make room for obj_main & exit proc */
38*0a6a1f1dSLionel Sambuc	movs	r4, r0			/* save ps_strings */
39e83f7ba2SBen Gras
40*0a6a1f1dSLionel Sambuc	ldr	r6, .Lgot
41*0a6a1f1dSLionel Sambuc	ldr	r5, .Ldynamic
42*0a6a1f1dSLionel Sambuc	add	r6, r6, pc		/* r6 = &GOT[0]; pc = &LPIC1; */
43*0a6a1f1dSLionel Sambuc	adds	r0, r6, r5		/* arg0 = &_DYNAMIC */
44*0a6a1f1dSLionel Sambuc.LPIC1:
45*0a6a1f1dSLionel Sambuc	ldr	r5, [r6]		/* GOT[0] = &_DYNAMIC */
46*0a6a1f1dSLionel Sambuc	subs	r5, r0, r5		/* relocbase = GOT[0] - &_DYNAMIC */
47*0a6a1f1dSLionel Sambuc	movs	r1, r5			/* arg1 = relocabase */
48e83f7ba2SBen Gras	bl	_rtld_relocate_nonplt_self
49e83f7ba2SBen Gras
50*0a6a1f1dSLionel Sambuc	movs	r1, r5			/* relocbase */
51e83f7ba2SBen Gras	mov	r0, sp			/* sp */
52e83f7ba2SBen Gras	bl	_rtld			/* call the shared loader */
53*0a6a1f1dSLionel Sambuc	movs	r3, r0			/* save entry point */
54e83f7ba2SBen Gras
55*0a6a1f1dSLionel Sambuc#ifdef __thumb__
56*0a6a1f1dSLionel Sambuc	ldr	r2, [sp, #0]		/* pop r2 = cleanup */
57*0a6a1f1dSLionel Sambuc	ldr	r1, [sp, #4]		/* pop r1 = obj_main */
58*0a6a1f1dSLionel Sambuc	add	sp, sp, #8
59*0a6a1f1dSLionel Sambuc#else
60f14fb602SLionel Sambuc	ldr	r2, [sp], #4		/* pop r2 = cleanup */
61f14fb602SLionel Sambuc	ldr	r1, [sp], #4		/* pop r1 = obj_main */
62e83f7ba2SBen Gras#endif
63*0a6a1f1dSLionel Sambuc	movs	r0, r4			/* restore ps_strings */
64*0a6a1f1dSLionel Sambuc	RETr(r3)
65e83f7ba2SBen Gras
66e83f7ba2SBen Gras	.align	0
67*0a6a1f1dSLionel Sambuc.Lgot:
68*0a6a1f1dSLionel Sambuc	.word	_GLOBAL_OFFSET_TABLE_ - .LPIC1
69*0a6a1f1dSLionel Sambuc.Ldynamic:
70*0a6a1f1dSLionel Sambuc	.word	_DYNAMIC(GOTOFF)
71*0a6a1f1dSLionel SambucEND(_rtld_start)
72*0a6a1f1dSLionel Sambuc
73e83f7ba2SBen Gras/*
74e83f7ba2SBen Gras *	stack[0] = RA
75e83f7ba2SBen Gras *	ip = &GOT[n+3]
76e83f7ba2SBen Gras *	lr = &GOT[2]
77e83f7ba2SBen Gras */
78*0a6a1f1dSLionel SambucARM_ENTRY_NP(_rtld_bind_start)
79f14fb602SLionel Sambuc	stmdb	sp!,{r0-r4,sl,fp}	/* 8 byte aligned (lr already saved) */
80e83f7ba2SBen Gras
81e83f7ba2SBen Gras	sub	r1, ip, lr		/* r1 = 4 * (n + 1) */
82e83f7ba2SBen Gras	sub	r1, r1, #4		/* r1 = 4 * n */
83e83f7ba2SBen Gras	add	r1, r1, r1		/* r1 = 8 * n */
84e83f7ba2SBen Gras
85e83f7ba2SBen Gras	ldr	r0, [lr, #-4]		/* get obj ptr from GOT[1] */
86e83f7ba2SBen Gras	mov	r4, ip			/* save GOT location */
87e83f7ba2SBen Gras
88e83f7ba2SBen Gras	bl	_rtld_bind		/* Call the binder */
89e83f7ba2SBen Gras
90e83f7ba2SBen Gras	str	r0, [r4]		/* save address in GOT */
91e83f7ba2SBen Gras	mov	ip, r0			/* save new address */
92e83f7ba2SBen Gras
93e83f7ba2SBen Gras	ldmia	sp!,{r0-r4,sl,fp,lr}	/* restore the stack */
94*0a6a1f1dSLionel Sambuc	RETr(ip)			/* jump to the new address */
95*0a6a1f1dSLionel SambucEND(_rtld_bind_start)
96