Re: [PATCH v2] x86: Avoid relocation information in final vmlinux

From: Petr Pavlu
Date: Wed Nov 23 2022 - 10:43:38 EST


On 11/23/22 13:30, Borislav Petkov wrote:
> On Tue, Sep 27, 2022 at 10:46:32AM +0200, Petr Pavlu wrote:
>> When building a kernel supporting KASLR with CONFIG_X86_NEED_RELOCS,
>> vmlinux contains also relocation information produced by using the
>> --emit-relocs linker option. This is utilized by subsequent build steps
>> to create vmlinux.relocs and produce a relocatable image. However, the
>> information is not needed by debuggers and other standard ELF tooling.
>
> Hm, my ld manpage says:
>
> -q
> --emit-relocs
> Leave relocation sections and contents in fully linked executables. Post
> ^^^^
> link analysis and optimization tools may need this information in order to
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> perform correct modifications of executables. This results in larger
> executables.
>
> So what's up?

The only post-link analysis tool in this case should be arch/x86/tools/relocs.
It produces a vmlinux.relocs file which is appended to vmlinux.bin. This is
all internal to the Linux build. I'm not aware of any external tooling, such
as kernel debuggers, that would require this relocation information in
vmlinux.

>> The issue is then that the collected vmlinux file and hence distribution
>> packages end up unnecessarily large because of this extra data. The
>> following is a size comparison of vmlinux v6.0-rc5 with and without the
>> relocation information:
>> | Configuration | With relocs | Stripped relocs |
>> | x86_64_defconfig | 70 MB | 43 MB |
>> | +CONFIG_DEBUG_INFO | 818 MB | 367 MB |
>
> Hmm, I see a different story with my tailored config here:
>
> text data bss dec hex filename
> 17131605 128673450 37339140 183144195 aea8f03 vmlinux.before
> 17132217 128677706 37363716 183173639 aeb0207 vmlinux.after
>
> 361M vmlinux.before
> 361M vmlinux.after
>
> and
>
> 738K vmlinux.relocs
>
> and before and after .configs simply have RANDOMIZE_BASE =n and =y,
> respectively.
>
> So how do you see such a big diff, even with defconfig?

The size command used in your example includes only allocatable code, data and
bss sections. It does not show size of any relocation sections.

My measurement was simply with 'ls -lh'. One can compare output of 'readelf
--sections' from the before and after binaries to see what sections are
removed with the patch and what is their size.

The following sections are dropped for defconfig on v6.1-rc6:

Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 2] .rela.text RELA 0000000000000000 02adf908
00000000009457f8 0000000000000018 I 60 1 8
[ 4] .rela.rodata RELA 0000000000000000 03425100
00000000001781d0 0000000000000018 I 60 3 8
[ 6] .rela.pci_fixup RELA 0000000000000000 0359d2d0
0000000000005028 0000000000000018 I 60 5 8
[ 8] .rela.tracedata RELA 0000000000000000 035a22f8
0000000000000120 0000000000000018 I 60 7 8
[10] .rela__ksymtab RELA 0000000000000000 035a2418
000000000006fff0 0000000000000018 I 60 9 8
[12] .rela__ksymt[...] RELA 0000000000000000 03612408
00000000000609a8 0000000000000018 I 60 11 8
[15] .rela__param RELA 0000000000000000 03672db0
0000000000009150 0000000000000018 I 60 14 8
[17] .rela__modver RELA 0000000000000000 0367bf00
0000000000000540 0000000000000018 I 60 16 8
[19] .rela__ex_table RELA 0000000000000000 0367c440
000000000000dec0 0000000000000018 I 60 18 8
[22] .rela.data RELA 0000000000000000 0368a300
000000000011e5a8 0000000000000018 I 60 21 8
[24] .rela__bug_table RELA 0000000000000000 037a88a8
0000000000073b30 0000000000000018 I 60 23 8
[26] .rela.orc_un[...] RELA 0000000000000000 0381c3d8
0000000000aea9e0 0000000000000018 I 60 25 8
[31] .rela.data..[...] RELA 0000000000000000 04306db8
0000000000000180 0000000000000018 I 60 30 8
[33] .rela.init.text RELA 0000000000000000 04306f38
000000000009f8a0 0000000000000018 I 60 32 8
[35] .rela.altins[...] RELA 0000000000000000 043a67d8
0000000000009dc8 0000000000000018 I 60 34 8
[37] .rela.init.data RELA 0000000000000000 043b05a0
000000000002ec50 0000000000000018 I 60 36 8
[39] .rela.x86_cp[...] RELA 0000000000000000 043df1f0
0000000000000078 0000000000000018 I 60 38 8
[41] .rela.parain[...] RELA 0000000000000000 043df268
00000000000015f0 0000000000000018 I 60 40 8
[43] .rela.retpol[...] RELA 0000000000000000 043e0858
000000000005c700 0000000000000018 I 60 42 8
[45] .rela.return[...] RELA 0000000000000000 0443cf58
0000000000170fe8 0000000000000018 I 60 44 8
[47] .rela.altins[...] RELA 0000000000000000 045adf40
000000000001b0f0 0000000000000018 I 60 46 8
[49] .rela.altins[...] RELA 0000000000000000 045c9030
0000000000004d28 0000000000000018 I 60 48 8
[51] .rela.apicdrivers RELA 0000000000000000 045cdd58
0000000000000030 0000000000000018 I 60 50 8
[53] .rela.exit.text RELA 0000000000000000 045cdd88
0000000000006870 0000000000000018 I 60 52 8
[55] .rela.smp_locks RELA 0000000000000000 045d45f8
00000000000420c0 0000000000000018 I 60 54 8

Total size of these sections is 27.2 MB.

>> The patch optimizes a resulting vmlinux by adding a postlink step that
>
> Avoid having "This/The patch" or "This commit" in the commit message. It is
> tautologically useless.
>
> Also, do
>
> $ git grep 'This patch' Documentation/process
>
> for more details.

Noted.

Thanks,
Petr