blob: e8c885470de8be00949cd1dd57d8e4c1dcba1e3a [file] [log] [blame]
Brian Silvermanb47f5552020-10-01 15:08:14 -07001#ifndef AOS_THREAD_LOCAL_H_
2#define AOS_THREAD_LOCAL_H_
3
4// Use AOS_THREAD_LOCAL instead of thread_local to pick up specifics for various
5// compilers/platforms.
6
7#ifdef __aarch64__
8// Workaround for https://bugs.llvm.org/show_bug.cgi?id=41527.
9// TODO(Brian): Remove this once we upgrade past LLVM 9.0.0.
10// 9.0.1 might have the fix, but I can't find prebuilt binaries for it, for some
11// reason. Going by release dates, 10.0.0 should definitely have the fix.
12//
13// https://reviews.llvm.org/D53906 broke it, https://reviews.llvm.org/D62055
14// reverted it, https://reviews.llvm.org/D61825 re-enabled it for only Android.
15//
16// Basically, LLD hacks the program header, but fails to change enough of the
17// values to be self-consistent. The resulting values cause glibc's dynamic
18// linker to do something different than lld is expecting, so then things
19// overlap at runtime and break horribly.
20//
21// This workaround ensures that the program header has the alignment lld wants
22// already, which ensures it's set there early enough in lld's processing that
23// it actually gets the proper alignment. This makes the hack a NOP so
24// everything works correctly.
25//
26// To check for the problem, build a binary (a complete binary, not a test
27// binary which references shared objects for all the code) and run `readelf
28// -aW` on it. Look for the TLS program header. If its alignment is 0x40, this
29// workaround is probably needed. Verify its address is aligned mod 0x40 to
30// verify the workaround is effective.
31#define AOS_THREAD_LOCAL __attribute__((aligned(0x40))) thread_local
32#else
33#define AOS_THREAD_LOCAL thread_local
34#endif
35
36#endif // AOS_THREAD_LOCAL_H_