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