Is there a way to query the TLS model of a shared library on Linux? (eg using ldd or some other tool).
I am having a trouble with loading too many libraries with the "initial-exec" model and would like to determine for sure which of the third party libs use this model (so I can free up some slots eg by linking statically).
This results in an error:
dlopen: cannot load any more object with static TLS
see this question.
I ran into this error myself, and while investigating it, I came on a mailing list post with this info:
If you link a shared object containing IE-model access relocs, the object will have the DF_STATIC_TLS flag set. By the spec, this means that dlopen might refuse to load it.
Looking at /usr/include/elf.h
, we have:
/* Values of `d_un.d_val' in the DT_FLAGS entry. */
...
#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
So you need to test if DF_STATIC_TLS
is set in the DT_FLAGS
entry of the shared library.
To test things, I created a simple piece of code using thread local storage:
static __thread int foo;
void set_foo(int new) {
foo = new;
}
I then compiled it twice with the two different thread local storage models:
gcc -ftls-model=initial-exec -fPIC -c tls.c -o tls-initial-exec.o
gcc -shared tls-initial-exec.o -o tls-initial-exec.so
gcc -ftls-model=global-dynamic -fPIC -c tls.c -o tls-global-dynamic.o
gcc -shared tls-global-dynamic.o -o tls-global-dynamic.so
And sure enough, I can see a difference between the two libraries using readelf
:
$ readelf --dynamic tls-initial-exec.so
Dynamic section at offset 0xe00 contains 25 entries:
Tag Type Name/Value
...
0x000000000000001e (FLAGS) STATIC_TLS
The tls-global-dynamic.so
version did not have a DT_FLAGS
entry, presumably because it didn't have any flags set. So it should be fairly easy to create a script using readelf
and grep
to find affected libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With