xref: /openbmc/linux/arch/powerpc/kernel/reloc_64.S (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
2549e8152SPaul Mackerras/*
3549e8152SPaul Mackerras * Code to process dynamic relocations in the kernel.
4549e8152SPaul Mackerras *
5549e8152SPaul Mackerras * Copyright 2008 Paul Mackerras, IBM Corp.
6549e8152SPaul Mackerras */
7549e8152SPaul Mackerras
8549e8152SPaul Mackerras#include <asm/ppc_asm.h>
9549e8152SPaul Mackerras
10549e8152SPaul MackerrasRELA = 7
11d7997691SAlexey KardashevskiyRELASZ = 8
12d7997691SAlexey KardashevskiyRELAENT = 9
13549e8152SPaul MackerrasR_PPC64_RELATIVE = 22
14d7997691SAlexey KardashevskiyR_PPC64_UADDR64 = 43
15549e8152SPaul Mackerras
16549e8152SPaul Mackerras/*
17549e8152SPaul Mackerras * r3 = desired final address of kernel
18549e8152SPaul Mackerras */
19549e8152SPaul Mackerras_GLOBAL(relocate)
20549e8152SPaul Mackerras	mflr	r0
21549e8152SPaul Mackerras	bcl	20,31,$+4
22549e8152SPaul Mackerras0:	mflr	r12		/* r12 has runtime addr of label 0 */
23549e8152SPaul Mackerras	mtlr	r0
24549e8152SPaul Mackerras	ld	r11,(p_dyn - 0b)(r12)
25549e8152SPaul Mackerras	add	r11,r11,r12	/* r11 has runtime addr of .dynamic section */
26549e8152SPaul Mackerras	ld	r9,(p_rela - 0b)(r12)
27549e8152SPaul Mackerras	add	r9,r9,r12	/* r9 has runtime addr of .rela.dyn section */
28549e8152SPaul Mackerras	ld	r10,(p_st - 0b)(r12)
29549e8152SPaul Mackerras	add	r10,r10,r12	/* r10 has runtime addr of _stext */
30*b830c875SNicholas Piggin	ld	r4,(p_sym - 0b)(r12)
31*b830c875SNicholas Piggin	add	r4,r4,r12	/* r4 has runtime addr of .dynsym */
32549e8152SPaul Mackerras
33549e8152SPaul Mackerras	/*
34d7997691SAlexey Kardashevskiy	 * Scan the dynamic section for the RELA, RELASZ and RELAENT entries.
35549e8152SPaul Mackerras	 */
36549e8152SPaul Mackerras	li	r7,0
37549e8152SPaul Mackerras	li	r8,0
38d7997691SAlexey Kardashevskiy.Ltags:
39d7997691SAlexey Kardashevskiy	ld	r6,0(r11)	/* get tag */
40549e8152SPaul Mackerras	cmpdi	r6,0
41d7997691SAlexey Kardashevskiy	beq	.Lend_of_list		/* end of list */
42549e8152SPaul Mackerras	cmpdi	r6,RELA
43549e8152SPaul Mackerras	bne	2f
44549e8152SPaul Mackerras	ld	r7,8(r11)	/* get RELA pointer in r7 */
45d7997691SAlexey Kardashevskiy	b	4f
46d7997691SAlexey Kardashevskiy2:	cmpdi	r6,RELASZ
47549e8152SPaul Mackerras	bne	3f
48d7997691SAlexey Kardashevskiy	ld	r8,8(r11)	/* get RELASZ value in r8 */
49d7997691SAlexey Kardashevskiy	b	4f
50d7997691SAlexey Kardashevskiy3:	cmpdi	r6,RELAENT
51d7997691SAlexey Kardashevskiy	bne	4f
52d7997691SAlexey Kardashevskiy	ld	r12,8(r11)	/* get RELAENT value in r12 */
53d7997691SAlexey Kardashevskiy4:	addi	r11,r11,16
54d7997691SAlexey Kardashevskiy	b	.Ltags
55d7997691SAlexey Kardashevskiy.Lend_of_list:
56d7997691SAlexey Kardashevskiy	cmpdi	r7,0		/* check we have RELA, RELASZ, RELAENT */
57549e8152SPaul Mackerras	cmpdi	cr1,r8,0
58d7997691SAlexey Kardashevskiy	beq	.Lout
59d7997691SAlexey Kardashevskiy	beq	cr1,.Lout
60d7997691SAlexey Kardashevskiy	cmpdi	r12,0
61d7997691SAlexey Kardashevskiy	beq	.Lout
62549e8152SPaul Mackerras
63549e8152SPaul Mackerras	/*
64549e8152SPaul Mackerras	 * Work out linktime address of _stext and hence the
65549e8152SPaul Mackerras	 * relocation offset to be applied.
66549e8152SPaul Mackerras	 * cur_offset [r7] = rela.run [r9] - rela.link [r7]
67549e8152SPaul Mackerras	 * _stext.link [r10] = _stext.run [r10] - cur_offset [r7]
68549e8152SPaul Mackerras	 * final_offset [r3] = _stext.final [r3] - _stext.link [r10]
69549e8152SPaul Mackerras	 */
70549e8152SPaul Mackerras	subf	r7,r7,r9	/* cur_offset */
71549e8152SPaul Mackerras	subf	r10,r7,r10
72549e8152SPaul Mackerras	subf	r3,r10,r3	/* final_offset */
73549e8152SPaul Mackerras
74549e8152SPaul Mackerras	/*
75549e8152SPaul Mackerras	 * Run through the list of relocations and process the
76d7997691SAlexey Kardashevskiy	 * R_PPC64_RELATIVE and R_PPC64_UADDR64 ones.
77549e8152SPaul Mackerras	 */
78d7997691SAlexey Kardashevskiy	divd	r8,r8,r12	/* RELASZ / RELAENT */
79549e8152SPaul Mackerras	mtctr	r8
80d7997691SAlexey Kardashevskiy.Lrels:	ld	r0,8(r9)		/* ELF64_R_TYPE(reloc->r_info) */
813b830c82SLaurent Dufour	cmpdi	r0,R_PPC64_RELATIVE
82d7997691SAlexey Kardashevskiy	bne	.Luaddr64
83549e8152SPaul Mackerras	ld	r6,0(r9)	/* reloc->r_offset */
84549e8152SPaul Mackerras	ld	r0,16(r9)	/* reloc->r_addend */
85d7997691SAlexey Kardashevskiy	b	.Lstore
86d7997691SAlexey Kardashevskiy.Luaddr64:
87*b830c875SNicholas Piggin	srdi	r5,r0,32	/* ELF64_R_SYM(reloc->r_info) */
88d7997691SAlexey Kardashevskiy	clrldi	r0,r0,32
89d7997691SAlexey Kardashevskiy	cmpdi	r0,R_PPC64_UADDR64
90d7997691SAlexey Kardashevskiy	bne	.Lnext
91d7997691SAlexey Kardashevskiy	ld	r6,0(r9)
92d7997691SAlexey Kardashevskiy	ld	r0,16(r9)
93*b830c875SNicholas Piggin	mulli	r5,r5,24	/* 24 == sizeof(elf64_sym) */
94*b830c875SNicholas Piggin	add	r5,r5,r4	/* elf64_sym[ELF64_R_SYM] */
95*b830c875SNicholas Piggin	ld	r5,8(r5)
96*b830c875SNicholas Piggin	add	r0,r0,r5
97d7997691SAlexey Kardashevskiy.Lstore:
98549e8152SPaul Mackerras	add	r0,r0,r3
99549e8152SPaul Mackerras	stdx	r0,r7,r6
100d7997691SAlexey Kardashevskiy.Lnext:
101d7997691SAlexey Kardashevskiy	add	r9,r9,r12
102d7997691SAlexey Kardashevskiy	bdnz	.Lrels
103d7997691SAlexey Kardashevskiy.Lout:
104d7997691SAlexey Kardashevskiy	blr
105549e8152SPaul Mackerras
106a5b2cf5bSAnton Blanchard.balign 8
107eb039161STobin C. Hardingp_dyn:	.8byte	__dynamic_start - 0b
108eb039161STobin C. Hardingp_rela:	.8byte	__rela_dyn_start - 0b
109d7997691SAlexey Kardashevskiyp_sym:		.8byte __dynamic_symtab - 0b
110eb039161STobin C. Hardingp_st:	.8byte	_stext - 0b
111549e8152SPaul Mackerras
112