/ go Public
cmd/link: c-archive Output Mode Forces
Initial-Exec TLS model
Issues related to the Go compiler and/or runtime.
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
What version of Go are you using (
Does this issue reproduce with the latest release?
What operating system and processor architecture are you using (
What did you do?
Full Gist is available here - https://gist.github.com/auzhva/6e3660c2433f7ead765d4d09e645013b
In provided example there are 3 files:
If built in below fashion it works:
Then when running
While if I do below it fails with
cannot allocate memory in static TLS blockerror.
More investigation on STATIC_TLS flag
It appears that Go always builds with
Initial-ExecTLS model, which appears to lead to
STATIC_TLSflag being set to produced ELF binaries.
This is easily visible with below:
This is a case with
c-sharedlibrary itself. But when
c-archiveis produced then whatever upper code will use it - it inherits STATIC_TLS flag.
So in second (faulty) example above the entire
libClibShared.soinherits STATIC_TLS flag as well. At least on x86_64 arch (in theory this can be arch-dependent).
Ok, there is STATIC_TLS flag. So what?
Loading STATIC_TLS images is a complicated thing.
In linux version glibc it allocates pre-populated constant
surplusof 512 bytes in TLS block for further unspecified use. It's defined here - https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/dl-tls.c;h=d554ae44976bc494da4e41aaa4f6ecb5ca2ca4be;hb=HEAD
If I'm checking sizes of
readelf -Sthen I see that go uses only 0x10 bytes of TLS. Which is lower then glibc surplus. And theoretically glibc is able to
dlopen()up to 32 go libs until it will run out of the buffer.
But it doesn't work with
c-archive. Go lib in
c-archivemode requires same 16 bytes of TLS stack, but other code may have additional TLS requirements. So if additional code needs more TLS then c-archive plus that code runs out of glibc boundaries and entire thing fails.
That wouldn't have been happening if
c-archivewould've not been forcing Initial-TLS TLS models. As this 512-byte glibc limit applies only to that model. And any of the other 3 models (General Dynamic, Local Dynamic, Local Executable) do not have this limit.
What did you expect to see?
Both c-shared and c-archive cases working.
What did you see instead?
C-archive case failing.
The text was updated successfully, but these errors were encountered: