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