Re: [PATCH 04/23] kallsyms: output binary data to speed output and kallsyms assembly

From: Lorenzo Stoakes (ARM)

Date: Fri Sep 11 2026 - 07:14:50 EST


On Thu, Sep 10, 2026 at 10:29:03AM +0100, David Laight wrote:
> On Tue, 08 Sep 2026 21:55:04 +0100
> "Lorenzo Stoakes (ARM)" <ljs@xxxxxxxxxx> wrote:
>
> > kallsyms generates an assembly file that consists mostly of .byte entries
> > containing compressed names, token strings and name-sorted sequence
> > numbers.
> >
> > For an x86-64 build with 158k symbols that is a 37 MiB .S file which takes
> > 0.57s to assemble each of the two to three times it is built over a kernel
> > build.
> >
> > Each time it is generated it also takes kallsyms a similar amount of time
> > to output it.
> >
> > Avoid this overhead by instead outputting this data as binary and importing
> > it into the assembly using the .incbin directive.
> >
> > Tables that are wider than a byte remain part of the assembly to ensure
> > endianness and relative relocations are performed correctly.
> >
> > With this change, the output assembly file shrinks from 37 MiB to 9.8 MiB,
> > with a 2.6 MiB binary data file alongside it, and the object remains
> > identical.
> >
> > The generated binary file is deleted correctly on build clean along with
> > all other ephemeral data.
> >
> > On an x86-64 system with CONFIG_KALLSYMS_ALL set:
> >
> > before after delta
> > scripts/kallsyms 0.24s 0.18s 0.06s
> > assemble 0.57s 0.16s 0.41s
> >
> > Per kallsyms invocation/assembly, for a total of 0.47s time saving upon
> > invocation.
> >
> > An incremental build on the same system was reduced from 11.15s to 9.65s,
> > indicating a total of 1.5 seconds saved over the build.
> >
> > The kallsyms runs and their assembly are on the serial tail of every build
> > that links vmlinux, no-op builds are unchanged.
> >
> > Whole build, 128-thread Threadripper 9980X, best of N runs:
> >
> > before after delta
> > -------------------------------
> > x86 defconfig, touch mm/vma.c, gcc 10.8s 9.9s -0.92s (-8%)
> > x86 defconfig, touch mm/vma.c, clang 10.7s 9.5s -1.2s (-11%)
> > x86 defconfig, clean, gcc 29.5s 28.7s -0.81s (-3%)
> > x86 defconfig, clean, clang 29.7s 28.6s -1.1s (-4%)
> > x86 allmodconfig, touch mm/vma.c, gcc 45.3s 44.0s -1.3s (-3%)
> > x86 allmodconfig, touch mm/vma.c, clang 42.9s 40.2s -2.7s (-6%)
> >
> > Assisted-by: LLM
> > Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
> > ---
> > scripts/kallsyms.c | 97 ++++++++++++++++++++++++++++++++++++++-----------
> > scripts/link-vmlinux.sh | 2 +-
> > 2 files changed, 77 insertions(+), 22 deletions(-)
> >
> > diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> > index 350d118c3b9e..61c5eb537ed4 100644
> > --- a/scripts/kallsyms.c
> > +++ b/scripts/kallsyms.c
> > @@ -5,7 +5,10 @@
> > * This software may be used and distributed according to the terms
> > * of the GNU General Public License, incorporated herein by reference.
> > *
> > - * Usage: kallsyms [--all-symbols] in.map > out.S
> > + * Usage: kallsyms [--all-symbols] [--pc-relative] in.map out.bin > out.S
> > + *
> > + * The byte tables go to out.bin and are pulled into out.S with .incbin;
> > + * wider tables stay assembler source for endianness and relocations.
> > *
> > * Table compression uses all the unused char codes on the symbols and
> > * maps these to the most used substrings (tokens). For instance, it might
> > @@ -102,7 +105,7 @@ static void sym_arr_free(struct sym_arr *arr)
> >
> > static void usage(void)
> > {
> > - fprintf(stderr, "Usage: kallsyms [--all-symbols] in.map > out.S\n");
> > + fprintf(stderr, "Usage: kallsyms [--all-symbols] [--pc-relative] in.map out.bin > out.S\n");
> > exit(1);
> > }
> >
> > @@ -319,6 +322,40 @@ static void output_label(const char *label)
> > printf("%s:\n", label);
> > }
> >
> > +static void write_bin(FILE *file, const void *data, size_t len)
> > +{
> > + if (fwrite(data, 1, len, file) == len)
> > + return;
> > +
> > + perror("kallsyms: write");
> > + exit(EXIT_FAILURE);
> > +}
>
> It is pretty pointless checking the return value from fwrite().
> Most of the time it is just doing a memcpy().
> Instead call fflush() and the ferror() prior to the fclose().
> (Or just rely on fclose() giving you that error status.)

Ack, will fix up in v2.

>
> David

--
Cheers, Lorenzo