diff mbox series

[libphobos] Committed move rt.sections modules to gcc.sections

Message ID CABOHX+cBHVqFf71S7bOXe9qL7yFNjnUQ-acDZk6HzbfFRFanTw@mail.gmail.com
State New
Headers show
Series [libphobos] Committed move rt.sections modules to gcc.sections | expand

Commit Message

Iain Buclaw April 13, 2019, 3:29 p.m. UTC
Hi,

This patch moved all rt.sections modules to a gcc.sections package.

These modules depend on a mixture between how the compiler emits
run-time module information, and what functions are exposed by the
platform to inquire about loaded global and thread-local data
sections.

As the upstream implementation is written to work only with how the
reference D compiler writes out data, much of what is present does not
apply to the GCC D front-end.  So it has been moved to a non-upstream
location in the source tree, where most of it will be rewritten once
each port has been completed.

The only tested module sections/elf_shared.d has been cleaned up so
that all deprecated declarations have been removed, as well as the
brittle module collision checking, which required bss_sections.c.  All
other ports have been left unchanged apart from a commonizing of
attributes.

Bootstrapped and regression tested on x86_64-linux-gnu.

Committed to trunk as r270341.
diff mbox series

Patch

diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index abefb435dc7..8e36ce21449 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -122,7 +122,7 @@  DRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d
 # https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
 DRUNTIME_SSOURCES = core/threadasm.S
 
-DRUNTIME_CSOURCES = core/stdc/errno_.c rt/bss_section.c
+DRUNTIME_CSOURCES = core/stdc/errno_.c
 
 DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/checkedint.d core/cpuid.d core/demangle.d core/exception.d \
@@ -140,14 +140,14 @@  DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/sync/config.d core/sync/exception.d core/sync/mutex.d \
 	core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \
 	core/vararg.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \
-	gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
-	gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \
-	rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \
-	rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \
-	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 \
+	gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
+	gcc/sections/package.d gcc/sections/solaris.d gcc/sections/win32.d \
+	gcc/sections/win64.d gcc/unwind/arm.d gcc/unwind/arm_common.d \
+	gcc/unwind/c6x.d gcc/unwind/generic.d gcc/unwind/package.d \
+	gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d \
+	rt/arrayassign.d rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d \
+	rt/critical_.d 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/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/Makefile.in b/libphobos/libdruntime/Makefile.in
index 4bfd04c3db5..0a27afac545 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -194,7 +194,10 @@  am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
 	core/sync/exception.lo core/sync/mutex.lo core/sync/rwmutex.lo \
 	core/sync/semaphore.lo core/thread.lo core/time.lo \
 	core/vararg.lo gcc/attribute.lo gcc/backtrace.lo \
-	gcc/builtins.lo gcc/deh.lo gcc/unwind/arm.lo \
+	gcc/builtins.lo gcc/deh.lo gcc/sections/android.lo \
+	gcc/sections/elf_shared.lo gcc/sections/osx.lo \
+	gcc/sections/package.lo gcc/sections/solaris.lo \
+	gcc/sections/win32.lo gcc/sections/win64.lo gcc/unwind/arm.lo \
 	gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \
 	gcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \
 	object.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \
@@ -202,31 +205,29 @@  am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
 	rt/config.lo rt/critical_.lo rt/deh.lo rt/dmain2.lo \
 	rt/invariant.lo rt/lifetime.lo rt/memory.lo rt/minfo.lo \
 	rt/monitor_.lo rt/obj.lo rt/qsort.lo rt/sections.lo \
-	rt/sections_android.lo rt/sections_elf_shared.lo \
-	rt/sections_osx.lo rt/sections_solaris.lo rt/sections_win32.lo \
-	rt/sections_win64.lo rt/switch_.lo rt/tlsgc.lo \
-	rt/typeinfo/ti_Acdouble.lo rt/typeinfo/ti_Acfloat.lo \
-	rt/typeinfo/ti_Acreal.lo rt/typeinfo/ti_Adouble.lo \
-	rt/typeinfo/ti_Afloat.lo rt/typeinfo/ti_Ag.lo \
-	rt/typeinfo/ti_Aint.lo rt/typeinfo/ti_Along.lo \
-	rt/typeinfo/ti_Areal.lo rt/typeinfo/ti_Ashort.lo \
-	rt/typeinfo/ti_C.lo rt/typeinfo/ti_byte.lo \
-	rt/typeinfo/ti_cdouble.lo rt/typeinfo/ti_cent.lo \
-	rt/typeinfo/ti_cfloat.lo rt/typeinfo/ti_char.lo \
-	rt/typeinfo/ti_creal.lo rt/typeinfo/ti_dchar.lo \
-	rt/typeinfo/ti_delegate.lo rt/typeinfo/ti_double.lo \
-	rt/typeinfo/ti_float.lo rt/typeinfo/ti_idouble.lo \
-	rt/typeinfo/ti_ifloat.lo rt/typeinfo/ti_int.lo \
-	rt/typeinfo/ti_ireal.lo rt/typeinfo/ti_long.lo \
-	rt/typeinfo/ti_n.lo rt/typeinfo/ti_ptr.lo \
-	rt/typeinfo/ti_real.lo rt/typeinfo/ti_short.lo \
-	rt/typeinfo/ti_ubyte.lo rt/typeinfo/ti_ucent.lo \
-	rt/typeinfo/ti_uint.lo rt/typeinfo/ti_ulong.lo \
-	rt/typeinfo/ti_ushort.lo rt/typeinfo/ti_void.lo \
-	rt/typeinfo/ti_wchar.lo rt/util/array.lo \
-	rt/util/container/array.lo rt/util/container/common.lo \
-	rt/util/container/hashtab.lo rt/util/container/treap.lo \
-	rt/util/random.lo rt/util/typeinfo.lo rt/util/utf.lo
+	rt/switch_.lo rt/tlsgc.lo rt/typeinfo/ti_Acdouble.lo \
+	rt/typeinfo/ti_Acfloat.lo rt/typeinfo/ti_Acreal.lo \
+	rt/typeinfo/ti_Adouble.lo rt/typeinfo/ti_Afloat.lo \
+	rt/typeinfo/ti_Ag.lo rt/typeinfo/ti_Aint.lo \
+	rt/typeinfo/ti_Along.lo rt/typeinfo/ti_Areal.lo \
+	rt/typeinfo/ti_Ashort.lo rt/typeinfo/ti_C.lo \
+	rt/typeinfo/ti_byte.lo rt/typeinfo/ti_cdouble.lo \
+	rt/typeinfo/ti_cent.lo rt/typeinfo/ti_cfloat.lo \
+	rt/typeinfo/ti_char.lo rt/typeinfo/ti_creal.lo \
+	rt/typeinfo/ti_dchar.lo rt/typeinfo/ti_delegate.lo \
+	rt/typeinfo/ti_double.lo rt/typeinfo/ti_float.lo \
+	rt/typeinfo/ti_idouble.lo rt/typeinfo/ti_ifloat.lo \
+	rt/typeinfo/ti_int.lo rt/typeinfo/ti_ireal.lo \
+	rt/typeinfo/ti_long.lo rt/typeinfo/ti_n.lo \
+	rt/typeinfo/ti_ptr.lo rt/typeinfo/ti_real.lo \
+	rt/typeinfo/ti_short.lo rt/typeinfo/ti_ubyte.lo \
+	rt/typeinfo/ti_ucent.lo rt/typeinfo/ti_uint.lo \
+	rt/typeinfo/ti_ulong.lo rt/typeinfo/ti_ushort.lo \
+	rt/typeinfo/ti_void.lo rt/typeinfo/ti_wchar.lo \
+	rt/util/array.lo rt/util/container/array.lo \
+	rt/util/container/common.lo rt/util/container/hashtab.lo \
+	rt/util/container/treap.lo rt/util/random.lo \
+	rt/util/typeinfo.lo rt/util/utf.lo
 am__objects_2 = gc/bits.lo gc/config.lo gc/gcinterface.lo \
 	gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \
 	gc/pooltable.lo gc/proxy.lo
@@ -425,8 +426,7 @@  am__objects_27 = $(am__objects_1) $(am__objects_3) $(am__objects_5) \
 	$(am__objects_13) $(am__objects_15) $(am__objects_17) \
 	$(am__objects_19) $(am__objects_21) $(am__objects_23) \
 	$(am__objects_25) $(am__objects_26)
-am__objects_28 = core/stdc/libgdruntime_la-errno_.lo \
-	rt/libgdruntime_la-bss_section.lo
+am__objects_28 = core/stdc/libgdruntime_la-errno_.lo
 am__objects_29 = core/libgdruntime_la-threadasm.lo
 am__objects_30 = $(am__objects_27) $(am__objects_28) $(am__objects_29)
 am_libgdruntime_la_OBJECTS = $(am__objects_30)
@@ -719,7 +719,7 @@  DRUNTIME_DSOURCES_GENERATED = gcc/config.d gcc/libbacktrace.d
 # Can't use wildcards here:
 # https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
 DRUNTIME_SSOURCES = core/threadasm.S
-DRUNTIME_CSOURCES = core/stdc/errno_.c rt/bss_section.c
+DRUNTIME_CSOURCES = core/stdc/errno_.c
 DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/checkedint.d core/cpuid.d core/demangle.d core/exception.d \
 	core/internal/abort.d core/internal/arrayop.d core/internal/convert.d \
@@ -736,14 +736,14 @@  DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
 	core/sync/config.d core/sync/exception.d core/sync/mutex.d \
 	core/sync/rwmutex.d core/sync/semaphore.d core/thread.d core/time.d \
 	core/vararg.d gcc/attribute.d gcc/backtrace.d gcc/builtins.d gcc/deh.d \
-	gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
-	gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \
-	rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \
-	rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \
-	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 \
+	gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
+	gcc/sections/package.d gcc/sections/solaris.d gcc/sections/win32.d \
+	gcc/sections/win64.d gcc/unwind/arm.d gcc/unwind/arm_common.d \
+	gcc/unwind/c6x.d gcc/unwind/generic.d gcc/unwind/package.d \
+	gcc/unwind/pe.d object.d rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d \
+	rt/arrayassign.d rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d \
+	rt/critical_.d 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/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 \
@@ -1083,6 +1083,16 @@  gcc/attribute.lo: gcc/$(am__dirstamp)
 gcc/backtrace.lo: gcc/$(am__dirstamp)
 gcc/builtins.lo: gcc/$(am__dirstamp)
 gcc/deh.lo: gcc/$(am__dirstamp)
+gcc/sections/$(am__dirstamp):
+	@$(MKDIR_P) gcc/sections
+	@: > gcc/sections/$(am__dirstamp)
+gcc/sections/android.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/elf_shared.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/osx.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/package.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/solaris.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/win32.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/win64.lo: gcc/sections/$(am__dirstamp)
 gcc/unwind/$(am__dirstamp):
 	@$(MKDIR_P) gcc/unwind
 	@: > gcc/unwind/$(am__dirstamp)
@@ -1115,12 +1125,6 @@  rt/monitor_.lo: rt/$(am__dirstamp)
 rt/obj.lo: rt/$(am__dirstamp)
 rt/qsort.lo: rt/$(am__dirstamp)
 rt/sections.lo: rt/$(am__dirstamp)
-rt/sections_android.lo: rt/$(am__dirstamp)
-rt/sections_elf_shared.lo: rt/$(am__dirstamp)
-rt/sections_osx.lo: rt/$(am__dirstamp)
-rt/sections_solaris.lo: rt/$(am__dirstamp)
-rt/sections_win32.lo: rt/$(am__dirstamp)
-rt/sections_win64.lo: rt/$(am__dirstamp)
 rt/switch_.lo: rt/$(am__dirstamp)
 rt/tlsgc.lo: rt/$(am__dirstamp)
 rt/typeinfo/$(am__dirstamp):
@@ -1627,7 +1631,6 @@  core/sys/solaris/time.lo: core/sys/solaris/$(am__dirstamp)
 gcc/config.lo: gcc/$(am__dirstamp)
 gcc/libbacktrace.lo: gcc/$(am__dirstamp)
 core/stdc/libgdruntime_la-errno_.lo: core/stdc/$(am__dirstamp)
-rt/libgdruntime_la-bss_section.lo: rt/$(am__dirstamp)
 core/libgdruntime_la-threadasm.lo: core/$(am__dirstamp)
 
 libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EXTRA_libgdruntime_la_DEPENDENCIES) 
@@ -1703,6 +1706,8 @@  mostlyclean-compile:
 	-rm -f gc/impl/manual/*.lo
 	-rm -f gcc/*.$(OBJEXT)
 	-rm -f gcc/*.lo
+	-rm -f gcc/sections/*.$(OBJEXT)
+	-rm -f gcc/sections/*.lo
 	-rm -f gcc/unwind/*.$(OBJEXT)
 	-rm -f gcc/unwind/*.lo
 	-rm -f gcstub/*.$(OBJEXT)
@@ -1743,9 +1748,6 @@  core/libgdruntime_la-threadasm.lo: core/threadasm.S
 core/stdc/libgdruntime_la-errno_.lo: core/stdc/errno_.c
 	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
 
-rt/libgdruntime_la-bss_section.lo: rt/bss_section.c
-	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rt/libgdruntime_la-bss_section.lo `test -f 'rt/bss_section.c' || echo '$(srcdir)/'`rt/bss_section.c
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -1785,6 +1787,7 @@  clean-libtool:
 	-rm -rf gc/impl/conservative/.libs gc/impl/conservative/_libs
 	-rm -rf gc/impl/manual/.libs gc/impl/manual/_libs
 	-rm -rf gcc/.libs gcc/_libs
+	-rm -rf gcc/sections/.libs gcc/sections/_libs
 	-rm -rf gcc/unwind/.libs gcc/unwind/_libs
 	-rm -rf gcstub/.libs gcstub/_libs
 	-rm -rf rt/.libs rt/_libs
@@ -1931,6 +1934,7 @@  distclean-generic:
 	-rm -f gc/impl/conservative/$(am__dirstamp)
 	-rm -f gc/impl/manual/$(am__dirstamp)
 	-rm -f gcc/$(am__dirstamp)
+	-rm -f gcc/sections/$(am__dirstamp)
 	-rm -f gcc/unwind/$(am__dirstamp)
 	-rm -f gcstub/$(am__dirstamp)
 	-rm -f rt/$(am__dirstamp)
diff --git a/libphobos/libdruntime/rt/sections_android.d b/libphobos/libdruntime/gcc/sections/android.d
similarity index 70%
rename from libphobos/libdruntime/rt/sections_android.d
rename to libphobos/libdruntime/gcc/sections/android.d
index 16c54655129..f00bb8926b7 100644
--- a/libphobos/libdruntime/rt/sections_android.d
+++ b/libphobos/libdruntime/gcc/sections/android.d
@@ -1,14 +1,26 @@ 
-/**
- * Written in the D programming language.
- * This module provides bionic-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_android.d)
- */
+// Bionic-specific support for sections.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
 
-module rt.sections_android;
+module gcc.sections.android;
 
 version (CRuntime_Bionic):
 
@@ -69,6 +81,8 @@  void initSections() nothrow @nogc
 
     auto pbeg = cast(void*)&_tlsend;
     auto pend = cast(void*)&__bss_end__;
+    // _tlsend is a 32-bit int and may not be 64-bit void*-aligned, so align pbeg.
+    version (D_LP64) pbeg = cast(void*)(cast(size_t)(pbeg + 7) & ~cast(size_t)7);
     _sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
 }
 
@@ -105,32 +119,14 @@  void scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) noth
  *       the corresponding address in the TLS dynamic per-thread data.
  */
 
-version (X86)
+extern(C) void* __tls_get_addr( void* p ) nothrow @nogc
 {
-    // NB: the compiler mangles this function as '___tls_get_addr'
-    // even though it is extern(D)
-    extern(D) void* ___tls_get_addr( void* p ) nothrow @nogc
-    {
-        debug(PRINTF) printf("  ___tls_get_addr input - %p\n", p);
-        immutable offset = cast(size_t)(p - cast(void*)&_tlsstart);
-        auto tls = getTLSBlockAlloc();
-        assert(offset < tls.length);
-        return tls.ptr + offset;
-    }
-}
-else version (ARM)
-{
-    extern(C) void* __tls_get_addr( void** p ) nothrow @nogc
-    {
-        debug(PRINTF) printf("  __tls_get_addr input - %p\n", *p);
-        immutable offset = cast(size_t)(*p - cast(void*)&_tlsstart);
-        auto tls = getTLSBlockAlloc();
-        assert(offset < tls.length);
-        return tls.ptr + offset;
-    }
+    debug(PRINTF) printf("  __tls_get_addr input - %p\n", p);
+    immutable offset = cast(size_t)(p - cast(void*)&_tlsstart);
+    auto tls = getTLSBlockAlloc();
+    assert(offset < tls.length);
+    return tls.ptr + offset;
 }
-else
-    static assert( false, "Android architecture not supported." );
 
 private:
 
@@ -182,7 +178,7 @@  extern(C)
 
         size_t __bss_end__;
 
-        void* _tlsstart;
-        void* _tlsend;
+        int _tlsstart;
+        int _tlsend;
     }
 }
diff --git a/libphobos/libdruntime/rt/sections_elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d
similarity index 76%
rename from libphobos/libdruntime/rt/sections_elf_shared.d
rename to libphobos/libdruntime/gcc/sections/elf_shared.d
index d4e1ff07699..f70c2329ade 100644
--- a/libphobos/libdruntime/rt/sections_elf_shared.d
+++ b/libphobos/libdruntime/gcc/sections/elf_shared.d
@@ -1,18 +1,33 @@ 
-/**
- * Written in the D programming language.
- * This module provides ELF-specific support for sections with shared libraries.
- *
- * 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_linux.d)
- */
+// ELF-specific support for sections with shared libraries.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
 
-module rt.sections_elf_shared;
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.elf_shared;
 
 version (CRuntime_Glibc) enum SharedELF = true;
+else version (CRuntime_Musl) enum SharedELF = true;
 else version (FreeBSD) enum SharedELF = true;
 else version (NetBSD) enum SharedELF = true;
+else version (DragonFlyBSD) enum SharedELF = true;
+else version (CRuntime_UClibc) enum SharedELF = true;
 else enum SharedELF = false;
 static if (SharedELF):
 
@@ -40,6 +55,12 @@  else version (NetBSD)
     import core.sys.netbsd.sys.elf;
     import core.sys.netbsd.sys.link_elf;
 }
+else version (DragonFlyBSD)
+{
+    import core.sys.dragonflybsd.dlfcn;
+    import core.sys.dragonflybsd.sys.elf;
+    import core.sys.dragonflybsd.sys.link_elf;
+}
 else
 {
     static assert(0, "unimplemented");
@@ -51,6 +72,18 @@  import rt.minfo;
 import rt.util.container.array;
 import rt.util.container.hashtab;
 
+/****
+ * Asserts the specified condition, independent from -release, by abort()ing.
+ * Regular assertions throw an AssertError and thus require an initialized
+ * GC, which isn't the case (yet or anymore) for the startup/shutdown code in
+ * this module (called by CRT ctors/dtors etc.).
+ */
+private void safeAssert(bool condition, scope string msg, size_t line = __LINE__) @nogc nothrow @safe
+{
+    import core.internal.abort;
+    condition || abort(msg, __FILE__, line);
+}
+
 alias DSO SectionGroup;
 struct DSO
 {
@@ -98,8 +131,8 @@  private:
 
     invariant()
     {
-        assert(_moduleGroup.modules.length);
-        assert(_tlsMod || !_tlsSize);
+        safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+        safeAssert(_tlsMod || !_tlsSize, "Inconsistent TLS fields for DSO.");
     }
 
     ModuleGroup _moduleGroup;
@@ -113,6 +146,12 @@  private:
         Array!(DSO*) _deps; // D libraries needed by this DSO
         void* _handle; // corresponding handle
     }
+
+    // get the TLS range for the executing thread
+    void[] tlsRange() const nothrow @nogc
+    {
+        return getTLSRange(_tlsMod, _tlsSize);
+    }
 }
 
 /****
@@ -122,6 +161,7 @@  __gshared bool _isRuntimeInitialized;
 
 
 version (FreeBSD) private __gshared void* dummy_ref;
+version (DragonFlyBSD) private __gshared void* dummy_ref;
 version (NetBSD) private __gshared void* dummy_ref;
 
 /****
@@ -132,6 +172,7 @@  void initSections() nothrow @nogc
     _isRuntimeInitialized = true;
     // reference symbol to support weak linkage
     version (FreeBSD) dummy_ref = &_d_dso_registry;
+    version (DragonFlyBSD) dummy_ref = &_d_dso_registry;
     version (NetBSD) dummy_ref = &_d_dso_registry;
 }
 
@@ -153,7 +194,7 @@  version (Shared)
      */
     Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
     {
-        return &_loadedDSOs;
+        return &_loadedDSOs();
     }
 
     void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
@@ -181,7 +222,8 @@  version (Shared)
             if (tdso._addCnt)
             {
                 // Increment the dlopen ref for explicitly loaded libraries to pin them.
-                .dlopen(linkMapForHandle(tdso._pdso._handle).l_name, RTLD_LAZY) !is null || assert(0);
+                const success = .dlopen(linkMapForHandle(tdso._pdso._handle).l_name, RTLD_LAZY) !is null;
+                safeAssert(success, "Failed to increment dlopen ref.");
                 (*res)[i]._addCnt = 1; // new array takes over the additional ref count
             }
         }
@@ -197,7 +239,7 @@  version (Shared)
             if (tdso._addCnt)
             {
                 auto handle = tdso._pdso._handle;
-                handle !is null || assert(0);
+                safeAssert(handle !is null, "Invalid library handle.");
                 .dlclose(handle);
             }
         }
@@ -209,7 +251,7 @@  version (Shared)
     // of the parent thread.
     void inheritLoadedLibraries(void* p) nothrow @nogc
     {
-        assert(_loadedDSOs.empty);
+        safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
         _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
         .free(p);
         foreach (ref dso; _loadedDSOs)
@@ -227,7 +269,7 @@  version (Shared)
             if (tdso._addCnt == 0) continue;
 
             auto handle = tdso._pdso._handle;
-            handle !is null || assert(0);
+            safeAssert(handle !is null, "Invalid DSO handle.");
             for (; tdso._addCnt > 0; --tdso._addCnt)
                 .dlclose(handle);
         }
@@ -243,7 +285,7 @@  else
      */
     Array!(void[])* initTLSRanges() nothrow @nogc
     {
-        return &_tlsRanges;
+        return &_tlsRanges();
     }
 
     void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
@@ -260,10 +302,6 @@  else
 
 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 (Shared)
 {
     /*
@@ -290,10 +328,10 @@  version (Shared)
         // update the _tlsRange for the executing thread
         void updateTLSRange() nothrow @nogc
         {
-            _tlsRange = getTLSRange(_pdso._tlsMod, _pdso._tlsSize);
+            _tlsRange = _pdso.tlsRange();
         }
     }
-    Array!(ThreadDSO) _loadedDSOs;
+    @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow { static Array!(ThreadDSO) x; return x; }
 
     /*
      * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
@@ -305,7 +343,7 @@  version (Shared)
      * The hash table is protected by a Mutex.
      */
     __gshared pthread_mutex_t _handleToDSOMutex;
-    __gshared HashTab!(void*, DSO*) _handleToDSO;
+    @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow { __gshared HashTab!(void*, DSO*) x; return x; }
 
     /*
      * Section in executable that contains copy relocations.
@@ -319,13 +357,13 @@  else
      * Static DSOs loaded by the runtime linker. This includes the
      * executable. These can't be unloaded.
      */
-    __gshared Array!(DSO*) _loadedDSOs;
+    @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow { __gshared Array!(DSO*) x; return x; }
 
     /*
      * Thread local array that contains TLS memory ranges for each
      * library initialized in this thread.
      */
-    Array!(void[]) _tlsRanges;
+    @property ref Array!(void[]) _tlsRanges() @nogc nothrow { static Array!(void[]) x; return x; }
 
     enum _rtLoading = false;
 }
@@ -334,8 +372,6 @@  else
 // Compiler to runtime interface.
 ///////////////////////////////////////////////////////////////////////////////
 
-import gcc.config;
-
 /*
  * This data structure is generated by the compiler, and then passed to
  * _d_dso_registry().
@@ -357,7 +393,7 @@  T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
 extern(C) void _d_dso_registry(CompilerDSOData* data)
 {
     // only one supported currently
-    data._version >= 1 || assert(0, "corrupt DSO data version");
+    safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
 
     // no backlink => register
     if (*data._slot is null)
@@ -372,7 +408,8 @@  extern(C) void _d_dso_registry(CompilerDSOData* data)
         pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
 
         dl_phdr_info info = void;
-        findDSOInfoForAddr(data._slot, &info) || assert(0);
+        const headerFound = findDSOInfoForAddr(data._slot, &info);
+        safeAssert(headerFound, "Failed to find image header.");
 
         scanSegments(info, pdso);
 
@@ -380,15 +417,6 @@  extern(C) void _d_dso_registry(CompilerDSOData* data)
         {
             auto handle = handleForAddr(data._slot);
 
-            if (firstDSO)
-            {
-                /// Assert that the first loaded DSO is druntime itself. Use a
-                /// local druntime symbol (rt_get_bss_start) to get the handle.
-                assert(handleForAddr(data._slot) == handleForAddr(&rt_get_bss_start));
-                _copyRelocSection = getCopyRelocSection();
-            }
-            checkModuleCollisions(info, pdso._moduleGroup.modules, _copyRelocSection);
-
             getDependencies(info, pdso._deps);
             pdso._handle = handle;
             setDSOForHandle(pdso, pdso._handle);
@@ -402,15 +430,15 @@  extern(C) void _d_dso_registry(CompilerDSOData* data)
                  * thread with a refCnt of 1 and call the TlsCtors.
                  */
                 immutable ushort refCnt = 1, addCnt = 0;
-                auto tlsRng = getTLSRange(pdso._tlsMod, pdso._tlsSize);
-                _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, tlsRng));
+                _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, pdso.tlsRange()));
             }
         }
         else
         {
-            foreach (p; _loadedDSOs) assert(p !is pdso);
+            foreach (p; _loadedDSOs)
+                safeAssert(p !is pdso, "DSO already registered.");
             _loadedDSOs.insertBack(pdso);
-            _tlsRanges.insertBack(getTLSRange(pdso._tlsMod, pdso._tlsSize));
+            _tlsRanges.insertBack(pdso.tlsRange());
         }
 
         // don't initialize modules before rt_init was called (see Bugzilla 11378)
@@ -457,25 +485,31 @@  extern(C) void _d_dso_registry(CompilerDSOData* data)
             }
 
             unsetDSOForHandle(pdso, pdso._handle);
-            pdso._handle = null;
         }
         else
         {
             // static DSOs are unloaded in reverse order
-            assert(pdso._tlsSize == _tlsRanges.back.length);
-            _tlsRanges.popBack();
-            assert(pdso == _loadedDSOs.back);
+            safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
             _loadedDSOs.popBack();
         }
 
         freeDSO(pdso);
 
-        if (_loadedDSOs.empty) finiLocks(); // last DSO
+        // last DSO being unloaded => shutdown registry
+        if (_loadedDSOs.empty)
+        {
+            version (Shared)
+            {
+                safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+                _handleToDSO.reset();
+            }
+            finiLocks();
+        }
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// dynamic loading
+// Dynamic loading
 ///////////////////////////////////////////////////////////////////////////////
 
 // Shared D libraries are only supported when linking against a shared druntime library.
@@ -501,8 +535,7 @@  version (Shared)
             foreach (dep; pdso._deps)
                 incThreadRef(dep, false);
             immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
-            auto tlsRng = getTLSRange(pdso._tlsMod, pdso._tlsSize);
-            _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, tlsRng));
+            _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt, pdso.tlsRange()));
             pdso._moduleGroup.runTlsCtors();
         }
     }
@@ -510,8 +543,8 @@  version (Shared)
     void decThreadRef(DSO* pdso, bool decAdd)
     {
         auto tdata = findThreadDSO(pdso);
-        tdata !is null || assert(0);
-        !decAdd || tdata._addCnt > 0 || assert(0, "Mismatching rt_unloadLibrary call.");
+        safeAssert(tdata !is null, "Failed to find thread DSO.");
+        safeAssert(!decAdd || tdata._addCnt > 0, "Mismatching rt_unloadLibrary call.");
 
         if (decAdd && --tdata._addCnt > 0) return;
         if (--tdata._refCnt > 0) return;
@@ -554,7 +587,7 @@  version (Shared)
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// helper functions
+// Helper functions
 ///////////////////////////////////////////////////////////////////////////////
 
 void initLocks() nothrow @nogc
@@ -603,29 +636,35 @@  version (Shared) void runFinalizers(DSO* pdso)
 void freeDSO(DSO* pdso) nothrow @nogc
 {
     pdso._gcRanges.reset();
-    version (Shared) pdso._codeSegments.reset();
+    version (Shared)
+    {
+        pdso._codeSegments.reset();
+        pdso._deps.reset();
+        pdso._handle = null;
+    }
     .free(pdso);
 }
 
 version (Shared)
 {
 @nogc nothrow:
-    link_map* linkMapForHandle(void* handle) nothrow @nogc
+    link_map* linkMapForHandle(void* handle)
     {
         link_map* map;
-        dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0 || assert(0);
+        const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0;
+        safeAssert(success, "Failed to get DSO info.");
         return map;
     }
 
-     link_map* exeLinkMap(link_map* map) nothrow @nogc
+     link_map* exeLinkMap(link_map* map)
      {
-         assert(map);
+         safeAssert(map !is null, "Invalid link_map.");
          while (map.l_prev !is null)
              map = map.l_prev;
          return map;
      }
 
-    DSO* dsoForHandle(void* handle) nothrow @nogc
+    DSO* dsoForHandle(void* handle)
     {
         DSO* pdso;
         !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);
@@ -635,23 +674,23 @@  version (Shared)
         return pdso;
     }
 
-    void setDSOForHandle(DSO* pdso, void* handle) nothrow @nogc
+    void setDSOForHandle(DSO* pdso, void* handle)
     {
         !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);
-        assert(handle !in _handleToDSO);
+        safeAssert(handle !in _handleToDSO, "DSO already registered.");
         _handleToDSO[handle] = pdso;
         !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);
     }
 
-    void unsetDSOForHandle(DSO* pdso, void* handle) nothrow @nogc
+    void unsetDSOForHandle(DSO* pdso, void* handle)
     {
         !pthread_mutex_lock(&_handleToDSOMutex) || assert(0);
-        assert(_handleToDSO[handle] == pdso);
+        safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
         _handleToDSO.remove(handle);
         !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0);
     }
 
-    void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps) nothrow @nogc
+    void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps)
     {
         // get the entries of the .dynamic section
         ElfW!"Dyn"[] dyns;
@@ -670,12 +709,16 @@  version (Shared)
         {
             if (dyn.d_tag == DT_STRTAB)
             {
-                version (linux)
+                version (CRuntime_Musl)
+                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
+                else version (linux)
                     strtab = cast(const(char)*)dyn.d_un.d_ptr;
                 else version (FreeBSD)
                     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 (DragonFlyBSD)
+                    strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
                 else
                     static assert(0, "unimplemented");
                 break;
@@ -692,14 +735,14 @@  version (Shared)
             // get handle without loading the library
             auto handle = handleForName(name);
             // the runtime linker has already loaded all dependencies
-            if (handle is null) assert(0);
+            safeAssert(handle !is null, "Failed to get library handle.");
             // if it's a D library
             if (auto pdso = dsoForHandle(handle))
                 deps.insertBack(pdso); // append it to the dependencies
         }
     }
 
-    void* handleForName(const char* name) nothrow @nogc
+    void* handleForName(const char* name)
     {
         auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY);
         if (handle !is null) .dlclose(handle); // drop reference count
@@ -735,7 +778,7 @@  void scanSegments(in ref dl_phdr_info info, DSO* pdso) nothrow @nogc
             break;
 
         case PT_TLS: // TLS segment
-            assert(!pdso._tlsSize); // is unique per DSO
+            safeAssert(!pdso._tlsSize, "Multiple TLS segments in image header.");
             pdso._tlsMod = info.dlpi_tls_modid;
             pdso._tlsSize = phdr.p_memsz;
             break;
@@ -748,55 +791,51 @@  void scanSegments(in ref dl_phdr_info info, DSO* pdso) nothrow @nogc
 
 /**************************
  * Input:
- *      result  where the output is to be written; dl_phdr_info is a Linux struct
+ *      result  where the output is to be written; dl_phdr_info is an OS struct
  * Returns:
  *      true if found, and *result is filled in
  * References:
  *      http://linux.die.net/man/3/dl_iterate_phdr
  */
-version (linux) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc
+bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc
 {
-    static struct DG { const(void)* addr; dl_phdr_info* result; }
+    version (linux)       enum IterateManually = true;
+    else version (NetBSD) enum IterateManually = true;
+    else                  enum IterateManually = false;
 
-    extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc
+    static if (IterateManually)
     {
-        auto p = cast(DG*)arg;
-        if (findSegmentForAddr(*info, p.addr))
+        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
         {
-            if (p.result !is null) *p.result = *info;
-            return 1; // break;
+            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
         }
-        return 0; // continue iteration
-    }
 
-    auto dg = DG(addr, result);
+        auto dg = DG(addr, result);
 
-    /* Linux function that walks through the list of an application's shared objects and
-     * calls 'callback' once for each object, until either all shared objects
-     * have been processed or 'callback' returns a nonzero value.
-     */
-    return dl_iterate_phdr(&callback, &dg) != 0;
-}
-else version (FreeBSD) bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc
-{
-    return !!_rtld_addr_phdr(addr, result);
-}
-else version (NetBSD) 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
+        /* OS function that walks through the list of an application's shared objects and
+         * calls 'callback' once for each object, until either all shared objects
+         * have been processed or 'callback' returns a nonzero value.
+         */
+        return dl_iterate_phdr(&callback, &dg) != 0;
+    }
+    else version (FreeBSD)
     {
-        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
+        return !!_rtld_addr_phdr(addr, result);
+    }
+    else version (DragonFlyBSD)
+    {
+        return !!_rtld_addr_phdr(addr, result);
     }
-    auto dg = DG(addr, result);
-    return dl_iterate_phdr(&callback, &dg) != 0;
+    else
+        static assert(0, "unimplemented");
 }
 
 /*********************************
@@ -823,12 +862,14 @@  bool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!"Phdr"* re
 version (linux) import core.sys.linux.errno : program_invocation_name;
 // should be in core.sys.freebsd.stdlib
 version (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc;
+version (DragonFlyBSD) extern(C) const(char)* getprogname() nothrow @nogc;
 version (NetBSD) extern(C) const(char)* getprogname() nothrow @nogc;
 
 @property const(char)* progname() nothrow @nogc
 {
     version (linux) return program_invocation_name;
     version (FreeBSD) return getprogname();
+    version (DragonFlyBSD) return getprogname();
     version (NetBSD) return getprogname();
 }
 
@@ -839,95 +880,6 @@  const(char)[] dsoName(const char* dlpi_name) nothrow @nogc
     return p[0 .. strlen(p)];
 }
 
-extern(C)
-{
-    void* rt_get_bss_start() @nogc nothrow;
-    void* rt_get_end() @nogc nothrow;
-}
-
-/// get the BSS section of the executable to check for copy relocations
-const(void)[] getCopyRelocSection() nothrow @nogc
-{
-    auto bss_start = rt_get_bss_start();
-    auto bss_end = rt_get_end();
-    immutable bss_size = bss_end - bss_start;
-
-    /**
-       Check whether __bss_start/_end both lie within the executable DSO.same DSO.
-
-       When a C host program dynamically loads druntime, i.e. it isn't linked
-       against, __bss_start/_end might be defined in different DSOs, b/c the
-       linker creates those symbols only when they are used.
-       But as there are no copy relocations when dynamically loading a shared
-       library, we can simply return a null bss range in that case.
-    */
-    if (bss_size <= 0)
-        return null;
-
-    version (linux)
-        enum ElfW!"Addr" exeBaseAddr = 0;
-    else version (FreeBSD)
-        enum ElfW!"Addr" exeBaseAddr = 0;
-    else version (NetBSD)
-        enum ElfW!"Addr" exeBaseAddr = 0;
-
-    dl_phdr_info info = void;
-    findDSOInfoForAddr(bss_start, &info) || assert(0);
-    if (info.dlpi_addr != exeBaseAddr)
-        return null;
-    findDSOInfoForAddr(bss_end - 1, &info) || assert(0);
-    if (info.dlpi_addr != exeBaseAddr)
-        return null;
-
-    return bss_start[0 .. bss_size];
-}
-
-/**
- * Check for module collisions. A module in a shared library collides
- * with an existing module if it's ModuleInfo is interposed (search
- * symbol interposition) by another DSO.  Therefor two modules with the
- * same name do not collide if their DSOs are in separate symbol resolution
- * chains.
- */
-void checkModuleCollisions(in ref dl_phdr_info info, in immutable(ModuleInfo)*[] modules,
-                           in void[] copyRelocSection) nothrow @nogc
-in { assert(modules.length); }
-body
-{
-    immutable(ModuleInfo)* conflicting;
-
-    foreach (m; modules)
-    {
-        auto addr = cast(const(void*))m;
-        if (cast(size_t)(addr - copyRelocSection.ptr) < copyRelocSection.length)
-        {
-            // Module is in .bss of the exe because it was copy relocated
-        }
-        else if (!findSegmentForAddr(info, addr))
-        {
-            // Module is in another DSO
-            conflicting = m;
-            break;
-        }
-    }
-
-    if (conflicting !is null)
-    {
-        dl_phdr_info other=void;
-        findDSOInfoForAddr(conflicting, &other) || assert(0);
-
-        auto modname = conflicting.name;
-        auto loading = dsoName(info.dlpi_name);
-        auto existing = dsoName(other.dlpi_name);
-        fprintf(stderr, "Fatal Error while loading '%.*s':\n\tThe module '%.*s' is already defined in '%.*s'.\n",
-                cast(int)loading.length, loading.ptr,
-                cast(int)modname.length, modname.ptr,
-                cast(int)existing.length, existing.ptr);
-        import core.stdc.stdlib : _Exit;
-        _Exit(1);
-    }
-}
-
 /**************************
  * Input:
  *      addr  an internal address of a DSO
diff --git a/libphobos/libdruntime/rt/sections_osx.d b/libphobos/libdruntime/gcc/sections/osx.d
similarity index 82%
rename from libphobos/libdruntime/rt/sections_osx.d
rename to libphobos/libdruntime/gcc/sections/osx.d
index 4bea1408ce2..55caee48a59 100644
--- a/libphobos/libdruntime/rt/sections_osx.d
+++ b/libphobos/libdruntime/gcc/sections/osx.d
@@ -1,16 +1,26 @@ 
-/**
- * Written in the D programming language.
- * This module provides OSX-specific support for sections.
- *
- * Copyright: Copyright Digital Mars 2008 - 2012.
- * License: Distributed under the
- *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
- *    (See accompanying file LICENSE)
- * Authors:   Walter Bright, Sean Kelly, Martin Nowak
- * Source: $(DRUNTIMESRC src/rt/_sections_osx.d)
- */
+// OSX-specific support for sections.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
 
-module rt.sections_osx;
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.osx;
 
 version (OSX):
 
@@ -35,22 +45,22 @@  struct SectionGroup
         return dg(_sections);
     }
 
-    @property immutable(ModuleInfo*)[] modules() const
+    @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
     {
         return _moduleGroup.modules;
     }
 
-    @property ref inout(ModuleGroup) moduleGroup() inout
+    @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
     {
         return _moduleGroup;
     }
 
-    @property inout(void[])[] gcRanges() inout
+    @property inout(void[])[] gcRanges() inout nothrow @nogc
     {
         return _gcRanges[];
     }
 
-    @property immutable(FuncTable)[] ehTables() const
+    @property immutable(FuncTable)[] ehTables() const nothrow @nogc
     {
         return _ehTables[];
     }
@@ -70,7 +80,7 @@  __gshared bool _isRuntimeInitialized;
 /****
  * Gets called on program startup just before GC is initialized.
  */
-void initSections()
+void initSections() nothrow @nogc
 {
     pthread_key_create(&_tlsKey, null);
     _dyld_register_func_for_add_image(&sections_osx_onAddImage);
@@ -80,19 +90,19 @@  void initSections()
 /***
  * Gets called on program shutdown just after GC is terminated.
  */
-void finiSections()
+void finiSections() nothrow @nogc
 {
     _sections._gcRanges.reset();
     pthread_key_delete(_tlsKey);
     _isRuntimeInitialized = false;
 }
 
-void[]* initTLSRanges()
+void[]* initTLSRanges() nothrow @nogc
 {
     return &getTLSBlock();
 }
 
-void finiTLSRanges(void[]* rng)
+void finiTLSRanges(void[]* rng) nothrow @nogc
 {
     .free(rng.ptr);
     .free(rng);
@@ -148,7 +158,7 @@  body
     assert(0);
 }
 
-ref void[] getTLSBlock()
+ref void[] getTLSBlock() nothrow @nogc
 {
     auto pary = cast(void[]*)pthread_getspecific(_tlsKey);
     if (pary is null)
@@ -180,7 +190,6 @@  ref void[] getTLSBlockAlloc()
     return *pary;
 }
 
-
 __gshared SectionGroup _sections;
 
 extern (C) void sections_osx_onAddImage(in mach_header* h, intptr_t slide)
@@ -245,12 +254,10 @@  struct SegRef
     string sect;
 }
 
-
 static immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA},
                                       {SEG_DATA, SECT_BSS},
                                       {SEG_DATA, SECT_COMMON}];
 
-
 ubyte[] getSection(in mach_header* header, intptr_t slide,
                    in char* segmentName, in char* sectionName)
 {
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
new file mode 100644
index 00000000000..07617ea977f
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -0,0 +1,48 @@ 
+// Run-time support for retrieving platform-specific sections.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections;
+
+version (CRuntime_Glibc)
+    public import gcc.sections.elf_shared;
+else version (CRuntime_Musl)
+    public import gcc.sections.elf_shared;
+else version (CRuntime_UClibc)
+    public import gcc.sections.elf_shared;
+else version (FreeBSD)
+    public import gcc.sections.elf_shared;
+else version (NetBSD)
+    public import gcc.sections.elf_shared;
+else version (DragonFlyBSD)
+    public import gcc.sections.elf_shared;
+else version (Solaris)
+    public import gcc.sections.solaris;
+else version (OSX)
+    public import gcc.sections.osx;
+else version (CRuntime_DigitalMars)
+    public import gcc.sections.win32;
+else version (CRuntime_Microsoft)
+    public import gcc.sections.win64;
+else version (CRuntime_Bionic)
+    public import gcc.sections.android;
+else
+    static assert(0, "unimplemented");
diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/gcc/sections/solaris.d
similarity index 68%
rename from libphobos/libdruntime/rt/sections_solaris.d
rename to libphobos/libdruntime/gcc/sections/solaris.d
index 75a43943f45..e66325b7a2c 100644
--- a/libphobos/libdruntime/rt/sections_solaris.d
+++ b/libphobos/libdruntime/gcc/sections/solaris.d
@@ -1,14 +1,26 @@ 
-/**
- * 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;
+// Solaris-specific support for sections.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.solaris;
 
 version (Solaris):
 
diff --git a/libphobos/libdruntime/rt/sections_win32.d b/libphobos/libdruntime/gcc/sections/win32.d
similarity index 78%
rename from libphobos/libdruntime/rt/sections_win32.d
rename to libphobos/libdruntime/gcc/sections/win32.d
index 14d91ba9c2d..4b76ca89995 100644
--- a/libphobos/libdruntime/rt/sections_win32.d
+++ b/libphobos/libdruntime/gcc/sections/win32.d
@@ -1,16 +1,26 @@ 
-/**
- * Written in the D programming language.
- * This module provides Win32-specific support for sections.
- *
- * Copyright: Copyright Digital Mars 2008 - 2012.
- * License: Distributed under the
- *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
- *    (See accompanying file LICENSE)
- * Authors:   Walter Bright, Sean Kelly, Martin Nowak
- * Source: $(DRUNTIMESRC src/rt/_sections_win32.d)
- */
-
-module rt.sections_win32;
+// Win32-specific support for sections.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.win32;
 
 version (CRuntime_DigitalMars):
 
diff --git a/libphobos/libdruntime/rt/sections_win64.d b/libphobos/libdruntime/gcc/sections/win64.d
similarity index 88%
rename from libphobos/libdruntime/rt/sections_win64.d
rename to libphobos/libdruntime/gcc/sections/win64.d
index 346be3b79a8..b98c3527e70 100644
--- a/libphobos/libdruntime/rt/sections_win64.d
+++ b/libphobos/libdruntime/gcc/sections/win64.d
@@ -1,16 +1,26 @@ 
-/**
- * Written in the D programming language.
- * This module provides Win32-specific support for sections.
- *
- * Copyright: Copyright Digital Mars 2008 - 2012.
- * License: Distributed under the
- *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
- *    (See accompanying file LICENSE)
- * Authors:   Walter Bright, Sean Kelly, Martin Nowak
- * Source: $(DRUNTIMESRC src/rt/_sections_win64.d)
- */
-
-module rt.sections_win64;
+// Win64-specific support for sections.
+// Copyright (C) 2019 Free Software Foundation, Inc.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+module gcc.sections.win64;
 
 version (CRuntime_Microsoft):
 
@@ -271,7 +281,7 @@  struct IMAGE_NT_HEADERS
 
 struct IMAGE_SECTION_HEADER
 {
-    char[8] Name;
+    char[8] Name = 0;
     union {
         uint   PhysicalAddress;
         uint   VirtualSize;
diff --git a/libphobos/libdruntime/rt/bss_section.c b/libphobos/libdruntime/rt/bss_section.c
deleted file mode 100644
index b00f40d51c0..00000000000
--- a/libphobos/libdruntime/rt/bss_section.c
+++ /dev/null
@@ -1,21 +0,0 @@ 
-/**
- * This module is used to detect copy relocated ModuleInfos (located in .bss section).
- *
- * Copyright: Copyright Martin Nowak 2014-.
- * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors:   Martin Nowak
- * Source: $(DRUNTIMESRC src/rt/_bss_section.c)
- */
-
-/* These symbols are defined in the linker script and bracket the
- * .bss, .lbss, .lrodata and .ldata sections.
- */
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
-// Need to use weak linkage to workaround a bug in ld.bfd (Bugzilla 13025).
-extern int __attribute__((weak)) __bss_start, _end;
-
-__attribute__ ((visibility ("hidden"))) void* rt_get_bss_start();
-__attribute__ ((visibility ("hidden"))) void* rt_get_end();
-void* rt_get_bss_start() { return (void*)&__bss_start; }
-void* rt_get_end() { return (void*)&_end; }
-#endif
diff --git a/libphobos/libdruntime/rt/sections.d b/libphobos/libdruntime/rt/sections.d
index 53357f68190..6009a79abc5 100644
--- a/libphobos/libdruntime/rt/sections.d
+++ b/libphobos/libdruntime/rt/sections.d
@@ -8,6 +8,9 @@ 
  * Source: $(DRUNTIMESRC src/rt/_sections.d)
  */
 
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
 module rt.sections;
 
 version (OSX)
@@ -19,7 +22,9 @@  else version (TVOS)
 else version (WatchOS)
     version = Darwin;
 
-version (CRuntime_Glibc)
+version (GNU)
+    public import gcc.sections;
+else version (CRuntime_Glibc)
     public import rt.sections_elf_shared;
 else version (FreeBSD)
     public import rt.sections_elf_shared;