forked from mirrors/linux
		
	 ddb5cdbafa
			
		
	
	
		ddb5cdbafa
		
	
	
	
	
		
			
			Commit7b4537199a("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") made modpost output CRCs in the same way whether the EXPORT_SYMBOL() is placed in *.c or *.S. For further cleanups, this commit applies a similar approach to the entire data structure of EXPORT_SYMBOL(). The EXPORT_SYMBOL() compilation is split into two stages. When a source file is compiled, EXPORT_SYMBOL() will be converted into a dummy symbol in the .export_symbol section. For example, EXPORT_SYMBOL(foo); EXPORT_SYMBOL_NS_GPL(bar, BAR_NAMESPACE); will be encoded into the following assembly code: .section ".export_symbol","a" __export_symbol_foo: .asciz "" /* license */ .asciz "" /* name space */ .balign 8 .quad foo /* symbol reference */ .previous .section ".export_symbol","a" __export_symbol_bar: .asciz "GPL" /* license */ .asciz "BAR_NAMESPACE" /* name space */ .balign 8 .quad bar /* symbol reference */ .previous They are mere markers to tell modpost the name, license, and namespace of the symbols. They will be dropped from the final vmlinux and modules because the *(.export_symbol) will go into /DISCARD/ in the linker script. Then, modpost extracts all the information about EXPORT_SYMBOL() from the .export_symbol section, and generates the final C code: KSYMTAB_FUNC(foo, "", ""); KSYMTAB_FUNC(bar, "_gpl", "BAR_NAMESPACE"); KSYMTAB_FUNC() (or KSYMTAB_DATA() if it is data) is expanded to struct kernel_symbol that will be linked to the vmlinux or a module. With this change, EXPORT_SYMBOL() works in the same way for *.c and *.S files, providing the following benefits. [1] Deprecate EXPORT_DATA_SYMBOL() In the old days, EXPORT_SYMBOL() was only available in C files. To export a symbol in *.S, EXPORT_SYMBOL() was placed in a separate *.c file. arch/arm/kernel/armksyms.c is one example written in the classic manner. Commit22823ab419("EXPORT_SYMBOL() for asm") removed this limitation. Since then, EXPORT_SYMBOL() can be placed close to the symbol definition in *.S files. It was a nice improvement. However, as that commit mentioned, you need to use EXPORT_DATA_SYMBOL() for data objects on some architectures. In the new approach, modpost checks symbol's type (STT_FUNC or not), and outputs KSYMTAB_FUNC() or KSYMTAB_DATA() accordingly. There are only two users of EXPORT_DATA_SYMBOL: EXPORT_DATA_SYMBOL_GPL(empty_zero_page) (arch/ia64/kernel/head.S) EXPORT_DATA_SYMBOL(ia64_ivt) (arch/ia64/kernel/ivt.S) They are transformed as follows and output into .vmlinux.export.c KSYMTAB_DATA(empty_zero_page, "_gpl", ""); KSYMTAB_DATA(ia64_ivt, "", ""); The other EXPORT_SYMBOL users in ia64 assembly are output as KSYMTAB_FUNC(). EXPORT_DATA_SYMBOL() is now deprecated. [2] merge <linux/export.h> and <asm-generic/export.h> There are two similar header implementations: include/linux/export.h for .c files include/asm-generic/export.h for .S files Ideally, the functionality should be consistent between them, but they tend to diverge. Commit8651ec01da("module: add support for symbol namespaces.") did not support the namespace for *.S files. This commit shifts the essential implementation part to C, which supports EXPORT_SYMBOL_NS() for *.S files. <asm/export.h> and <asm-generic/export.h> will remain as a wrapper of <linux/export.h> for a while. They will be removed after #include <asm/export.h> directives are all replaced with #include <linux/export.h>. [3] Implement CONFIG_TRIM_UNUSED_KSYMS in one-pass algorithm (by a later commit) When CONFIG_TRIM_UNUSED_KSYMS is enabled, Kbuild recursively traverses the directory tree to determine which EXPORT_SYMBOL to trim. If an EXPORT_SYMBOL turns out to be unused by anyone, Kbuild begins the second traverse, where some source files are recompiled with their EXPORT_SYMBOL() tuned into a no-op. We can do this better now; modpost can selectively emit KSYMTAB entries that are really used by modules. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
		
			
				
	
	
		
			68 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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>
 | |
| 
 | |
| #if defined(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)
 | |
| /*
 | |
|  * relative reference: this reduces the size by half on 64-bit architectures,
 | |
|  * and eliminates the need for absolute relocations that require runtime
 | |
|  * processing on relocatable kernels.
 | |
|  */
 | |
| #define __KSYM_REF(sym)		".long " #sym "- ."
 | |
| #elif defined(CONFIG_64BIT)
 | |
| #define __KSYM_REF(sym)		".quad " #sym
 | |
| #else
 | |
| #define __KSYM_REF(sym)		".long " #sym
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * For every exported symbol, do the following:
 | |
|  *
 | |
|  * - Put the name of the symbol and namespace (empty string "" for none) in
 | |
|  *   __ksymtab_strings.
 | |
|  * - Place a struct kernel_symbol entry in the __ksymtab section.
 | |
|  *
 | |
|  * Note on .section use: we specify progbits since usage of the "M" (SHF_MERGE)
 | |
|  * section flag requires it. Use '%progbits' instead of '@progbits' since the
 | |
|  * former apparently works on all arches according to the binutils source.
 | |
|  */
 | |
| #define __KSYMTAB(name, sym, sec, ns)						\
 | |
| 	asm("	.section \"__ksymtab_strings\",\"aMS\",%progbits,1"	"\n"	\
 | |
| 	    "__kstrtab_" #name ":"					"\n"	\
 | |
| 	    "	.asciz \"" #name "\""					"\n"	\
 | |
| 	    "__kstrtabns_" #name ":"					"\n"	\
 | |
| 	    "	.asciz \"" ns "\""					"\n"	\
 | |
| 	    "	.previous"						"\n"	\
 | |
| 	    "	.section \"___ksymtab" sec "+" #name "\", \"a\""	"\n"	\
 | |
| 	    "	.balign	4"						"\n"	\
 | |
| 	    "__ksymtab_" #name ":"					"\n"	\
 | |
| 		__KSYM_REF(sym)						"\n"	\
 | |
| 		__KSYM_REF(__kstrtab_ ##name)				"\n"	\
 | |
| 		__KSYM_REF(__kstrtabns_ ##name)				"\n"	\
 | |
| 	    "	.previous"						"\n"	\
 | |
| 	)
 | |
| 
 | |
| #ifdef CONFIG_IA64
 | |
| #define KSYM_FUNC(name)		@fptr(name)
 | |
| #else
 | |
| #define KSYM_FUNC(name)		name
 | |
| #endif
 | |
| 
 | |
| #define KSYMTAB_FUNC(name, sec, ns)	__KSYMTAB(name, KSYM_FUNC(name), sec, ns)
 | |
| #define KSYMTAB_DATA(name, sec, ns)	__KSYMTAB(name, name, sec, ns)
 | |
| 
 | |
| #define SYMBOL_CRC(sym, crc, sec)   \
 | |
| 	asm(".section \"___kcrctab" sec "+" #sym "\",\"a\""	"\n" \
 | |
| 	    "__crc_" #sym ":"					"\n" \
 | |
| 	    ".long " #crc					"\n" \
 | |
| 	    ".previous"						"\n")
 | |
| 
 | |
| #endif /* __LINUX_EXPORT_INTERNAL_H__ */
 |