mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	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 <masahiroy@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nicolas Schier <nicolas@fjasle.eu>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com> # LLVM-14 (x86-64)
			
			
This commit is contained in:
		
							parent
							
								
									f292d875d0
								
							
						
					
					
						commit
						7b4537199a
					
				
					 15 changed files with 108 additions and 96 deletions
				
			
		|  | @ -1,5 +1,6 @@ | ||||||
| # SPDX-License-Identifier: GPL-2.0 | # SPDX-License-Identifier: GPL-2.0 | ||||||
| generated-y += syscall_table.h | generated-y += syscall_table.h | ||||||
|  | generic-y += export.h | ||||||
| generic-y += extable.h | generic-y += extable.h | ||||||
| generic-y += kvm_para.h | generic-y += kvm_para.h | ||||||
| generic-y += mcs_spinlock.h | generic-y += mcs_spinlock.h | ||||||
|  |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| #define KCRC_ALIGN 2 |  | ||||||
| #include <asm-generic/export.h> |  | ||||||
|  | @ -566,7 +566,6 @@ config RELOCATABLE | ||||||
| 	bool "Build a relocatable kernel" | 	bool "Build a relocatable kernel" | ||||||
| 	depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) | 	depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) | ||||||
| 	select NONSTATIC_KERNEL | 	select NONSTATIC_KERNEL | ||||||
| 	select MODULE_REL_CRCS if MODVERSIONS |  | ||||||
| 	help | 	help | ||||||
| 	  This builds a kernel image that is capable of running at the | 	  This builds a kernel image that is capable of running at the | ||||||
| 	  location the kernel is loaded at. For ppc32, there is no any | 	  location the kernel is loaded at. For ppc32, there is no any | ||||||
|  |  | ||||||
|  | @ -567,7 +567,6 @@ endchoice | ||||||
| 
 | 
 | ||||||
| config RELOCATABLE | config RELOCATABLE | ||||||
| 	bool "Build a relocatable kernel" | 	bool "Build a relocatable kernel" | ||||||
| 	select MODULE_REL_CRCS if MODVERSIONS |  | ||||||
| 	default y | 	default y | ||||||
| 	help | 	help | ||||||
| 	  This builds a kernel image that retains relocation information | 	  This builds a kernel image that retains relocation information | ||||||
|  |  | ||||||
|  | @ -106,7 +106,6 @@ config LD_SCRIPT_DYN | ||||||
| 	bool | 	bool | ||||||
| 	default y | 	default y | ||||||
| 	depends on !LD_SCRIPT_STATIC | 	depends on !LD_SCRIPT_STATIC | ||||||
| 	select MODULE_REL_CRCS if MODVERSIONS |  | ||||||
| 
 | 
 | ||||||
| config LD_SCRIPT_DYN_RPATH | config LD_SCRIPT_DYN_RPATH | ||||||
| 	bool "set rpath in the binary" if EXPERT | 	bool "set rpath in the binary" if EXPERT | ||||||
|  |  | ||||||
|  | @ -2,6 +2,14 @@ | ||||||
| #ifndef __ASM_GENERIC_EXPORT_H | #ifndef __ASM_GENERIC_EXPORT_H | ||||||
| #define __ASM_GENERIC_EXPORT_H | #define __ASM_GENERIC_EXPORT_H | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * This comment block is used by fixdep. Please do not remove. | ||||||
|  |  * | ||||||
|  |  * When CONFIG_MODVERSIONS is changed from n to y, all source files having | ||||||
|  |  * EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a | ||||||
|  |  * side effect of the *.o build rule. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| #ifndef KSYM_FUNC | #ifndef KSYM_FUNC | ||||||
| #define KSYM_FUNC(x) x | #define KSYM_FUNC(x) x | ||||||
| #endif | #endif | ||||||
|  | @ -12,9 +20,6 @@ | ||||||
| #else | #else | ||||||
| #define KSYM_ALIGN 4 | #define KSYM_ALIGN 4 | ||||||
| #endif | #endif | ||||||
| #ifndef KCRC_ALIGN |  | ||||||
| #define KCRC_ALIGN 4 |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| .macro __put, val, name | .macro __put, val, name | ||||||
| #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | ||||||
|  | @ -43,17 +48,6 @@ __ksymtab_\name: | ||||||
| __kstrtab_\name: | __kstrtab_\name: | ||||||
| 	.asciz "\name" | 	.asciz "\name" | ||||||
| 	.previous | 	.previous | ||||||
| #ifdef CONFIG_MODVERSIONS |  | ||||||
| 	.section ___kcrctab\sec+\name,"a" |  | ||||||
| 	.balign KCRC_ALIGN |  | ||||||
| #if defined(CONFIG_MODULE_REL_CRCS) |  | ||||||
| 	.long __crc_\name - . |  | ||||||
| #else |  | ||||||
| 	.long __crc_\name |  | ||||||
| #endif |  | ||||||
| 	.weak __crc_\name |  | ||||||
| 	.previous |  | ||||||
| #endif |  | ||||||
| #endif | #endif | ||||||
| .endm | .endm | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								include/linux/export-internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/linux/export-internal.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | /* SPDX-License-Identifier: GPL-2.0-only */ | ||||||
|  | /*
 | ||||||
|  |  * Please do not include this explicitly. | ||||||
|  |  * This is used by C files generated by modpost. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __LINUX_EXPORT_INTERNAL_H__ | ||||||
|  | #define __LINUX_EXPORT_INTERNAL_H__ | ||||||
|  | 
 | ||||||
|  | #include <linux/compiler.h> | ||||||
|  | #include <linux/types.h> | ||||||
|  | 
 | ||||||
|  | /* __used is needed to keep __crc_* for LTO */ | ||||||
|  | #define SYMBOL_CRC(sym, crc, sec)   \ | ||||||
|  | 	u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc | ||||||
|  | 
 | ||||||
|  | #endif /* __LINUX_EXPORT_INTERNAL_H__ */ | ||||||
|  | @ -11,6 +11,14 @@ | ||||||
|  * hackers place grumpy comments in header files. |  * hackers place grumpy comments in header files. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * This comment block is used by fixdep. Please do not remove. | ||||||
|  |  * | ||||||
|  |  * When CONFIG_MODVERSIONS is changed from n to y, all source files having | ||||||
|  |  * EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a | ||||||
|  |  * side effect of the *.o build rule. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| #ifndef __ASSEMBLY__ | #ifndef __ASSEMBLY__ | ||||||
| #ifdef MODULE | #ifdef MODULE | ||||||
| extern struct module __this_module; | extern struct module __this_module; | ||||||
|  | @ -19,26 +27,6 @@ extern struct module __this_module; | ||||||
| #define THIS_MODULE ((struct module *)0) | #define THIS_MODULE ((struct module *)0) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_MODVERSIONS |  | ||||||
| /* Mark the CRC weak since genksyms apparently decides not to
 |  | ||||||
|  * generate a checksums for some symbols */ |  | ||||||
| #if defined(CONFIG_MODULE_REL_CRCS) |  | ||||||
| #define __CRC_SYMBOL(sym, sec)						\ |  | ||||||
| 	asm("	.section \"___kcrctab" sec "+" #sym "\", \"a\"	\n"	\ |  | ||||||
| 	    "	.weak	__crc_" #sym "				\n"	\ |  | ||||||
| 	    "	.long	__crc_" #sym " - .			\n"	\ |  | ||||||
| 	    "	.previous					\n") |  | ||||||
| #else |  | ||||||
| #define __CRC_SYMBOL(sym, sec)						\ |  | ||||||
| 	asm("	.section \"___kcrctab" sec "+" #sym "\", \"a\"	\n"	\ |  | ||||||
| 	    "	.weak	__crc_" #sym "				\n"	\ |  | ||||||
| 	    "	.long	__crc_" #sym "				\n"	\ |  | ||||||
| 	    "	.previous					\n") |  | ||||||
| #endif |  | ||||||
| #else |  | ||||||
| #define __CRC_SYMBOL(sym, sec) |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | ||||||
| #include <linux/compiler.h> | #include <linux/compiler.h> | ||||||
| /*
 | /*
 | ||||||
|  | @ -85,7 +73,6 @@ struct kernel_symbol { | ||||||
| /*
 | /*
 | ||||||
|  * For every exported symbol, do the following: |  * For every exported symbol, do the following: | ||||||
|  * |  * | ||||||
|  * - If applicable, place a CRC entry in the __kcrctab section. |  | ||||||
|  * - Put the name of the symbol and namespace (empty string "" for none) in |  * - Put the name of the symbol and namespace (empty string "" for none) in | ||||||
|  *   __ksymtab_strings. |  *   __ksymtab_strings. | ||||||
|  * - Place a struct kernel_symbol entry in the __ksymtab section. |  * - Place a struct kernel_symbol entry in the __ksymtab section. | ||||||
|  | @ -98,7 +85,6 @@ struct kernel_symbol { | ||||||
| 	extern typeof(sym) sym;							\ | 	extern typeof(sym) sym;							\ | ||||||
| 	extern const char __kstrtab_##sym[];					\ | 	extern const char __kstrtab_##sym[];					\ | ||||||
| 	extern const char __kstrtabns_##sym[];					\ | 	extern const char __kstrtabns_##sym[];					\ | ||||||
| 	__CRC_SYMBOL(sym, sec);							\ |  | ||||||
| 	asm("	.section \"__ksymtab_strings\",\"aMS\",%progbits,1	\n"	\ | 	asm("	.section \"__ksymtab_strings\",\"aMS\",%progbits,1	\n"	\ | ||||||
| 	    "__kstrtab_" #sym ":					\n"	\ | 	    "__kstrtab_" #sym ":					\n"	\ | ||||||
| 	    "	.asciz 	\"" #sym "\"					\n"	\ | 	    "	.asciz 	\"" #sym "\"					\n"	\ | ||||||
|  |  | ||||||
|  | @ -2136,10 +2136,6 @@ config ASM_MODVERSIONS | ||||||
| 	  assembly. This can be enabled only when the target architecture | 	  assembly. This can be enabled only when the target architecture | ||||||
| 	  supports it. | 	  supports it. | ||||||
| 
 | 
 | ||||||
| config MODULE_REL_CRCS |  | ||||||
| 	bool |  | ||||||
| 	depends on MODVERSIONS |  | ||||||
| 
 |  | ||||||
| config MODULE_SRCVERSION_ALL | config MODULE_SRCVERSION_ALL | ||||||
| 	bool "Source checksum for all modules" | 	bool "Source checksum for all modules" | ||||||
| 	help | 	help | ||||||
|  |  | ||||||
|  | @ -1231,11 +1231,6 @@ static int try_to_force_load(struct module *mod, const char *reason) | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_MODVERSIONS | #ifdef CONFIG_MODVERSIONS | ||||||
| 
 | 
 | ||||||
| static u32 resolve_rel_crc(const s32 *crc) |  | ||||||
| { |  | ||||||
| 	return *(u32 *)((void *)crc + *crc); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int check_version(const struct load_info *info, | static int check_version(const struct load_info *info, | ||||||
| 			 const char *symname, | 			 const char *symname, | ||||||
| 			 struct module *mod, | 			 struct module *mod, | ||||||
|  | @ -1264,10 +1259,7 @@ static int check_version(const struct load_info *info, | ||||||
| 		if (strcmp(versions[i].name, symname) != 0) | 		if (strcmp(versions[i].name, symname) != 0) | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
| 		if (IS_ENABLED(CONFIG_MODULE_REL_CRCS)) | 		crcval = *crc; | ||||||
| 			crcval = resolve_rel_crc(crc); |  | ||||||
| 		else |  | ||||||
| 			crcval = *crc; |  | ||||||
| 		if (versions[i].crc == crcval) | 		if (versions[i].crc == crcval) | ||||||
| 			return 1; | 			return 1; | ||||||
| 		pr_debug("Found checksum %X vs module %lX\n", | 		pr_debug("Found checksum %X vs module %lX\n", | ||||||
|  |  | ||||||
|  | @ -128,7 +128,6 @@ $(obj)/%.i: $(src)/%.c FORCE | ||||||
| 
 | 
 | ||||||
| genksyms = scripts/genksyms/genksyms		\ | genksyms = scripts/genksyms/genksyms		\ | ||||||
| 	$(if $(1), -T $(2))			\ | 	$(if $(1), -T $(2))			\ | ||||||
| 	$(if $(CONFIG_MODULE_REL_CRCS), -R)	\ |  | ||||||
| 	$(if $(KBUILD_PRESERVE), -p)		\ | 	$(if $(KBUILD_PRESERVE), -p)		\ | ||||||
| 	-r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) | 	-r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) | ||||||
| 
 | 
 | ||||||
|  | @ -162,19 +161,11 @@ ifdef CONFIG_MODVERSIONS | ||||||
| # o if <file>.o doesn't contain a __ksymtab version, i.e. does | # o if <file>.o doesn't contain a __ksymtab version, i.e. does | ||||||
| #   not export symbols, it's done. | #   not export symbols, it's done. | ||||||
| # o otherwise, we calculate symbol versions using the good old | # o otherwise, we calculate symbol versions using the good old | ||||||
| #   genksyms on the preprocessed source and postprocess them in a way | #   genksyms on the preprocessed source and dump them into the .cmd file. | ||||||
| #   that they are usable as a linker script | # o modpost will extract versions from that file and create *.c files that will | ||||||
| # o generate .tmp_<file>.o from <file>.o using the linker to | #   be compiled and linked to the kernel and/or modules. | ||||||
| #   replace the unresolved symbols __crc_exported_symbol with |  | ||||||
| #   the actual value of the checksum generated by genksyms |  | ||||||
| # o remove .tmp_<file>.o to <file>.o |  | ||||||
| 
 | 
 | ||||||
| # Generate .o.symversions files for each .o with exported symbols, and link these | genksyms_format := __crc_\(.*\) = \(.*\); | ||||||
| # to the kernel and/or modules at the end. |  | ||||||
| 
 |  | ||||||
| genksyms_format_rel_crc := [^_]*__crc_\([^ ]*\) = \.; LONG(\([^)]*\)).* |  | ||||||
| genksyms_format_normal := __crc_\(.*\) = \(.*\); |  | ||||||
| genksyms_format := $(if $(CONFIG_MODULE_REL_CRCS),$(genksyms_format_rel_crc),$(genksyms_format_normal)) |  | ||||||
| 
 | 
 | ||||||
| gen_symversions =								\ | gen_symversions =								\ | ||||||
| 	if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then			\ | 	if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then			\ | ||||||
|  | @ -188,12 +179,6 @@ gen_symversions =								\ | ||||||
| 
 | 
 | ||||||
| cmd_gen_symversions_c =	$(call gen_symversions,c) | cmd_gen_symversions_c =	$(call gen_symversions,c) | ||||||
| 
 | 
 | ||||||
| cmd_modversions =								\ |  | ||||||
| 	if [ -r $@.symversions ]; then						\ |  | ||||||
| 		$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ 		\ |  | ||||||
| 			-T $@.symversions;					\ |  | ||||||
| 		mv -f $(@D)/.tmp_$(@F) $@;					\ |  | ||||||
| 	fi |  | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT | ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT | ||||||
|  | @ -273,7 +258,6 @@ define rule_cc_o_c | ||||||
| 	$(call cmd,checkdoc) | 	$(call cmd,checkdoc) | ||||||
| 	$(call cmd,gen_objtooldep) | 	$(call cmd,gen_objtooldep) | ||||||
| 	$(call cmd,gen_symversions_c) | 	$(call cmd,gen_symversions_c) | ||||||
| 	$(if $(CONFIG_LTO_CLANG),,$(call cmd,modversions)) |  | ||||||
| 	$(call cmd,record_mcount) | 	$(call cmd,record_mcount) | ||||||
| endef | endef | ||||||
| 
 | 
 | ||||||
|  | @ -282,7 +266,6 @@ define rule_as_o_S | ||||||
| 	$(call cmd,gen_ksymdeps) | 	$(call cmd,gen_ksymdeps) | ||||||
| 	$(call cmd,gen_objtooldep) | 	$(call cmd,gen_objtooldep) | ||||||
| 	$(call cmd,gen_symversions_S) | 	$(call cmd,gen_symversions_S) | ||||||
| 	$(call cmd,modversions) |  | ||||||
| endef | endef | ||||||
| 
 | 
 | ||||||
| # Built-in and composite module parts | # Built-in and composite module parts | ||||||
|  | @ -296,8 +279,6 @@ ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) | ||||||
| quiet_cmd_cc_prelink_modules = LD [M]  $@ | quiet_cmd_cc_prelink_modules = LD [M]  $@ | ||||||
|       cmd_cc_prelink_modules =						\ |       cmd_cc_prelink_modules =						\ | ||||||
| 	$(LD) $(ld_flags) -r -o $@					\ | 	$(LD) $(ld_flags) -r -o $@					\ | ||||||
|                $(shell [ -s $(@:.prelink.o=.o.symversions) ] &&		\ |  | ||||||
|                        echo -T $(@:.prelink.o=.o.symversions))		\ |  | ||||||
| 		--whole-archive $(filter-out FORCE,$^)			\ | 		--whole-archive $(filter-out FORCE,$^)			\ | ||||||
| 		$(cmd_objtool) | 		$(cmd_objtool) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										32
									
								
								scripts/Makefile.vmlinux
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								scripts/Makefile.vmlinux
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  | 
 | ||||||
|  | include include/config/auto.conf | ||||||
|  | include $(srctree)/scripts/Kbuild.include | ||||||
|  | 
 | ||||||
|  | # for c_flags | ||||||
|  | include $(srctree)/scripts/Makefile.lib | ||||||
|  | 
 | ||||||
|  | quiet_cmd_cc_o_c = CC      $@ | ||||||
|  |       cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< | ||||||
|  | 
 | ||||||
|  | %.o: %.c FORCE | ||||||
|  | 	$(call if_changed_dep,cc_o_c) | ||||||
|  | 
 | ||||||
|  | targets := $(MAKECMDGOALS) | ||||||
|  | 
 | ||||||
|  | # Add FORCE to the prequisites of a target to force it to be always rebuilt. | ||||||
|  | # --------------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | PHONY += FORCE | ||||||
|  | FORCE: | ||||||
|  | 
 | ||||||
|  | # Read all saved command lines and dependencies for the $(targets) we | ||||||
|  | # may be building above, using $(if_changed{,_dep}). As an | ||||||
|  | # optimization, we don't need to read them if the target does not | ||||||
|  | # exist, we will rebuild anyway in that case. | ||||||
|  | 
 | ||||||
|  | existing-targets := $(wildcard $(sort $(targets))) | ||||||
|  | 
 | ||||||
|  | -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) | ||||||
|  | 
 | ||||||
|  | .PHONY: $(PHONY) | ||||||
|  | @ -33,7 +33,7 @@ char *cur_filename; | ||||||
| int in_source_file; | int in_source_file; | ||||||
| 
 | 
 | ||||||
| static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, | static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, | ||||||
| 	   flag_preserve, flag_warnings, flag_rel_crcs; | 	   flag_preserve, flag_warnings; | ||||||
| 
 | 
 | ||||||
| static int errors; | static int errors; | ||||||
| static int nsyms; | static int nsyms; | ||||||
|  | @ -680,11 +680,7 @@ void export_symbol(const char *name) | ||||||
| 		if (flag_dump_defs) | 		if (flag_dump_defs) | ||||||
| 			fputs(">\n", debugfile); | 			fputs(">\n", debugfile); | ||||||
| 
 | 
 | ||||||
| 		/* Used as a linker script. */ | 		printf("__crc_%s = 0x%08lx;\n", name, crc); | ||||||
| 		printf(!flag_rel_crcs ? "__crc_%s = 0x%08lx;\n" : |  | ||||||
| 		       "SECTIONS { .rodata : ALIGN(4) { " |  | ||||||
| 		       "__crc_%s = .; LONG(0x%08lx); } }\n", |  | ||||||
| 		       name, crc); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -733,7 +729,6 @@ static void genksyms_usage(void) | ||||||
| 	      "  -q, --quiet           Disable warnings (default)\n" | 	      "  -q, --quiet           Disable warnings (default)\n" | ||||||
| 	      "  -h, --help            Print this message\n" | 	      "  -h, --help            Print this message\n" | ||||||
| 	      "  -V, --version         Print the release version\n" | 	      "  -V, --version         Print the release version\n" | ||||||
| 	      "  -R, --relative-crc    Emit section relative symbol CRCs\n" |  | ||||||
| #else				/* __GNU_LIBRARY__ */ | #else				/* __GNU_LIBRARY__ */ | ||||||
| 	      "  -s                    Select symbol prefix\n" | 	      "  -s                    Select symbol prefix\n" | ||||||
| 	      "  -d                    Increment the debug level (repeatable)\n" | 	      "  -d                    Increment the debug level (repeatable)\n" | ||||||
|  | @ -745,7 +740,6 @@ static void genksyms_usage(void) | ||||||
| 	      "  -q                    Disable warnings (default)\n" | 	      "  -q                    Disable warnings (default)\n" | ||||||
| 	      "  -h                    Print this message\n" | 	      "  -h                    Print this message\n" | ||||||
| 	      "  -V                    Print the release version\n" | 	      "  -V                    Print the release version\n" | ||||||
| 	      "  -R                    Emit section relative symbol CRCs\n" |  | ||||||
| #endif				/* __GNU_LIBRARY__ */ | #endif				/* __GNU_LIBRARY__ */ | ||||||
| 	      , stderr); | 	      , stderr); | ||||||
| } | } | ||||||
|  | @ -766,14 +760,13 @@ int main(int argc, char **argv) | ||||||
| 		{"preserve", 0, 0, 'p'}, | 		{"preserve", 0, 0, 'p'}, | ||||||
| 		{"version", 0, 0, 'V'}, | 		{"version", 0, 0, 'V'}, | ||||||
| 		{"help", 0, 0, 'h'}, | 		{"help", 0, 0, 'h'}, | ||||||
| 		{"relative-crc", 0, 0, 'R'}, |  | ||||||
| 		{0, 0, 0, 0} | 		{0, 0, 0, 0} | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	while ((o = getopt_long(argc, argv, "s:dwqVDr:T:phR", | 	while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph", | ||||||
| 				&long_opts[0], NULL)) != EOF) | 				&long_opts[0], NULL)) != EOF) | ||||||
| #else				/* __GNU_LIBRARY__ */ | #else				/* __GNU_LIBRARY__ */ | ||||||
| 	while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF) | 	while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF) | ||||||
| #endif				/* __GNU_LIBRARY__ */ | #endif				/* __GNU_LIBRARY__ */ | ||||||
| 		switch (o) { | 		switch (o) { | ||||||
| 		case 'd': | 		case 'd': | ||||||
|  | @ -813,9 +806,6 @@ int main(int argc, char **argv) | ||||||
| 		case 'h': | 		case 'h': | ||||||
| 			genksyms_usage(); | 			genksyms_usage(); | ||||||
| 			return 0; | 			return 0; | ||||||
| 		case 'R': |  | ||||||
| 			flag_rel_crcs = 1; |  | ||||||
| 			break; |  | ||||||
| 		default: | 		default: | ||||||
| 			genksyms_usage(); | 			genksyms_usage(); | ||||||
| 			return 1; | 			return 1; | ||||||
|  |  | ||||||
|  | @ -90,7 +90,6 @@ modpost_link() | ||||||
| 
 | 
 | ||||||
| 		if is_enabled CONFIG_MODVERSIONS; then | 		if is_enabled CONFIG_MODVERSIONS; then | ||||||
| 			gen_symversions | 			gen_symversions | ||||||
| 			lds="${lds} -T .tmp_symversions.lds" |  | ||||||
| 		fi | 		fi | ||||||
| 
 | 
 | ||||||
| 		# This might take a while, so indicate that we're doing | 		# This might take a while, so indicate that we're doing | ||||||
|  | @ -183,6 +182,10 @@ vmlinux_link() | ||||||
| 		libs="${KBUILD_VMLINUX_LIBS}" | 		libs="${KBUILD_VMLINUX_LIBS}" | ||||||
| 	fi | 	fi | ||||||
| 
 | 
 | ||||||
|  | 	if is_enabled CONFIG_MODULES; then | ||||||
|  | 		objs="${objs} .vmlinux.export.o" | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
| 	if [ "${SRCARCH}" = "um" ]; then | 	if [ "${SRCARCH}" = "um" ]; then | ||||||
| 		wl=-Wl, | 		wl=-Wl, | ||||||
| 		ld="${CC}" | 		ld="${CC}" | ||||||
|  | @ -312,6 +315,7 @@ cleanup() | ||||||
| 	rm -f vmlinux.o | 	rm -f vmlinux.o | ||||||
| 	rm -f .vmlinux.d | 	rm -f .vmlinux.d | ||||||
| 	rm -f .vmlinux.objs | 	rm -f .vmlinux.objs | ||||||
|  | 	rm -f .vmlinux.export.c | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # Use "make V=1" to debug this script | # Use "make V=1" to debug this script | ||||||
|  | @ -363,6 +367,10 @@ info GEN modules.builtin | ||||||
| tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | | tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | | ||||||
| 	tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin | 	tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin | ||||||
| 
 | 
 | ||||||
|  | if is_enabled CONFIG_MODULES; then | ||||||
|  | 	${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o | ||||||
|  | fi | ||||||
|  | 
 | ||||||
| btf_vmlinux_bin_o="" | btf_vmlinux_bin_o="" | ||||||
| if is_enabled CONFIG_DEBUG_INFO_BTF; then | if is_enabled CONFIG_DEBUG_INFO_BTF; then | ||||||
| 	btf_vmlinux_bin_o=.btf.vmlinux.bin.o | 	btf_vmlinux_bin_o=.btf.vmlinux.bin.o | ||||||
|  |  | ||||||
|  | @ -2234,6 +2234,7 @@ static void add_header(struct buffer *b, struct module *mod) | ||||||
| 	buf_printf(b, "#define INCLUDE_VERMAGIC\n"); | 	buf_printf(b, "#define INCLUDE_VERMAGIC\n"); | ||||||
| 	buf_printf(b, "#include <linux/build-salt.h>\n"); | 	buf_printf(b, "#include <linux/build-salt.h>\n"); | ||||||
| 	buf_printf(b, "#include <linux/elfnote-lto.h>\n"); | 	buf_printf(b, "#include <linux/elfnote-lto.h>\n"); | ||||||
|  | 	buf_printf(b, "#include <linux/export-internal.h>\n"); | ||||||
| 	buf_printf(b, "#include <linux/vermagic.h>\n"); | 	buf_printf(b, "#include <linux/vermagic.h>\n"); | ||||||
| 	buf_printf(b, "#include <linux/compiler.h>\n"); | 	buf_printf(b, "#include <linux/compiler.h>\n"); | ||||||
| 	buf_printf(b, "\n"); | 	buf_printf(b, "\n"); | ||||||
|  | @ -2268,20 +2269,26 @@ static void add_header(struct buffer *b, struct module *mod) | ||||||
| 		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); | 		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void check_symversions(struct module *mod) | static void add_exported_symbols(struct buffer *buf, struct module *mod) | ||||||
| { | { | ||||||
| 	struct symbol *sym; | 	struct symbol *sym; | ||||||
| 
 | 
 | ||||||
| 	if (!modversions) | 	if (!modversions) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | 	/* record CRCs for exported symbols */ | ||||||
|  | 	buf_printf(buf, "\n"); | ||||||
| 	list_for_each_entry(sym, &mod->exported_symbols, list) { | 	list_for_each_entry(sym, &mod->exported_symbols, list) { | ||||||
| 		if (!sym->crc_valid) { | 		if (!sym->crc_valid) { | ||||||
| 			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" | 			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" | ||||||
| 			     "Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n", | 			     "Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n", | ||||||
| 			     sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", | 			     sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", | ||||||
| 			     sym->name); | 			     sym->name); | ||||||
|  | 			continue; | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", | ||||||
|  | 			   sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2418,6 +2425,18 @@ static void write_if_changed(struct buffer *b, const char *fname) | ||||||
| 	write_buf(b, fname); | 	write_buf(b, fname); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void write_vmlinux_export_c_file(struct module *mod) | ||||||
|  | { | ||||||
|  | 	struct buffer buf = { }; | ||||||
|  | 
 | ||||||
|  | 	buf_printf(&buf, | ||||||
|  | 		   "#include <linux/export-internal.h>\n"); | ||||||
|  | 
 | ||||||
|  | 	add_exported_symbols(&buf, mod); | ||||||
|  | 	write_if_changed(&buf, ".vmlinux.export.c"); | ||||||
|  | 	free(buf.p); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* do sanity checks, and generate *.mod.c file */ | /* do sanity checks, and generate *.mod.c file */ | ||||||
| static void write_mod_c_file(struct module *mod) | static void write_mod_c_file(struct module *mod) | ||||||
| { | { | ||||||
|  | @ -2429,6 +2448,7 @@ static void write_mod_c_file(struct module *mod) | ||||||
| 	check_exports(mod); | 	check_exports(mod); | ||||||
| 
 | 
 | ||||||
| 	add_header(&buf, mod); | 	add_header(&buf, mod); | ||||||
|  | 	add_exported_symbols(&buf, mod); | ||||||
| 	add_versions(&buf, mod); | 	add_versions(&buf, mod); | ||||||
| 	add_depends(&buf, mod); | 	add_depends(&buf, mod); | ||||||
| 	add_moddevtable(&buf, mod); | 	add_moddevtable(&buf, mod); | ||||||
|  | @ -2626,9 +2646,9 @@ int main(int argc, char **argv) | ||||||
| 		if (mod->from_dump) | 		if (mod->from_dump) | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
| 		check_symversions(mod); | 		if (mod->is_vmlinux) | ||||||
| 
 | 			write_vmlinux_export_c_file(mod); | ||||||
| 		if (!mod->is_vmlinux) | 		else | ||||||
| 			write_mod_c_file(mod); | 			write_mod_c_file(mod); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Masahiro Yamada
						Masahiro Yamada