Hi Iain, > On Tue, 9 Apr 2019 at 21:27, Rainer Orth <r...@cebitec.uni-bielefeld.de> > wrote: >> >> Rainer Orth <r...@cebitec.uni-bielefeld.de> writes: >> >> > Before Solaris 11.5, struct dl_phdr_info lacked the dlpi_tls_modid >> > member. While the support might be backported to Solaris 11.4, it >> > certainly won't to previous Solaris releases. To work around this, I've >> > used the following patch. Again, it's pretty straightforward. >> > >> > Point of note: >> > >> > * On Solaris, FreeBSD and NetBSD, dl_phdr_info is always visible in >> > <link.h>, while on Linux one needs to define _GNU_SOURCE. >> > AC_USE_SYSTEM_EXTENSION takes care of this, but needs to be called >> > early (i.e. not in DRUNTIME_OS_DLPI_TLS_MODID) to avoid an autoconf >> > warning: >> > >> > configure.ac:129: warning: AC_COMPILE_IFELSE was called before >> > AC_USE_SYSTEM_EXTENSIONS >> > m4/druntime/os.m4:190: DRUNTIME_OS_DLPI_TLS_MODID is expanded from... >> > configure.ac:129: the top level >> > >> > Tested on i386-pc-solaris2.11 (Solaris 11.4) and x86_64-pc-linux-gnu. >> > >> > Not unexpectedly, there are a couple of regressions compared to the >> > Solaris 11.5/x86 results: >> > >> > +FAIL: gdc.test/runnable/testaa.d execution test >> > +FAIL: gdc.test/runnable/testaa.d -fPIC execution test >> > +FAIL: gdc.test/runnable/testaa.d -fPIC -shared-libphobos execution test >> > +FAIL: gdc.test/runnable/testaa.d -shared-libphobos execution test >> > >> > 32 and 64-bit >> > >> > +FAIL: gdc.test/runnable/xtest55.d execution test >> > +FAIL: gdc.test/runnable/xtest55.d -shared-libphobos execution test >> > >> > 64-bit only >> > >> > +FAIL: libphobos.shared/link_linkdep.d >> > -I/vol/gcc/src/hg/trunk/local/libphobos/t >> > estsuite/libphobos.shared liblinkdep.so lib.so -shared-libphobos >> > execution test >> > >> > +FAIL: libphobos.shared/load_linkdep.d -shared-libphobos -ldl execution >> > test >> > +FAIL: libphobos.shared/load_loaddep.d -shared-libphobos -ldl execution >> > test >> > >> > +FAIL: libphobos.shared/linkDR.c -shared-libphobos -ldl -pthread >> > execution test >> > +FAIL: libphobos.shared/host.c -ldl -pthread execution test >> > +FAIL: libphobos.shared/loadDR.c -ldl -pthread -g execution test >> > >> > 32 and 64-bit >> > >> > +FAIL: libphobos.shared/link.d >> > -I/vol/gcc/src/hg/trunk/local/libphobos/testsuite/libphobos.shared >> > lib.so -shared-libphobos execution test >> > >> > 64-bit only >> > >> > I haven't looked much closer yet, just posting this to see if anything >> > along those lines could be acceptable at all. >> >> Fortunately, Iain just discovered a way better way to work around the >> lack of dlpi_tls_modid: dlinfo(RTLD_DI_LINKMAP) returns not only a >> pointer to a Link_map * as documented in the man page, but rather a >> pointer to a struct Rt_map which also includes a rt_tlsmodid member. >> It has been this way since at least Solaris 9 and the Solaris/Illumos >> sources ($SRC/cmd/sgs/include/rtld.h) explicitly have a comment around >> the start of the structure stateing >> >> Exposed to rtld_db - don't move, don't delete >> >> which pretty much guarantees that this can be relied on. >> >> The only other quirk of note is that before dlpi_tls_modid got added, >> tlsmodid started at 0 for the main executable, not 1 as the glibc spec >> required and libdruntime assumes. I account for this by adjusting >> _tlsMod on dlinfo and undoing the adjustment before passing it to >> __tls_get_adddr, the only consumer. >> >> With the revised patch below, I get clean gdc testresults on Solaris >> 11.3 and 11.4 (and still on 11.5 which uses the dlpi_tls_modid path), >> and almost identical libphobos testresults on all three versions. >> >> I hope this is good to go in (the sections_elf_shared.d part via >> upstream, the rest directly) now? >> >> Thanks a lot to Iain for discovering this. >> > > I've finally managed to get around to moving the guts of rt.sections_* > to gcc.sections.*, with the patch amended to apply to > gcc/sections/elf_shared.d, this is OK.
Here's the rebased patch for this. Tested as the previous one and installed on mainline. Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University 2019-01-22 Rainer Orth <r...@cebitec.uni-bielefeld.de> Iain Buclaw <ibuc...@gdcproject.org> PR d/88150 * m4/druntime/os.m4 (DRUNTIME_OS_DLPI_TLS_MODID): New macro. * configure.ac: Use it. Call AC_USE_SYSTEM_EXTENSIONS. * configure: Regenerate. * Makefile.in, libdruntime/Makefile.in, src/Makefile.in, testsuite/Makefile.in: Regenerate. * libdruntime/gcc/config.d.in (OS_Have_Dlpi_Tls_Modid): Define. * libdruntime/gcc/sections/elf_shared.d: Import gcc.config. (scanSegments) <PT_TLS> [OS_Have_Dlpi_Tls_Modid]: Use dlpi_tls_modid. [Solaris]: Use dlinfo(RTLD_DI_LINKMAP) to get rt_tlsmodid. Otherwise clear pdso._tlsMod, pdso._tlsSize. (getTLSRange) [Solaris && !OS_Have_Dlpi_Tls_Modid]: Readjust mod.
# HG changeset patch # Parent 88c053a22857705ed80d4c41da85c0ff943abecc Work around lack of dlpi_tls_modid before Solaris 11.5 diff --git a/libphobos/configure.ac b/libphobos/configure.ac --- a/libphobos/configure.ac +++ b/libphobos/configure.ac @@ -32,6 +32,7 @@ AC_CONFIG_HEADERS(config.h) AM_ENABLE_MULTILIB(, ..) AC_CANONICAL_SYSTEM +AC_USE_SYSTEM_EXTENSIONS target_alias=${target_alias-$target} AC_SUBST(target_alias) @@ -125,6 +126,7 @@ DRUNTIME_OS_SOURCES DRUNTIME_OS_THREAD_MODEL DRUNTIME_OS_ARM_EABI_UNWINDER DRUNTIME_OS_MINFO_BRACKETING +DRUNTIME_OS_DLPI_TLS_MODID DRUNTIME_OS_LINK_SPEC DRUNTIME_LIBRARIES_CLIB diff --git a/libphobos/libdruntime/gcc/config.d.in b/libphobos/libdruntime/gcc/config.d.in --- a/libphobos/libdruntime/gcc/config.d.in +++ b/libphobos/libdruntime/gcc/config.d.in @@ -35,6 +35,9 @@ enum ThreadModel enum ThreadModel GNU_Thread_Model = ThreadModel.@DCFG_THREAD_MODEL@; +// Whether struct dl_phdr_info has dlpi_tls_modid member. +enum OS_Have_Dlpi_Tls_Modid = @DCFG_DLPI_TLS_MODID@; + // Whether target has support for builtin atomics. enum GNU_Have_Atomics = @DCFG_HAVE_ATOMIC_BUILTINS@; diff --git a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d --- a/libphobos/libdruntime/gcc/sections/elf_shared.d +++ b/libphobos/libdruntime/gcc/sections/elf_shared.d @@ -74,6 +74,7 @@ else static assert(0, "unimplemented"); } import core.sys.posix.pthread; +import gcc.config; import rt.deh; import rt.dmain2; import rt.minfo; @@ -792,8 +793,40 @@ void scanSegments(in ref dl_phdr_info in case PT_TLS: // TLS segment safeAssert(!pdso._tlsSize, "Multiple TLS segments in image header."); - pdso._tlsMod = info.dlpi_tls_modid; - pdso._tlsSize = phdr.p_memsz; + static if (OS_Have_Dlpi_Tls_Modid) + { + pdso._tlsMod = info.dlpi_tls_modid; + pdso._tlsSize = phdr.p_memsz; + } + else version (Solaris) + { + 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; + } + + Rt_map* map; + version (Shared) + dlinfo(handleForName(info.dlpi_name), RTLD_DI_LINKMAP, &map); + else + dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); + // Until Solaris 11.4, tlsmodid for the executable is 0. + // Let it start at 1 as the rest of the code expects. + pdso._tlsMod = map.rt_tlsmodid + 1; + pdso._tlsSize = phdr.p_memsz; + } + else + { + pdso._tlsMod = 0; + pdso._tlsSize = 0; + } break; default: @@ -1004,6 +1037,12 @@ void[] getTLSRange(size_t mod, size_t sz if (mod == 0) return null; + version (Solaris) + { + static if (!OS_Have_Dlpi_Tls_Modid) + mod -= 1; + } + // base offset auto ti = tls_index(mod, 0); return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4 --- a/libphobos/m4/druntime/os.m4 +++ b/libphobos/m4/druntime/os.m4 @@ -184,6 +184,20 @@ AC_DEFUN([DRUNTIME_OS_MINFO_BRACKETING], AC_LANG_POP([C]) ]) +# DRUNTIME_OS_DLPI_TLS_MODID +# ---------------------------- +# Check if struct dl_phdr_info includes the dlpi_tls_modid member and +# substitute DCFG_DLPI_TLS_MODID. +AC_DEFUN([DRUNTIME_OS_DLPI_TLS_MODID], +[ + AC_LANG_PUSH([C]) + AC_CHECK_MEMBER([struct dl_phdr_info.dlpi_tls_modid], + [DCFG_DLPI_TLS_MODID=true], [DCFG_DLPI_TLS_MODID=false], + [[#include <link.h>]]) + AC_SUBST(DCFG_DLPI_TLS_MODID) + AC_LANG_POP([C]) +]) + # DRUNTIME_OS_LINK_SPEC # --------------------- # Add target-specific link options to link_spec.