Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Code to process dynamic relocations in the kernel.
0004  *
0005  * Copyright 2008 Paul Mackerras, IBM Corp.
0006  */
0007 
0008 #include <asm/ppc_asm.h>
0009 
0010 RELA = 7
0011 RELASZ = 8
0012 RELAENT = 9
0013 R_PPC64_RELATIVE = 22
0014 R_PPC64_UADDR64 = 43
0015 
0016 /*
0017  * r3 = desired final address of kernel
0018  */
0019 _GLOBAL(relocate)
0020     mflr    r0
0021     bcl 20,31,$+4
0022 0:  mflr    r12     /* r12 has runtime addr of label 0 */
0023     mtlr    r0
0024     ld  r11,(p_dyn - 0b)(r12)
0025     add r11,r11,r12 /* r11 has runtime addr of .dynamic section */
0026     ld  r9,(p_rela - 0b)(r12)
0027     add r9,r9,r12   /* r9 has runtime addr of .rela.dyn section */
0028     ld  r10,(p_st - 0b)(r12)
0029     add r10,r10,r12 /* r10 has runtime addr of _stext */
0030     ld  r13,(p_sym - 0b)(r12)
0031     add r13,r13,r12 /* r13 has runtime addr of .dynsym */
0032 
0033     /*
0034      * Scan the dynamic section for the RELA, RELASZ and RELAENT entries.
0035      */
0036     li  r7,0
0037     li  r8,0
0038 .Ltags:
0039     ld  r6,0(r11)   /* get tag */
0040     cmpdi   r6,0
0041     beq .Lend_of_list       /* end of list */
0042     cmpdi   r6,RELA
0043     bne 2f
0044     ld  r7,8(r11)   /* get RELA pointer in r7 */
0045     b   4f
0046 2:  cmpdi   r6,RELASZ
0047     bne 3f
0048     ld  r8,8(r11)   /* get RELASZ value in r8 */
0049     b   4f
0050 3:  cmpdi   r6,RELAENT
0051     bne 4f
0052     ld  r12,8(r11)  /* get RELAENT value in r12 */
0053 4:  addi    r11,r11,16
0054     b   .Ltags
0055 .Lend_of_list:
0056     cmpdi   r7,0        /* check we have RELA, RELASZ, RELAENT */
0057     cmpdi   cr1,r8,0
0058     beq .Lout
0059     beq cr1,.Lout
0060     cmpdi   r12,0
0061     beq .Lout
0062 
0063     /*
0064      * Work out linktime address of _stext and hence the
0065      * relocation offset to be applied.
0066      * cur_offset [r7] = rela.run [r9] - rela.link [r7]
0067      * _stext.link [r10] = _stext.run [r10] - cur_offset [r7]
0068      * final_offset [r3] = _stext.final [r3] - _stext.link [r10]
0069      */
0070     subf    r7,r7,r9    /* cur_offset */
0071     subf    r10,r7,r10
0072     subf    r3,r10,r3   /* final_offset */
0073 
0074     /*
0075      * Run through the list of relocations and process the
0076      * R_PPC64_RELATIVE and R_PPC64_UADDR64 ones.
0077      */
0078     divd    r8,r8,r12   /* RELASZ / RELAENT */
0079     mtctr   r8
0080 .Lrels: ld  r0,8(r9)        /* ELF64_R_TYPE(reloc->r_info) */
0081     cmpdi   r0,R_PPC64_RELATIVE
0082     bne .Luaddr64
0083     ld  r6,0(r9)    /* reloc->r_offset */
0084     ld  r0,16(r9)   /* reloc->r_addend */
0085     b   .Lstore
0086 .Luaddr64:
0087     srdi    r14,r0,32   /* ELF64_R_SYM(reloc->r_info) */
0088     clrldi  r0,r0,32
0089     cmpdi   r0,R_PPC64_UADDR64
0090     bne .Lnext
0091     ld  r6,0(r9)
0092     ld  r0,16(r9)
0093     mulli   r14,r14,24  /* 24 == sizeof(elf64_sym) */
0094     add r14,r14,r13 /* elf64_sym[ELF64_R_SYM] */
0095     ld  r14,8(r14)
0096     add r0,r0,r14
0097 .Lstore:
0098     add r0,r0,r3
0099     stdx    r0,r7,r6
0100 .Lnext:
0101     add r9,r9,r12
0102     bdnz    .Lrels
0103 .Lout:
0104     blr
0105 
0106 .balign 8
0107 p_dyn:  .8byte  __dynamic_start - 0b
0108 p_rela: .8byte  __rela_dyn_start - 0b
0109 p_sym:      .8byte __dynamic_symtab - 0b
0110 p_st:   .8byte  _stext - 0b
0111