This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[libphobos] Use sections_elf_shared.d on Solaris 11.5 (PR d/88150)


I've successfully been using a late prototype of an implementation of
the dlpi_tls_modid field of struct dl_phdr_info on Solaris 11.5 Beta.
This allowed me to get pretty reasonable test results using
sections_elf_shared.d on Solaris.

This pretty straightforward patch implements this.  Only a few points
are worth mentioning:

* libdruntime/rt/bss_sections.c refers to __bss_start, which only gld
  defines.  Unfortunately, it's marked weak, so the absence with Solaris
  ld went unnoticed at first.  Lacking an exact equivalent, I'm using
  _edata instead, which is pretty close modulo section alignment.

* As detailed in the PR, not dlclose()ing the handle in handleForName is
  necessary to avoid an assertion failure.

* I'm removing sections_solaris.d since it wouldn't even compile and
  seems pretty useless.

This patch gave me the following testsuite results on Solaris 11.5/x86
(a few more minor testsuite fixes were included, too):

		=== gdc tests ===


Running target unix
FAIL: gdc.test/runnable/nulltype.d   execution test
FAIL: gdc.test/runnable/nulltype.d -O2   execution test
FAIL: gdc.test/runnable/nulltype.d -O2 -shared-libphobos   execution test
FAIL: gdc.test/runnable/nulltype.d -g   execution test
FAIL: gdc.test/runnable/nulltype.d -g -O2   execution test
FAIL: gdc.test/runnable/nulltype.d -g -O2 -shared-libphobos   execution test
FAIL: gdc.test/runnable/nulltype.d -g -shared-libphobos   execution test
FAIL: gdc.test/runnable/nulltype.d -shared-libphobos   execution test

		=== gdc Summary for unix ===

# of expected passes		30785
# of unexpected failures	8

Running target unix/-m64

		=== gdc Summary for unix/-m64 ===

# of expected passes		30793

		=== gdc Summary ===

# of expected passes		61578
# of unexpected failures	8
/var/gcc/gcc-9.0.1-20190128/11.5-gcc-gas-libphobos/gcc/gdc  version 9.0.1 20190128 (experimental) [trunk revision 268335] (GCC) 

		=== libphobos tests ===


Running target unix
FAIL: libphobos.shared/load.d -shared-libphobos -ldl execution test
FAIL: libphobos.shared/load_13414.d -shared-libphobos -ldl execution test
FAIL: libphobos.shared/finalize.d -shared-libphobos -ldl execution test
FAIL: libphobos.shared/linkD.c lib.so -ldl -pthread execution test
FAIL: libphobos.unittests/druntime/shared/core.sync.mutex
FAIL: libphobos.unittests/druntime/shared/core.time

		=== libphobos Summary for unix ===

# of expected passes		119
# of unexpected failures	6

Running target unix/-m64
FAIL: libphobos.shared/load.d -shared-libphobos -ldl execution test
FAIL: libphobos.shared/load_13414.d -shared-libphobos -ldl execution test
FAIL: libphobos.shared/finalize.d -shared-libphobos -ldl execution test
FAIL: libphobos.shared/linkD.c lib.so -ldl -pthread execution test
FAIL: libphobos.unittests/druntime/shared/ld.so.1:
FAIL: libphobos.unittests/druntime/shared/unittest:
FAIL: libphobos.unittests/druntime/shared/fatal:
FAIL: libphobos.unittests/druntime/shared/libgdruntime_t.so.0:
FAIL: libphobos.unittests/druntime/shared/open
FAIL: libphobos.unittests/druntime/shared/failed:
FAIL: libphobos.unittests/druntime/shared/No
FAIL: libphobos.unittests/druntime/shared/such
FAIL: libphobos.unittests/druntime/shared/file
FAIL: libphobos.unittests/druntime/shared/or
FAIL: libphobos.unittests/druntime/shared/directory

		=== libphobos Summary for unix/-m64 ===

# of expected passes		78
# of unexpected failures	15

		=== libphobos Summary ===

# of expected passes		197
# of unexpected failures	21

The 32-bit nulltype.d failures occur on Linux, too (PR d/87824), and the
64-bit libphobos.unittests/druntime/shared failures happen because
libgdruntime_t.so.0 is only built for the default multilib.  The
libphobos.shared failures clearly bear investigating.

For the amd64 results, I needed a separate patch to workaround an ld
bug, to be submitted shortly.

While I did run a sparc-sun-solaris2.11 bootstrap, too, results are
pretty useless due to PR d/88462 (the minfo alignment issue).

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2018-11-21  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libphobos:
	PR d/88150
	* libdruntime/core/sys/solaris/dlfcn.d: Mark @nogc.
	* libdruntime/core/sys/solaris/link.d (struct dl_phdr_info):
	Declare dlpi_tls_modid, dlpi_tls_data members.
	* libdruntime/core/sys/solaris/sys/link.d (Elf32_Dyn, Elf64_Dyn):
	Fix syntax.
	* libdruntime/rt/sections_elf_shared.d [Solaris] (SharedELF): Set
	to true.
	Import core.sys.solaris.dlfcn, core.sys.solaris.link,
	core.sys.solaris.sys.elf, core.sys.solaris.sys.link.
	(dummy_ref): Declare.
	(initSections): Initialize dummy_ref.
	(_Dmodule_ref): Declare.
	(getDependencies): Set strtab.
	(handleForName): Don't dlclose handle.
	(findDSOInfoForAddr): New function.
	(getprogname): Declare.
	(progname): Use it.
	(getCopyRelocSection): Set exeBaseAddr.
	* libdruntime/rt/sections.d [Solaris]: Import
	rt.sections_elf_shared instead of rt.sections_solaris.

	* libdruntime/rt/bss_section.c: Also build if __sun__ && __svr4__.
	[__sun__ && __svr4__] (_edata): Declare.
	(rt_get_bss_start): Return &_edata.

	* libdruntime/rt/sections_solaris.d: Remove.
	* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Remove
	rt/sections_solaris.d.
	* libdruntime/Makefile.in: Regenerate.

# HG changeset patch
# Parent  7f08ce6ae7a8b4709e973ef8e3765976030c4f53
Use sections_elf_shared.d on Solaris 11.5 (PR d/88150)

Fixes for dlpi_tls_modid support.

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -181,7 +181,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/a
 	rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \
 	rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \
 	rt/sections_android.d rt/sections_elf_shared.d rt/sections_osx.d \
-	rt/sections_solaris.d rt/sections_win32.d rt/sections_win64.d \
+	rt/sections_win32.d rt/sections_win64.d \
 	rt/switch_.d rt/tlsgc.d rt/typeinfo/ti_Acdouble.d \
 	rt/typeinfo/ti_Acfloat.d rt/typeinfo/ti_Acreal.d \
 	rt/typeinfo/ti_Adouble.d rt/typeinfo/ti_Afloat.d rt/typeinfo/ti_Ag.d \
diff --git a/libphobos/libdruntime/core/sys/solaris/dlfcn.d b/libphobos/libdruntime/core/sys/solaris/dlfcn.d
--- a/libphobos/libdruntime/core/sys/solaris/dlfcn.d
+++ b/libphobos/libdruntime/core/sys/solaris/dlfcn.d
@@ -9,6 +9,7 @@ module core.sys.solaris.dlfcn;
 version (Solaris):
 extern (C):
 nothrow:
+@nogc:
 
 public import core.sys.posix.dlfcn;
 import core.stdc.config;
@@ -109,4 +110,4 @@ struct Dl_serinfo
     Dl_serpath[1]  dls_serpath;
 }
 
-// FIXME: Dl_argsinfo, Dl_mapinfo, Dl_amd64_unwindinfo are missing
\ No newline at end of file
+// FIXME: Dl_argsinfo, Dl_mapinfo, Dl_amd64_unwindinfo are missing
diff --git a/libphobos/libdruntime/core/sys/solaris/link.d b/libphobos/libdruntime/core/sys/solaris/link.d
--- a/libphobos/libdruntime/core/sys/solaris/link.d
+++ b/libphobos/libdruntime/core/sys/solaris/link.d
@@ -165,6 +165,8 @@ struct dl_phdr_info {
     ElfW!"Half"        dlpi_phnum;
     uint64_t           dlpi_adds;
     uint64_t           dlpi_subs;
+    size_t             dlpi_tls_modid;
+    void*              dlpi_tls_data;
 };
 
 private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/link.d b/libphobos/libdruntime/core/sys/solaris/sys/link.d
--- a/libphobos/libdruntime/core/sys/solaris/sys/link.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/link.d
@@ -15,22 +15,22 @@ import core.stdc.config;
 struct Elf32_Dyn
 {
     Elf32_Sword d_tag;
-    union d_un
+    union _d_un
     {
         Elf32_Word d_val;
         Elf32_Addr d_ptr;
         Elf32_Off  d_off;
-    }
+    } _d_un d_un;
 }
 
 struct Elf64_Dyn
 {
     Elf64_Xword d_tag;
-    union d_un
+    union _d_un
     {
         Elf64_Xword d_val;
         Elf64_Addr  d_ptr;
-    }
+    } _d_un d_un;
 }
 
 enum DT_NULL         = 0;
diff --git a/libphobos/libdruntime/rt/bss_section.c b/libphobos/libdruntime/rt/bss_section.c
--- a/libphobos/libdruntime/rt/bss_section.c
+++ b/libphobos/libdruntime/rt/bss_section.c
@@ -10,12 +10,20 @@
 /* These symbols are defined in the linker script and bracket the
  * .bss, .lbss, .lrodata and .ldata sections.
  */
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__sun__) && defined(__svr4__))
 // Need to use weak linkage to workaround a bug in ld.bfd (Bugzilla 13025).
 extern int __attribute__((weak)) __bss_start, _end;
+#if defined(__sun__) && defined(__svr4__)
+extern int _edata;
+#endif
 
 __attribute__ ((visibility ("hidden"))) void* rt_get_bss_start();
 __attribute__ ((visibility ("hidden"))) void* rt_get_end();
+#if defined(__sun__) && defined(__svr4__)
+// FIXME: This is wrong: begin of .bss and _edata don't always coincide.
+void* rt_get_bss_start() { return (void*)&_edata; }
+#else
 void* rt_get_bss_start() { return (void*)&__bss_start; }
+#endif
 void* rt_get_end() { return (void*)&_end; }
 #endif
diff --git a/libphobos/libdruntime/rt/sections.d b/libphobos/libdruntime/rt/sections.d
--- a/libphobos/libdruntime/rt/sections.d
+++ b/libphobos/libdruntime/rt/sections.d
@@ -26,7 +26,7 @@ else version (FreeBSD)
 else version (NetBSD)
     public import rt.sections_elf_shared;
 else version (Solaris)
-    public import rt.sections_solaris;
+    public import rt.sections_elf_shared;
 else version (Darwin)
 {
     version (X86_64)
diff --git a/libphobos/libdruntime/rt/sections_elf_shared.d b/libphobos/libdruntime/rt/sections_elf_shared.d
--- a/libphobos/libdruntime/rt/sections_elf_shared.d
+++ b/libphobos/libdruntime/rt/sections_elf_shared.d
@@ -13,6 +13,7 @@ module rt.sections_elf_shared;
 version (CRuntime_Glibc) enum SharedELF = true;
 else version (FreeBSD) enum SharedELF = true;
 else version (NetBSD) enum SharedELF = true;
+else version (Solaris) enum SharedELF = true;
 else enum SharedELF = false;
 static if (SharedELF):
 
@@ -40,6 +41,13 @@ else version (NetBSD)
     import core.sys.netbsd.sys.elf;
     import core.sys.netbsd.sys.link_elf;
 }
+else version (Solaris)
+{
+    import core.sys.solaris.dlfcn;
+    import core.sys.solaris.link;
+    import core.sys.solaris.sys.elf;
+    import core.sys.solaris.sys.link;
+}
 else
 {
     static assert(0, "unimplemented");
@@ -123,6 +131,7 @@ private:
 
 version (FreeBSD) private __gshared void* dummy_ref;
 version (NetBSD) private __gshared void* dummy_ref;
+version (Solaris) private __gshared void* dummy_ref;
 
 /****
  * Gets called on program startup just before GC is initialized.
@@ -133,6 +142,7 @@ void initSections() nothrow @nogc
     // reference symbol to support weak linkage
     version (FreeBSD) dummy_ref = &_d_dso_registry;
     version (NetBSD) dummy_ref = &_d_dso_registry;
+    version (Solaris) dummy_ref = &_d_dso_registry;
 }
 
 
@@ -263,6 +273,7 @@ private:
 // start of linked list for ModuleInfo references
 version (FreeBSD) deprecated extern (C) __gshared void* _Dmodule_ref;
 version (NetBSD) deprecated extern (C) __gshared void* _Dmodule_ref;
+version (Solaris) deprecated extern (C) __gshared void* _Dmodule_ref;
 
 version (Shared)
 {
@@ -677,6 +688,8 @@ version (Shared)
                     strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
                 else version (NetBSD)
                     strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
+                else version (Solaris)
+                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
                 else
                     static assert(0, "unimplemented");
                 break;
@@ -703,7 +716,8 @@ version (Shared)
     void* handleForName(const char* name) nothrow @nogc
     {
         auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY);
-        if (handle !is null) .dlclose(handle); // drop reference count
+        version (Solaris) { }
+        else if (handle !is null) .dlclose(handle); // drop reference count
         return handle;
     }
 }
@@ -799,6 +813,23 @@ else version (NetBSD) bool findDSOInfoFo
     auto dg = DG(addr, result);
     return dl_iterate_phdr(&callback, &dg) != 0;
 }
+else version (Solaris) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc
+{
+    static struct DG { const(void)* addr; dl_phdr_info* result; }
+
+    extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc
+    {
+        auto p = cast(DG*)arg;
+        if (findSegmentForAddr(*info, p.addr))
+        {
+            if (p.result !is null) *p.result = *info;
+            return 1; // break;
+        }
+        return 0; // continue iteration
+    }
+    auto dg = DG(addr, result);
+    return dl_iterate_phdr(&callback, &dg) != 0;
+}
 
 /*********************************
  * Determine if 'addr' lies within shared object 'info'.
@@ -825,12 +856,14 @@ version (linux) import core.sys.linux.er
 // should be in core.sys.freebsd.stdlib
 version (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc;
 version (NetBSD) extern(C) const(char)* getprogname() nothrow @nogc;
+version (Solaris) extern(C) const(char)* getprogname() nothrow @nogc;
 
 @property const(char)* progname() nothrow @nogc
 {
     version (linux) return program_invocation_name;
     version (FreeBSD) return getprogname();
     version (NetBSD) return getprogname();
+    version (Solaris) return getprogname();
 }
 
 const(char)[] dsoName(const char* dlpi_name) nothrow @nogc
@@ -871,6 +904,8 @@ const(void)[] getCopyRelocSection() noth
         enum ElfW!"Addr" exeBaseAddr = 0;
     else version (NetBSD)
         enum ElfW!"Addr" exeBaseAddr = 0;
+    else version (Solaris)
+        enum ElfW!"Addr" exeBaseAddr = 0;
 
     dl_phdr_info info = void;
     findDSOInfoForAddr(bss_start, &info) || assert(0);
diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/rt/sections_solaris.d
deleted file mode 100644
--- a/libphobos/libdruntime/rt/sections_solaris.d
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Written in the D programming language.
- * This module provides Solaris-specific support for sections.
- *
- * Copyright: Copyright Martin Nowak 2012-2013.
- * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors:   Martin Nowak
- * Source: $(DRUNTIMESRC src/rt/_sections_solaris.d)
- */
-
-module rt.sections_solaris;
-
-version (Solaris):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import core.stdc.stdlib : malloc, free;
-import rt.deh, rt.minfo;
-
-struct SectionGroup
-{
-    static int opApply(scope int delegate(ref SectionGroup) dg)
-    {
-        return dg(_sections);
-    }
-
-    static int opApplyReverse(scope int delegate(ref SectionGroup) dg)
-    {
-        return dg(_sections);
-    }
-
-    @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
-    {
-        return _moduleGroup.modules;
-    }
-
-    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
-    {
-        return _moduleGroup;
-    }
-
-    @property immutable(FuncTable)[] ehTables() const nothrow @nogc
-    {
-        auto pbeg = cast(immutable(FuncTable)*)&__start_deh;
-        auto pend = cast(immutable(FuncTable)*)&__stop_deh;
-        return pbeg[0 .. pend - pbeg];
-    }
-
-    @property inout(void[])[] gcRanges() inout nothrow @nogc
-    {
-        return _gcRanges[];
-    }
-
-private:
-    ModuleGroup _moduleGroup;
-    void[][1] _gcRanges;
-}
-
-void initSections() nothrow @nogc
-{
-    auto mbeg = cast(immutable ModuleInfo**)&__start_minfo;
-    auto mend = cast(immutable ModuleInfo**)&__stop_minfo;
-    _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);
-
-    auto pbeg = cast(void*)&__dso_handle;
-    auto pend = cast(void*)&_end;
-    _sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
-}
-
-void finiSections() nothrow @nogc
-{
-}
-
-void[] initTLSRanges() nothrow @nogc
-{
-    auto pbeg = cast(void*)&_tlsstart;
-    auto pend = cast(void*)&_tlsend;
-    return pbeg[0 .. pend - pbeg];
-}
-
-void finiTLSRanges(void[] rng) nothrow @nogc
-{
-}
-
-void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow
-{
-    dg(rng.ptr, rng.ptr + rng.length);
-}
-
-private:
-
-__gshared SectionGroup _sections;
-
-extern(C)
-{
-    /* Symbols created by the compiler/linker and inserted into the
-     * object file that 'bracket' sections.
-     */
-    extern __gshared
-    {
-        void* __start_deh;
-        void* __stop_deh;
-        void* __start_minfo;
-        void* __stop_minfo;
-        int __dso_handle;
-        int _end;
-    }
-
-    extern
-    {
-        void* _tlsstart;
-        void* _tlsend;
-    }
-}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]