Skip to content

Commit 7b45371

Browse files
committed
kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS
include/{linux,asm-generic}/export.h defines a weak symbol, __crc_* as a placeholder. Genksyms writes the version CRCs into the linker script, which will be used for filling the __crc_* symbols. The linker script format depends on CONFIG_MODULE_REL_CRCS. If it is enabled, __crc_* holds the offset to the reference of CRC. It is time to get rid of this complexity. Now that modpost parses text files (.*.cmd) to collect all the CRCs, it can generate C code that will be linked to the vmlinux or modules. Generate a new C file, .vmlinux.export.c, which contains the CRCs of symbols exported by vmlinux. It is compiled and linked to vmlinux in scripts/link-vmlinux.sh. Put the CRCs of symbols exported by modules into the existing *.mod.c files. No additional build step is needed for modules. As before, *.mod.c are compiled and linked to *.ko in scripts/Makefile.modfinal. No linker magic is used here. The new C implementation works in the same way, whether CONFIG_RELOCATABLE is enabled or not. CONFIG_MODULE_REL_CRCS is no longer needed. Previously, Kbuild invoked additional $(LD) to update the CRCs in objects, but this step is unneeded too. Signed-off-by: Masahiro Yamada <[email protected]> Tested-by: Nathan Chancellor <[email protected]> Tested-by: Nicolas Schier <[email protected]> Reviewed-by: Nicolas Schier <[email protected]> Tested-by: Sedat Dilek <[email protected]> # LLVM-14 (x86-64)
1 parent f292d87 commit 7b45371

File tree

15 files changed

+108
-96
lines changed

15 files changed

+108
-96
lines changed

arch/m68k/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0
22
generated-y += syscall_table.h
3+
generic-y += export.h
34
generic-y += extable.h
45
generic-y += kvm_para.h
56
generic-y += mcs_spinlock.h

arch/m68k/include/asm/export.h

Lines changed: 0 additions & 2 deletions
This file was deleted.

arch/powerpc/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,6 @@ config RELOCATABLE
566566
bool "Build a relocatable kernel"
567567
depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE))
568568
select NONSTATIC_KERNEL
569-
select MODULE_REL_CRCS if MODVERSIONS
570569
help
571570
This builds a kernel image that is capable of running at the
572571
location the kernel is loaded at. For ppc32, there is no any

arch/s390/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,6 @@ endchoice
567567

568568
config RELOCATABLE
569569
bool "Build a relocatable kernel"
570-
select MODULE_REL_CRCS if MODVERSIONS
571570
default y
572571
help
573572
This builds a kernel image that retains relocation information

arch/um/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ config LD_SCRIPT_DYN
106106
bool
107107
default y
108108
depends on !LD_SCRIPT_STATIC
109-
select MODULE_REL_CRCS if MODVERSIONS
110109

111110
config LD_SCRIPT_DYN_RPATH
112111
bool "set rpath in the binary" if EXPERT

include/asm-generic/export.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
#ifndef __ASM_GENERIC_EXPORT_H
33
#define __ASM_GENERIC_EXPORT_H
44

5+
/*
6+
* This comment block is used by fixdep. Please do not remove.
7+
*
8+
* When CONFIG_MODVERSIONS is changed from n to y, all source files having
9+
* EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a
10+
* side effect of the *.o build rule.
11+
*/
12+
513
#ifndef KSYM_FUNC
614
#define KSYM_FUNC(x) x
715
#endif
@@ -12,9 +20,6 @@
1220
#else
1321
#define KSYM_ALIGN 4
1422
#endif
15-
#ifndef KCRC_ALIGN
16-
#define KCRC_ALIGN 4
17-
#endif
1823

1924
.macro __put, val, name
2025
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
@@ -43,17 +48,6 @@ __ksymtab_\name:
4348
__kstrtab_\name:
4449
.asciz "\name"
4550
.previous
46-
#ifdef CONFIG_MODVERSIONS
47-
.section ___kcrctab\sec+\name,"a"
48-
.balign KCRC_ALIGN
49-
#if defined(CONFIG_MODULE_REL_CRCS)
50-
.long __crc_\name - .
51-
#else
52-
.long __crc_\name
53-
#endif
54-
.weak __crc_\name
55-
.previous
56-
#endif
5751
#endif
5852
.endm
5953

include/linux/export-internal.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Please do not include this explicitly.
4+
* This is used by C files generated by modpost.
5+
*/
6+
7+
#ifndef __LINUX_EXPORT_INTERNAL_H__
8+
#define __LINUX_EXPORT_INTERNAL_H__
9+
10+
#include <linux/compiler.h>
11+
#include <linux/types.h>
12+
13+
/* __used is needed to keep __crc_* for LTO */
14+
#define SYMBOL_CRC(sym, crc, sec) \
15+
u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc
16+
17+
#endif /* __LINUX_EXPORT_INTERNAL_H__ */

include/linux/export.h

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
* hackers place grumpy comments in header files.
1212
*/
1313

14+
/*
15+
* This comment block is used by fixdep. Please do not remove.
16+
*
17+
* When CONFIG_MODVERSIONS is changed from n to y, all source files having
18+
* EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a
19+
* side effect of the *.o build rule.
20+
*/
21+
1422
#ifndef __ASSEMBLY__
1523
#ifdef MODULE
1624
extern struct module __this_module;
@@ -19,26 +27,6 @@ extern struct module __this_module;
1927
#define THIS_MODULE ((struct module *)0)
2028
#endif
2129

22-
#ifdef CONFIG_MODVERSIONS
23-
/* Mark the CRC weak since genksyms apparently decides not to
24-
* generate a checksums for some symbols */
25-
#if defined(CONFIG_MODULE_REL_CRCS)
26-
#define __CRC_SYMBOL(sym, sec) \
27-
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
28-
" .weak __crc_" #sym " \n" \
29-
" .long __crc_" #sym " - . \n" \
30-
" .previous \n")
31-
#else
32-
#define __CRC_SYMBOL(sym, sec) \
33-
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
34-
" .weak __crc_" #sym " \n" \
35-
" .long __crc_" #sym " \n" \
36-
" .previous \n")
37-
#endif
38-
#else
39-
#define __CRC_SYMBOL(sym, sec)
40-
#endif
41-
4230
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
4331
#include <linux/compiler.h>
4432
/*
@@ -85,7 +73,6 @@ struct kernel_symbol {
8573
/*
8674
* For every exported symbol, do the following:
8775
*
88-
* - If applicable, place a CRC entry in the __kcrctab section.
8976
* - Put the name of the symbol and namespace (empty string "" for none) in
9077
* __ksymtab_strings.
9178
* - Place a struct kernel_symbol entry in the __ksymtab section.
@@ -98,7 +85,6 @@ struct kernel_symbol {
9885
extern typeof(sym) sym; \
9986
extern const char __kstrtab_##sym[]; \
10087
extern const char __kstrtabns_##sym[]; \
101-
__CRC_SYMBOL(sym, sec); \
10288
asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
10389
"__kstrtab_" #sym ": \n" \
10490
" .asciz \"" #sym "\" \n" \

init/Kconfig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,10 +2136,6 @@ config ASM_MODVERSIONS
21362136
assembly. This can be enabled only when the target architecture
21372137
supports it.
21382138

2139-
config MODULE_REL_CRCS
2140-
bool
2141-
depends on MODVERSIONS
2142-
21432139
config MODULE_SRCVERSION_ALL
21442140
bool "Source checksum for all modules"
21452141
help

kernel/module.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,11 +1231,6 @@ static int try_to_force_load(struct module *mod, const char *reason)
12311231

12321232
#ifdef CONFIG_MODVERSIONS
12331233

1234-
static u32 resolve_rel_crc(const s32 *crc)
1235-
{
1236-
return *(u32 *)((void *)crc + *crc);
1237-
}
1238-
12391234
static int check_version(const struct load_info *info,
12401235
const char *symname,
12411236
struct module *mod,
@@ -1264,10 +1259,7 @@ static int check_version(const struct load_info *info,
12641259
if (strcmp(versions[i].name, symname) != 0)
12651260
continue;
12661261

1267-
if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
1268-
crcval = resolve_rel_crc(crc);
1269-
else
1270-
crcval = *crc;
1262+
crcval = *crc;
12711263
if (versions[i].crc == crcval)
12721264
return 1;
12731265
pr_debug("Found checksum %X vs module %lX\n",

scripts/Makefile.build

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ $(obj)/%.i: $(src)/%.c FORCE
128128

129129
genksyms = scripts/genksyms/genksyms \
130130
$(if $(1), -T $(2)) \
131-
$(if $(CONFIG_MODULE_REL_CRCS), -R) \
132131
$(if $(KBUILD_PRESERVE), -p) \
133132
-r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null)
134133

@@ -162,19 +161,11 @@ ifdef CONFIG_MODVERSIONS
162161
# o if <file>.o doesn't contain a __ksymtab version, i.e. does
163162
# not export symbols, it's done.
164163
# o otherwise, we calculate symbol versions using the good old
165-
# genksyms on the preprocessed source and postprocess them in a way
166-
# that they are usable as a linker script
167-
# o generate .tmp_<file>.o from <file>.o using the linker to
168-
# replace the unresolved symbols __crc_exported_symbol with
169-
# the actual value of the checksum generated by genksyms
170-
# o remove .tmp_<file>.o to <file>.o
164+
# genksyms on the preprocessed source and dump them into the .cmd file.
165+
# o modpost will extract versions from that file and create *.c files that will
166+
# be compiled and linked to the kernel and/or modules.
171167

172-
# Generate .o.symversions files for each .o with exported symbols, and link these
173-
# to the kernel and/or modules at the end.
174-
175-
genksyms_format_rel_crc := [^_]*__crc_\([^ ]*\) = \.; LONG(\([^)]*\)).*
176-
genksyms_format_normal := __crc_\(.*\) = \(.*\);
177-
genksyms_format := $(if $(CONFIG_MODULE_REL_CRCS),$(genksyms_format_rel_crc),$(genksyms_format_normal))
168+
genksyms_format := __crc_\(.*\) = \(.*\);
178169

179170
gen_symversions = \
180171
if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \
@@ -188,12 +179,6 @@ gen_symversions = \
188179

189180
cmd_gen_symversions_c = $(call gen_symversions,c)
190181

191-
cmd_modversions = \
192-
if [ -r [email protected] ]; then \
193-
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
194-
195-
mv -f $(@D)/.tmp_$(@F) $@; \
196-
fi
197182
endif
198183

199184
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
@@ -273,7 +258,6 @@ define rule_cc_o_c
273258
$(call cmd,checkdoc)
274259
$(call cmd,gen_objtooldep)
275260
$(call cmd,gen_symversions_c)
276-
$(if $(CONFIG_LTO_CLANG),,$(call cmd,modversions))
277261
$(call cmd,record_mcount)
278262
endef
279263

@@ -282,7 +266,6 @@ define rule_as_o_S
282266
$(call cmd,gen_ksymdeps)
283267
$(call cmd,gen_objtooldep)
284268
$(call cmd,gen_symversions_S)
285-
$(call cmd,modversions)
286269
endef
287270

288271
# Built-in and composite module parts
@@ -296,8 +279,6 @@ ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
296279
quiet_cmd_cc_prelink_modules = LD [M] $@
297280
cmd_cc_prelink_modules = \
298281
$(LD) $(ld_flags) -r -o $@ \
299-
$(shell [ -s $(@:.prelink.o=.o.symversions) ] && \
300-
echo -T $(@:.prelink.o=.o.symversions)) \
301282
--whole-archive $(filter-out FORCE,$^) \
302283
$(cmd_objtool)
303284

scripts/Makefile.vmlinux

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
3+
include include/config/auto.conf
4+
include $(srctree)/scripts/Kbuild.include
5+
6+
# for c_flags
7+
include $(srctree)/scripts/Makefile.lib
8+
9+
quiet_cmd_cc_o_c = CC $@
10+
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
11+
12+
%.o: %.c FORCE
13+
$(call if_changed_dep,cc_o_c)
14+
15+
targets := $(MAKECMDGOALS)
16+
17+
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
18+
# ---------------------------------------------------------------------------
19+
20+
PHONY += FORCE
21+
FORCE:
22+
23+
# Read all saved command lines and dependencies for the $(targets) we
24+
# may be building above, using $(if_changed{,_dep}). As an
25+
# optimization, we don't need to read them if the target does not
26+
# exist, we will rebuild anyway in that case.
27+
28+
existing-targets := $(wildcard $(sort $(targets)))
29+
30+
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
31+
32+
.PHONY: $(PHONY)

scripts/genksyms/genksyms.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ char *cur_filename;
3333
int in_source_file;
3434

3535
static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
36-
flag_preserve, flag_warnings, flag_rel_crcs;
36+
flag_preserve, flag_warnings;
3737

3838
static int errors;
3939
static int nsyms;
@@ -680,11 +680,7 @@ void export_symbol(const char *name)
680680
if (flag_dump_defs)
681681
fputs(">\n", debugfile);
682682

683-
/* Used as a linker script. */
684-
printf(!flag_rel_crcs ? "__crc_%s = 0x%08lx;\n" :
685-
"SECTIONS { .rodata : ALIGN(4) { "
686-
"__crc_%s = .; LONG(0x%08lx); } }\n",
687-
name, crc);
683+
printf("__crc_%s = 0x%08lx;\n", name, crc);
688684
}
689685
}
690686

@@ -733,7 +729,6 @@ static void genksyms_usage(void)
733729
" -q, --quiet Disable warnings (default)\n"
734730
" -h, --help Print this message\n"
735731
" -V, --version Print the release version\n"
736-
" -R, --relative-crc Emit section relative symbol CRCs\n"
737732
#else /* __GNU_LIBRARY__ */
738733
" -s Select symbol prefix\n"
739734
" -d Increment the debug level (repeatable)\n"
@@ -745,7 +740,6 @@ static void genksyms_usage(void)
745740
" -q Disable warnings (default)\n"
746741
" -h Print this message\n"
747742
" -V Print the release version\n"
748-
" -R Emit section relative symbol CRCs\n"
749743
#endif /* __GNU_LIBRARY__ */
750744
, stderr);
751745
}
@@ -766,14 +760,13 @@ int main(int argc, char **argv)
766760
{"preserve", 0, 0, 'p'},
767761
{"version", 0, 0, 'V'},
768762
{"help", 0, 0, 'h'},
769-
{"relative-crc", 0, 0, 'R'},
770763
{0, 0, 0, 0}
771764
};
772765

773-
while ((o = getopt_long(argc, argv, "s:dwqVDr:T:phR",
766+
while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph",
774767
&long_opts[0], NULL)) != EOF)
775768
#else /* __GNU_LIBRARY__ */
776-
while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF)
769+
while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF)
777770
#endif /* __GNU_LIBRARY__ */
778771
switch (o) {
779772
case 'd':
@@ -813,9 +806,6 @@ int main(int argc, char **argv)
813806
case 'h':
814807
genksyms_usage();
815808
return 0;
816-
case 'R':
817-
flag_rel_crcs = 1;
818-
break;
819809
default:
820810
genksyms_usage();
821811
return 1;

scripts/link-vmlinux.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ modpost_link()
9090

9191
if is_enabled CONFIG_MODVERSIONS; then
9292
gen_symversions
93-
lds="${lds} -T .tmp_symversions.lds"
9493
fi
9594

9695
# This might take a while, so indicate that we're doing
@@ -183,6 +182,10 @@ vmlinux_link()
183182
libs="${KBUILD_VMLINUX_LIBS}"
184183
fi
185184

185+
if is_enabled CONFIG_MODULES; then
186+
objs="${objs} .vmlinux.export.o"
187+
fi
188+
186189
if [ "${SRCARCH}" = "um" ]; then
187190
wl=-Wl,
188191
ld="${CC}"
@@ -312,6 +315,7 @@ cleanup()
312315
rm -f vmlinux.o
313316
rm -f .vmlinux.d
314317
rm -f .vmlinux.objs
318+
rm -f .vmlinux.export.c
315319
}
316320

317321
# Use "make V=1" to debug this script
@@ -363,6 +367,10 @@ info GEN modules.builtin
363367
tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
364368
tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
365369

370+
if is_enabled CONFIG_MODULES; then
371+
${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o
372+
fi
373+
366374
btf_vmlinux_bin_o=""
367375
if is_enabled CONFIG_DEBUG_INFO_BTF; then
368376
btf_vmlinux_bin_o=.btf.vmlinux.bin.o

0 commit comments

Comments
 (0)