https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88150
--- Comment #10 from Iain Buclaw <ibuclaw at gdcproject dot org> --- I've got a (horrible?) hack for getting tls_modid from Solaris. Looking at dlinfo(RTLD_DI_LINKMAP): https://github.com/illumos/illumos-gate/blob/4e0c5eff9af325c80994e9527b7cb8b3a1ffd1d4/usr/src/cmd/sgs/rtld/common/dlfcns.c#L1927-L1934 The lmp variable returned is originally an Rt_map*, layout is: --- struct Rt_map { Link_map rt_public; const char* rt_pathname; c_ulong rt_padstart; c_ulong rt_padimlen; c_ulong rt_msize; uint rt_flags; uint rt_flags1; c_ulong rt_tlsmodid; } --- Let's do a little test... --- case PT_TLS: // TLS segment assert(!pdso._tlsSize); // is unique per DSO static if (OS_Have_Dlpi_Tls_Modid) { pdso._tlsMod = info.dlpi_tls_modid; pdso._tlsSize = phdr.p_memsz; } else version (Solaris) { Rt_map* map; version (Shared) dlinfo(handleForName(info.dlpi_name), RTLD_DI_LINKMAP, &map); else dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); pdso._tlsMod = map.rt_tlsmodid; pdso._tlsSize = phdr.p_memsz; } else { pdso._tlsMod = 0; pdso._tlsSize = 0; } break; --- Inspecting this in gdb --- (gdb) p map $1 = (struct Rt_map *) 0xfedb001 (gdb) p *map $2 = {rt_public = {l_addr = 4275896320, l_name = 0xfc0f02e4 "/mnt/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.so.76", l_ld = 0xfedd00d4, l_next = 0xfedb0678, l_prev = 0xfef206c8, l_refname = 0x0}, rt_pathname = 0xfc0f0334 "/mnt/build/i386-pc-solaris2.11/libphobos/libdruntime/.libs/libgdruntime.so.76.0.3", rt_padstart = 4275896320, rt_padimlen = 1272912, rt_msize = 1272912, rt_flags = 272761348, rt_flags1 = 1155, rt_tlsmodid = 2} --- And there it is, a valid rt_tlsmodid. Interestingly, Solaris sets the first tlsmodid to zero. https://github.com/illumos/illumos-gate/blob/8a06b3d6467c15646e663c05086378f16288af85/usr/src/cmd/sgs/rtld/common/tls.c#L52-L60 This is in stark contrast to what elf_shared expects, given that there's an assert that it is always non-zero if _tlsSize is set.
