xref: /minix3/libexec/ld.elf_so/arch/riscv/rtld_start.S (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc/*	$NetBSD: rtld_start.S,v 1.2 2015/03/27 23:14:53 matt Exp $	*/
2*0a6a1f1dSLionel Sambuc
3*0a6a1f1dSLionel Sambuc/*-
4*0a6a1f1dSLionel Sambuc * Copyright (c) 2014 The NetBSD Foundation, Inc.
5*0a6a1f1dSLionel Sambuc * All rights reserved.
6*0a6a1f1dSLionel Sambuc *
7*0a6a1f1dSLionel Sambuc * This code is derived from software contributed to The NetBSD Foundation
8*0a6a1f1dSLionel Sambuc * by Matt Thomas of 3am Software Foundry.
9*0a6a1f1dSLionel Sambuc *
10*0a6a1f1dSLionel Sambuc * Redistribution and use in source and binary forms, with or without
11*0a6a1f1dSLionel Sambuc * modification, are permitted provided that the following conditions
12*0a6a1f1dSLionel Sambuc * are met:
13*0a6a1f1dSLionel Sambuc * 1. Redistributions of source code must retain the above copyright
14*0a6a1f1dSLionel Sambuc *    notice, this list of conditions and the following disclaimer.
15*0a6a1f1dSLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16*0a6a1f1dSLionel Sambuc *    notice, this list of conditions and the following disclaimer in the
17*0a6a1f1dSLionel Sambuc *    documentation and/or other materials provided with the distribution.
18*0a6a1f1dSLionel Sambuc *
19*0a6a1f1dSLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*0a6a1f1dSLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*0a6a1f1dSLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*0a6a1f1dSLionel Sambuc * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*0a6a1f1dSLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*0a6a1f1dSLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*0a6a1f1dSLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*0a6a1f1dSLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*0a6a1f1dSLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*0a6a1f1dSLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*0a6a1f1dSLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
30*0a6a1f1dSLionel Sambuc */
31*0a6a1f1dSLionel Sambuc
32*0a6a1f1dSLionel Sambuc#include <machine/asm.h>
33*0a6a1f1dSLionel Sambuc
34*0a6a1f1dSLionel Sambuc	.globl _C_LABEL(_rtld_relocate_nonplt_self)
35*0a6a1f1dSLionel Sambuc	.globl _C_LABEL(_rtld)
36*0a6a1f1dSLionel Sambuc
37*0a6a1f1dSLionel Sambuc/*
38*0a6a1f1dSLionel Sambuc * void
39*0a6a1f1dSLionel Sambuc * ___start(void (*cleanup)(void),
40*0a6a1f1dSLionel Sambuc *     const Obj_Entry *obj,
41*0a6a1f1dSLionel Sambuc *     struct ps_strings *ps_strings)
42*0a6a1f1dSLionel Sambuc */
43*0a6a1f1dSLionel SambucENTRY(_rtld_start)
44*0a6a1f1dSLionel Sambuc	move	s0, sp			# save stack pointer
45*0a6a1f1dSLionel Sambuc	addi	sp, sp, -4*__SIZEOF_POINTER__
46*0a6a1f1dSLionel Sambuc					# adjust stack pointer
47*0a6a1f1dSLionel Sambuc					# -> 2*PTR_SIZE(sp) for atexit
48*0a6a1f1dSLionel Sambuc					# -> 3*PTR_SIZE(sp) for obj_main
49*0a6a1f1dSLionel Sambuc	move	s1, a2			# save ps_strings pointer
50*0a6a1f1dSLionel Sambuc
51*0a6a1f1dSLionel Sambuc.L0:	auipc	gp, %pcrel_hi(_GLOBAL_OFFSET_TABLE_)
52*0a6a1f1dSLionel Sambuc	PTR_L	t0, %pcrel_lo(.L0)(gp) # &_DYNAMIC
53*0a6a1f1dSLionel Sambuc.L1:	auipc	a0, %pcrel_hi(_DYNAMIC)
54*0a6a1f1dSLionel Sambuc	addi	a0, a0, %pcrel_lo(.L1)
55*0a6a1f1dSLionel Sambuc	sub	s2, a0, t0		# save for _rtld
56*0a6a1f1dSLionel Sambuc	move	a1, s2
57*0a6a1f1dSLionel Sambuc	call	_C_LABEL(_rtld_relocate_nonplt_self)
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc	move	a1, s2			# relocbase
60*0a6a1f1dSLionel Sambuc	addi	a0, sp, 2*__SIZEOF_POINTER__	# sp
61*0a6a1f1dSLionel Sambuc	call	_C_LABEL(_rtld)		# a0 = _rtld(sp, relocbase)
62*0a6a1f1dSLionel Sambuc	mv	t0, a0
63*0a6a1f1dSLionel Sambuc
64*0a6a1f1dSLionel Sambuc	PTR_L	a0, 2*__SIZEOF_POINTER__(sp)	# cleanup function
65*0a6a1f1dSLionel Sambuc	PTR_L	a1, 3*__SIZEOF_POINTER__(sp)	# obj_main entry
66*0a6a1f1dSLionel Sambuc	move	a2, s1			# restore ps_strings
67*0a6a1f1dSLionel Sambuc	move	sp, s0			# readjust stack
68*0a6a1f1dSLionel Sambuc	move	s0, zero		# break stack chain
69*0a6a1f1dSLionel Sambuc	jr	t0			# _start(cleanup, obj_main, ps_strings);
70*0a6a1f1dSLionel SambucEND(_rtld_start)
71*0a6a1f1dSLionel Sambuc
72*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_SIZ		(12*SZREG)
73*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_RA		(8*SZREG)
74*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A7		(7*SZREG)
75*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A6		(6*SZREG)
76*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A5		(5*SZREG)
77*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A4		(4*SZREG)
78*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A3		(3*SZREG)
79*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A2		(2*SZREG)
80*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A1		(1*SZREG)
81*0a6a1f1dSLionel Sambuc#define	XCALLFRAME_A0		(0*SZREG)
82*0a6a1f1dSLionel Sambuc
83*0a6a1f1dSLionel Sambuc/*
84*0a6a1f1dSLionel Sambuc * t0 = obj pointer
85*0a6a1f1dSLionel Sambuc * t1 = reloc offset
86*0a6a1f1dSLionel Sambuc */
87*0a6a1f1dSLionel SambucENTRY_NP(_rtld_bind_start)
88*0a6a1f1dSLionel Sambuc	addi	sp, sp, -XCALLFRAME_SIZ	// save arguments on stack
89*0a6a1f1dSLionel Sambuc	REG_S	a0,  XCALLFRAME_A0(sp)
90*0a6a1f1dSLionel Sambuc	REG_S	a1,  XCALLFRAME_A1(sp)
91*0a6a1f1dSLionel Sambuc	REG_S	a2,  XCALLFRAME_A2(sp)
92*0a6a1f1dSLionel Sambuc	REG_S	a3,  XCALLFRAME_A3(sp)
93*0a6a1f1dSLionel Sambuc	REG_S	a4,  XCALLFRAME_A4(sp)
94*0a6a1f1dSLionel Sambuc	REG_S	a5,  XCALLFRAME_A5(sp)
95*0a6a1f1dSLionel Sambuc	REG_S	a6,  XCALLFRAME_A6(sp)
96*0a6a1f1dSLionel Sambuc	REG_S	a7,  XCALLFRAME_A7(sp)
97*0a6a1f1dSLionel Sambuc	REG_S	ra,  XCALLFRAME_RA(sp)
98*0a6a1f1dSLionel Sambuc
99*0a6a1f1dSLionel Sambuc	mv	a0, t0			/* object from got.plt[1] */
100*0a6a1f1dSLionel Sambuc	mv	a1, t1			/* reloc offset */
101*0a6a1f1dSLionel Sambuc
102*0a6a1f1dSLionel Sambuc	call	_C_LABEL(_rtld_bind)
103*0a6a1f1dSLionel Sambuc	mv	t0, a0			/* save function pointer */
104*0a6a1f1dSLionel Sambuc
105*0a6a1f1dSLionel Sambuc	REG_L	a0, XCALLFRAME_A0(sp)
106*0a6a1f1dSLionel Sambuc	REG_L	a1, XCALLFRAME_A1(sp)
107*0a6a1f1dSLionel Sambuc	REG_L	a2, XCALLFRAME_A2(sp)
108*0a6a1f1dSLionel Sambuc	REG_L	a3, XCALLFRAME_A3(sp)
109*0a6a1f1dSLionel Sambuc	REG_L	a4, XCALLFRAME_A4(sp)
110*0a6a1f1dSLionel Sambuc	REG_L	a5, XCALLFRAME_A5(sp)
111*0a6a1f1dSLionel Sambuc	REG_L	a6, XCALLFRAME_A6(sp)
112*0a6a1f1dSLionel Sambuc	REG_L	a7, XCALLFRAME_A7(sp)
113*0a6a1f1dSLionel Sambuc	REG_L	ra, XCALLFRAME_RA(sp)
114*0a6a1f1dSLionel Sambuc	addi	sp, sp, XCALLFRAME_SIZ
115*0a6a1f1dSLionel Sambuc	jr	t0
116*0a6a1f1dSLionel SambucEND(_rtld_bind_start)
117