Brian Silverman | b47f555 | 2020-10-01 15:08:14 -0700 | [diff] [blame^] | 1 | #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_ |