CONFIG_DEBUG_INFO_BTF=y requires one additional link step.
(.tmp_vmlinux.btf)
CONFIG_KALLSYMS=y requires two additional link steps.
(.tmp_vmlinux.kallsyms1 and .tmp_vmlinux.kallsyms2)
Enabling both requires three additional link steps.
When CONFIG_DEBUG_INFO_BTF=y and CONFIG_KALLSYMS=y, the current build
process is as follows:
KSYMS .tmp_vmlinux.kallsyms0.S
AS .tmp_vmlinux.kallsyms0.o
LD .tmp_vmlinux.btf # temporary vmlinux for BTF
BTF .btf.vmlinux.bin.o
LD .tmp_vmlinux.kallsyms1 # temporary vmlinux for kallsyms step 1
NM .tmp_vmlinux.kallsyms1.syms
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.o
LD .tmp_vmlinux.kallsyms2 # temporary vmlinux for kallsyms step 2
NM .tmp_vmlinux.kallsyms2.syms
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.o
LD vmlinux # final vmlinux
This is redundant because the BTF generation and the kallsyms step 1 can
be performed against the same temporary vmlinux.
When both CONFIG_DEBUG_INFO_BTF and CONFIG_KALLSYMS are enabled, we can
reduce the number of link steps by one.
This commit changes the build process as follows:
KSYMS .tmp_vmlinux0.kallsyms.S
AS .tmp_vmlinux0.kallsyms.o
LD .tmp_vmlinux1 # temporary vmlinux for BTF and kallsyms step 1
BTF .tmp_vmlinux1.btf.o
NM .tmp_vmlinux1.syms
KSYMS .tmp_vmlinux1.kallsyms.S
AS .tmp_vmlinux1.kallsyms.o
LD .tmp_vmlinux2 # temporary vmlinux for kallsyms step 2
NM .tmp_vmlinux2.syms
KSYMS .tmp_vmlinux2.kallsyms.S
AS .tmp_vmlinux2.kallsyms.o
LD vmlinux # final vmlinux
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
This reimplements commit 951bcae6c5 ("kallsyms: Avoid weak references
for kallsyms symbols") because I am not a big fan of PROVIDE().
As an alternative solution, this commit prepends one more kallsyms step.
KSYMS .tmp_vmlinux.kallsyms0.S # added
AS .tmp_vmlinux.kallsyms0.o # added
LD .tmp_vmlinux.btf
BTF .btf.vmlinux.bin.o
LD .tmp_vmlinux.kallsyms1
NM .tmp_vmlinux.kallsyms1.syms
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.o
LD .tmp_vmlinux.kallsyms2
NM .tmp_vmlinux.kallsyms2.syms
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.o
LD vmlinux
Step 0 takes /dev/null as input, and generates .tmp_vmlinux.kallsyms0.o,
which has a valid kallsyms format with the empty symbol list, and can be
linked to vmlinux. Since it is really small, the added compile-time cost
is negligible.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
Clean up the variables in scripts/link-vmlinux.sh
- Specify the extra objects directly in vmlinux_link()
- Move the AS rule to kallsyms()
- Set kallsymso and btf_vmlinux_bin_o where they are generated
- Remove unneeded variable, kallsymso_prev
- Introduce the btf_data variable
- Introduce the strip_debug flag instead of checking the output name
No functional change intended.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
In commit b18b047002 ("kbuild: change scripts/mksysmap into sed
script"), the mksysmap script was transformed into a sed script,
made directly executable with "#!/bin/sed -f". Apparently, the path to
sed is different on NixOS.
The shebang can't use the env command, otherwise the "sed -f" command
would be treated as a single argument. This can be solved with the -S
flag, but that is a GNU extension. Explicitly use sed instead of relying
on the executable shebang to fix NixOS builds without breaking build
environments using Busybox.
Fixes: b18b047002 ("kbuild: change scripts/mksysmap into sed script")
Reported-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Dmitry Safonov <0x7f454c46@gmail.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
In convention, short logs print the output file, not the input file.
Let's change the suffix for 'AS' since it assembles *.S into *.o.
[Before]
LD .tmp_vmlinux.kallsyms1
NM .tmp_vmlinux.kallsyms1.syms
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.S
LD .tmp_vmlinux.kallsyms2
NM .tmp_vmlinux.kallsyms2.syms
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.S
LD vmlinux
[After]
LD .tmp_vmlinux.kallsyms1
NM .tmp_vmlinux.kallsyms1.syms
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.o
LD .tmp_vmlinux.kallsyms2
NM .tmp_vmlinux.kallsyms2.syms
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.o
LD vmlinux
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
The previous commit removed the subshell execution from scripts/mksysmap,
which is now simple enough to become a sed script.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Since commit 951bcae6c5 ("kallsyms: Avoid weak references for kallsyms
symbols"), the kallsyms step 3 always occurs.
You can compare the build logs.
[Before 951bcae6c5]
$ git checkout 951bcae6c5a0^
$ make defconfig all
[ snip ]
LD .tmp_vmlinux.kallsyms1
NM .tmp_vmlinux.kallsyms1.syms
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.S
LD .tmp_vmlinux.kallsyms2
NM .tmp_vmlinux.kallsyms2.syms
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.S
LD vmlinux
[After 951bcae6c5]
$ git checkout 951bcae6c5
$ make defconfig all
[ snip ]
LD .tmp_vmlinux.kallsyms1
NM .tmp_vmlinux.kallsyms1.syms
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.S
LD .tmp_vmlinux.kallsyms2
NM .tmp_vmlinux.kallsyms2.syms
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.S
LD .tmp_vmlinux.kallsyms3 # should not happen
NM .tmp_vmlinux.kallsyms3.syms # should not happen
KSYMS .tmp_vmlinux.kallsyms3.S # should not happen
AS .tmp_vmlinux.kallsyms3.S # should not happen
LD vmlinux
The resulting vmlinux is correct, but it always requires an additional
linking step.
The symbols produced by kallsyms are excluded from kallsyms itself
because they were previously missing in step 1. With those symbols
excluded, the symbol lists matched between step 1 and step 2,
eliminating the need for step 3. Now, this has a negative effect.
Since 951bcae6c5, the PROVIDE() directives provide the fallback
definitions, which are not trimmed from the sysbol list in step 1
because ${kallsymso_prev} is empty at this point.
In step 2, ${kallsymso_prev} is set, and the kallsyms_* symbols are
trimmed from the symbol list.
Due to the table size difference between step 1 and step 2 (the former
is larger due to the presence of kallsyms_*), step 3 is triggered.
Now that the kallsyms_* symbols are always linked, let's stop omitting
them from kallsyms. This avoids unnecessary step 3.
Fixes: 951bcae6c5 ("kallsyms: Avoid weak references for kallsyms symbols")
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Pull Kbuild updates from Masahiro Yamada:
- Refactor scripts/kallsyms to make it faster and easier to maintain
- Clean up menuconfig
- Provide Clang with hard-coded target triple instead of CROSS_COMPILE
- Use -z pack-relative-relocs flags instead of --use-android-relr-tags
for arm64 CONFIG_RELR
- Add srcdeb-pkg target to build only a Debian source package
- Add KDEB_SOURCE_COMPRESS option to specify the compression for a
Debian source package
- Misc cleanups and fixes
* tag 'kbuild-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild:
kbuild: deb-pkg: specify targets in debian/rules as .PHONY
sparc: unify sparc32/sparc64 archhelp
kbuild: rpm-pkg: remove kernel-drm PROVIDES
kbuild: deb-pkg: add KDEB_SOURCE_COMPRESS to specify source compression
kbuild: add srcdeb-pkg target
Makefile: use -z pack-relative-relocs
kbuild: clang: do not use CROSS_COMPILE for target triple
kconfig: menuconfig: reorder functions to remove forward declarations
kconfig: menuconfig: remove unused M_EVENT macro
kconfig: menuconfig: remove OLD_NCURSES macro
kbuild: builddeb: Eliminate debian/arch use
scripts/kallsyms: update the usage in the comment block
scripts/kallsyms: decrease expand_symbol() / cleanup_symbol_name() calls
scripts/kallsyms: change the output order
scripts/kallsyms: move compiler-generated symbol patterns to mksysmap
scripts/kallsyms: exclude symbols generated by itself dynamically
scripts/mksysmap: use sed with in-line comments
scripts/mksysmap: remove comments described in nm(1)
scripts/kallsyms: remove redundant code for omitting U and N
kallsyms: expand symbol name into comment for debugging
Drop the symbols generated by scripts/kallsyms itself automatically
instead of maintaining the symbol list manually.
Pass the kallsyms object from the previous kallsyms step (if it exists)
as the third parameter of scripts/mksysmap, which will weed out the
generated symbols from the input to the next kallsyms step.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
LLVM appends various suffixes for local functions and variables, suffixes
observed:
- foo.llvm.[0-9a-f]+
- foo.[0-9a-f]+
Therefore, when CONFIG_LTO_CLANG=y, kallsyms_lookup_name() needs to
truncate the suffix of the symbol name before comparing the local function
or variable name.
Old implementation code:
- if (strcmp(namebuf, name) == 0)
- return kallsyms_sym_address(i);
- if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0)
- return kallsyms_sym_address(i);
The preceding process is traversed by address from low to high. That is,
for those with the same name after the suffix is removed, the one with
the smallest address is returned first. Therefore, when sorting in the
tool, if the raw names are the same, they should be sorted by address in
ascending order.
ASCII[.] = 2e
ASCII[0-9] = 30,39
ASCII[A-Z] = 41,5a
ASCII[_] = 5f
ASCII[a-z] = 61,7a
According to the preceding ASCII code values, the following sorting result
is strictly followed.
---------------------------------
| main-key | sub-key |
|---------------------------------|
| | addr_lowest |
| <name> | ... |
| <name>.<suffix> | ... |
| | addr_highest |
|---------------------------------|
| <name>?<others> | | //? is [_A-Za-z0-9]
---------------------------------
Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
When include/linux/export-internal.h is updated, .vmlinux.export.o
must be rebuilt, but it does not happen because its rule is hidden
behind scripts/link-vmlinux.sh.
Move it out of the shell script, so that Make can see the dependency
between vmlinux and .vmlinux.export.o.
Move the vmlinux rule to scripts/Makefile.vmlinux.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Do not build modules.builtin(.modinfo) as a side-effect of vmlinux.
There are no good reason to rebuild them just because any of vmlinux's
prerequistes (vmlinux.lds, .vmlinux.export.c, etc.) has been updated.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
This gets rid of the pipe operator connected with 'cat'.
Also use getopt_long() to parse the command line.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
scripts/mksysmap internally runs ${NM} (dropping some symbols).
When CONFIG_KALLSYMS=y, mksysmap creates .tmp_System.map, but it is
almost the same as the output from the ${NM} invocation in kallsyms().
It is true scripts/mksysmap drops some symbols, but scripts/kallsyms.c
ignores more anyway.
Keep the mksysmap output as *.syms, and reuse it for kallsyms and
'cmp -s'. It saves one ${NM} invocation.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
The objects placed at the head of vmlinux need special treatments:
- arch/$(SRCARCH)/Makefile adds them to head-y in order to place
them before other archives in the linker command line.
- arch/$(SRCARCH)/kernel/Makefile adds them to extra-y instead of
obj-y to avoid them going into built-in.a.
This commit gets rid of the latter.
Create vmlinux.a to collect all the objects that are unconditionally
linked to vmlinux. The objects listed in head-y are moved to the head
of vmlinux.a by using 'ar m'.
With this, arch/$(SRCARCH)/kernel/Makefile can consistently use obj-y
for builtin objects.
There is no *.o that is directly linked to vmlinux. Drop unneeded code
in scripts/clang-tools/gen_compile_commands.py.
$(AR) mPi needs 'T' to workaround the llvm-ar bug. The fix was suggested
by Nathan Chancellor [1].
[1]: https://lore.kernel.org/llvm/YyjjT5gQ2hGMH0ni@dev-arch.thelio-3990X/
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
Currently, modpost is executed twice; first for vmlinux, second
for modules.
This commit merges them.
Current build flow
==================
1) build obj-y and obj-m objects
2) link vmlinux.o
3) modpost for vmlinux
4) link vmlinux
5) modpost for modules
6) link modules (*.ko)
The build steps 1) through 6) are serialized, that is, modules are
built after vmlinux. You do not get benefits of parallel builds when
scripts/link-vmlinux.sh is being run.
New build flow
==============
1) build obj-y and obj-m objects
2) link vmlinux.o
3) modpost for vmlinux and modules
4a) link vmlinux
4b) link modules (*.ko)
In the new build flow, modpost is invoked just once.
vmlinux and modules are built in parallel. One exception is
CONFIG_DEBUG_INFO_BTF_MODULES=y, where modules depend on vmlinux.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
Move the build rules of vmlinux.o out of scripts/link-vmlinux.sh to
clearly separate 1) pre-modpost, 2) modpost, 3) post-modpost stages.
This will make further refactoring possible.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
.vmlinux.objs is used by modpost, so scripts/Makefile.modpost is
a better place to generate it.
It is used only when CONFIG_MODVERSIONS=y. It should be guarded
by "ifdef CONFIG_MODVERSIONS".
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
Kbuild builds init/built-in.a twice; first during the ordinary
directory descending, second from scripts/link-vmlinux.sh.
We do this because UTS_VERSION contains the build version and the
timestamp. We cannot update it during the normal directory traversal
since we do not yet know if we need to update vmlinux. UTS_VERSION is
temporarily calculated, but omitted from the update check. Otherwise,
vmlinux would be rebuilt every time.
When Kbuild results in running link-vmlinux.sh, it increments the
version number in the .version file and takes the timestamp at that
time to really fix UTS_VERSION.
However, updating the same file twice is a footgun. To avoid nasty
timestamp issues, all build artifacts that depend on init/built-in.a
are atomically generated in link-vmlinux.sh, where some of them do not
need rebuilding.
To fix this issue, this commit changes as follows:
[1] Split UTS_VERSION out to include/generated/utsversion.h from
include/generated/compile.h
include/generated/utsversion.h is generated just before the
vmlinux link. It is generated under include/generated/ because
some decompressors (s390, x86) use UTS_VERSION.
[2] Split init_uts_ns and linux_banner out to init/version-timestamp.c
from init/version.c
init_uts_ns and linux_banner contain UTS_VERSION. During the ordinary
directory descending, they are compiled with __weak and used to
determine if vmlinux needs relinking. Just before the vmlinux link,
they are compiled without __weak to embed the real version and
timestamp.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
scripts/Makefile.build and scripts/link-vmlinux.sh have similar setups
for the objtool arguments.
It was difficult to factor out them because all the vmlinux build rules
were written in a shell script. It is somewhat tedious to touch the two
files every time a new objtool option is supported.
To reduce the code duplication, move the objtool for vmlinux.o into
scripts/Makefile.vmlinux_o. Then, move the common macros to Makefile.lib
so they are shared between Makefile.build and Makefile.vmlinux_o.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com> # LLVM-14 (x86-64)
This is a preparation for moving the objtool rule in the next commit.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com> # LLVM-14 (x86-64)