[PATCH] powerpc/64s: Add load address to plt branch targets before moved to linked location for non-relocatable kernels
Christophe Leroy
christophe.leroy at csgroup.eu
Wed Apr 21 21:59:43 AEST 2021
Le 21/04/2021 à 04:17, Jordan Niethe a écrit :
> Large branches will go through the plt which includes a stub that loads
> a target address from the .branch_lt section. On a relocatable kernel the
> targets in .branch_lt have relocations so they will be fixed up for
> where the kernel is running by relocate().
>
> For a non-relocatable kernel obviously there are no relocations.
> However, until the kernel is moved down to its linked address it is
> expected to be able to run where ever it is loaded. For pseries machines
> prom_init() is called before running at the linked address.
>
> Certain configs result in a large kernel such as STRICT_KERNEL_RWX
> (because of the larger data shift):
>
> config DATA_SHIFT
> int "Data shift" if DATA_SHIFT_BOOL
> default 24 if STRICT_KERNEL_RWX && PPC64
>
> These large kernels lead to prom_init()'s final call to __start()
> generating a plt branch:
>
> bl c000000002000018 <00000078.plt_branch.__start>
>
> This results in the kernel jumping to the linked address of __start,
> 0xc000000000000000, when really it needs to jump to the
> 0xc000000000000000 + the runtime address because the kernel is still
> running at the load address.
On ppc32 it seems to be different. I can't find plt_branch or lt_branch or whatever.
Looks like the stubs are placed at the end of .head section, and just after prom_init:
c0003858 <setup_disp_bat>:
c0003858: 7d 08 02 a6 mflr r8
c000385c: 48 00 d5 35 bl c0010d90 <reloc_offset>
c0003860: 7d 08 03 a6 mtlr r8
c0003864: 3d 03 c2 04 addis r8,r3,-15868
c0003868: 39 08 1d 08 addi r8,r8,7432
c000386c: 2c 08 00 00 cmpwi r8,0
c0003870: 4d 82 00 20 beqlr
c0003874: 81 68 00 00 lwz r11,0(r8)
c0003878: 81 08 00 04 lwz r8,4(r8)
c000387c: 7d 1f 83 a6 mtdbatl 3,r8
c0003880: 7d 7e 83 a6 mtdbatu 3,r11
c0003884: 4e 80 00 20 blr
c0003888: 3d 80 c2 00 lis r12,-15872
c000388c: 39 8c 16 dc addi r12,r12,5852
c0003890: 7d 89 03 a6 mtctr r12
c0003894: 4e 80 04 20 bctr
c0003898: 3d 80 c2 01 lis r12,-15871
c000389c: 39 8c e1 38 addi r12,r12,-7880
c00038a0: 7d 89 03 a6 mtctr r12
c00038a4: 4e 80 04 20 bctr
c00038a8: 3d 80 c2 00 lis r12,-15872
c00038ac: 39 8c 74 d0 addi r12,r12,29904
c00038b0: 7d 89 03 a6 mtctr r12
c00038b4: 4e 80 04 20 bctr
c00038b8: 3d 80 c2 00 lis r12,-15872
c00038bc: 39 8c 73 38 addi r12,r12,29496
c00038c0: 7d 89 03 a6 mtctr r12
c00038c4: 4e 80 04 20 bctr
c00038c8: 3d 80 c2 01 lis r12,-15871
c00038cc: 39 8c 83 6c addi r12,r12,-31892
c00038d0: 7d 89 03 a6 mtctr r12
c00038d4: 4e 80 04 20 bctr
c00038d8: 3d 80 c2 01 lis r12,-15871
c00038dc: 39 8c 8f 08 addi r12,r12,-28920
c00038e0: 7d 89 03 a6 mtctr r12
c00038e4: 4e 80 04 20 bctr
Disassembly of section .text:
c0004000 <Reset_virt>:
c20016dc <prom_init>:
c20016dc: 94 21 ff 50 stwu r1,-176(r1)
c20016e0: 7c 08 02 a6 mflr r0
c20016e4: 42 9f 00 05 bcl 20,4*cr7+so,c20016e8 <prom_init+0xc>
c20016e8: bd c1 00 68 stmw r14,104(r1)
c20016ec: 7f c8 02 a6 mflr r30
c20016f0: 90 01 00 b4 stw r0,180(r1)
c20016f4: 7c bb 2b 78 mr r27,r5
c20016f8: 80 1e ff f0 lwz r0,-16(r30)
....
c20026d4: 4a 00 ed 69 bl c001143c <reloc_got2>
c20026d8: 7f e3 fb 78 mr r3,r31
c20026dc: 7f 24 cb 78 mr r4,r25
c20026e0: 39 20 00 00 li r9,0
c20026e4: 39 00 00 00 li r8,0
c20026e8: 38 e0 00 00 li r7,0
c20026ec: 38 c0 00 00 li r6,0
c20026f0: 38 a0 00 00 li r5,0
c20026f4: 48 00 00 61 bl c2002754 <prom_init+0x1078>
c20026f8: 38 60 00 00 li r3,0
c20026fc: 80 01 00 b4 lwz r0,180(r1)
c2002700: 81 c1 00 68 lwz r14,104(r1)
c2002704: 81 e1 00 6c lwz r15,108(r1)
c2002708: 7c 08 03 a6 mtlr r0
c200270c: 82 01 00 70 lwz r16,112(r1)
c2002710: 82 21 00 74 lwz r17,116(r1)
c2002714: 82 41 00 78 lwz r18,120(r1)
c2002718: 82 61 00 7c lwz r19,124(r1)
c200271c: 82 81 00 80 lwz r20,128(r1)
c2002720: 82 a1 00 84 lwz r21,132(r1)
c2002724: 82 c1 00 88 lwz r22,136(r1)
c2002728: 82 e1 00 8c lwz r23,140(r1)
c200272c: 83 01 00 90 lwz r24,144(r1)
c2002730: 83 21 00 94 lwz r25,148(r1)
c2002734: 83 41 00 98 lwz r26,152(r1)
c2002738: 83 61 00 9c lwz r27,156(r1)
c200273c: 83 81 00 a0 lwz r28,160(r1)
c2002740: 83 a1 00 a4 lwz r29,164(r1)
c2002744: 83 c1 00 a8 lwz r30,168(r1)
c2002748: 83 e1 00 ac lwz r31,172(r1)
c200274c: 38 21 00 b0 addi r1,r1,176
c2002750: 4e 80 00 20 blr
c2002754: 3d 80 c0 00 lis r12,-16384
c2002758: 39 8c 00 0c addi r12,r12,12
c200275c: 7d 89 03 a6 mtctr r12
c2002760: 4e 80 04 20 bctr
Any idea on how the GNU ld does it and how we can alter it, or force generation of dedicated section
like on PPC64 ?
Christophe
More information about the Linuxppc-dev
mailing list