^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Code to process dynamic relocations in the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2008 Paul Mackerras, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/ppc_asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) RELA = 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) RELACOUNT = 0x6ffffff9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) R_PPC64_RELATIVE = 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * r3 = desired final address of kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) _GLOBAL(relocate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) mflr r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) bcl 20,31,$+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 0: mflr r12 /* r12 has runtime addr of label 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) mtlr r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) ld r11,(p_dyn - 0b)(r12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) add r11,r11,r12 /* r11 has runtime addr of .dynamic section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ld r9,(p_rela - 0b)(r12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) add r9,r9,r12 /* r9 has runtime addr of .rela.dyn section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ld r10,(p_st - 0b)(r12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) add r10,r10,r12 /* r10 has runtime addr of _stext */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Scan the dynamic section for the RELA and RELACOUNT entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) li r7,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) li r8,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 1: ld r6,0(r11) /* get tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) cmpdi r6,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) beq 4f /* end of list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) cmpdi r6,RELA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) bne 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ld r7,8(r11) /* get RELA pointer in r7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) b 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 2: addis r6,r6,(-RELACOUNT)@ha
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) cmpdi r6,RELACOUNT@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bne 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ld r8,8(r11) /* get RELACOUNT value in r8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 3: addi r11,r11,16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) b 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 4: cmpdi r7,0 /* check we have both RELA and RELACOUNT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) cmpdi cr1,r8,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) beq 6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) beq cr1,6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Work out linktime address of _stext and hence the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * relocation offset to be applied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * cur_offset [r7] = rela.run [r9] - rela.link [r7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * _stext.link [r10] = _stext.run [r10] - cur_offset [r7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * final_offset [r3] = _stext.final [r3] - _stext.link [r10]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) subf r7,r7,r9 /* cur_offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) subf r10,r7,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) subf r3,r10,r3 /* final_offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * Run through the list of relocations and process the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * R_PPC64_RELATIVE ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mtctr r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 5: ld r0,8(9) /* ELF64_R_TYPE(reloc->r_info) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) cmpdi r0,R_PPC64_RELATIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bne 6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ld r6,0(r9) /* reloc->r_offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ld r0,16(r9) /* reloc->r_addend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) add r0,r0,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) stdx r0,r7,r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) addi r9,r9,24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bdnz 5b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 6: blr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .balign 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) p_dyn: .8byte __dynamic_start - 0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) p_rela: .8byte __rela_dyn_start - 0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) p_st: .8byte _stext - 0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)