diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/init.h | 20 | ||||
-rw-r--r-- | include/linux/io.h | 2 | ||||
-rw-r--r-- | include/linux/linkage.h | 4 | ||||
-rw-r--r-- | include/linux/lockdep.h | 2 |
4 files changed, 23 insertions, 5 deletions
diff --git a/include/linux/init.h b/include/linux/init.h index e1688802964..a3ba2707634 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -163,6 +163,23 @@ extern bool initcall_debug; #ifndef __ASSEMBLY__ +#ifdef CONFIG_LTO +/* Work around a LTO gcc problem: when there is no reference to a variable + * in a module it will be moved to the end of the program. This causes + * reordering of initcalls which the kernel does not like. + * Add a dummy reference function to avoid this. The function is + * deleted by the linker. + */ +#define LTO_REFERENCE_INITCALL(x) \ + ; /* yes this is needed */ \ + static __used __exit void *reference_##x(void) \ + { \ + return &x; \ + } +#else +#define LTO_REFERENCE_INITCALL(x) +#endif + /* initcalls are now grouped by functionality into separate * subsections. Ordering inside the subsections is determined * by link order. @@ -175,7 +192,8 @@ extern bool initcall_debug; #define __define_initcall(fn, id) \ static initcall_t __initcall_##fn##id __used \ - __attribute__((__section__(".initcall" #id ".init"))) = fn + __attribute__((__section__(".initcall" #id ".init"))) = fn; \ + LTO_REFERENCE_INITCALL(__initcall_##fn##id) /* * Early initcalls run before initializing SMP. diff --git a/include/linux/io.h b/include/linux/io.h index f4f42faec68..8a18e75600c 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -24,7 +24,7 @@ struct device; -void __iowrite32_copy(void __iomem *to, const void *from, size_t count); +__visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count); void __iowrite64_copy(void __iomem *to, const void *from, size_t count); #ifdef CONFIG_MMU diff --git a/include/linux/linkage.h b/include/linux/linkage.h index a6a42dd0246..34a513a2727 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -12,9 +12,9 @@ #endif #ifdef __cplusplus -#define CPP_ASMLINKAGE extern "C" +#define CPP_ASMLINKAGE extern "C" __visible #else -#define CPP_ASMLINKAGE +#define CPP_ASMLINKAGE __visible #endif #ifndef asmlinkage diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 060e5137fd8..008388f920d 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -265,7 +265,7 @@ extern void lockdep_info(void); extern void lockdep_reset(void); extern void lockdep_reset_lock(struct lockdep_map *lock); extern void lockdep_free_key_range(void *start, unsigned long size); -extern void lockdep_sys_exit(void); +extern asmlinkage void lockdep_sys_exit(void); extern void lockdep_off(void); extern void lockdep_on(void); |