diff mbox series

[1/2] kallsyms: output rodata to ".kallsyms_rodata"

Message ID 20250207012045.2129841-2-stephen.s.brennan@oracle.com (mailing list archive)
State New
Headers show
Series Add option for generating BTF types of global variables | expand

Commit Message

Stephen Brennan Feb. 7, 2025, 1:20 a.m. UTC
When vmlinux is linked, the rodata from kallsyms is placed arbitrarily
within the .rodata section. The linking process is repeated several
times, since the kallsyms data size changes, which shifts symbols,
requiring re-generating the data and re-linking.

BTF is generated during the first link only. For variables, BTF includes
a BTF_K_DATASEC for each data section that may contain a variable, which
includes the variable's name, type, and offset within the data section.
Because the size of kallsyms data changes during later links, the
offsets of variables placed after it in .rodata will change. This means
that BTF_K_DATASEC information for those variables becomes inaccurate.

This is not currently a problem, because BTF currently only generates
variable data for percpu variables. However, the next commit will add
support for generating BTF for all global variables, including for the
.rodata section.

We could re-generate BTF each time vmlinux is linked, but this is quite
expensive, and should be avoided at all costs. Further as each chunk of
data (BTF and kallsyms) are re-generated, there's no guarantee that
their sizes will converge anyway.

Instead, we can take advantage of the fact that BTF only cares to store
the offset of variables from the start of their section. Therefore, so
long as the kallsyms data is stored last in the .rodata section, no
offsets will be affected. Adjust kallsyms to output to .rodata.kallsyms,
and update the linker script to include this at the end of .rodata.

Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
---
 include/asm-generic/vmlinux.lds.h | 1 +
 scripts/kallsyms.c                | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

Comments

Masahiro Yamada Feb. 15, 2025, 2:21 p.m. UTC | #1
On Fri, Feb 7, 2025 at 10:21 AM Stephen Brennan
<stephen.s.brennan@oracle.com> wrote:
>
> When vmlinux is linked, the rodata from kallsyms is placed arbitrarily
> within the .rodata section. The linking process is repeated several
> times, since the kallsyms data size changes, which shifts symbols,
> requiring re-generating the data and re-linking.
>
> BTF is generated during the first link only. For variables, BTF includes
> a BTF_K_DATASEC for each data section that may contain a variable, which
> includes the variable's name, type, and offset within the data section.
> Because the size of kallsyms data changes during later links, the
> offsets of variables placed after it in .rodata will change. This means
> that BTF_K_DATASEC information for those variables becomes inaccurate.
>
> This is not currently a problem, because BTF currently only generates
> variable data for percpu variables. However, the next commit will add
> support for generating BTF for all global variables, including for the
> .rodata section.
>
> We could re-generate BTF each time vmlinux is linked, but this is quite
> expensive, and should be avoided at all costs. Further as each chunk of
> data (BTF and kallsyms) are re-generated, there's no guarantee that
> their sizes will converge anyway.
>
> Instead, we can take advantage of the fact that BTF only cares to store
> the offset of variables from the start of their section. Therefore, so
> long as the kallsyms data is stored last in the .rodata section, no
> offsets will be affected. Adjust kallsyms to output to .rodata.kallsyms,
> and update the linker script to include this at the end of .rodata.
>
> Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
> ---

I am fine if this is helpful for BTF.
Andrii Nakryiko Feb. 24, 2025, 6:51 p.m. UTC | #2
On Sat, Feb 15, 2025 at 6:21 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Fri, Feb 7, 2025 at 10:21 AM Stephen Brennan
> <stephen.s.brennan@oracle.com> wrote:
> >
> > When vmlinux is linked, the rodata from kallsyms is placed arbitrarily
> > within the .rodata section. The linking process is repeated several
> > times, since the kallsyms data size changes, which shifts symbols,
> > requiring re-generating the data and re-linking.
> >
> > BTF is generated during the first link only. For variables, BTF includes
> > a BTF_K_DATASEC for each data section that may contain a variable, which
> > includes the variable's name, type, and offset within the data section.
> > Because the size of kallsyms data changes during later links, the
> > offsets of variables placed after it in .rodata will change. This means
> > that BTF_K_DATASEC information for those variables becomes inaccurate.
> >
> > This is not currently a problem, because BTF currently only generates
> > variable data for percpu variables. However, the next commit will add
> > support for generating BTF for all global variables, including for the
> > .rodata section.
> >
> > We could re-generate BTF each time vmlinux is linked, but this is quite
> > expensive, and should be avoided at all costs. Further as each chunk of
> > data (BTF and kallsyms) are re-generated, there's no guarantee that
> > their sizes will converge anyway.
> >
> > Instead, we can take advantage of the fact that BTF only cares to store
> > the offset of variables from the start of their section. Therefore, so
> > long as the kallsyms data is stored last in the .rodata section, no
> > offsets will be affected. Adjust kallsyms to output to .rodata.kallsyms,
> > and update the linker script to include this at the end of .rodata.
> >
> > Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
> > ---
>
> I am fine if this is helpful for BTF.

This seems like a useful change all by itself even while the main
feature of this patch set is still being developed and reviewed.
Should we land just this .kallsyms_rodata change?

>
>
>
> --
> Best Regards
> Masahiro Yamada
Stephen Brennan Feb. 25, 2025, 1:24 a.m. UTC | #3
Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:
> On Sat, Feb 15, 2025 at 6:21 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>>
>> On Fri, Feb 7, 2025 at 10:21 AM Stephen Brennan
>> <stephen.s.brennan@oracle.com> wrote:
>> >
>> > When vmlinux is linked, the rodata from kallsyms is placed arbitrarily
>> > within the .rodata section. The linking process is repeated several
>> > times, since the kallsyms data size changes, which shifts symbols,
>> > requiring re-generating the data and re-linking.
>> >
>> > BTF is generated during the first link only. For variables, BTF includes
>> > a BTF_K_DATASEC for each data section that may contain a variable, which
>> > includes the variable's name, type, and offset within the data section.
>> > Because the size of kallsyms data changes during later links, the
>> > offsets of variables placed after it in .rodata will change. This means
>> > that BTF_K_DATASEC information for those variables becomes inaccurate.
>> >
>> > This is not currently a problem, because BTF currently only generates
>> > variable data for percpu variables. However, the next commit will add
>> > support for generating BTF for all global variables, including for the
>> > .rodata section.
>> >
>> > We could re-generate BTF each time vmlinux is linked, but this is quite
>> > expensive, and should be avoided at all costs. Further as each chunk of
>> > data (BTF and kallsyms) are re-generated, there's no guarantee that
>> > their sizes will converge anyway.
>> >
>> > Instead, we can take advantage of the fact that BTF only cares to store
>> > the offset of variables from the start of their section. Therefore, so
>> > long as the kallsyms data is stored last in the .rodata section, no
>> > offsets will be affected. Adjust kallsyms to output to .rodata.kallsyms,
>> > and update the linker script to include this at the end of .rodata.
>> >
>> > Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
>> > ---
>>
>> I am fine if this is helpful for BTF.
>
> This seems like a useful change all by itself even while the main
> feature of this patch set is still being developed and reviewed.
> Should we land just this .kallsyms_rodata change?

I would be happy to see it merged now.

I don't think it would help anything other than BTF, because most other
things (e.g. kallsyms) refer to symbols via an absolute address. Using
the section offset seems pretty uncommon.

But it still is a nice cleanup anyway.

Thanks,
Stephen
Andrii Nakryiko Feb. 25, 2025, 4:59 p.m. UTC | #4
On Mon, Feb 24, 2025 at 5:24 PM Stephen Brennan
<stephen.s.brennan@oracle.com> wrote:
>
> Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:
> > On Sat, Feb 15, 2025 at 6:21 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
> >>
> >> On Fri, Feb 7, 2025 at 10:21 AM Stephen Brennan
> >> <stephen.s.brennan@oracle.com> wrote:
> >> >
> >> > When vmlinux is linked, the rodata from kallsyms is placed arbitrarily
> >> > within the .rodata section. The linking process is repeated several
> >> > times, since the kallsyms data size changes, which shifts symbols,
> >> > requiring re-generating the data and re-linking.
> >> >
> >> > BTF is generated during the first link only. For variables, BTF includes
> >> > a BTF_K_DATASEC for each data section that may contain a variable, which
> >> > includes the variable's name, type, and offset within the data section.
> >> > Because the size of kallsyms data changes during later links, the
> >> > offsets of variables placed after it in .rodata will change. This means
> >> > that BTF_K_DATASEC information for those variables becomes inaccurate.
> >> >
> >> > This is not currently a problem, because BTF currently only generates
> >> > variable data for percpu variables. However, the next commit will add
> >> > support for generating BTF for all global variables, including for the
> >> > .rodata section.
> >> >
> >> > We could re-generate BTF each time vmlinux is linked, but this is quite
> >> > expensive, and should be avoided at all costs. Further as each chunk of
> >> > data (BTF and kallsyms) are re-generated, there's no guarantee that
> >> > their sizes will converge anyway.
> >> >
> >> > Instead, we can take advantage of the fact that BTF only cares to store
> >> > the offset of variables from the start of their section. Therefore, so
> >> > long as the kallsyms data is stored last in the .rodata section, no
> >> > offsets will be affected. Adjust kallsyms to output to .rodata.kallsyms,
> >> > and update the linker script to include this at the end of .rodata.
> >> >
> >> > Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
> >> > ---
> >>
> >> I am fine if this is helpful for BTF.
> >
> > This seems like a useful change all by itself even while the main
> > feature of this patch set is still being developed and reviewed.
> > Should we land just this .kallsyms_rodata change?
>
> I would be happy to see it merged now.
>
> I don't think it would help anything other than BTF, because most other
> things (e.g. kallsyms) refer to symbols via an absolute address. Using
> the section offset seems pretty uncommon.
>
> But it still is a nice cleanup anyway.

I was thinking about possible use cases of some tooling wanting to
access kallsyms data from vmlinux (instead of from /proc/kallsyms).
But, frankly, having a separate section doesn't help all that much
even there. We either way seem to have ELF symbols pointing to
relevant pieces of information, so it's not hard to get it even if
it's part of .rodata. So I guess we don't have to rush landing this
patch separately.

>
> Thanks,
> Stephen
diff mbox series

Patch

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 54504013c7491..9284f0e502e27 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -463,6 +463,7 @@  defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
 		. = ALIGN(8);						\
 		BOUNDED_SECTION_BY(__tracepoints_ptrs, ___tracepoints_ptrs) \
 		*(__tracepoints_strings)/* Tracepoints: strings */	\
+		*(.kallsyms_rodata)					\
 	}								\
 									\
 	.rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {		\
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 03852da3d2490..743d3dd453599 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -365,7 +365,7 @@  static void write_src(void)
 	printf("#define ALGN .balign 4\n");
 	printf("#endif\n");
 
-	printf("\t.section .rodata, \"a\"\n");
+	printf("\t.section .kallsyms_rodata, \"a\"\n");
 
 	output_label("kallsyms_num_syms");
 	printf("\t.long\t%u\n", table_cnt);