ANDROID: HACK: init: ensure initcall ordering with LTO
authorSami Tolvanen <samitolvanen@google.com>
Fri, 8 Dec 2017 23:49:24 +0000 (15:49 -0800)
committerSami Tolvanen <samitolvanen@google.com>
Thu, 26 Apr 2018 23:03:37 +0000 (16:03 -0700)
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.

Bug: 62093296
Bug: 67506682
Change-Id: I4fa3cb93cba967a1440ac53328eb6b8ac649ff36
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
include/linux/init.h

index 07cab8a053af91936951c38d9ab004549498cfeb..750739747e2edee6755b355f7dfd7e2ff2bf8176 100644 (file)
@@ -153,6 +153,15 @@ extern bool initcall_debug;
 
 #ifndef __ASSEMBLY__
 
+#ifdef CONFIG_LTO_CLANG
+  /* prepend the variable name with __COUNTER__ to ensure correct ordering */
+  #define ___initcall_name2(c, fn, id)         __initcall_##c##_##fn##id
+  #define ___initcall_name1(c, fn, id) ___initcall_name2(c, fn, id)
+  #define __initcall_name(fn, id)      ___initcall_name1(__COUNTER__, 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
@@ -170,7 +179,7 @@ extern bool initcall_debug;
  */
 
 #define __define_initcall(fn, id) \
-       static initcall_t __initcall_##fn##id __used \
+       static initcall_t __initcall_name(fn, id) __used \
        __attribute__((__section__(".initcall" #id ".init"))) = fn;
 
 /*