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 <samitolvanen@google.com>
This commit is contained in:
committed by
Alistair Strachan
parent
acd5c72821
commit
9730a6289c
@@ -167,6 +167,20 @@ extern bool initcall_debug;
|
|||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#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
|
* initcalls are now grouped by functionality into separate
|
||||||
* subsections. Ordering inside the subsections is determined
|
* subsections. Ordering inside the subsections is determined
|
||||||
@@ -187,12 +201,12 @@ extern bool initcall_debug;
|
|||||||
#define ___define_initcall(fn, id, __sec) \
|
#define ___define_initcall(fn, id, __sec) \
|
||||||
__ADDRESSABLE(fn) \
|
__ADDRESSABLE(fn) \
|
||||||
asm(".section \"" #__sec ".init\", \"a\" \n" \
|
asm(".section \"" #__sec ".init\", \"a\" \n" \
|
||||||
"__initcall_" #fn #id ": \n" \
|
__stringify(__initcall_name(fn, id)) ": \n" \
|
||||||
".long " #fn " - . \n" \
|
".long " #fn " - . \n" \
|
||||||
".previous \n");
|
".previous \n");
|
||||||
#else
|
#else
|
||||||
#define ___define_initcall(fn, id, __sec) \
|
#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;
|
__attribute__((__section__(#__sec ".init"))) = fn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user