From 9730a6289c31ff03f15671ca7dea848fc14b9bfe Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Fri, 8 Dec 2017 15:49:24 -0800 Subject: [PATCH] ANDROID: init: ensure initcall ordering with LTO With LTO, LLVM sorts initcalls in a single translation unit alphabetically based on the name of the function (or actually, the variable stored in the initcall section). Use __COUNTER__ in the variable name in an attempt to preserve the intended order. In addition, LTO requires all initcall variables to have unique names. Use __LINE__ in the name to reduce the chance of name collisions. Bug: 62093296 Bug: 67506682 Bug: 133186739 Change-Id: I4fa3cb93cba967a1440ac53328eb6b8ac649ff36 Signed-off-by: Sami Tolvanen --- include/linux/init.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/include/linux/init.h b/include/linux/init.h index 2538d176dd1f..892fe8e04c82 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -167,6 +167,20 @@ extern bool initcall_debug; #ifndef __ASSEMBLY__ +#ifdef CONFIG_LTO_CLANG + /* + * Use __COUNTER__ prefix in the variable to help ensure ordering + * inside a compilation unit that defines multiple initcalls, and + * __LINE__ to help prevent naming collisions. + */ + #define ___initcall_name2(c, l, fn, id) __initcall_##c##_##l##_##fn##id + #define ___initcall_name1(c, l, fn, id) ___initcall_name2(c, l, fn, id) + #define __initcall_name(fn, id) \ + ___initcall_name1(__COUNTER__, __LINE__, fn, id) +#else + #define __initcall_name(fn, id) __initcall_##fn##id +#endif + /* * initcalls are now grouped by functionality into separate * subsections. Ordering inside the subsections is determined @@ -187,12 +201,12 @@ extern bool initcall_debug; #define ___define_initcall(fn, id, __sec) \ __ADDRESSABLE(fn) \ asm(".section \"" #__sec ".init\", \"a\" \n" \ - "__initcall_" #fn #id ": \n" \ + __stringify(__initcall_name(fn, id)) ": \n" \ ".long " #fn " - . \n" \ ".previous \n"); #else #define ___define_initcall(fn, id, __sec) \ - static initcall_t __initcall_##fn##id __used \ + static initcall_t __initcall_name(fn, id) __used \ __attribute__((__section__(#__sec ".init"))) = fn; #endif