summaryrefslogtreecommitdiff
path: root/include/linux/export.h
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2019-09-09 13:53:17 +0300
committerMasahiro Yamada <yamada.masahiro@socionext.com>2019-09-14 05:40:13 +0300
commit69a94abb82eed2789d52b58665ddf4b454d9adb9 (patch)
tree44726fe41be6d99ecadfbedeae87722f317ad77a /include/linux/export.h
parenta0469f989fe1d051820cda7ead496f1a7371f3d8 (diff)
downloadlinux-69a94abb82eed2789d52b58665ddf4b454d9adb9.tar.xz
export.h, genksyms: do not make genksyms calculate CRC of trimmed symbols
Arnd Bergmann reported false-positive modpost warnings detected by his randconfig testing of linux-next. Actually, this happens under the combination of CONFIG_MODVERSIONS and CONFIG_TRIM_UNUSED_KSYMS since commit 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions"). For example, arch/arm/config/multi_v7_defconfig + CONFIG_MODVERSIONS + CONFIG_TRIM_UNUSED_KSYMS produces the following false-positives: WARNING: "__lshrdi3" [vmlinux] is a static (unknown) WARNING: "__ashrdi3" [vmlinux] is a static (unknown) WARNING: "__aeabi_lasr" [vmlinux] is a static (unknown) WARNING: "__aeabi_llsr" [vmlinux] is a static (unknown) WARNING: "ftrace_set_clr_event" [vmlinux] is a static (unknown) WARNING: "__muldi3" [vmlinux] is a static (unknown) WARNING: "__aeabi_ulcmp" [vmlinux] is a static (unknown) WARNING: "__ucmpdi2" [vmlinux] is a static (unknown) WARNING: "__aeabi_lmul" [vmlinux] is a static (unknown) WARNING: "__bswapsi2" [vmlinux] is a static (unknown) WARNING: "__bswapdi2" [vmlinux] is a static (unknown) WARNING: "__ashldi3" [vmlinux] is a static (unknown) WARNING: "__aeabi_llsl" [vmlinux] is a static (unknown) The root cause of the problem is not in the modpost, but in the implementation of CONFIG_TRIM_UNUSED_KSYMS. If there is at least one untrimmed symbol in the file, genksyms is invoked to calculate CRC of *all* the exported symbols in that file even if some of them have been trimmed due to no caller existing. As a result, .tmp_*.ver files contain CRC of trimmed symbols, thus unneeded, orphan __crc* symbols are added to objects. It had been harmless until recently. With commit 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions"), it is now harmful because the bogus __crc* symbols make modpost call sym_update_crc() to add the symbols to the hash table, but there is no one that clears the ->is_static member. I gave Fixes to the first commit that uncovered the issue, but the potential problem has long existed since commit f235541699bc ("export.h: allow for per-symbol configurable EXPORT_SYMBOL()"). Fixes: 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions") Reported-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Tested-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'include/linux/export.h')
-rw-r--r--include/linux/export.h42
1 files changed, 16 insertions, 26 deletions
diff --git a/include/linux/export.h b/include/linux/export.h
index cdd98a0d918c..7d8c112a8b61 100644
--- a/include/linux/export.h
+++ b/include/linux/export.h
@@ -18,9 +18,6 @@ extern struct module __this_module;
#define THIS_MODULE ((struct module *)0)
#endif
-#ifdef CONFIG_MODULES
-
-#if !defined(__GENKSYMS__)
#ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */
@@ -74,6 +71,12 @@ struct kernel_symbol {
};
#endif
+#ifdef __GENKSYMS__
+
+#define ___EXPORT_SYMBOL(sym, sec) __GENKSYMS_EXPORT_SYMBOL(sym)
+
+#else
+
/* For every exported symbol, place a struct in the __ksymtab section */
#define ___EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
@@ -83,7 +86,9 @@ struct kernel_symbol {
= #sym; \
__KSYMTAB_ENTRY(sym, sec)
-#if defined(__DISABLE_EXPORTS)
+#endif
+
+#if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS)
/*
* Allow symbol exports to be disabled completely so that C code may
@@ -117,37 +122,22 @@ struct kernel_symbol {
#define __cond_export_sym_0(sym, sec) /* nothing */
#else
-#define __EXPORT_SYMBOL ___EXPORT_SYMBOL
-#endif
-#define EXPORT_SYMBOL(sym) \
- __EXPORT_SYMBOL(sym, "")
+#define __EXPORT_SYMBOL(sym, sec) ___EXPORT_SYMBOL(sym, sec)
-#define EXPORT_SYMBOL_GPL(sym) \
- __EXPORT_SYMBOL(sym, "_gpl")
-
-#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
- __EXPORT_SYMBOL(sym, "_gpl_future")
+#endif /* CONFIG_MODULES */
+#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "")
+#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl")
+#define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future")
#ifdef CONFIG_UNUSED_SYMBOLS
-#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
-#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
+#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
+#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
#else
#define EXPORT_UNUSED_SYMBOL(sym)
#define EXPORT_UNUSED_SYMBOL_GPL(sym)
#endif
-#endif /* __GENKSYMS__ */
-
-#else /* !CONFIG_MODULES... */
-
-#define EXPORT_SYMBOL(sym)
-#define EXPORT_SYMBOL_GPL(sym)
-#define EXPORT_SYMBOL_GPL_FUTURE(sym)
-#define EXPORT_UNUSED_SYMBOL(sym)
-#define EXPORT_UNUSED_SYMBOL_GPL(sym)
-
-#endif /* CONFIG_MODULES */
#endif /* !__ASSEMBLY__ */
#endif /* _LINUX_EXPORT_H */