xref: /optee_os/ldelf/start_a32.S (revision 7509ff7ce5e5a7679319e6fa059b71dd6f6cc8b9)
1*7509ff7cSJens Wiklander/* SPDX-License-Identifier: BSD-2-Clause */
2*7509ff7cSJens Wiklander/*
3*7509ff7cSJens Wiklander * Copyright (c) 2019, Linaro Limited
4*7509ff7cSJens Wiklander */
5*7509ff7cSJens Wiklander
6*7509ff7cSJens Wiklander#include <asm.S>
7*7509ff7cSJens Wiklander#include <elf_common.h>
8*7509ff7cSJens Wiklander
9*7509ff7cSJens Wiklander/*
10*7509ff7cSJens Wiklander * _start() - Entry of ldelf
11*7509ff7cSJens Wiklander *
12*7509ff7cSJens Wiklander * See include/ldelf.h for details on TEE Core interaction.
13*7509ff7cSJens Wiklander *
14*7509ff7cSJens Wiklander * void start(struct ldelf_arg *arg);
15*7509ff7cSJens Wiklander */
16*7509ff7cSJens WiklanderFUNC _ldelf_start , :
17*7509ff7cSJens Wiklander	/*
18*7509ff7cSJens Wiklander	 * First ldelf needs to be relocated. The binary is compiled to
19*7509ff7cSJens Wiklander	 * contain only a minimal number of R_ARM_RELATIVE relocations in
20*7509ff7cSJens Wiklander	 * read/write memory, leaving read-only and executeble memory
21*7509ff7cSJens Wiklander	 * untouched.
22*7509ff7cSJens Wiklander	 */
23*7509ff7cSJens Wiklander	adr	r4, reloc_begin_rel
24*7509ff7cSJens Wiklander	ldr	r5, reloc_begin_rel
25*7509ff7cSJens Wiklander	ldr	r6, reloc_end_rel
26*7509ff7cSJens Wiklander	add	r5, r5, r4
27*7509ff7cSJens Wiklander	add	r6, r6, r4
28*7509ff7cSJens Wiklander	cmp	r5, r6
29*7509ff7cSJens Wiklander	beq	2f
30*7509ff7cSJens Wiklander
31*7509ff7cSJens Wiklander	adr	r4, _ldelf_start	/* Get the load offset */
32*7509ff7cSJens Wiklander
33*7509ff7cSJens Wiklander	/* Loop over the relocations (Elf32_Rel) and process all entries */
34*7509ff7cSJens Wiklander1:	ldmia	r5!, {r7-r8} /* r7 == r_offset, r8 = r_info */
35*7509ff7cSJens Wiklander	and	r8, r8, #0xff
36*7509ff7cSJens Wiklander	cmp	r8, #R_ARM_RELATIVE
37*7509ff7cSJens Wiklander	/* We're currently only supporting R_ARM_RELATIVE relocations */
38*7509ff7cSJens Wiklander	bne	3f
39*7509ff7cSJens Wiklander
40*7509ff7cSJens Wiklander	/* Update the pointer at r_offset + load_offset */
41*7509ff7cSJens Wiklander	add	r7, r7, r4
42*7509ff7cSJens Wiklander	ldr	r8, [r7]
43*7509ff7cSJens Wiklander	add	r8, r8, r4
44*7509ff7cSJens Wiklander	str	r8, [r7]
45*7509ff7cSJens Wiklander
46*7509ff7cSJens Wiklander	cmp	r5, r6
47*7509ff7cSJens Wiklander	blo	1b
48*7509ff7cSJens Wiklander
49*7509ff7cSJens Wiklander2:	bl	ldelf
50*7509ff7cSJens Wiklander	mov	r0, #0
51*7509ff7cSJens Wiklander	bl	utee_return
52*7509ff7cSJens Wiklander3:	mov	r0, #0
53*7509ff7cSJens Wiklander	bl	utee_panic
54*7509ff7cSJens Wiklanderreloc_begin_rel:
55*7509ff7cSJens Wiklander    .word __reloc_begin - reloc_begin_rel
56*7509ff7cSJens Wiklanderreloc_end_rel:
57*7509ff7cSJens Wiklander    .word __reloc_end - reloc_end_rel
58*7509ff7cSJens WiklanderEND_FUNC _ldelf_start
59