PowerPC64 future proof kernel toc, revised for lld
Alexey Kardashevskiy
aik at linux.ibm.com
Wed Mar 10 15:44:44 AEDT 2021
On 10/03/2021 14:48, Alan Modra wrote:
> This patch future-proofs the kernel against linker changes that might
> put the toc pointer at some location other than .got+0x8000, by
> replacing __toc_start+0x8000 with .TOC. throughout. If the kernel's
> idea of the toc pointer doesn't agree with the linker, bad things
> happen.
Works great with gcc (v8, v10), ld (2.23), clang-11, lld-11.
>
> prom_init.c code relocating its toc is also changed so that a symbolic
> __prom_init_toc_start toc-pointer relative address is calculated
> rather than assuming that it is always at toc-pointer - 0x8000. The
> length calculations loading values from the toc are also avoided.
> It's a little incestuous to do that with unreloc_toc picking up
> adjusted values (which is fine in practice, they both adjust by the
> same amount if all goes well).
>
> I've also changed the way .got is aligned in vmlinux.lds and
> zImage.lds, mostly so that dumping out section info by objdump or
> readelf plainly shows the alignment is 256. This linker script
> feature was added 2005-09-27, available in FSF binutils releases from
> 2.17 onwards. Should be safe to use in the kernel, I think.
>
> Finally, put *(.got) before the prom_init.o entry which only needs
> *(.toc), so that the GOT header goes in the correct place. I don't
> believe this makes any difference for the kernel as it would for
> dynamic objects being loaded by ld.so. That change is just to stop
> lusers who blindly copy kernel scripts being led astray. Of course,
> this change needs the prom_init.c changes.
>
> Some notes on .toc and .got.
>
> .toc is a compiler generated section of addresses. .got is a linker
> generated section of addresses, generally built when the linker sees
> R_*_*GOT* relocations. In the case of powerpc64 ld.bfd, there are
> multiple generated .got sections, one per input object file. So you
> can somewhat reasonably write in a linker script an input section
> statement like *prom_init.o(.got .toc) to mean "the .got and .toc
> section for files matching *prom_init.o".
For my own education, is .got for prom_init.o still generated by ld or gcc?
In other words, should "objdump -D -s -j .got" ever dump .got for any .o
file, like below?
===
objdump -D -s -j .got
~/pbuild/kernel-llvm-ld/arch/powerpc/kernel/prom_init.o
/home/aik/pbuild/kernel-llvm-ld/arch/powerpc/kernel/prom_init.o:
file format elf64-powerpcle
objdump: section '.got' mentioned in a -j option, but not found in any
input file
===
--
Alexey Kardashevskiy
IBM OzLabs, LTC Team
e-mail: aik at linux.ibm.com
More information about the Linuxppc-dev
mailing list