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

Reply via email to