I suppose the symbols in libclang_rt.10.4.a are hidden because they are set to 
be hidden in the build:


cmake/Modules/CompilerRTDarwinUtils.cmake
266:  set(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall 
-fomit-frame-pointer")


But I don't at this point understand how that is supposed to be useful if the 
symbols are hidden. How can you use them?

Ken




On 2018-12-07, at 11:29 AM, Ken Cunningham wrote:

> 
> 
> As per the details in the previous post below that I sent a few weeks ago, I 
> have clang/llvm thread_local support working nicely on 10.6.8 and earlier 
> locally.  This is becoming a common issue now.
> 
> On 10.6.8 and earlier thread_local is implemented using existing llvm 
> infrastructure that is in place for other OS systems that needed emulated 
> TLS. I enabled it and forced it to be used for 10.6 and earlier on macOS. 
> This is exactly the same emulated_tls that gcc uses.
> 
> It works perfectly well when linked against macports-libstdc++ (currently the 
> default) as the supporting objects are built into libgcc. So from that point 
> of view it could roll out right now, for stock users who are not using libc++.
> 
> That is really quite simple enough, and I should probably put that into a PR 
> and get it on the PR list soon.
> 
> 
> 
> However I also have thread_local working when linking against libc++, and it 
> would be my preference to fully fix this and share the solution to all before 
> rolling it out.
> 
> The issue is the "___emutls_get_address" function, which is called from 
> libc++abi.dylib, and is built into clang_rt:
> 
> $ nm 
> /opt/local/libexec/llvm-5.0/lib/clang/5.0.1/lib/darwin/libclang_rt.10.4.a  | 
> grep emu
> /opt/local/libexec/llvm-5.0/lib/clang/5.0.1/lib/darwin/libclang_rt.10.4.a(emutls.c.o):
> 0000000000000000 T ___emutls_get_address
> 00000000000001a0 t _emutls_init
> 0000000000000210 d _emutls_init_once.once
> 00000000000001c0 t _emutls_key_destructor
> 0000000000000220 d _emutls_mutex
> 00000000000002f8 b _emutls_num_object
> 0000000000000300 b _emutls_pthread_key
> 
> 
> 
> These objects appear to be included in the built executables,  but are 
> apparently NOT visible to libc++abi.dylib at runtime (you can see the small 
> "t" indicating they are local only, and generate a runtime error when you try 
> to run it.
> 
> $ nm 4 | grep emu
> 0000000100007070 t ___emutls_get_address
> 0000000100009480 d 
> ___emutls_v._ZGVZL18thread_with_accessPvE23counting_function_local
> 0000000100009400 d ___emutls_v._ZL15counting_static
> 0000000100009420 d 
> ___emutls_v._ZN12_GLOBAL__N_128counting_anonymous_namespaceE
> 0000000100009460 d 
> ___emutls_v._ZZL18thread_with_accessPvE23counting_function_local
> 00000001000094a0 d ___emutls_v.__tls_guard
> 0000000100009440 d ___emutls_v.counting_extern
> 0000000100007200 t _emutls_init
> 00000001000094c0 d _emutls_init_once.once
> 0000000100007220 t _emutls_key_destructor
> 00000001000094d0 d _emutls_mutex
> 0000000100009538 b _emutls_num_object
> 0000000100009540 b _emutls_pthread_key
> 
> 
> $ ./4
> info: testing pthread_create
> dyld: lazy symbol binding failed: Symbol not found: ___emutls_get_address
>  Referenced from: /usr/lib/libc++abi.dylib
>  Expected in: flat namespace
> 
> dyld: Symbol not found: ___emutls_get_address
>  Referenced from: /usr/lib/libc++abi.dylib
>  Expected in: flat namespace
> 
> Trace/BPT trap
> 
> 
> 
> 
> Adding -Wl,-flat_namespace does not make the symbols visible.
> 
> 
> If I try to fix it like this by forcing the symbol to be exported, I get a 
> clue:
> 
> $ clang++ -std=c++11 -stdlib=libc++ 
> -Wl,-exported_symbol,___emutls_get_address  -o 4 4.cpp
> ld: warning: cannot export hidden symbol ___emutls_get_address from 
> /opt/local/libexec/llvm-5.0/lib/clang/5.0.1/lib/darwin/libclang_rt.osx.a(emutls.c.o)
> 
> 
> 
> 
> 
> Things DO work however if I build emutls.c directly into libc++abi.dylib, 
> however, using a slightly modified version of libcxxabi that includes the 
> emutls.c source file in the build:
> 
> $ nm libc++abi.kenspecial.20181206.dylib | grep emutls_
> 0000000000020054 T ___emutls_get_address
> 0000000000025458 s ___emutls_t._ZN10__cxxabiv112_GLOBAL__N_15dtorsE
> 000000000002a270 d ___emutls_v._ZN10__cxxabiv112_GLOBAL__N_111dtors_aliveE
> 000000000002a290 d ___emutls_v._ZN10__cxxabiv112_GLOBAL__N_15dtorsE
> 000000000002a2b0 d _emutls_get_index.once
> 00000000000201c8 t _emutls_init
> 00000000000201ea t _emutls_key_destructor
> 000000000002a2c0 d _emutls_mutex
> 000000000002a360 b _emutls_num_object
> 000000000002a368 b _emutls_pthread_key
> 
> 
> and with this modified libc++abi.dylib, all the symbols are found, things 
> work correctly, and all the tests that should pass in the llvm "testit" suite 
> do pass.
> 
> 
> SO here is my question:
> 
> is there some simple way I am missing to force the symbols from emutls.c to 
> be made visible in the executables built by clang using libclang_rt.10.4.a 
> that I am not seeing? If so, I would  need to change very little here, other 
> than making those symbols visible, however that is done.
> 
> OR -- if there is no way -- I can roll emutls.c into libc++abi.dylib. It's a 
> tiny bit tricky, and might well need to be manual steps. You have to build 
> clang-5.0 first with thread support enabled as below, and then use that to 
> build the new libc++abi.dylib. And once that new libc++abi.dylib is 
> installed, everything works.
> 
> 
> Ken
> 
> 
> 
> 
> 
> 
> 
> On 2018-10-05, at 10:50 AM, Ken Cunningham wrote:
> 
>> With a couple of very minor modifications, recent versions of clang will 
>> support thread_local storage including support for complex destructors on 
>> 10.6.8 using the same emutls.c system that gcc uses to support it. I'll 
>> attach the (amazingly simple) patches below. It picks up the emutls.c 
>> support from libgcc and libstdc++:
>> 
>> $ nm  /opt/local/lib/libgcc/libstdc++.6.dylib | grep cxa_thread
>> 0000000000001e16 T ___cxa_thread_atexit
>> 
>> $ nm /opt/local/lib/libgcc/libgcc_s.1.dylib | grep emu
>> 000000000000bd56 T ___emutls_get_address
>> 000000000000bec7 T ___emutls_register_common
>> 
>> 
>> This works when we use the MacPorts alternate c++11 support Marcus came up 
>> with, using
>> 
>> -stdlib=macports-libstdc++
>> 
>> and it seems to me to pass all the tests of how thread_local should work 
>> that I can throw at it. So this seems very usable to me at present.
>> 
>> 
>> 
>> 
>> However, when using libc++ (my preferred setup) I'm still having a couple of 
>> issues getting cxa_thread_atexit and emutls_get_address to build into 
>> libc++abi and show up at runtime.
>> 
>> Using RJVB's libcxx Port, I have built libc++abi more in the LINUX way, with 
>> cxa_thread_atexit.cpp included (that was fairly easy), but it doesn't find 
>> the symbols in 
>> 
>> /opt/local/libexec/llvm-7.0/lib/clang/7.0.0/lib/darwin/libclang_rt.osx.a
>> 
>> that it needs to find and dies at runtime. I think it's possibly a 
>> visibility thing.
>> 
>> If there is anyone out there with any skills and interest in working on this 
>> please speak up and I'll bring you fully up to speed offline regarding my 
>> libc++/libc++abi build efforts
>> 
>> Best,
>> 
>> Ken
>> 
>> 
>> Patches for llvm/clang-7.0 to enable thread_local support using 
>> -stdlib=macports-libstdc++:
>> 
>> ==========================
>> --- a/include/llvm/ADT/Triple.h.orig 2018-10-02 17:38:10.000000000 -0700
>> +++ b/include/llvm/ADT/Triple.h      2018-10-02 17:38:58.000000000 -0700
>> @@ -682,7 +682,7 @@
>> 
>>  /// Tests whether the target uses emulated TLS as default.
>>  bool hasDefaultEmulatedTLS() const {
>> -    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
>> +    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment() || 
>> isMacOSXVersionLT(10, 7);
>>  }
>> 
>>  /// @}
>> ==========================
>> --- a/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp.orig 2018-10-02 
>> 18:31:17.000000000 -0700
>> +++ b/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp      2018-10-02 
>> 18:32:35.000000000 -0700
>> @@ -2255,7 +2255,7 @@
>>  const char *Name = "__cxa_atexit";
>>  if (TLS) {
>>    const llvm::Triple &T = CGF.getTarget().getTriple();
>> -    Name = T.isOSDarwin() ?  "_tlv_atexit" : "__cxa_thread_atexit";
>> +    Name = (T.isOSDarwin() && !T.isMacOSXVersionLT(10, 7)) ?  "_tlv_atexit" 
>> : "__cxa_thread_atexit";
>>  }
>> 
>>  // We're assuming that the destructor function is something we can
>> --- a/tools/clang/lib/Basic/Targets/OSTargets.h.orig 2018-10-02 
>> 17:14:10.000000000 -0700
>> +++ b/tools/clang/lib/Basic/Targets/OSTargets.h      2018-10-02 
>> 17:14:41.000000000 -0700
>> @@ -93,7 +93,7 @@
>>    this->TLSSupported = false;
>> 
>>    if (Triple.isMacOSX())
>> -      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
>> +      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 4);
>>    else if (Triple.isiOS()) {
>>      // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
>>      // 32-bit simulator from 10 onwards.
>> ==========================
>> 
> 

Reply via email to