public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ibuclaw/heads/mingw)] More MSVC support
@ 2021-03-24 15:25 Iain Buclaw
0 siblings, 0 replies; 5+ messages in thread
From: Iain Buclaw @ 2021-03-24 15:25 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:ab68c3421560f9546c77a7a7f1693a55259715b1
commit ab68c3421560f9546c77a7a7f1693a55259715b1
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Wed Mar 24 16:24:04 2021 +0100
More MSVC support
Diff:
---
gcc/config/i386/cygming.h | 2 +
gcc/config/i386/i386-d.c | 11 +
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/i386/winnt-d.c | 5 +
gcc/d/d-target-def.h | 1 +
gcc/d/d-target.cc | 10 +-
gcc/d/d-target.def | 7 +
gcc/d/d-target.h | 3 +
gcc/doc/tm.texi | 2 +
gcc/doc/tm.texi.in | 2 +
libphobos/Makefile.in | 3 +
libphobos/configure | 24 +-
libphobos/configure.ac | 17 +-
libphobos/libdruntime/Makefile.am | 7 +-
libphobos/libdruntime/Makefile.in | 68 +-
libphobos/libdruntime/config/mingw/msvc.c | 54 ++
libphobos/libdruntime/config/mingw/switchcontext.S | 12 +-
libphobos/libdruntime/core/stdc/stdlib.d | 27 +-
libphobos/libdruntime/core/stdc/tgmath.d | 11 +-
libphobos/libdruntime/core/sys/windows/com.d | 4 +-
libphobos/libdruntime/core/sys/windows/dbghelp.d | 2 +-
libphobos/libdruntime/core/sys/windows/dll.d | 12 +-
libphobos/libdruntime/core/thread/osthread.d | 4 +-
libphobos/libdruntime/gcc/deh.d | 2 +-
libphobos/libdruntime/gcc/gthread.d | 6 +-
libphobos/libdruntime/gcc/sections/package.d | 28 +-
libphobos/libdruntime/gcc/sections/pecoff.d | 830 +++++++++++++++++++++
libphobos/libdruntime/gcc/sections/win32.d | 183 -----
libphobos/libdruntime/gcc/sections/win64.d | 8 -
libphobos/libdruntime/gcc/unwind/generic.d | 2 +-
libphobos/libdruntime/rt/dmain2.d | 64 --
libphobos/src/Makefile.am | 2 +-
libphobos/src/Makefile.in | 5 +-
libphobos/testsuite/Makefile.in | 3 +
35 files changed, 1066 insertions(+), 359 deletions(-)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index cfbca34f996..59eb812c1cf 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -209,6 +209,8 @@ along with GCC; see the file COPYING3. If not see
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
flag_pic = TARGET_64BIT ? 1 : 0; \
+ if (!global_options_set.x_dwarf_version) \
+ dwarf_version = 4; \
} while (0)
/* Define this macro if references to a symbol must be treated
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..05c0f21066d 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,14 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Implement TARGET_D_EXTERN_SYSTEM_LINKAGE for x86 targets. */
+
+int
+ix86_d_extern_system_linkage (void)
+{
+ if (ix86_abi == MS_ABI)
+ return LINKwindows;
+
+ return LINKc;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..d07bf09bc65 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern int ix86_d_extern_system_linkage (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 058c1cc25b2..10954fb0aab 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_EXTERN_SYSTEM_LINKAGE ix86_d_extern_system_linkage
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index 3b5791a7bff..5d20fbf51dc 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -30,6 +30,11 @@ winnt_d_os_builtins (void)
{
d_add_builtin_version ("Windows");
+ if (ix86_abi == SYSV_ABI)
+ d_add_builtin_version ("SYSV_ABI");
+ else
+ d_add_builtin_version ("MS_ABI");
+
#define builtin_version(TXT) d_add_builtin_version (TXT)
#ifdef EXTRA_TARGET_D_OS_VERSIONS
diff --git a/gcc/d/d-target-def.h b/gcc/d/d-target-def.h
index eb3236f174d..63389a5d82a 100644
--- a/gcc/d/d-target-def.h
+++ b/gcc/d/d-target-def.h
@@ -17,4 +17,5 @@
#include "d/d-target-hooks-def.h"
#include "tree.h"
+#include "d-target.h"
#include "hooks.h"
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..a33e04197b8 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -417,10 +417,18 @@ TargetCPP::fundamentalType (const Type *, bool &)
return false;
}
-/* Return the default system linkage for the target. */
+/* Return the default `extern (System)` linkage for the target. */
LINK
Target::systemLinkage (void)
+{
+ return (LINK) targetdm.d_extern_system_linkage ();
+}
+
+/* */
+
+int
+d_default_system_linkage (void)
{
return LINKc;
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..5a419731faa 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,13 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* */
+DEFHOOK
+(d_extern_system_linkage,
+ "",
+ int, (void),
+ d_default_system_linkage)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/d-target.h b/gcc/d/d-target.h
index 56595d225bf..2020b3c2e76 100644
--- a/gcc/d/d-target.h
+++ b/gcc/d/d-target.h
@@ -46,4 +46,7 @@ struct d_target_info_spec
/* Used by target to add getTargetInfo handlers. */
extern void d_add_target_info_handlers (const d_target_info_spec *);
+/* If the target does not provide its own override. */
+extern LINK d_default_system_linkage (void);
+
#endif /* GCC_D_TARGET_H */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..84de504775d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,8 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} int TARGET_D_EXTERN_SYSTEM_LINKAGE (void)
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..ef15417a791 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,8 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_EXTERN_SYSTEM_LINKAGE
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index d42248405a2..eab12688867 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -298,6 +298,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -327,6 +329,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..59ca64aa1e0 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -705,6 +705,9 @@ libphobos_builddir
get_gcc_base_ver
phobos_compiler_shared_flag
phobos_compiler_pic_flag
+phobos_lt_pic_flag
+enable_static
+enable_shared
OTOOL64
OTOOL
LIPO
@@ -11746,7 +11749,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11749 "configure"
+#line 11752 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11852,7 +11855,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11855 "configure"
+#line 11858 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13997,8 +14000,14 @@ CFLAGS=$lt_save_CFLAGS
GDCFLAGS=$gdc_save_DFLAGS
+
+
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -14010,26 +14019,23 @@ CFLAGS=$lt_save_CFLAGS
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index cc9af29754f..248d0ebbc19 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -91,9 +91,15 @@ AC_SUBST(CFLAGS_FOR_BUILD)
LT_INIT(dlopen)
AM_PROG_LIBTOOL
WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -105,26 +111,23 @@ WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+AC_SUBST(phobos_lt_pic_flag)
AC_SUBST(phobos_compiler_pic_flag)
AC_SUBST(phobos_compiler_shared_flag)
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 945271e028f..bedd7a325ec 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -23,7 +23,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
@@ -69,7 +69,8 @@ if DRUNTIME_OS_LINUX
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
endif
if DRUNTIME_OS_MINGW
- DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
+ DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS) \
+ config/mingw/msvc.c
endif
if DRUNTIME_OS_SOLARIS
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
@@ -187,7 +188,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/backtrace.d \
gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 06c02961c86..665af30e09d 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -117,7 +117,9 @@ target_triplet = @target@
@DRUNTIME_OS_NETBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_NETBSD)
@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)
@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)
-@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)
+@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/msvc.c
+
@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)
# CPU specific sources
@DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S
@@ -213,7 +215,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
gcc/builtins.lo gcc/deh.lo gcc/emutls.lo gcc/gthread.lo \
gcc/sections/android.lo gcc/sections/elf_shared.lo \
gcc/sections/osx.lo gcc/sections/package.lo \
- gcc/sections/win32.lo gcc/sections/win64.lo gcc/unwind/arm.lo \
+ gcc/sections/pecoff.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 \
@@ -425,7 +427,8 @@ am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/winspool.lo core/sys/windows/winsvc.lo \
core/sys/windows/winuser.lo core/sys/windows/winver.lo \
core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19)
+@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \
core/sys/solaris/libelf.lo core/sys/solaris/link.lo \
@@ -460,24 +463,26 @@ am_libgdruntime_la_OBJECTS = $(am__objects_33)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__objects_34 = core/stdc/libgdruntime_convenience_la-errno_.lo
-@DRUNTIME_CPU_AARCH64_TRUE@am__objects_35 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_ARM_TRUE@am__objects_36 = config/arm/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_MIPS_TRUE@am__objects_37 = config/mips/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_38 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_39 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_40 = config/x86/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_41 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
-@DRUNTIME_CPU_S390_TRUE@am__objects_42 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
-am__objects_43 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_35 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_36 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_37 = config/arm/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_38 = config/mips/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_39 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_40 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_41 = config/x86/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_42 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
+@DRUNTIME_CPU_S390_TRUE@am__objects_43 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
+am__objects_44 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
$(am__objects_10) $(am__objects_12) $(am__objects_14) \
- $(am__objects_16) $(am__objects_18) $(am__objects_20) \
- $(am__objects_22) $(am__objects_35) $(am__objects_36) \
- $(am__objects_37) $(am__objects_38) $(am__objects_39) \
- $(am__objects_40) $(am__objects_41) $(am__objects_42)
-am__objects_44 = $(am__objects_1) $(am__objects_34) $(am__objects_43) \
+ $(am__objects_16) $(am__objects_18) $(am__objects_35) \
+ $(am__objects_22) $(am__objects_36) $(am__objects_37) \
+ $(am__objects_38) $(am__objects_39) $(am__objects_40) \
+ $(am__objects_41) $(am__objects_42) $(am__objects_43)
+am__objects_45 = $(am__objects_1) $(am__objects_34) $(am__objects_44) \
$(am__objects_32)
-am__objects_45 = $(am__objects_44)
-am_libgdruntime_convenience_la_OBJECTS = $(am__objects_45)
+am__objects_46 = $(am__objects_45)
+am_libgdruntime_convenience_la_OBJECTS = $(am__objects_46)
libgdruntime_convenience_la_OBJECTS = \
$(am_libgdruntime_convenience_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
@@ -659,6 +664,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -688,6 +695,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -720,7 +728,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
@@ -813,7 +821,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/backtrace.d \
gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
@@ -1213,8 +1221,7 @@ 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/win32.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/win64.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/pecoff.lo: gcc/sections/$(am__dirstamp)
gcc/unwind/$(am__dirstamp):
@$(MKDIR_P) gcc/unwind
@: > gcc/unwind/$(am__dirstamp)
@@ -1720,6 +1727,10 @@ core/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+ @$(MKDIR_P) config/mingw
+ @: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/$(am__dirstamp)
core/sys/solaris/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris
@: > core/sys/solaris/$(am__dirstamp)
@@ -1769,9 +1780,6 @@ config/powerpc/$(am__dirstamp):
@: > config/powerpc/$(am__dirstamp)
config/powerpc/libgdruntime_la-switchcontext.lo: \
config/powerpc/$(am__dirstamp)
-config/mingw/$(am__dirstamp):
- @$(MKDIR_P) config/mingw
- @: > config/mingw/$(am__dirstamp)
config/mingw/libgdruntime_la-switchcontext.lo: \
config/mingw/$(am__dirstamp)
config/x86/$(am__dirstamp):
@@ -1796,6 +1804,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+config/mingw/libgdruntime_convenience_la-msvc.lo: \
+ config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
config/aarch64/$(am__dirstamp)
config/arm/libgdruntime_convenience_la-switchcontext.lo: \
@@ -1991,9 +2001,15 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
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
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.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 config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/libphobos/libdruntime/config/mingw/msvc.c b/libphobos/libdruntime/config/mingw/msvc.c
new file mode 100644
index 00000000000..25b15a06950
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/msvc.c
@@ -0,0 +1,54 @@
+/* Windows support code to wrap differences between different
+ versions of the Microsoft C libaries.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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/>. */
+
+#include <stdio.h>
+
+/* The symbols for stdin, stdout, and stderr are defined for D in the
+ core.stdc.stdio module. Save the macros and redeclare them here. */
+#define c_stdin stdin
+#undef stdin
+extern FILE *stdin;
+
+#define c_stdout stdout
+#undef stdout
+extern FILE *stdout;
+
+#define c_stderr stderr
+#undef stderr
+extern FILE *stderr;
+
+/* Set to 1 if run-time is using ucrtbase.dll. */
+unsigned char msvcUsesUCRT;
+
+void init_msvc()
+{
+#if __MSVCRT_VERSION__ >= 0x1400
+ msvcUsedUCRT = 1;
+#endif
+
+ stdin = c_stdin;
+ stdout = c_stdout;
+ stderr = c_stderr;
+}
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
index 6592ff604bc..0cb8b015bfc 100644
--- a/libphobos/libdruntime/config/mingw/switchcontext.S
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -63,13 +66,15 @@ CSYM(fiber_switchContext):
popq %RCX;
jmp *%RCX;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#elif defined(_X86_)
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -104,6 +109,5 @@ CSYM(fiber_switchContext):
// 'return' to complete switch
ret;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#endif
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 7caef4c1339..b048a944a88 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
version (CRuntime_Microsoft)
{
- // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
- ///
- extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
- { // Fake it 'till we make it
- return strtod(nptr, endptr);
+ version (MinGW)
+ {
+ ///
+ real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+ ///
+ alias __mingw_strtold strtold;
+ }
+ else
+ {
+ // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+ ///
+ extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+ { // Fake it 'till we make it
+ return strtod(nptr, endptr);
+ }
}
-}
-else version (MinGW)
-{
- ///
- real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
- ///
- alias __mingw_strtold strtold;
}
else
{
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 4dd1b3ccc66..9a351db3861 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1409,13 +1409,20 @@ else
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
///
- alias core.stdc.math.fabsf fabs;
+ alias core.stdc.math.fabsf fabs;
///
- alias core.stdc.math.fabsl fabs;
+ alias core.stdc.math.fabsl fabs;
}
///
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 90a294343fc..2808a6c59fc 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
public import core.sys.windows.uuid;
-extern (System)
+extern (Windows)
{
class ComObject : IUnknown
{
-extern (System):
+extern (Windows):
HRESULT QueryInterface(const(IID)* riid, void** ppv)
{
if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
public import core.sys.windows.dbghelp_types;
-extern(System)
+extern(Windows)
{
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 9f36ac389a6..3df0d7fd41b 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -31,17 +31,7 @@ public import core.sys.windows.threadaux;
// not access tls_array[tls_index] as needed for thread local _tlsstart and _tlsend
extern (C)
{
- version (MinGW)
- {
- extern __gshared void* _tls_start;
- extern __gshared void* _tls_end;
- extern __gshared void* __xl_a;
-
- alias _tls_start _tlsstart;
- alias _tls_end _tlsend;
- alias __xl_a _tls_callbacks_a;
- }
- else version (Win32)
+ version (Win32)
{
version (CRuntime_DigitalMars)
{
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index defdc9586f1..638eada3e43 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -1539,9 +1539,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
void *bottom;
version (X86)
- asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
else version (X86_64)
- asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
else
static assert(false, "Platform not supported.");
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index c747b5132d1..7e02dabd221 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -805,7 +805,7 @@ version (GNU_SEH_Exceptions)
void* ms_orig_context, void* ms_disp)
{
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
- ms_disp, &__gdc_personality_imp);
+ ms_disp, &gdc_personality);
}
}
else version (GNU_SjLj_Exceptions)
diff --git a/libphobos/libdruntime/gcc/gthread.d b/libphobos/libdruntime/gcc/gthread.d
index ef35a3c27ec..5003637b9ea 100644
--- a/libphobos/libdruntime/gcc/gthread.d
+++ b/libphobos/libdruntime/gcc/gthread.d
@@ -86,10 +86,12 @@ else static if (GNU_Thread_Model == ThreadModel.Single)
}
else static if (GNU_Thread_Model == ThreadModel.Win32)
{
+ import core.stdc.config;
+
struct __gthread_once_t
{
- INT done;
- LONG started;
+ int done;
+ c_long started;
}
int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor);
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
index fdaf039fcfa..5d76072af25 100644
--- a/libphobos/libdruntime/gcc/sections/package.d
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -22,26 +22,20 @@
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)
+version (CRuntime_Glibc) version = ElfShared;
+version (CRuntime_Musl) version = ElfShared;
+version (CRuntime_UClibc) version = ElfShared;
+version (FreeBSD) version = ElfShared;
+version (NetBSD) version = ElfShared;
+version (DragonFlyBSD) version = ElfShared;
+version (Solaris) version = ElfShared;
+
+version (ElfShared)
public import gcc.sections.elf_shared;
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 (Windows)
+ public import gcc.sections.pecoff;
else version (CRuntime_Bionic)
public import gcc.sections.android;
else
diff --git a/libphobos/libdruntime/gcc/sections/pecoff.d b/libphobos/libdruntime/gcc/sections/pecoff.d
new file mode 100644
index 00000000000..5fa1df2ac54
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/pecoff.d
@@ -0,0 +1,830 @@
+// PE/COFF-specific support for sections.
+// Copyright (C) 2021 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.pecoff;
+
+version (Windows):
+
+import core.memory;
+import core.stdc.stdlib;
+import core.sys.windows.winbase;
+import core.sys.windows.windef;
+import core.sys.windows.winnt;
+import rt.minfo;
+import rt.util.container.array;
+import rt.util.container.hashtab;
+
+version (GNU_EMUTLS)
+ import gcc.emutls;
+
+/****
+ * 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.).
+ */
+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
+{
+ static int opApply(scope int delegate(ref DSO) dg)
+ {
+ foreach (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ static int opApplyReverse(scope int delegate(ref DSO) dg)
+ {
+ foreach_reverse (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
+ {
+ return _moduleGroup.modules;
+ }
+
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
+ {
+ return _moduleGroup;
+ }
+
+ @property inout(void[])[] gcRanges() inout nothrow @nogc
+ {
+ return _gcRanges[];
+ }
+
+private:
+
+ invariant()
+ {
+ safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+ }
+
+ void** _slot;
+ ModuleGroup _moduleGroup;
+ Array!(void[]) _gcRanges;
+
+ version (Shared)
+ {
+ Array!(void[]) _codeSegments; // array of code segments
+ Array!(DSO*) _deps; // D libraries needed by this DSO
+ void* _handle; // corresponding handle
+ }
+}
+
+/****
+ * Boolean flag set to true while the runtime is initialized.
+ */
+__gshared bool _isRuntimeInitialized;
+
+/****
+ * Gets called on program startup just before GC is initialized.
+ */
+void initSections() nothrow @nogc
+{
+ _isRuntimeInitialized = true;
+}
+
+/***
+ * Gets called on program shutdown just after GC is terminated.
+ */
+void finiSections() nothrow @nogc
+{
+ _isRuntimeInitialized = false;
+}
+
+alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
+
+version (Shared)
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
+ {
+ return &_loadedDSOs();
+ }
+
+ void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
+ {
+ // Nothing to do here. tdsos used to point to the _loadedDSOs instance
+ // in the dying thread's TLS segment and as such is not valid anymore.
+ // The memory for the array contents was already reclaimed in
+ // cleanupLoadedLibraries().
+ }
+
+ void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+
+ // interface for core.thread to inherit loaded libraries
+ void* pinLoadedLibraries() nothrow @nogc
+ {
+ auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
+ res.length = _loadedDSOs.length;
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ (*res)[i] = tdso;
+ if (tdso._addCnt)
+ {
+ // Increment the DLL ref for explicitly loaded libraries to pin them.
+ char[MAX_PATH] buf;
+ char[] buffer = buf[];
+ const success = .LoadLibraryA(nameForDSO(tdso._pdso, buffer)) !is null;
+ safeAssert(success, "Failed to increment DLL ref.");
+ (*res)[i]._addCnt = 1; // new array takes over the additional ref count
+ }
+ }
+ return res;
+ }
+
+ void unpinLoadedLibraries(void* p) nothrow @nogc
+ {
+ auto pary = cast(Array!(ThreadDSO)*)p;
+ // In case something failed we need to undo the pinning.
+ foreach (ref tdso; *pary)
+ {
+ if (tdso._addCnt)
+ {
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid library handle.");
+ .FreeLibrary(handle);
+ }
+ }
+ pary.reset();
+ .free(pary);
+ }
+
+ // Called before TLS ctors are ran, copy over the loaded libraries
+ // of the parent thread.
+ void inheritLoadedLibraries(void* p) nothrow @nogc
+ {
+ safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
+ _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
+ .free(p);
+ }
+
+ // Called after all TLS dtors ran, decrements all remaining DLL refs.
+ void cleanupLoadedLibraries() nothrow @nogc
+ {
+ foreach (ref tdso; _loadedDSOs)
+ {
+ if (tdso._addCnt == 0) continue;
+
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid DSO handle.");
+ for (; tdso._addCnt > 0; --tdso._addCnt)
+ .FreeLibrary(handle);
+ }
+
+ // Free the memory for the array contents.
+ _loadedDSOs.reset();
+ }
+}
+else
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(void[])* initTLSRanges() nothrow @nogc
+ {
+ return null;
+ }
+
+ void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
+ {
+ }
+
+ void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+}
+
+private:
+
+version (Shared)
+{
+ /*
+ * Array of thread local DSO metadata for all libraries loaded and
+ * initialized in this thread.
+ *
+ * Note:
+ * A newly spawned thread will inherit these libraries.
+ * Note:
+ * We use an array here to preserve the order of
+ * initialization. If that became a performance issue, we
+ * could use a hash table and enumerate the DSOs during
+ * loading so that the hash table values could be sorted when
+ * necessary.
+ */
+ struct ThreadDSO
+ {
+ DSO* _pdso;
+ static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;
+ else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;
+ else static assert(0, "unimplemented");
+ alias _pdso this;
+ }
+
+ @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow
+ {
+ static Array!(ThreadDSO) x;
+ return x;
+ }
+
+ /*
+ * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
+ */
+ bool _rtLoading;
+
+ /*
+ * Hash table to map the native handle (as returned by dlopen)
+ * to the corresponding DSO*, protected by a mutex.
+ */
+ __gshared CRITICAL_SECTION _handleToDSOMutex;
+ @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow
+ {
+ __gshared HashTab!(void*, DSO*) x;
+ return x;
+ }
+}
+else
+{
+ /*
+ * Static DSOs loaded by the runtime linker. This includes the
+ * executable. These can't be unloaded.
+ */
+ @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow
+ {
+ __gshared Array!(DSO*) x;
+ return x;
+ }
+
+ enum _rtLoading = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Compiler to runtime interface.
+///////////////////////////////////////////////////////////////////////////////
+
+/****
+ * This data structure is generated by the compiler, and then passed to
+ * _d_dso_registry().
+ */
+struct CompilerDSOData
+{
+ size_t _version; // currently 1
+ void** _slot; // can be used to store runtime data
+ immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file
+}
+
+T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
+
+/* For each shared library and executable, the compiler generates code that
+ * sets up CompilerDSOData and calls _d_dso_registry().
+ * A pointer to that code is inserted into both the .ctors and .dtors
+ * segment so it gets called by the loader on startup and shutdown.
+ */
+extern(C) void _d_dso_registry(CompilerDSOData* data)
+{
+ // only one supported currently
+ safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
+
+ // no backlink => register
+ if (*data._slot is null)
+ {
+ immutable firstDSO = _loadedDSOs.empty;
+ if (firstDSO) initLocks();
+
+ DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);
+ assert(typeid(DSO).initializer().ptr is null);
+ pdso._slot = data._slot;
+ *data._slot = pdso; // store backlink in library record
+
+ pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
+
+ HMODULE handle = void;
+ const moduleFound = findModuleHandleForAddr(data._slot, handle);
+ safeAssert(moduleFound, "Failed to find image header.");
+
+ scanSegments(handle, pdso);
+
+ version (Shared)
+ {
+ getDependencies(handle, pdso._deps);
+ pdso._handle = handle;
+ setDSOForHandle(pdso, pdso._handle);
+
+ if (!_rtLoading)
+ {
+ /* This DSO was not loaded by rt_loadLibrary which
+ * happens for all dependencies of an executable or
+ * the first dlopen call from a C program.
+ * In this case we add the DSO to the _loadedDSOs of this
+ * thread with a refCnt of 1 and call the TlsCtors.
+ */
+ immutable ushort refCnt = 1, addCnt = 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ }
+ }
+ else
+ {
+ foreach (p; _loadedDSOs)
+ safeAssert(p !is pdso, "DSO already registered.");
+ _loadedDSOs.insertBack(pdso);
+ }
+
+ // don't initialize modules before rt_init was called
+ if (_isRuntimeInitialized)
+ {
+ registerGCRanges(pdso);
+ // rt_loadLibrary will run tls ctors, so do this only for dlopen
+ immutable runTlsCtors = !_rtLoading;
+ runModuleConstructors(pdso, runTlsCtors);
+ }
+ }
+ // has backlink => unregister
+ else
+ {
+ DSO* pdso = cast(DSO*)*data._slot;
+ *data._slot = null;
+
+ // don't finalizes modules after rt_term was called (see Bugzilla 11378)
+ if (_isRuntimeInitialized)
+ {
+ // rt_unloadLibrary already ran tls dtors, so do this only for dlclose
+ immutable runTlsDtors = !_rtLoading;
+ runModuleDestructors(pdso, runTlsDtors);
+ unregisterGCRanges(pdso);
+ // run finalizers after module dtors (same order as in rt_term)
+ version (Shared) runFinalizers(pdso);
+ }
+
+ version (Shared)
+ {
+ if (!_rtLoading)
+ {
+ /* This DSO was not unloaded by rt_unloadLibrary so we
+ * have to remove it from _loadedDSOs here.
+ */
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ if (tdso._pdso == pdso)
+ {
+ _loadedDSOs.remove(i);
+ break;
+ }
+ }
+ }
+
+ unsetDSOForHandle(pdso, pdso._handle);
+ }
+ else
+ {
+ // static DSOs are unloaded in reverse order
+ safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
+ _loadedDSOs.popBack();
+ }
+
+ freeDSO(pdso);
+
+ // last DSO being unloaded => shutdown registry
+ if (_loadedDSOs.empty)
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_destroy();
+ version (Shared)
+ {
+ safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+ _handleToDSO.reset();
+ }
+ finiLocks();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dynamic loading
+///////////////////////////////////////////////////////////////////////////////
+
+// Shared D libraries are only supported when linking against a shared druntime library.
+
+version (Shared)
+{
+ ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc
+ {
+ foreach (ref tdata; _loadedDSOs)
+ if (tdata._pdso == pdso) return &tdata;
+ return null;
+ }
+
+ void incThreadRef(DSO* pdso, bool incAdd)
+ {
+ if (auto tdata = findThreadDSO(pdso)) // already initialized
+ {
+ if (incAdd && ++tdata._addCnt > 1) return;
+ ++tdata._refCnt;
+ }
+ else
+ {
+ foreach (dep; pdso._deps)
+ incThreadRef(dep, false);
+ immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ pdso._moduleGroup.runTlsCtors();
+ }
+ }
+
+ void decThreadRef(DSO* pdso, bool decAdd)
+ {
+ auto tdata = findThreadDSO(pdso);
+ 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;
+
+ pdso._moduleGroup.runTlsDtors();
+ foreach (i, ref td; _loadedDSOs)
+ if (td._pdso == pdso) _loadedDSOs.remove(i);
+ foreach (dep; pdso._deps)
+ decThreadRef(dep, false);
+ }
+}
+
+/***********************************
+ * These are a temporary means of providing a GC hook for DLL use. They may be
+ * replaced with some other similar functionality later.
+ */
+extern (C)
+{
+ void* gc_getProxy();
+ void gc_setProxy(void* p);
+ void gc_clrProxy();
+
+ alias void function(void*) gcSetFn;
+ alias void function() gcClrFn;
+}
+
+/*******************************************
+ * Loads a DLL written in D with the name 'name'.
+ * Returns:
+ * opaque handle to the DLL if successfully loaded
+ * null if failure
+ */
+extern(C) void* rt_loadLibrary(const char* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryA(name));
+}
+
+extern (C) void* rt_loadLibraryW(const wchar_t* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryW(name));
+}
+
+void* initLibrary(void* handle)
+{
+ if (handle is null)
+ return null;
+
+ version (Shared)
+ {
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ incThreadRef(pdso, true);
+ }
+ gcSetFn gcSet = cast(gcSetFn) GetProcAddress(handle, "gc_setProxy");
+ if (gcSet !is null)
+ {
+ // BUG: Set proxy, but too late
+ gcSet(gc_getProxy());
+ }
+ return handle;
+}
+
+/*************************************
+ * Unloads DLL that was previously loaded by rt_loadLibrary().
+ * Input:
+ * handle the handle returned by rt_loadLibrary()
+ * Returns:
+ * 1 succeeded
+ * 0 some failure happened
+ */
+extern(C) int rt_unloadLibrary(void* handle)
+{
+ if (handle is null)
+ return false;
+
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ decThreadRef(pdso, true);
+ }
+ gcClrFn gcClr = cast(gcClrFn) GetProcAddress(handle, "gc_clrProxy");
+ if (gcClr !is null)
+ gcClr();
+ return .FreeLibrary(handle) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// helper functions
+///////////////////////////////////////////////////////////////////////////////
+
+void initLocks() nothrow @nogc
+{
+ version (Shared)
+ InitializeCriticalSection(&_handleToDSOMutex);
+}
+
+void finiLocks() nothrow @nogc
+{
+ version (Shared)
+ DeleteCriticalSection(&_handleToDSOMutex);
+}
+
+void runModuleConstructors(DSO* pdso, bool runTlsCtors)
+{
+ pdso._moduleGroup.sortCtors();
+ pdso._moduleGroup.runCtors();
+ if (runTlsCtors) pdso._moduleGroup.runTlsCtors();
+}
+
+void runModuleDestructors(DSO* pdso, bool runTlsDtors)
+{
+ if (runTlsDtors) pdso._moduleGroup.runTlsDtors();
+ pdso._moduleGroup.runDtors();
+}
+
+void registerGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.addRange(rng.ptr, rng.length);
+}
+
+void unregisterGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.removeRange(rng.ptr);
+}
+
+version (Shared) void runFinalizers(DSO* pdso)
+{
+ foreach (seg; pdso._codeSegments)
+ GC.runFinalizers(seg);
+}
+
+void freeDSO(DSO* pdso) nothrow @nogc
+{
+ pdso._gcRanges.reset();
+ version (Shared)
+ {
+ pdso._codeSegments.reset();
+ pdso._deps.reset();
+ pdso._handle = null;
+ }
+ .free(pdso);
+}
+
+version (Shared)
+{
+@nogc nothrow:
+ const(char)* nameForDSO(DSO* pdso, ref char[] buffer)
+ {
+ const success = GetModuleFileNameA(pdso._handle, buffer.ptr, cast(DWORD)buffer.length) != 0;
+ safeAssert(success, "Failed to get DLL name.");
+ return buffer.ptr;
+ }
+
+ DSO* dsoForHandle(in void* handle)
+ {
+ DSO* pdso;
+ .EnterCriticalSection(&_handleToDSOMutex);
+ if (auto ppdso = handle in _handleToDSO)
+ pdso = *ppdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ return pdso;
+ }
+
+ void setDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(handle !in _handleToDSO, "DSO already registered.");
+ _handleToDSO[handle] = pdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void unsetDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
+ _handleToDSO.remove(handle);
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void getDependencies(in HMODULE handle, ref Array!(DSO*) deps)
+ {
+ auto nthdr = getNTHeader(handle);
+ auto import_entry = nthdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ auto addr = import_entry.VirtualAddress;
+ auto datasize = import_entry.Size;
+
+ if (addr == 0 && datasize == 0)
+ {
+ // Maybe the optional header isn't there, look for the section.
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ addr = section.VirtualAddress;
+ datasize = section.Misc.VirtualSize;
+ break;
+ }
+ if (datasize == 0)
+ return;
+ }
+ else
+ {
+ bool foundSection = false;
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ // Section containing import table has no contents.
+ if (section.Misc.VirtualSize == 0)
+ return;
+ foundSection = true;
+ break;
+ }
+ // There is an import table, but the section containing it could not be found
+ if (!foundSection)
+ return;
+ }
+
+ // Get the names of each DLL
+ for (uint i = 0; i + IMAGE_IMPORT_DESCRIPTOR.sizeof <= datasize;
+ i += IMAGE_IMPORT_DESCRIPTOR.sizeof)
+ {
+ const data = cast(PIMAGE_IMPORT_DESCRIPTOR)(handle + addr + i);
+ if (data.Name == 0)
+ break;
+
+ // dll name of dependency
+ auto name = cast(char*)(handle + data.Name);
+ // get handle without loading the library
+ auto libhandle = handleForName(name);
+ // the runtime linker has already loaded all dependencies
+ 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)
+ {
+ return GetModuleHandleA(name);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PE/COFF program header iteration
+///////////////////////////////////////////////////////////////////////////////
+
+bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
+{
+ if (name[] != cast(char[])section.Name[0 .. name.length])
+ return false;
+ return name.length == 8 || section.Name[name.length] == 0;
+}
+
+/************
+ * Scan segments in the image header and store
+ * the writeable data segments in *pdso.
+ */
+
+void scanSegments(in HMODULE handle, DSO* pdso) nothrow @nogc
+{
+ foreach (section; getSectionHeader(handle))
+ {
+ // the ".data" image section includes both object file sections ".data" and ".bss"
+ if (compareSectionName(section, ".data"))
+ {
+ auto data = cast(void*)handle + section.VirtualAddress;
+ pdso._gcRanges.insertBack(data[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+
+ version (Shared)
+ {
+ if (compareSectionName(section, ".text"))
+ {
+ auto text = cast(void*)handle + section.VirtualAddress;
+ pdso._codeSegments.insertBack(text[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+ }
+ }
+}
+
+/**************************
+ * Input:
+ * handle where the output is to be written
+ * Returns:
+ * true if found, and *handle is filled in
+ */
+
+bool findModuleHandleForAddr(in void* addr, out HMODULE handle) nothrow @nogc
+{
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ cast(const(wchar)*) addr, &handle))
+ return true;
+
+ return false;
+}
+
+/**
+ * Returns the image NT header for the HMODULE handle passed,
+ * or null if not found.
+ */
+PIMAGE_NT_HEADERS getNTHeader(in HMODULE handle) nothrow @nogc
+{
+ auto doshdr = cast(PIMAGE_DOS_HEADER)handle;
+ if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
+ return null;
+
+ return cast(typeof(return))(cast(void*)doshdr + doshdr.e_lfanew);
+}
+
+/**
+ * Returns the image section header for the HMODULE handle passed,
+ * or null if not found.
+ */
+IMAGE_SECTION_HEADER[] getSectionHeader(in HMODULE handle) nothrow @nogc
+{
+ if (auto nthdr = getNTHeader(handle))
+ {
+ const void* opthdr = &nthdr.OptionalHeader;
+ const offset = nthdr.FileHeader.SizeOfOptionalHeader;
+ const length = nthdr.FileHeader.NumberOfSections;
+ return (cast(PIMAGE_SECTION_HEADER)(opthdr + offset))[0 .. length];
+ }
+ return null;
+}
diff --git a/libphobos/libdruntime/gcc/sections/win32.d b/libphobos/libdruntime/gcc/sections/win32.d
deleted file mode 100644
index b355dfc5068..00000000000
--- a/libphobos/libdruntime/gcc/sections/win32.d
+++ /dev/null
@@ -1,183 +0,0 @@
-// Win32-specific support for sections.
-// Copyright (C) 2019-2021 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):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import rt.minfo;
-import core.stdc.stdlib : malloc, free;
-
-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 inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][] _gcRanges;
-}
-
-shared(bool) conservative;
-
-void initSections() nothrow @nogc
-{
- _sections._moduleGroup = ModuleGroup(getModuleInfos());
-
- import rt.sections;
- conservative = !scanDataSegPrecisely();
-
- if (conservative)
- {
- _sections._gcRanges = (cast(void[]*) malloc(2 * (void[]).sizeof))[0..2];
-
- auto databeg = cast(void*)&_xi_a;
- auto dataend = cast(void*)_moduleinfo_array.ptr;
- _sections._gcRanges[0] = databeg[0 .. dataend - databeg];
-
- // skip module info and CONST segment
- auto bssbeg = cast(void*)&_edata;
- auto bssend = cast(void*)&_end;
- _sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];
- }
- else
- {
- size_t count = &_DPend - &_DPbegin;
- auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);
- size_t r = 0;
- void* prev = null;
- for (size_t i = 0; i < count; i++)
- {
- void* addr = (&_DPbegin)[i];
- if (prev + (void*).sizeof == addr)
- ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];
- else
- ranges[r++] = (cast(void**)addr)[0..1];
- prev = addr;
- }
- _sections._gcRanges = ranges[0..r];
- }
-}
-
-void finiSections() nothrow @nogc
-{
- free(_sections._gcRanges.ptr);
-}
-
-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
-{
- if (conservative)
- {
- dg(rng.ptr, rng.ptr + rng.length);
- }
- else
- {
- for (auto p = &_TPbegin; p < &_TPend; )
- {
- uint beg = *p++;
- uint end = beg + cast(uint)((void*).sizeof);
- while (p < &_TPend && *p == end)
- {
- end += (void*).sizeof;
- p++;
- }
- dg(rng.ptr + beg, rng.ptr + end);
- }
- }
-}
-
-private:
-
-__gshared SectionGroup _sections;
-
-// Windows: this gets initialized by minit.asm
-extern(C) __gshared immutable(ModuleInfo*)[] _moduleinfo_array;
-extern(C) void _minit() nothrow @nogc;
-
-immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
-out (result)
-{
- foreach (m; result)
- assert(m !is null);
-}
-body
-{
- // _minit directly alters the global _moduleinfo_array
- _minit();
- return _moduleinfo_array;
-}
-
-extern(C)
-{
- extern __gshared
- {
- int _xi_a; // &_xi_a just happens to be start of data segment
- int _edata; // &_edata is start of BSS segment
- int _end; // &_end is past end of BSS
-
- void* _DPbegin; // first entry in the array of pointers addresses
- void* _DPend; // &_DPend points after last entry of array
- uint _TPbegin; // first entry in the array of TLS offsets of pointers
- uint _TPend; // &_DPend points after last entry of array
- }
-
- extern
- {
- int _tlsstart;
- int _tlsend;
- }
-}
diff --git a/libphobos/libdruntime/gcc/sections/win64.d b/libphobos/libdruntime/gcc/sections/win64.d
index 357940ba821..512693c071d 100644
--- a/libphobos/libdruntime/gcc/sections/win64.d
+++ b/libphobos/libdruntime/gcc/sections/win64.d
@@ -51,14 +51,6 @@ struct SectionGroup
return _moduleGroup;
}
- version (Win64)
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;
- auto pend = cast(immutable(FuncTable)*)&_deh_end;
- return pbeg[0 .. pend - pbeg];
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d
index 5315739f82f..592b3afcb71 100644
--- a/libphobos/libdruntime/gcc/unwind/generic.d
+++ b/libphobos/libdruntime/gcc/unwind/generic.d
@@ -269,6 +269,6 @@ version (GNU_SEH_Exceptions)
ExceptionCollidedUnwind
}
- extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,
+ extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*, void*,
_Unwind_Personality_Fn);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 3d5ba299863..e4a2c6571d4 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -70,70 +70,6 @@ version (CRuntime_Microsoft)
extern(C) void init_msvc();
}
-/***********************************
- * These are a temporary means of providing a GC hook for DLL use. They may be
- * replaced with some other similar functionality later.
- */
-extern (C)
-{
- void* gc_getProxy();
- void gc_setProxy(void* p);
- void gc_clrProxy();
-
- alias void* function() gcGetFn;
- alias void function(void*) gcSetFn;
- alias void function() gcClrFn;
-}
-
-version (Windows)
-{
- /*******************************************
- * Loads a DLL written in D with the name 'name'.
- * Returns:
- * opaque handle to the DLL if successfully loaded
- * null if failure
- */
- extern (C) void* rt_loadLibrary(const char* name)
- {
- return initLibrary(.LoadLibraryA(name));
- }
-
- extern (C) void* rt_loadLibraryW(const wchar_t* name)
- {
- return initLibrary(.LoadLibraryW(name));
- }
-
- void* initLibrary(void* mod)
- {
- // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
- // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
- if (mod is null)
- return mod;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, "gc_setProxy");
- if (gcSet !is null)
- { // BUG: Set proxy, but too late
- gcSet(gc_getProxy());
- }
- return mod;
- }
-
- /*************************************
- * Unloads DLL that was previously loaded by rt_loadLibrary().
- * Input:
- * ptr the handle returned by rt_loadLibrary()
- * Returns:
- * 1 succeeded
- * 0 some failure happened
- */
- extern (C) int rt_unloadLibrary(void* ptr)
- {
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
- if (gcClr !is null)
- gcClr();
- return FreeLibrary(ptr) != 0;
- }
-}
-
/* To get out-of-band access to the args[] passed to main().
*/
diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am
index 2de8ab951b4..0dc2a2625a9 100644
--- a/libphobos/src/Makefile.am
+++ b/libphobos/src/Makefile.am
@@ -24,7 +24,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 2e721783d06..33453517153 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -414,6 +414,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -443,6 +445,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -477,7 +480,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index c38a4688258..51eb4efc79d 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -242,6 +242,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -271,6 +273,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gcc(refs/users/ibuclaw/heads/mingw)] More MSVC support
@ 2021-04-10 15:22 Iain Buclaw
0 siblings, 0 replies; 5+ messages in thread
From: Iain Buclaw @ 2021-04-10 15:22 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:df32ce552c241bd63ef401bafedc31f10fff06c8
commit df32ce552c241bd63ef401bafedc31f10fff06c8
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Wed Mar 24 16:24:04 2021 +0100
More MSVC support
Diff:
---
gcc/config/i386/cygming.h | 2 +
gcc/config/i386/i386-d.c | 11 ++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/i386/winnt-d.c | 5 ++
gcc/d/d-target.cc | 5 +-
gcc/d/d-target.def | 10 ++++
gcc/doc/tm.texi | 7 +++
gcc/doc/tm.texi.in | 2 +
libphobos/libdruntime/Makefile.am | 3 +-
libphobos/libdruntime/Makefile.in | 56 ++++++++++++-------
libphobos/libdruntime/config/mingw/msvc.c | 54 ++++++++++++++++++
libphobos/libdruntime/config/mingw/switchcontext.S | 12 ++--
libphobos/libdruntime/core/stdc/stdlib.d | 27 +++++----
libphobos/libdruntime/core/stdc/tgmath.d | 11 +++-
libphobos/libdruntime/core/sys/windows/com.d | 4 +-
libphobos/libdruntime/core/sys/windows/dbghelp.d | 2 +-
libphobos/libdruntime/core/thread/osthread.d | 4 +-
libphobos/libdruntime/gcc/deh.d | 2 +-
libphobos/libdruntime/gcc/gthread.d | 6 +-
libphobos/libdruntime/gcc/unwind/generic.d | 2 +-
libphobos/libdruntime/rt/dmain2.d | 64 ----------------------
22 files changed, 178 insertions(+), 115 deletions(-)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index cfbca34f996..59eb812c1cf 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -209,6 +209,8 @@ along with GCC; see the file COPYING3. If not see
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
flag_pic = TARGET_64BIT ? 1 : 0; \
+ if (!global_options_set.x_dwarf_version) \
+ dwarf_version = 4; \
} while (0)
/* Define this macro if references to a symbol must be treated
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index b79be85e661..34f53ba046d 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -44,3 +44,14 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Implement TARGET_D_EXTERN_SYSTEM_LINKAGE for x86 targets. */
+
+int
+ix86_d_extern_system_linkage (void)
+{
+ if (ix86_abi == MS_ABI)
+ return LINKwindows;
+
+ return LINKc;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..d07bf09bc65 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern int ix86_d_extern_system_linkage (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b4001d21b70..0c24ada8bd5 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -801,8 +801,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_EXTERN_SYSTEM_LINKAGE ix86_d_extern_system_linkage
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index 8a6b9c57d8d..d05ea8a92bf 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -32,6 +32,11 @@ winnt_d_os_builtins (void)
{
d_add_builtin_version ("Windows");
+ if (ix86_abi == SYSV_ABI)
+ d_add_builtin_version ("SYSV_ABI");
+ else
+ d_add_builtin_version ("MS_ABI");
+
#define builtin_version(TXT) d_add_builtin_version (TXT)
#ifdef EXTRA_TARGET_D_OS_VERSIONS
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index a1dc2ee286f..4e37c998934 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -435,11 +435,14 @@ TargetCPP::derivedClassOffset(ClassDeclaration *base_class)
return base_class->structsize;
}
-/* Return the default system linkage for the target. */
+/* Return the default `extern (System)` linkage for the target. */
LINK
Target::systemLinkage (void)
{
+ if (targetdm.d_extern_system_linkage)
+ return (LINK) targetdm.d_extern_system_linkage ();
+
return LINKc;
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..9fb3c7d23d9 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,16 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* */
+DEFHOOK
+(d_extern_system_linkage,
+ "If defined, this hook returns the extern linkage which should be applied\n\
+ for all declarations annotated with @code{extern (System)}. Typically,\n\
+ @code{extern (System)} is the same as @code{extern (Windows)} on Microsoft\n\
+ Windows platforms, and @code{extern (C)} on other platforms.",
+ int, (void),
+ NULL)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..0265ef0df5c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,13 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} int TARGET_D_EXTERN_SYSTEM_LINKAGE (void)
+If defined, this hook returns the extern linkage which should be applied
+ for all declarations annotated with @code{extern (System)}. Typically,
+ @code{extern (System)} is the same as @code{extern (Windows)} on Microsoft
+ Windows platforms, and @code{extern (C)} on other platforms.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..ef15417a791 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,8 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_EXTERN_SYSTEM_LINKAGE
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 02a68b10424..fdac627364d 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -69,7 +69,8 @@ if DRUNTIME_OS_LINUX
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
endif
if DRUNTIME_OS_MINGW
- DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
+ DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS) \
+ config/mingw/msvc.c
endif
if DRUNTIME_OS_SOLARIS
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 853a7fc1981..1ff2ac665ee 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -117,7 +117,9 @@ target_triplet = @target@
@DRUNTIME_OS_NETBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_NETBSD)
@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)
@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)
-@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)
+@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/msvc.c
+
@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)
# CPU specific sources
@DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S
@@ -428,7 +430,8 @@ am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/winsvc.lo core/sys/windows/winuser.lo \
core/sys/windows/winver.lo core/sys/windows/wtsapi32.lo \
core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19)
+@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \
core/sys/solaris/libelf.lo core/sys/solaris/link.lo \
@@ -463,24 +466,26 @@ am_libgdruntime_la_OBJECTS = $(am__objects_33)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__objects_34 = core/stdc/libgdruntime_convenience_la-errno_.lo
-@DRUNTIME_CPU_AARCH64_TRUE@am__objects_35 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_ARM_TRUE@am__objects_36 = config/arm/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_MIPS_TRUE@am__objects_37 = config/mips/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_38 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_39 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_40 = config/x86/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_41 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
-@DRUNTIME_CPU_S390_TRUE@am__objects_42 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
-am__objects_43 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_35 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_36 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_37 = config/arm/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_38 = config/mips/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_39 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_40 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_41 = config/x86/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_42 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
+@DRUNTIME_CPU_S390_TRUE@am__objects_43 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
+am__objects_44 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
$(am__objects_10) $(am__objects_12) $(am__objects_14) \
- $(am__objects_16) $(am__objects_18) $(am__objects_20) \
- $(am__objects_22) $(am__objects_35) $(am__objects_36) \
- $(am__objects_37) $(am__objects_38) $(am__objects_39) \
- $(am__objects_40) $(am__objects_41) $(am__objects_42)
-am__objects_44 = $(am__objects_1) $(am__objects_34) $(am__objects_43) \
+ $(am__objects_16) $(am__objects_18) $(am__objects_35) \
+ $(am__objects_22) $(am__objects_36) $(am__objects_37) \
+ $(am__objects_38) $(am__objects_39) $(am__objects_40) \
+ $(am__objects_41) $(am__objects_42) $(am__objects_43)
+am__objects_45 = $(am__objects_1) $(am__objects_34) $(am__objects_44) \
$(am__objects_32)
-am__objects_45 = $(am__objects_44)
-am_libgdruntime_convenience_la_OBJECTS = $(am__objects_45)
+am__objects_46 = $(am__objects_45)
+am_libgdruntime_convenience_la_OBJECTS = $(am__objects_46)
libgdruntime_convenience_la_OBJECTS = \
$(am_libgdruntime_convenience_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
@@ -1732,6 +1737,10 @@ core/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+ @$(MKDIR_P) config/mingw
+ @: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/$(am__dirstamp)
core/sys/solaris/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris
@: > core/sys/solaris/$(am__dirstamp)
@@ -1781,9 +1790,6 @@ config/powerpc/$(am__dirstamp):
@: > config/powerpc/$(am__dirstamp)
config/powerpc/libgdruntime_la-switchcontext.lo: \
config/powerpc/$(am__dirstamp)
-config/mingw/$(am__dirstamp):
- @$(MKDIR_P) config/mingw
- @: > config/mingw/$(am__dirstamp)
config/mingw/libgdruntime_la-switchcontext.lo: \
config/mingw/$(am__dirstamp)
config/x86/$(am__dirstamp):
@@ -1808,6 +1814,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+config/mingw/libgdruntime_convenience_la-msvc.lo: \
+ config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
config/aarch64/$(am__dirstamp)
config/arm/libgdruntime_convenience_la-switchcontext.lo: \
@@ -2003,9 +2011,15 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
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
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.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 config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/libphobos/libdruntime/config/mingw/msvc.c b/libphobos/libdruntime/config/mingw/msvc.c
new file mode 100644
index 00000000000..25b15a06950
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/msvc.c
@@ -0,0 +1,54 @@
+/* Windows support code to wrap differences between different
+ versions of the Microsoft C libaries.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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/>. */
+
+#include <stdio.h>
+
+/* The symbols for stdin, stdout, and stderr are defined for D in the
+ core.stdc.stdio module. Save the macros and redeclare them here. */
+#define c_stdin stdin
+#undef stdin
+extern FILE *stdin;
+
+#define c_stdout stdout
+#undef stdout
+extern FILE *stdout;
+
+#define c_stderr stderr
+#undef stderr
+extern FILE *stderr;
+
+/* Set to 1 if run-time is using ucrtbase.dll. */
+unsigned char msvcUsesUCRT;
+
+void init_msvc()
+{
+#if __MSVCRT_VERSION__ >= 0x1400
+ msvcUsedUCRT = 1;
+#endif
+
+ stdin = c_stdin;
+ stdout = c_stdout;
+ stderr = c_stderr;
+}
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
index 6592ff604bc..0cb8b015bfc 100644
--- a/libphobos/libdruntime/config/mingw/switchcontext.S
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -63,13 +66,15 @@ CSYM(fiber_switchContext):
popq %RCX;
jmp *%RCX;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#elif defined(_X86_)
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -104,6 +109,5 @@ CSYM(fiber_switchContext):
// 'return' to complete switch
ret;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#endif
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 5d69b880bc8..35e81a25414 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
version (CRuntime_Microsoft)
{
- // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
- ///
- extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
- { // Fake it 'till we make it
- return strtod(nptr, endptr);
+ version (MinGW)
+ {
+ ///
+ real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+ ///
+ alias __mingw_strtold strtold;
+ }
+ else
+ {
+ // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+ ///
+ extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+ { // Fake it 'till we make it
+ return strtod(nptr, endptr);
+ }
}
-}
-else version (MinGW)
-{
- ///
- real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
- ///
- alias __mingw_strtold strtold;
}
else
{
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 2ff1522fd81..cd80bf7c9b1 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1285,13 +1285,20 @@ else
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
///
- alias core.stdc.math.fabsf fabs;
+ alias core.stdc.math.fabsf fabs;
///
- alias core.stdc.math.fabsl fabs;
+ alias core.stdc.math.fabsl fabs;
}
// @@@DEPRECATED_2.105@@@
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 88007adb141..6935dd94f95 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
public import core.sys.windows.uuid;
-extern (System)
+extern (Windows)
{
class ComObject : IUnknown
{
-extern (System):
+extern (Windows):
HRESULT QueryInterface(const(IID)* riid, void** ppv)
{
if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
public import core.sys.windows.dbghelp_types;
-extern(System)
+extern(Windows)
{
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index 880836e3a25..5ee909ae793 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -1539,9 +1539,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
void *bottom;
version (X86)
- asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
else version (X86_64)
- asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
else
static assert(false, "Platform not supported.");
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index 2e679320c38..5ce4869d096 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -805,7 +805,7 @@ version (GNU_SEH_Exceptions)
void* ms_orig_context, void* ms_disp)
{
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
- ms_disp, &__gdc_personality_imp);
+ ms_disp, &gdc_personality);
}
}
else version (GNU_SjLj_Exceptions)
diff --git a/libphobos/libdruntime/gcc/gthread.d b/libphobos/libdruntime/gcc/gthread.d
index ef35a3c27ec..5003637b9ea 100644
--- a/libphobos/libdruntime/gcc/gthread.d
+++ b/libphobos/libdruntime/gcc/gthread.d
@@ -86,10 +86,12 @@ else static if (GNU_Thread_Model == ThreadModel.Single)
}
else static if (GNU_Thread_Model == ThreadModel.Win32)
{
+ import core.stdc.config;
+
struct __gthread_once_t
{
- INT done;
- LONG started;
+ int done;
+ c_long started;
}
int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor);
diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d
index 5315739f82f..592b3afcb71 100644
--- a/libphobos/libdruntime/gcc/unwind/generic.d
+++ b/libphobos/libdruntime/gcc/unwind/generic.d
@@ -269,6 +269,6 @@ version (GNU_SEH_Exceptions)
ExceptionCollidedUnwind
}
- extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,
+ extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*, void*,
_Unwind_Personality_Fn);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 3d5ba299863..e4a2c6571d4 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -70,70 +70,6 @@ version (CRuntime_Microsoft)
extern(C) void init_msvc();
}
-/***********************************
- * These are a temporary means of providing a GC hook for DLL use. They may be
- * replaced with some other similar functionality later.
- */
-extern (C)
-{
- void* gc_getProxy();
- void gc_setProxy(void* p);
- void gc_clrProxy();
-
- alias void* function() gcGetFn;
- alias void function(void*) gcSetFn;
- alias void function() gcClrFn;
-}
-
-version (Windows)
-{
- /*******************************************
- * Loads a DLL written in D with the name 'name'.
- * Returns:
- * opaque handle to the DLL if successfully loaded
- * null if failure
- */
- extern (C) void* rt_loadLibrary(const char* name)
- {
- return initLibrary(.LoadLibraryA(name));
- }
-
- extern (C) void* rt_loadLibraryW(const wchar_t* name)
- {
- return initLibrary(.LoadLibraryW(name));
- }
-
- void* initLibrary(void* mod)
- {
- // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
- // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
- if (mod is null)
- return mod;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, "gc_setProxy");
- if (gcSet !is null)
- { // BUG: Set proxy, but too late
- gcSet(gc_getProxy());
- }
- return mod;
- }
-
- /*************************************
- * Unloads DLL that was previously loaded by rt_loadLibrary().
- * Input:
- * ptr the handle returned by rt_loadLibrary()
- * Returns:
- * 1 succeeded
- * 0 some failure happened
- */
- extern (C) int rt_unloadLibrary(void* ptr)
- {
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
- if (gcClr !is null)
- gcClr();
- return FreeLibrary(ptr) != 0;
- }
-}
-
/* To get out-of-band access to the args[] passed to main().
*/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gcc(refs/users/ibuclaw/heads/mingw)] More MSVC support
@ 2021-04-08 13:35 Iain Buclaw
0 siblings, 0 replies; 5+ messages in thread
From: Iain Buclaw @ 2021-04-08 13:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e280567b330fca770add9808c9ea2cf766c55bd9
commit e280567b330fca770add9808c9ea2cf766c55bd9
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Wed Mar 24 16:24:04 2021 +0100
More MSVC support
Diff:
---
gcc/config/i386/cygming.h | 2 +
gcc/config/i386/i386-d.c | 11 +
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/i386/winnt-d.c | 5 +
gcc/d/d-target.cc | 5 +-
gcc/d/d-target.def | 10 +
gcc/doc/tm.texi | 7 +
gcc/doc/tm.texi.in | 2 +
libphobos/libdruntime/Makefile.am | 5 +-
libphobos/libdruntime/Makefile.in | 62 +-
libphobos/libdruntime/config/mingw/msvc.c | 54 ++
libphobos/libdruntime/config/mingw/switchcontext.S | 12 +-
libphobos/libdruntime/core/stdc/stdlib.d | 27 +-
libphobos/libdruntime/core/stdc/tgmath.d | 11 +-
libphobos/libdruntime/core/sys/windows/com.d | 4 +-
libphobos/libdruntime/core/sys/windows/dbghelp.d | 2 +-
libphobos/libdruntime/core/thread/osthread.d | 4 +-
libphobos/libdruntime/gcc/deh.d | 2 +-
libphobos/libdruntime/gcc/gthread.d | 6 +-
libphobos/libdruntime/gcc/sections/package.d | 28 +-
libphobos/libdruntime/gcc/sections/pecoff.d | 830 +++++++++++++++++++++
libphobos/libdruntime/gcc/sections/win32.d | 183 -----
libphobos/libdruntime/gcc/sections/win64.d | 8 -
libphobos/libdruntime/gcc/unwind/generic.d | 2 +-
libphobos/libdruntime/rt/dmain2.d | 64 --
26 files changed, 1023 insertions(+), 327 deletions(-)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index cfbca34f996..59eb812c1cf 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -209,6 +209,8 @@ along with GCC; see the file COPYING3. If not see
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
flag_pic = TARGET_64BIT ? 1 : 0; \
+ if (!global_options_set.x_dwarf_version) \
+ dwarf_version = 4; \
} while (0)
/* Define this macro if references to a symbol must be treated
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index b79be85e661..34f53ba046d 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -44,3 +44,14 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Implement TARGET_D_EXTERN_SYSTEM_LINKAGE for x86 targets. */
+
+int
+ix86_d_extern_system_linkage (void)
+{
+ if (ix86_abi == MS_ABI)
+ return LINKwindows;
+
+ return LINKc;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..d07bf09bc65 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern int ix86_d_extern_system_linkage (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b4001d21b70..0c24ada8bd5 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -801,8 +801,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_EXTERN_SYSTEM_LINKAGE ix86_d_extern_system_linkage
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index 8a6b9c57d8d..d05ea8a92bf 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -32,6 +32,11 @@ winnt_d_os_builtins (void)
{
d_add_builtin_version ("Windows");
+ if (ix86_abi == SYSV_ABI)
+ d_add_builtin_version ("SYSV_ABI");
+ else
+ d_add_builtin_version ("MS_ABI");
+
#define builtin_version(TXT) d_add_builtin_version (TXT)
#ifdef EXTRA_TARGET_D_OS_VERSIONS
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index a1dc2ee286f..4e37c998934 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -435,11 +435,14 @@ TargetCPP::derivedClassOffset(ClassDeclaration *base_class)
return base_class->structsize;
}
-/* Return the default system linkage for the target. */
+/* Return the default `extern (System)` linkage for the target. */
LINK
Target::systemLinkage (void)
{
+ if (targetdm.d_extern_system_linkage)
+ return (LINK) targetdm.d_extern_system_linkage ();
+
return LINKc;
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..9fb3c7d23d9 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,16 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* */
+DEFHOOK
+(d_extern_system_linkage,
+ "If defined, this hook returns the extern linkage which should be applied\n\
+ for all declarations annotated with @code{extern (System)}. Typically,\n\
+ @code{extern (System)} is the same as @code{extern (Windows)} on Microsoft\n\
+ Windows platforms, and @code{extern (C)} on other platforms.",
+ int, (void),
+ NULL)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..0265ef0df5c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,13 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} int TARGET_D_EXTERN_SYSTEM_LINKAGE (void)
+If defined, this hook returns the extern linkage which should be applied
+ for all declarations annotated with @code{extern (System)}. Typically,
+ @code{extern (System)} is the same as @code{extern (Windows)} on Microsoft
+ Windows platforms, and @code{extern (C)} on other platforms.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..ef15417a791 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,8 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_EXTERN_SYSTEM_LINKAGE
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 5137f85b571..385ab7a497a 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -69,7 +69,8 @@ if DRUNTIME_OS_LINUX
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
endif
if DRUNTIME_OS_MINGW
- DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
+ DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS) \
+ config/mingw/msvc.c
endif
if DRUNTIME_OS_SOLARIS
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
@@ -187,7 +188,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/attributes.d \
gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 4a93b4921a4..70d9e0cbfc2 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -117,7 +117,9 @@ target_triplet = @target@
@DRUNTIME_OS_NETBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_NETBSD)
@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)
@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)
-@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)
+@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/msvc.c
+
@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)
# CPU specific sources
@DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S
@@ -213,7 +215,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
gcc/backtrace.lo gcc/builtins.lo gcc/deh.lo gcc/emutls.lo \
gcc/gthread.lo gcc/sections/android.lo \
gcc/sections/elf_shared.lo gcc/sections/osx.lo \
- gcc/sections/package.lo gcc/sections/win32.lo \
+ gcc/sections/package.lo gcc/sections/pecoff.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 \
@@ -429,7 +431,8 @@ am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/winsvc.lo core/sys/windows/winuser.lo \
core/sys/windows/winver.lo core/sys/windows/wtsapi32.lo \
core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19)
+@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \
core/sys/solaris/libelf.lo core/sys/solaris/link.lo \
@@ -464,24 +467,26 @@ am_libgdruntime_la_OBJECTS = $(am__objects_33)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__objects_34 = core/stdc/libgdruntime_convenience_la-errno_.lo
-@DRUNTIME_CPU_AARCH64_TRUE@am__objects_35 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_ARM_TRUE@am__objects_36 = config/arm/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_MIPS_TRUE@am__objects_37 = config/mips/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_38 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_39 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_40 = config/x86/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_41 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
-@DRUNTIME_CPU_S390_TRUE@am__objects_42 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
-am__objects_43 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_35 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_36 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_37 = config/arm/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_38 = config/mips/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_39 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_40 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_41 = config/x86/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_42 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
+@DRUNTIME_CPU_S390_TRUE@am__objects_43 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
+am__objects_44 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
$(am__objects_10) $(am__objects_12) $(am__objects_14) \
- $(am__objects_16) $(am__objects_18) $(am__objects_20) \
- $(am__objects_22) $(am__objects_35) $(am__objects_36) \
- $(am__objects_37) $(am__objects_38) $(am__objects_39) \
- $(am__objects_40) $(am__objects_41) $(am__objects_42)
-am__objects_44 = $(am__objects_1) $(am__objects_34) $(am__objects_43) \
+ $(am__objects_16) $(am__objects_18) $(am__objects_35) \
+ $(am__objects_22) $(am__objects_36) $(am__objects_37) \
+ $(am__objects_38) $(am__objects_39) $(am__objects_40) \
+ $(am__objects_41) $(am__objects_42) $(am__objects_43)
+am__objects_45 = $(am__objects_1) $(am__objects_34) $(am__objects_44) \
$(am__objects_32)
-am__objects_45 = $(am__objects_44)
-am_libgdruntime_convenience_la_OBJECTS = $(am__objects_45)
+am__objects_46 = $(am__objects_45)
+am_libgdruntime_convenience_la_OBJECTS = $(am__objects_46)
libgdruntime_convenience_la_OBJECTS = \
$(am_libgdruntime_convenience_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
@@ -820,7 +825,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/attributes.d \
gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
@@ -1223,7 +1228,7 @@ 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/win32.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/pecoff.lo: gcc/sections/$(am__dirstamp)
gcc/sections/win64.lo: gcc/sections/$(am__dirstamp)
gcc/unwind/$(am__dirstamp):
@$(MKDIR_P) gcc/unwind
@@ -1734,6 +1739,10 @@ core/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+ @$(MKDIR_P) config/mingw
+ @: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/$(am__dirstamp)
core/sys/solaris/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris
@: > core/sys/solaris/$(am__dirstamp)
@@ -1783,9 +1792,6 @@ config/powerpc/$(am__dirstamp):
@: > config/powerpc/$(am__dirstamp)
config/powerpc/libgdruntime_la-switchcontext.lo: \
config/powerpc/$(am__dirstamp)
-config/mingw/$(am__dirstamp):
- @$(MKDIR_P) config/mingw
- @: > config/mingw/$(am__dirstamp)
config/mingw/libgdruntime_la-switchcontext.lo: \
config/mingw/$(am__dirstamp)
config/x86/$(am__dirstamp):
@@ -1810,6 +1816,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+config/mingw/libgdruntime_convenience_la-msvc.lo: \
+ config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
config/aarch64/$(am__dirstamp)
config/arm/libgdruntime_convenience_la-switchcontext.lo: \
@@ -2005,9 +2013,15 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
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
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.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 config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/libphobos/libdruntime/config/mingw/msvc.c b/libphobos/libdruntime/config/mingw/msvc.c
new file mode 100644
index 00000000000..25b15a06950
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/msvc.c
@@ -0,0 +1,54 @@
+/* Windows support code to wrap differences between different
+ versions of the Microsoft C libaries.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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/>. */
+
+#include <stdio.h>
+
+/* The symbols for stdin, stdout, and stderr are defined for D in the
+ core.stdc.stdio module. Save the macros and redeclare them here. */
+#define c_stdin stdin
+#undef stdin
+extern FILE *stdin;
+
+#define c_stdout stdout
+#undef stdout
+extern FILE *stdout;
+
+#define c_stderr stderr
+#undef stderr
+extern FILE *stderr;
+
+/* Set to 1 if run-time is using ucrtbase.dll. */
+unsigned char msvcUsesUCRT;
+
+void init_msvc()
+{
+#if __MSVCRT_VERSION__ >= 0x1400
+ msvcUsedUCRT = 1;
+#endif
+
+ stdin = c_stdin;
+ stdout = c_stdout;
+ stderr = c_stderr;
+}
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
index 6592ff604bc..0cb8b015bfc 100644
--- a/libphobos/libdruntime/config/mingw/switchcontext.S
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -63,13 +66,15 @@ CSYM(fiber_switchContext):
popq %RCX;
jmp *%RCX;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#elif defined(_X86_)
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -104,6 +109,5 @@ CSYM(fiber_switchContext):
// 'return' to complete switch
ret;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#endif
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 5d69b880bc8..35e81a25414 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
version (CRuntime_Microsoft)
{
- // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
- ///
- extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
- { // Fake it 'till we make it
- return strtod(nptr, endptr);
+ version (MinGW)
+ {
+ ///
+ real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+ ///
+ alias __mingw_strtold strtold;
+ }
+ else
+ {
+ // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+ ///
+ extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+ { // Fake it 'till we make it
+ return strtod(nptr, endptr);
+ }
}
-}
-else version (MinGW)
-{
- ///
- real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
- ///
- alias __mingw_strtold strtold;
}
else
{
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 2ff1522fd81..cd80bf7c9b1 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1285,13 +1285,20 @@ else
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
///
- alias core.stdc.math.fabsf fabs;
+ alias core.stdc.math.fabsf fabs;
///
- alias core.stdc.math.fabsl fabs;
+ alias core.stdc.math.fabsl fabs;
}
// @@@DEPRECATED_2.105@@@
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 88007adb141..6935dd94f95 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
public import core.sys.windows.uuid;
-extern (System)
+extern (Windows)
{
class ComObject : IUnknown
{
-extern (System):
+extern (Windows):
HRESULT QueryInterface(const(IID)* riid, void** ppv)
{
if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
public import core.sys.windows.dbghelp_types;
-extern(System)
+extern(Windows)
{
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index defdc9586f1..638eada3e43 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -1539,9 +1539,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
void *bottom;
version (X86)
- asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
else version (X86_64)
- asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
else
static assert(false, "Platform not supported.");
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index 2e679320c38..5ce4869d096 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -805,7 +805,7 @@ version (GNU_SEH_Exceptions)
void* ms_orig_context, void* ms_disp)
{
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
- ms_disp, &__gdc_personality_imp);
+ ms_disp, &gdc_personality);
}
}
else version (GNU_SjLj_Exceptions)
diff --git a/libphobos/libdruntime/gcc/gthread.d b/libphobos/libdruntime/gcc/gthread.d
index ef35a3c27ec..5003637b9ea 100644
--- a/libphobos/libdruntime/gcc/gthread.d
+++ b/libphobos/libdruntime/gcc/gthread.d
@@ -86,10 +86,12 @@ else static if (GNU_Thread_Model == ThreadModel.Single)
}
else static if (GNU_Thread_Model == ThreadModel.Win32)
{
+ import core.stdc.config;
+
struct __gthread_once_t
{
- INT done;
- LONG started;
+ int done;
+ c_long started;
}
int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor);
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
index fdaf039fcfa..5d76072af25 100644
--- a/libphobos/libdruntime/gcc/sections/package.d
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -22,26 +22,20 @@
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)
+version (CRuntime_Glibc) version = ElfShared;
+version (CRuntime_Musl) version = ElfShared;
+version (CRuntime_UClibc) version = ElfShared;
+version (FreeBSD) version = ElfShared;
+version (NetBSD) version = ElfShared;
+version (DragonFlyBSD) version = ElfShared;
+version (Solaris) version = ElfShared;
+
+version (ElfShared)
public import gcc.sections.elf_shared;
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 (Windows)
+ public import gcc.sections.pecoff;
else version (CRuntime_Bionic)
public import gcc.sections.android;
else
diff --git a/libphobos/libdruntime/gcc/sections/pecoff.d b/libphobos/libdruntime/gcc/sections/pecoff.d
new file mode 100644
index 00000000000..5fa1df2ac54
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/pecoff.d
@@ -0,0 +1,830 @@
+// PE/COFF-specific support for sections.
+// Copyright (C) 2021 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.pecoff;
+
+version (Windows):
+
+import core.memory;
+import core.stdc.stdlib;
+import core.sys.windows.winbase;
+import core.sys.windows.windef;
+import core.sys.windows.winnt;
+import rt.minfo;
+import rt.util.container.array;
+import rt.util.container.hashtab;
+
+version (GNU_EMUTLS)
+ import gcc.emutls;
+
+/****
+ * 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.).
+ */
+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
+{
+ static int opApply(scope int delegate(ref DSO) dg)
+ {
+ foreach (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ static int opApplyReverse(scope int delegate(ref DSO) dg)
+ {
+ foreach_reverse (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
+ {
+ return _moduleGroup.modules;
+ }
+
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
+ {
+ return _moduleGroup;
+ }
+
+ @property inout(void[])[] gcRanges() inout nothrow @nogc
+ {
+ return _gcRanges[];
+ }
+
+private:
+
+ invariant()
+ {
+ safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+ }
+
+ void** _slot;
+ ModuleGroup _moduleGroup;
+ Array!(void[]) _gcRanges;
+
+ version (Shared)
+ {
+ Array!(void[]) _codeSegments; // array of code segments
+ Array!(DSO*) _deps; // D libraries needed by this DSO
+ void* _handle; // corresponding handle
+ }
+}
+
+/****
+ * Boolean flag set to true while the runtime is initialized.
+ */
+__gshared bool _isRuntimeInitialized;
+
+/****
+ * Gets called on program startup just before GC is initialized.
+ */
+void initSections() nothrow @nogc
+{
+ _isRuntimeInitialized = true;
+}
+
+/***
+ * Gets called on program shutdown just after GC is terminated.
+ */
+void finiSections() nothrow @nogc
+{
+ _isRuntimeInitialized = false;
+}
+
+alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
+
+version (Shared)
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
+ {
+ return &_loadedDSOs();
+ }
+
+ void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
+ {
+ // Nothing to do here. tdsos used to point to the _loadedDSOs instance
+ // in the dying thread's TLS segment and as such is not valid anymore.
+ // The memory for the array contents was already reclaimed in
+ // cleanupLoadedLibraries().
+ }
+
+ void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+
+ // interface for core.thread to inherit loaded libraries
+ void* pinLoadedLibraries() nothrow @nogc
+ {
+ auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
+ res.length = _loadedDSOs.length;
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ (*res)[i] = tdso;
+ if (tdso._addCnt)
+ {
+ // Increment the DLL ref for explicitly loaded libraries to pin them.
+ char[MAX_PATH] buf;
+ char[] buffer = buf[];
+ const success = .LoadLibraryA(nameForDSO(tdso._pdso, buffer)) !is null;
+ safeAssert(success, "Failed to increment DLL ref.");
+ (*res)[i]._addCnt = 1; // new array takes over the additional ref count
+ }
+ }
+ return res;
+ }
+
+ void unpinLoadedLibraries(void* p) nothrow @nogc
+ {
+ auto pary = cast(Array!(ThreadDSO)*)p;
+ // In case something failed we need to undo the pinning.
+ foreach (ref tdso; *pary)
+ {
+ if (tdso._addCnt)
+ {
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid library handle.");
+ .FreeLibrary(handle);
+ }
+ }
+ pary.reset();
+ .free(pary);
+ }
+
+ // Called before TLS ctors are ran, copy over the loaded libraries
+ // of the parent thread.
+ void inheritLoadedLibraries(void* p) nothrow @nogc
+ {
+ safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
+ _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
+ .free(p);
+ }
+
+ // Called after all TLS dtors ran, decrements all remaining DLL refs.
+ void cleanupLoadedLibraries() nothrow @nogc
+ {
+ foreach (ref tdso; _loadedDSOs)
+ {
+ if (tdso._addCnt == 0) continue;
+
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid DSO handle.");
+ for (; tdso._addCnt > 0; --tdso._addCnt)
+ .FreeLibrary(handle);
+ }
+
+ // Free the memory for the array contents.
+ _loadedDSOs.reset();
+ }
+}
+else
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(void[])* initTLSRanges() nothrow @nogc
+ {
+ return null;
+ }
+
+ void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
+ {
+ }
+
+ void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+}
+
+private:
+
+version (Shared)
+{
+ /*
+ * Array of thread local DSO metadata for all libraries loaded and
+ * initialized in this thread.
+ *
+ * Note:
+ * A newly spawned thread will inherit these libraries.
+ * Note:
+ * We use an array here to preserve the order of
+ * initialization. If that became a performance issue, we
+ * could use a hash table and enumerate the DSOs during
+ * loading so that the hash table values could be sorted when
+ * necessary.
+ */
+ struct ThreadDSO
+ {
+ DSO* _pdso;
+ static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;
+ else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;
+ else static assert(0, "unimplemented");
+ alias _pdso this;
+ }
+
+ @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow
+ {
+ static Array!(ThreadDSO) x;
+ return x;
+ }
+
+ /*
+ * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
+ */
+ bool _rtLoading;
+
+ /*
+ * Hash table to map the native handle (as returned by dlopen)
+ * to the corresponding DSO*, protected by a mutex.
+ */
+ __gshared CRITICAL_SECTION _handleToDSOMutex;
+ @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow
+ {
+ __gshared HashTab!(void*, DSO*) x;
+ return x;
+ }
+}
+else
+{
+ /*
+ * Static DSOs loaded by the runtime linker. This includes the
+ * executable. These can't be unloaded.
+ */
+ @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow
+ {
+ __gshared Array!(DSO*) x;
+ return x;
+ }
+
+ enum _rtLoading = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Compiler to runtime interface.
+///////////////////////////////////////////////////////////////////////////////
+
+/****
+ * This data structure is generated by the compiler, and then passed to
+ * _d_dso_registry().
+ */
+struct CompilerDSOData
+{
+ size_t _version; // currently 1
+ void** _slot; // can be used to store runtime data
+ immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file
+}
+
+T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
+
+/* For each shared library and executable, the compiler generates code that
+ * sets up CompilerDSOData and calls _d_dso_registry().
+ * A pointer to that code is inserted into both the .ctors and .dtors
+ * segment so it gets called by the loader on startup and shutdown.
+ */
+extern(C) void _d_dso_registry(CompilerDSOData* data)
+{
+ // only one supported currently
+ safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
+
+ // no backlink => register
+ if (*data._slot is null)
+ {
+ immutable firstDSO = _loadedDSOs.empty;
+ if (firstDSO) initLocks();
+
+ DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);
+ assert(typeid(DSO).initializer().ptr is null);
+ pdso._slot = data._slot;
+ *data._slot = pdso; // store backlink in library record
+
+ pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
+
+ HMODULE handle = void;
+ const moduleFound = findModuleHandleForAddr(data._slot, handle);
+ safeAssert(moduleFound, "Failed to find image header.");
+
+ scanSegments(handle, pdso);
+
+ version (Shared)
+ {
+ getDependencies(handle, pdso._deps);
+ pdso._handle = handle;
+ setDSOForHandle(pdso, pdso._handle);
+
+ if (!_rtLoading)
+ {
+ /* This DSO was not loaded by rt_loadLibrary which
+ * happens for all dependencies of an executable or
+ * the first dlopen call from a C program.
+ * In this case we add the DSO to the _loadedDSOs of this
+ * thread with a refCnt of 1 and call the TlsCtors.
+ */
+ immutable ushort refCnt = 1, addCnt = 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ }
+ }
+ else
+ {
+ foreach (p; _loadedDSOs)
+ safeAssert(p !is pdso, "DSO already registered.");
+ _loadedDSOs.insertBack(pdso);
+ }
+
+ // don't initialize modules before rt_init was called
+ if (_isRuntimeInitialized)
+ {
+ registerGCRanges(pdso);
+ // rt_loadLibrary will run tls ctors, so do this only for dlopen
+ immutable runTlsCtors = !_rtLoading;
+ runModuleConstructors(pdso, runTlsCtors);
+ }
+ }
+ // has backlink => unregister
+ else
+ {
+ DSO* pdso = cast(DSO*)*data._slot;
+ *data._slot = null;
+
+ // don't finalizes modules after rt_term was called (see Bugzilla 11378)
+ if (_isRuntimeInitialized)
+ {
+ // rt_unloadLibrary already ran tls dtors, so do this only for dlclose
+ immutable runTlsDtors = !_rtLoading;
+ runModuleDestructors(pdso, runTlsDtors);
+ unregisterGCRanges(pdso);
+ // run finalizers after module dtors (same order as in rt_term)
+ version (Shared) runFinalizers(pdso);
+ }
+
+ version (Shared)
+ {
+ if (!_rtLoading)
+ {
+ /* This DSO was not unloaded by rt_unloadLibrary so we
+ * have to remove it from _loadedDSOs here.
+ */
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ if (tdso._pdso == pdso)
+ {
+ _loadedDSOs.remove(i);
+ break;
+ }
+ }
+ }
+
+ unsetDSOForHandle(pdso, pdso._handle);
+ }
+ else
+ {
+ // static DSOs are unloaded in reverse order
+ safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
+ _loadedDSOs.popBack();
+ }
+
+ freeDSO(pdso);
+
+ // last DSO being unloaded => shutdown registry
+ if (_loadedDSOs.empty)
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_destroy();
+ version (Shared)
+ {
+ safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+ _handleToDSO.reset();
+ }
+ finiLocks();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dynamic loading
+///////////////////////////////////////////////////////////////////////////////
+
+// Shared D libraries are only supported when linking against a shared druntime library.
+
+version (Shared)
+{
+ ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc
+ {
+ foreach (ref tdata; _loadedDSOs)
+ if (tdata._pdso == pdso) return &tdata;
+ return null;
+ }
+
+ void incThreadRef(DSO* pdso, bool incAdd)
+ {
+ if (auto tdata = findThreadDSO(pdso)) // already initialized
+ {
+ if (incAdd && ++tdata._addCnt > 1) return;
+ ++tdata._refCnt;
+ }
+ else
+ {
+ foreach (dep; pdso._deps)
+ incThreadRef(dep, false);
+ immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ pdso._moduleGroup.runTlsCtors();
+ }
+ }
+
+ void decThreadRef(DSO* pdso, bool decAdd)
+ {
+ auto tdata = findThreadDSO(pdso);
+ 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;
+
+ pdso._moduleGroup.runTlsDtors();
+ foreach (i, ref td; _loadedDSOs)
+ if (td._pdso == pdso) _loadedDSOs.remove(i);
+ foreach (dep; pdso._deps)
+ decThreadRef(dep, false);
+ }
+}
+
+/***********************************
+ * These are a temporary means of providing a GC hook for DLL use. They may be
+ * replaced with some other similar functionality later.
+ */
+extern (C)
+{
+ void* gc_getProxy();
+ void gc_setProxy(void* p);
+ void gc_clrProxy();
+
+ alias void function(void*) gcSetFn;
+ alias void function() gcClrFn;
+}
+
+/*******************************************
+ * Loads a DLL written in D with the name 'name'.
+ * Returns:
+ * opaque handle to the DLL if successfully loaded
+ * null if failure
+ */
+extern(C) void* rt_loadLibrary(const char* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryA(name));
+}
+
+extern (C) void* rt_loadLibraryW(const wchar_t* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryW(name));
+}
+
+void* initLibrary(void* handle)
+{
+ if (handle is null)
+ return null;
+
+ version (Shared)
+ {
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ incThreadRef(pdso, true);
+ }
+ gcSetFn gcSet = cast(gcSetFn) GetProcAddress(handle, "gc_setProxy");
+ if (gcSet !is null)
+ {
+ // BUG: Set proxy, but too late
+ gcSet(gc_getProxy());
+ }
+ return handle;
+}
+
+/*************************************
+ * Unloads DLL that was previously loaded by rt_loadLibrary().
+ * Input:
+ * handle the handle returned by rt_loadLibrary()
+ * Returns:
+ * 1 succeeded
+ * 0 some failure happened
+ */
+extern(C) int rt_unloadLibrary(void* handle)
+{
+ if (handle is null)
+ return false;
+
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ decThreadRef(pdso, true);
+ }
+ gcClrFn gcClr = cast(gcClrFn) GetProcAddress(handle, "gc_clrProxy");
+ if (gcClr !is null)
+ gcClr();
+ return .FreeLibrary(handle) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// helper functions
+///////////////////////////////////////////////////////////////////////////////
+
+void initLocks() nothrow @nogc
+{
+ version (Shared)
+ InitializeCriticalSection(&_handleToDSOMutex);
+}
+
+void finiLocks() nothrow @nogc
+{
+ version (Shared)
+ DeleteCriticalSection(&_handleToDSOMutex);
+}
+
+void runModuleConstructors(DSO* pdso, bool runTlsCtors)
+{
+ pdso._moduleGroup.sortCtors();
+ pdso._moduleGroup.runCtors();
+ if (runTlsCtors) pdso._moduleGroup.runTlsCtors();
+}
+
+void runModuleDestructors(DSO* pdso, bool runTlsDtors)
+{
+ if (runTlsDtors) pdso._moduleGroup.runTlsDtors();
+ pdso._moduleGroup.runDtors();
+}
+
+void registerGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.addRange(rng.ptr, rng.length);
+}
+
+void unregisterGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.removeRange(rng.ptr);
+}
+
+version (Shared) void runFinalizers(DSO* pdso)
+{
+ foreach (seg; pdso._codeSegments)
+ GC.runFinalizers(seg);
+}
+
+void freeDSO(DSO* pdso) nothrow @nogc
+{
+ pdso._gcRanges.reset();
+ version (Shared)
+ {
+ pdso._codeSegments.reset();
+ pdso._deps.reset();
+ pdso._handle = null;
+ }
+ .free(pdso);
+}
+
+version (Shared)
+{
+@nogc nothrow:
+ const(char)* nameForDSO(DSO* pdso, ref char[] buffer)
+ {
+ const success = GetModuleFileNameA(pdso._handle, buffer.ptr, cast(DWORD)buffer.length) != 0;
+ safeAssert(success, "Failed to get DLL name.");
+ return buffer.ptr;
+ }
+
+ DSO* dsoForHandle(in void* handle)
+ {
+ DSO* pdso;
+ .EnterCriticalSection(&_handleToDSOMutex);
+ if (auto ppdso = handle in _handleToDSO)
+ pdso = *ppdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ return pdso;
+ }
+
+ void setDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(handle !in _handleToDSO, "DSO already registered.");
+ _handleToDSO[handle] = pdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void unsetDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
+ _handleToDSO.remove(handle);
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void getDependencies(in HMODULE handle, ref Array!(DSO*) deps)
+ {
+ auto nthdr = getNTHeader(handle);
+ auto import_entry = nthdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ auto addr = import_entry.VirtualAddress;
+ auto datasize = import_entry.Size;
+
+ if (addr == 0 && datasize == 0)
+ {
+ // Maybe the optional header isn't there, look for the section.
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ addr = section.VirtualAddress;
+ datasize = section.Misc.VirtualSize;
+ break;
+ }
+ if (datasize == 0)
+ return;
+ }
+ else
+ {
+ bool foundSection = false;
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ // Section containing import table has no contents.
+ if (section.Misc.VirtualSize == 0)
+ return;
+ foundSection = true;
+ break;
+ }
+ // There is an import table, but the section containing it could not be found
+ if (!foundSection)
+ return;
+ }
+
+ // Get the names of each DLL
+ for (uint i = 0; i + IMAGE_IMPORT_DESCRIPTOR.sizeof <= datasize;
+ i += IMAGE_IMPORT_DESCRIPTOR.sizeof)
+ {
+ const data = cast(PIMAGE_IMPORT_DESCRIPTOR)(handle + addr + i);
+ if (data.Name == 0)
+ break;
+
+ // dll name of dependency
+ auto name = cast(char*)(handle + data.Name);
+ // get handle without loading the library
+ auto libhandle = handleForName(name);
+ // the runtime linker has already loaded all dependencies
+ 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)
+ {
+ return GetModuleHandleA(name);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PE/COFF program header iteration
+///////////////////////////////////////////////////////////////////////////////
+
+bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
+{
+ if (name[] != cast(char[])section.Name[0 .. name.length])
+ return false;
+ return name.length == 8 || section.Name[name.length] == 0;
+}
+
+/************
+ * Scan segments in the image header and store
+ * the writeable data segments in *pdso.
+ */
+
+void scanSegments(in HMODULE handle, DSO* pdso) nothrow @nogc
+{
+ foreach (section; getSectionHeader(handle))
+ {
+ // the ".data" image section includes both object file sections ".data" and ".bss"
+ if (compareSectionName(section, ".data"))
+ {
+ auto data = cast(void*)handle + section.VirtualAddress;
+ pdso._gcRanges.insertBack(data[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+
+ version (Shared)
+ {
+ if (compareSectionName(section, ".text"))
+ {
+ auto text = cast(void*)handle + section.VirtualAddress;
+ pdso._codeSegments.insertBack(text[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+ }
+ }
+}
+
+/**************************
+ * Input:
+ * handle where the output is to be written
+ * Returns:
+ * true if found, and *handle is filled in
+ */
+
+bool findModuleHandleForAddr(in void* addr, out HMODULE handle) nothrow @nogc
+{
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ cast(const(wchar)*) addr, &handle))
+ return true;
+
+ return false;
+}
+
+/**
+ * Returns the image NT header for the HMODULE handle passed,
+ * or null if not found.
+ */
+PIMAGE_NT_HEADERS getNTHeader(in HMODULE handle) nothrow @nogc
+{
+ auto doshdr = cast(PIMAGE_DOS_HEADER)handle;
+ if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
+ return null;
+
+ return cast(typeof(return))(cast(void*)doshdr + doshdr.e_lfanew);
+}
+
+/**
+ * Returns the image section header for the HMODULE handle passed,
+ * or null if not found.
+ */
+IMAGE_SECTION_HEADER[] getSectionHeader(in HMODULE handle) nothrow @nogc
+{
+ if (auto nthdr = getNTHeader(handle))
+ {
+ const void* opthdr = &nthdr.OptionalHeader;
+ const offset = nthdr.FileHeader.SizeOfOptionalHeader;
+ const length = nthdr.FileHeader.NumberOfSections;
+ return (cast(PIMAGE_SECTION_HEADER)(opthdr + offset))[0 .. length];
+ }
+ return null;
+}
diff --git a/libphobos/libdruntime/gcc/sections/win32.d b/libphobos/libdruntime/gcc/sections/win32.d
deleted file mode 100644
index b355dfc5068..00000000000
--- a/libphobos/libdruntime/gcc/sections/win32.d
+++ /dev/null
@@ -1,183 +0,0 @@
-// Win32-specific support for sections.
-// Copyright (C) 2019-2021 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):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import rt.minfo;
-import core.stdc.stdlib : malloc, free;
-
-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 inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][] _gcRanges;
-}
-
-shared(bool) conservative;
-
-void initSections() nothrow @nogc
-{
- _sections._moduleGroup = ModuleGroup(getModuleInfos());
-
- import rt.sections;
- conservative = !scanDataSegPrecisely();
-
- if (conservative)
- {
- _sections._gcRanges = (cast(void[]*) malloc(2 * (void[]).sizeof))[0..2];
-
- auto databeg = cast(void*)&_xi_a;
- auto dataend = cast(void*)_moduleinfo_array.ptr;
- _sections._gcRanges[0] = databeg[0 .. dataend - databeg];
-
- // skip module info and CONST segment
- auto bssbeg = cast(void*)&_edata;
- auto bssend = cast(void*)&_end;
- _sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];
- }
- else
- {
- size_t count = &_DPend - &_DPbegin;
- auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);
- size_t r = 0;
- void* prev = null;
- for (size_t i = 0; i < count; i++)
- {
- void* addr = (&_DPbegin)[i];
- if (prev + (void*).sizeof == addr)
- ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];
- else
- ranges[r++] = (cast(void**)addr)[0..1];
- prev = addr;
- }
- _sections._gcRanges = ranges[0..r];
- }
-}
-
-void finiSections() nothrow @nogc
-{
- free(_sections._gcRanges.ptr);
-}
-
-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
-{
- if (conservative)
- {
- dg(rng.ptr, rng.ptr + rng.length);
- }
- else
- {
- for (auto p = &_TPbegin; p < &_TPend; )
- {
- uint beg = *p++;
- uint end = beg + cast(uint)((void*).sizeof);
- while (p < &_TPend && *p == end)
- {
- end += (void*).sizeof;
- p++;
- }
- dg(rng.ptr + beg, rng.ptr + end);
- }
- }
-}
-
-private:
-
-__gshared SectionGroup _sections;
-
-// Windows: this gets initialized by minit.asm
-extern(C) __gshared immutable(ModuleInfo*)[] _moduleinfo_array;
-extern(C) void _minit() nothrow @nogc;
-
-immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
-out (result)
-{
- foreach (m; result)
- assert(m !is null);
-}
-body
-{
- // _minit directly alters the global _moduleinfo_array
- _minit();
- return _moduleinfo_array;
-}
-
-extern(C)
-{
- extern __gshared
- {
- int _xi_a; // &_xi_a just happens to be start of data segment
- int _edata; // &_edata is start of BSS segment
- int _end; // &_end is past end of BSS
-
- void* _DPbegin; // first entry in the array of pointers addresses
- void* _DPend; // &_DPend points after last entry of array
- uint _TPbegin; // first entry in the array of TLS offsets of pointers
- uint _TPend; // &_DPend points after last entry of array
- }
-
- extern
- {
- int _tlsstart;
- int _tlsend;
- }
-}
diff --git a/libphobos/libdruntime/gcc/sections/win64.d b/libphobos/libdruntime/gcc/sections/win64.d
index 357940ba821..512693c071d 100644
--- a/libphobos/libdruntime/gcc/sections/win64.d
+++ b/libphobos/libdruntime/gcc/sections/win64.d
@@ -51,14 +51,6 @@ struct SectionGroup
return _moduleGroup;
}
- version (Win64)
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;
- auto pend = cast(immutable(FuncTable)*)&_deh_end;
- return pbeg[0 .. pend - pbeg];
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d
index 5315739f82f..592b3afcb71 100644
--- a/libphobos/libdruntime/gcc/unwind/generic.d
+++ b/libphobos/libdruntime/gcc/unwind/generic.d
@@ -269,6 +269,6 @@ version (GNU_SEH_Exceptions)
ExceptionCollidedUnwind
}
- extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,
+ extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*, void*,
_Unwind_Personality_Fn);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 3d5ba299863..e4a2c6571d4 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -70,70 +70,6 @@ version (CRuntime_Microsoft)
extern(C) void init_msvc();
}
-/***********************************
- * These are a temporary means of providing a GC hook for DLL use. They may be
- * replaced with some other similar functionality later.
- */
-extern (C)
-{
- void* gc_getProxy();
- void gc_setProxy(void* p);
- void gc_clrProxy();
-
- alias void* function() gcGetFn;
- alias void function(void*) gcSetFn;
- alias void function() gcClrFn;
-}
-
-version (Windows)
-{
- /*******************************************
- * Loads a DLL written in D with the name 'name'.
- * Returns:
- * opaque handle to the DLL if successfully loaded
- * null if failure
- */
- extern (C) void* rt_loadLibrary(const char* name)
- {
- return initLibrary(.LoadLibraryA(name));
- }
-
- extern (C) void* rt_loadLibraryW(const wchar_t* name)
- {
- return initLibrary(.LoadLibraryW(name));
- }
-
- void* initLibrary(void* mod)
- {
- // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
- // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
- if (mod is null)
- return mod;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, "gc_setProxy");
- if (gcSet !is null)
- { // BUG: Set proxy, but too late
- gcSet(gc_getProxy());
- }
- return mod;
- }
-
- /*************************************
- * Unloads DLL that was previously loaded by rt_loadLibrary().
- * Input:
- * ptr the handle returned by rt_loadLibrary()
- * Returns:
- * 1 succeeded
- * 0 some failure happened
- */
- extern (C) int rt_unloadLibrary(void* ptr)
- {
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
- if (gcClr !is null)
- gcClr();
- return FreeLibrary(ptr) != 0;
- }
-}
-
/* To get out-of-band access to the args[] passed to main().
*/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gcc(refs/users/ibuclaw/heads/mingw)] More MSVC support
@ 2021-03-24 16:10 Iain Buclaw
0 siblings, 0 replies; 5+ messages in thread
From: Iain Buclaw @ 2021-03-24 16:10 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:c8979afc92dfcdb4650900192a455d14618392df
commit c8979afc92dfcdb4650900192a455d14618392df
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Wed Mar 24 16:24:04 2021 +0100
More MSVC support
Diff:
---
gcc/config/aarch64/aarch64-d.c | 2 +
gcc/config/arm/arm-d.c | 2 +
gcc/config/i386/cygming.h | 2 +
gcc/config/i386/i386-d.c | 13 +
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/i386/winnt-d.c | 7 +
gcc/config/mips/mips-d.c | 2 +
gcc/config/pa/pa-d.c | 2 +
gcc/config/riscv/riscv-d.c | 2 +
gcc/config/rs6000/rs6000-d.c | 2 +
gcc/config/s390/s390-d.c | 2 +
gcc/config/sparc/sparc-d.c | 2 +
gcc/d/d-target.cc | 5 +-
gcc/d/d-target.def | 10 +
gcc/doc/tm.texi | 7 +
gcc/doc/tm.texi.in | 2 +
libphobos/Makefile.in | 3 +
libphobos/configure | 24 +-
libphobos/configure.ac | 17 +-
libphobos/libdruntime/Makefile.am | 7 +-
libphobos/libdruntime/Makefile.in | 68 +-
libphobos/libdruntime/config/mingw/msvc.c | 54 ++
libphobos/libdruntime/config/mingw/switchcontext.S | 12 +-
libphobos/libdruntime/core/stdc/stdlib.d | 27 +-
libphobos/libdruntime/core/stdc/tgmath.d | 11 +-
libphobos/libdruntime/core/sys/windows/com.d | 4 +-
libphobos/libdruntime/core/sys/windows/dbghelp.d | 2 +-
libphobos/libdruntime/core/sys/windows/dll.d | 12 +-
libphobos/libdruntime/core/thread/osthread.d | 4 +-
libphobos/libdruntime/gcc/deh.d | 2 +-
libphobos/libdruntime/gcc/gthread.d | 6 +-
libphobos/libdruntime/gcc/sections/package.d | 28 +-
libphobos/libdruntime/gcc/sections/pecoff.d | 830 +++++++++++++++++++++
libphobos/libdruntime/gcc/sections/win32.d | 183 -----
libphobos/libdruntime/gcc/sections/win64.d | 8 -
libphobos/libdruntime/gcc/unwind/generic.d | 2 +-
libphobos/libdruntime/rt/dmain2.d | 64 --
libphobos/src/Makefile.am | 2 +-
libphobos/src/Makefile.in | 5 +-
libphobos/testsuite/Makefile.in | 3 +
41 files changed, 1085 insertions(+), 359 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..4fce593ac27 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..2cb9f4bd899 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index cfbca34f996..59eb812c1cf 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -209,6 +209,8 @@ along with GCC; see the file COPYING3. If not see
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
flag_pic = TARGET_64BIT ? 1 : 0; \
+ if (!global_options_set.x_dwarf_version) \
+ dwarf_version = 4; \
} while (0)
/* Define this macro if references to a symbol must be treated
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..34f53ba046d 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -42,3 +44,14 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Implement TARGET_D_EXTERN_SYSTEM_LINKAGE for x86 targets. */
+
+int
+ix86_d_extern_system_linkage (void)
+{
+ if (ix86_abi == MS_ABI)
+ return LINKwindows;
+
+ return LINKc;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..d07bf09bc65 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern int ix86_d_extern_system_linkage (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 058c1cc25b2..10954fb0aab 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_EXTERN_SYSTEM_LINKAGE ix86_d_extern_system_linkage
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index 3b5791a7bff..d05ea8a92bf 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -30,6 +32,11 @@ winnt_d_os_builtins (void)
{
d_add_builtin_version ("Windows");
+ if (ix86_abi == SYSV_ABI)
+ d_add_builtin_version ("SYSV_ABI");
+ else
+ d_add_builtin_version ("MS_ABI");
+
#define builtin_version(TXT) d_add_builtin_version (TXT)
#ifdef EXTRA_TARGET_D_OS_VERSIONS
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..dc57127791c 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..663e749995a 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..b20b778bd35 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..6bfe8130dd3 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..2f945ebfa12 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..0eb663bb132 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..e95dd01b0ee 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -417,11 +417,14 @@ TargetCPP::fundamentalType (const Type *, bool &)
return false;
}
-/* Return the default system linkage for the target. */
+/* Return the default `extern (System)` linkage for the target. */
LINK
Target::systemLinkage (void)
{
+ if (targetdm.d_extern_system_linkage)
+ return (LINK) targetdm.d_extern_system_linkage ();
+
return LINKc;
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..9fb3c7d23d9 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,16 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* */
+DEFHOOK
+(d_extern_system_linkage,
+ "If defined, this hook returns the extern linkage which should be applied\n\
+ for all declarations annotated with @code{extern (System)}. Typically,\n\
+ @code{extern (System)} is the same as @code{extern (Windows)} on Microsoft\n\
+ Windows platforms, and @code{extern (C)} on other platforms.",
+ int, (void),
+ NULL)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..0265ef0df5c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,13 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} int TARGET_D_EXTERN_SYSTEM_LINKAGE (void)
+If defined, this hook returns the extern linkage which should be applied
+ for all declarations annotated with @code{extern (System)}. Typically,
+ @code{extern (System)} is the same as @code{extern (Windows)} on Microsoft
+ Windows platforms, and @code{extern (C)} on other platforms.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..ef15417a791 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,8 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_EXTERN_SYSTEM_LINKAGE
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index d42248405a2..eab12688867 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -298,6 +298,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -327,6 +329,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..59ca64aa1e0 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -705,6 +705,9 @@ libphobos_builddir
get_gcc_base_ver
phobos_compiler_shared_flag
phobos_compiler_pic_flag
+phobos_lt_pic_flag
+enable_static
+enable_shared
OTOOL64
OTOOL
LIPO
@@ -11746,7 +11749,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11749 "configure"
+#line 11752 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11852,7 +11855,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11855 "configure"
+#line 11858 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13997,8 +14000,14 @@ CFLAGS=$lt_save_CFLAGS
GDCFLAGS=$gdc_save_DFLAGS
+
+
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -14010,26 +14019,23 @@ CFLAGS=$lt_save_CFLAGS
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index cc9af29754f..248d0ebbc19 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -91,9 +91,15 @@ AC_SUBST(CFLAGS_FOR_BUILD)
LT_INIT(dlopen)
AM_PROG_LIBTOOL
WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -105,26 +111,23 @@ WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+AC_SUBST(phobos_lt_pic_flag)
AC_SUBST(phobos_compiler_pic_flag)
AC_SUBST(phobos_compiler_shared_flag)
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 945271e028f..bedd7a325ec 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -23,7 +23,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
@@ -69,7 +69,8 @@ if DRUNTIME_OS_LINUX
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
endif
if DRUNTIME_OS_MINGW
- DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
+ DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS) \
+ config/mingw/msvc.c
endif
if DRUNTIME_OS_SOLARIS
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
@@ -187,7 +188,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/backtrace.d \
gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 06c02961c86..665af30e09d 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -117,7 +117,9 @@ target_triplet = @target@
@DRUNTIME_OS_NETBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_NETBSD)
@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)
@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)
-@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)
+@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/msvc.c
+
@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)
# CPU specific sources
@DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S
@@ -213,7 +215,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
gcc/builtins.lo gcc/deh.lo gcc/emutls.lo gcc/gthread.lo \
gcc/sections/android.lo gcc/sections/elf_shared.lo \
gcc/sections/osx.lo gcc/sections/package.lo \
- gcc/sections/win32.lo gcc/sections/win64.lo gcc/unwind/arm.lo \
+ gcc/sections/pecoff.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 \
@@ -425,7 +427,8 @@ am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/winspool.lo core/sys/windows/winsvc.lo \
core/sys/windows/winuser.lo core/sys/windows/winver.lo \
core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19)
+@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \
core/sys/solaris/libelf.lo core/sys/solaris/link.lo \
@@ -460,24 +463,26 @@ am_libgdruntime_la_OBJECTS = $(am__objects_33)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__objects_34 = core/stdc/libgdruntime_convenience_la-errno_.lo
-@DRUNTIME_CPU_AARCH64_TRUE@am__objects_35 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_ARM_TRUE@am__objects_36 = config/arm/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_MIPS_TRUE@am__objects_37 = config/mips/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_38 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_39 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_40 = config/x86/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_41 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
-@DRUNTIME_CPU_S390_TRUE@am__objects_42 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
-am__objects_43 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_35 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_36 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_37 = config/arm/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_38 = config/mips/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_39 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_40 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_41 = config/x86/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_42 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
+@DRUNTIME_CPU_S390_TRUE@am__objects_43 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
+am__objects_44 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
$(am__objects_10) $(am__objects_12) $(am__objects_14) \
- $(am__objects_16) $(am__objects_18) $(am__objects_20) \
- $(am__objects_22) $(am__objects_35) $(am__objects_36) \
- $(am__objects_37) $(am__objects_38) $(am__objects_39) \
- $(am__objects_40) $(am__objects_41) $(am__objects_42)
-am__objects_44 = $(am__objects_1) $(am__objects_34) $(am__objects_43) \
+ $(am__objects_16) $(am__objects_18) $(am__objects_35) \
+ $(am__objects_22) $(am__objects_36) $(am__objects_37) \
+ $(am__objects_38) $(am__objects_39) $(am__objects_40) \
+ $(am__objects_41) $(am__objects_42) $(am__objects_43)
+am__objects_45 = $(am__objects_1) $(am__objects_34) $(am__objects_44) \
$(am__objects_32)
-am__objects_45 = $(am__objects_44)
-am_libgdruntime_convenience_la_OBJECTS = $(am__objects_45)
+am__objects_46 = $(am__objects_45)
+am_libgdruntime_convenience_la_OBJECTS = $(am__objects_46)
libgdruntime_convenience_la_OBJECTS = \
$(am_libgdruntime_convenience_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
@@ -659,6 +664,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -688,6 +695,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -720,7 +728,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
@@ -813,7 +821,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/backtrace.d \
gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
@@ -1213,8 +1221,7 @@ 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/win32.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/win64.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/pecoff.lo: gcc/sections/$(am__dirstamp)
gcc/unwind/$(am__dirstamp):
@$(MKDIR_P) gcc/unwind
@: > gcc/unwind/$(am__dirstamp)
@@ -1720,6 +1727,10 @@ core/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+ @$(MKDIR_P) config/mingw
+ @: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/$(am__dirstamp)
core/sys/solaris/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris
@: > core/sys/solaris/$(am__dirstamp)
@@ -1769,9 +1780,6 @@ config/powerpc/$(am__dirstamp):
@: > config/powerpc/$(am__dirstamp)
config/powerpc/libgdruntime_la-switchcontext.lo: \
config/powerpc/$(am__dirstamp)
-config/mingw/$(am__dirstamp):
- @$(MKDIR_P) config/mingw
- @: > config/mingw/$(am__dirstamp)
config/mingw/libgdruntime_la-switchcontext.lo: \
config/mingw/$(am__dirstamp)
config/x86/$(am__dirstamp):
@@ -1796,6 +1804,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+config/mingw/libgdruntime_convenience_la-msvc.lo: \
+ config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
config/aarch64/$(am__dirstamp)
config/arm/libgdruntime_convenience_la-switchcontext.lo: \
@@ -1991,9 +2001,15 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
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
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.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 config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/libphobos/libdruntime/config/mingw/msvc.c b/libphobos/libdruntime/config/mingw/msvc.c
new file mode 100644
index 00000000000..25b15a06950
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/msvc.c
@@ -0,0 +1,54 @@
+/* Windows support code to wrap differences between different
+ versions of the Microsoft C libaries.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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/>. */
+
+#include <stdio.h>
+
+/* The symbols for stdin, stdout, and stderr are defined for D in the
+ core.stdc.stdio module. Save the macros and redeclare them here. */
+#define c_stdin stdin
+#undef stdin
+extern FILE *stdin;
+
+#define c_stdout stdout
+#undef stdout
+extern FILE *stdout;
+
+#define c_stderr stderr
+#undef stderr
+extern FILE *stderr;
+
+/* Set to 1 if run-time is using ucrtbase.dll. */
+unsigned char msvcUsesUCRT;
+
+void init_msvc()
+{
+#if __MSVCRT_VERSION__ >= 0x1400
+ msvcUsedUCRT = 1;
+#endif
+
+ stdin = c_stdin;
+ stdout = c_stdout;
+ stderr = c_stderr;
+}
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
index 6592ff604bc..0cb8b015bfc 100644
--- a/libphobos/libdruntime/config/mingw/switchcontext.S
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -63,13 +66,15 @@ CSYM(fiber_switchContext):
popq %RCX;
jmp *%RCX;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#elif defined(_X86_)
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -104,6 +109,5 @@ CSYM(fiber_switchContext):
// 'return' to complete switch
ret;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#endif
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 7caef4c1339..b048a944a88 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
version (CRuntime_Microsoft)
{
- // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
- ///
- extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
- { // Fake it 'till we make it
- return strtod(nptr, endptr);
+ version (MinGW)
+ {
+ ///
+ real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+ ///
+ alias __mingw_strtold strtold;
+ }
+ else
+ {
+ // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+ ///
+ extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+ { // Fake it 'till we make it
+ return strtod(nptr, endptr);
+ }
}
-}
-else version (MinGW)
-{
- ///
- real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
- ///
- alias __mingw_strtold strtold;
}
else
{
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 4dd1b3ccc66..9a351db3861 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1409,13 +1409,20 @@ else
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
///
- alias core.stdc.math.fabsf fabs;
+ alias core.stdc.math.fabsf fabs;
///
- alias core.stdc.math.fabsl fabs;
+ alias core.stdc.math.fabsl fabs;
}
///
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 90a294343fc..2808a6c59fc 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
public import core.sys.windows.uuid;
-extern (System)
+extern (Windows)
{
class ComObject : IUnknown
{
-extern (System):
+extern (Windows):
HRESULT QueryInterface(const(IID)* riid, void** ppv)
{
if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
public import core.sys.windows.dbghelp_types;
-extern(System)
+extern(Windows)
{
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 9f36ac389a6..3df0d7fd41b 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -31,17 +31,7 @@ public import core.sys.windows.threadaux;
// not access tls_array[tls_index] as needed for thread local _tlsstart and _tlsend
extern (C)
{
- version (MinGW)
- {
- extern __gshared void* _tls_start;
- extern __gshared void* _tls_end;
- extern __gshared void* __xl_a;
-
- alias _tls_start _tlsstart;
- alias _tls_end _tlsend;
- alias __xl_a _tls_callbacks_a;
- }
- else version (Win32)
+ version (Win32)
{
version (CRuntime_DigitalMars)
{
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index defdc9586f1..638eada3e43 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -1539,9 +1539,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
void *bottom;
version (X86)
- asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
else version (X86_64)
- asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
else
static assert(false, "Platform not supported.");
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index c747b5132d1..7e02dabd221 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -805,7 +805,7 @@ version (GNU_SEH_Exceptions)
void* ms_orig_context, void* ms_disp)
{
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
- ms_disp, &__gdc_personality_imp);
+ ms_disp, &gdc_personality);
}
}
else version (GNU_SjLj_Exceptions)
diff --git a/libphobos/libdruntime/gcc/gthread.d b/libphobos/libdruntime/gcc/gthread.d
index ef35a3c27ec..5003637b9ea 100644
--- a/libphobos/libdruntime/gcc/gthread.d
+++ b/libphobos/libdruntime/gcc/gthread.d
@@ -86,10 +86,12 @@ else static if (GNU_Thread_Model == ThreadModel.Single)
}
else static if (GNU_Thread_Model == ThreadModel.Win32)
{
+ import core.stdc.config;
+
struct __gthread_once_t
{
- INT done;
- LONG started;
+ int done;
+ c_long started;
}
int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor);
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
index fdaf039fcfa..5d76072af25 100644
--- a/libphobos/libdruntime/gcc/sections/package.d
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -22,26 +22,20 @@
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)
+version (CRuntime_Glibc) version = ElfShared;
+version (CRuntime_Musl) version = ElfShared;
+version (CRuntime_UClibc) version = ElfShared;
+version (FreeBSD) version = ElfShared;
+version (NetBSD) version = ElfShared;
+version (DragonFlyBSD) version = ElfShared;
+version (Solaris) version = ElfShared;
+
+version (ElfShared)
public import gcc.sections.elf_shared;
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 (Windows)
+ public import gcc.sections.pecoff;
else version (CRuntime_Bionic)
public import gcc.sections.android;
else
diff --git a/libphobos/libdruntime/gcc/sections/pecoff.d b/libphobos/libdruntime/gcc/sections/pecoff.d
new file mode 100644
index 00000000000..5fa1df2ac54
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/pecoff.d
@@ -0,0 +1,830 @@
+// PE/COFF-specific support for sections.
+// Copyright (C) 2021 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.pecoff;
+
+version (Windows):
+
+import core.memory;
+import core.stdc.stdlib;
+import core.sys.windows.winbase;
+import core.sys.windows.windef;
+import core.sys.windows.winnt;
+import rt.minfo;
+import rt.util.container.array;
+import rt.util.container.hashtab;
+
+version (GNU_EMUTLS)
+ import gcc.emutls;
+
+/****
+ * 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.).
+ */
+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
+{
+ static int opApply(scope int delegate(ref DSO) dg)
+ {
+ foreach (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ static int opApplyReverse(scope int delegate(ref DSO) dg)
+ {
+ foreach_reverse (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
+ {
+ return _moduleGroup.modules;
+ }
+
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
+ {
+ return _moduleGroup;
+ }
+
+ @property inout(void[])[] gcRanges() inout nothrow @nogc
+ {
+ return _gcRanges[];
+ }
+
+private:
+
+ invariant()
+ {
+ safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+ }
+
+ void** _slot;
+ ModuleGroup _moduleGroup;
+ Array!(void[]) _gcRanges;
+
+ version (Shared)
+ {
+ Array!(void[]) _codeSegments; // array of code segments
+ Array!(DSO*) _deps; // D libraries needed by this DSO
+ void* _handle; // corresponding handle
+ }
+}
+
+/****
+ * Boolean flag set to true while the runtime is initialized.
+ */
+__gshared bool _isRuntimeInitialized;
+
+/****
+ * Gets called on program startup just before GC is initialized.
+ */
+void initSections() nothrow @nogc
+{
+ _isRuntimeInitialized = true;
+}
+
+/***
+ * Gets called on program shutdown just after GC is terminated.
+ */
+void finiSections() nothrow @nogc
+{
+ _isRuntimeInitialized = false;
+}
+
+alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
+
+version (Shared)
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
+ {
+ return &_loadedDSOs();
+ }
+
+ void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
+ {
+ // Nothing to do here. tdsos used to point to the _loadedDSOs instance
+ // in the dying thread's TLS segment and as such is not valid anymore.
+ // The memory for the array contents was already reclaimed in
+ // cleanupLoadedLibraries().
+ }
+
+ void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+
+ // interface for core.thread to inherit loaded libraries
+ void* pinLoadedLibraries() nothrow @nogc
+ {
+ auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
+ res.length = _loadedDSOs.length;
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ (*res)[i] = tdso;
+ if (tdso._addCnt)
+ {
+ // Increment the DLL ref for explicitly loaded libraries to pin them.
+ char[MAX_PATH] buf;
+ char[] buffer = buf[];
+ const success = .LoadLibraryA(nameForDSO(tdso._pdso, buffer)) !is null;
+ safeAssert(success, "Failed to increment DLL ref.");
+ (*res)[i]._addCnt = 1; // new array takes over the additional ref count
+ }
+ }
+ return res;
+ }
+
+ void unpinLoadedLibraries(void* p) nothrow @nogc
+ {
+ auto pary = cast(Array!(ThreadDSO)*)p;
+ // In case something failed we need to undo the pinning.
+ foreach (ref tdso; *pary)
+ {
+ if (tdso._addCnt)
+ {
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid library handle.");
+ .FreeLibrary(handle);
+ }
+ }
+ pary.reset();
+ .free(pary);
+ }
+
+ // Called before TLS ctors are ran, copy over the loaded libraries
+ // of the parent thread.
+ void inheritLoadedLibraries(void* p) nothrow @nogc
+ {
+ safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
+ _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
+ .free(p);
+ }
+
+ // Called after all TLS dtors ran, decrements all remaining DLL refs.
+ void cleanupLoadedLibraries() nothrow @nogc
+ {
+ foreach (ref tdso; _loadedDSOs)
+ {
+ if (tdso._addCnt == 0) continue;
+
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid DSO handle.");
+ for (; tdso._addCnt > 0; --tdso._addCnt)
+ .FreeLibrary(handle);
+ }
+
+ // Free the memory for the array contents.
+ _loadedDSOs.reset();
+ }
+}
+else
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(void[])* initTLSRanges() nothrow @nogc
+ {
+ return null;
+ }
+
+ void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
+ {
+ }
+
+ void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+}
+
+private:
+
+version (Shared)
+{
+ /*
+ * Array of thread local DSO metadata for all libraries loaded and
+ * initialized in this thread.
+ *
+ * Note:
+ * A newly spawned thread will inherit these libraries.
+ * Note:
+ * We use an array here to preserve the order of
+ * initialization. If that became a performance issue, we
+ * could use a hash table and enumerate the DSOs during
+ * loading so that the hash table values could be sorted when
+ * necessary.
+ */
+ struct ThreadDSO
+ {
+ DSO* _pdso;
+ static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;
+ else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;
+ else static assert(0, "unimplemented");
+ alias _pdso this;
+ }
+
+ @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow
+ {
+ static Array!(ThreadDSO) x;
+ return x;
+ }
+
+ /*
+ * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
+ */
+ bool _rtLoading;
+
+ /*
+ * Hash table to map the native handle (as returned by dlopen)
+ * to the corresponding DSO*, protected by a mutex.
+ */
+ __gshared CRITICAL_SECTION _handleToDSOMutex;
+ @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow
+ {
+ __gshared HashTab!(void*, DSO*) x;
+ return x;
+ }
+}
+else
+{
+ /*
+ * Static DSOs loaded by the runtime linker. This includes the
+ * executable. These can't be unloaded.
+ */
+ @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow
+ {
+ __gshared Array!(DSO*) x;
+ return x;
+ }
+
+ enum _rtLoading = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Compiler to runtime interface.
+///////////////////////////////////////////////////////////////////////////////
+
+/****
+ * This data structure is generated by the compiler, and then passed to
+ * _d_dso_registry().
+ */
+struct CompilerDSOData
+{
+ size_t _version; // currently 1
+ void** _slot; // can be used to store runtime data
+ immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file
+}
+
+T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
+
+/* For each shared library and executable, the compiler generates code that
+ * sets up CompilerDSOData and calls _d_dso_registry().
+ * A pointer to that code is inserted into both the .ctors and .dtors
+ * segment so it gets called by the loader on startup and shutdown.
+ */
+extern(C) void _d_dso_registry(CompilerDSOData* data)
+{
+ // only one supported currently
+ safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
+
+ // no backlink => register
+ if (*data._slot is null)
+ {
+ immutable firstDSO = _loadedDSOs.empty;
+ if (firstDSO) initLocks();
+
+ DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);
+ assert(typeid(DSO).initializer().ptr is null);
+ pdso._slot = data._slot;
+ *data._slot = pdso; // store backlink in library record
+
+ pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
+
+ HMODULE handle = void;
+ const moduleFound = findModuleHandleForAddr(data._slot, handle);
+ safeAssert(moduleFound, "Failed to find image header.");
+
+ scanSegments(handle, pdso);
+
+ version (Shared)
+ {
+ getDependencies(handle, pdso._deps);
+ pdso._handle = handle;
+ setDSOForHandle(pdso, pdso._handle);
+
+ if (!_rtLoading)
+ {
+ /* This DSO was not loaded by rt_loadLibrary which
+ * happens for all dependencies of an executable or
+ * the first dlopen call from a C program.
+ * In this case we add the DSO to the _loadedDSOs of this
+ * thread with a refCnt of 1 and call the TlsCtors.
+ */
+ immutable ushort refCnt = 1, addCnt = 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ }
+ }
+ else
+ {
+ foreach (p; _loadedDSOs)
+ safeAssert(p !is pdso, "DSO already registered.");
+ _loadedDSOs.insertBack(pdso);
+ }
+
+ // don't initialize modules before rt_init was called
+ if (_isRuntimeInitialized)
+ {
+ registerGCRanges(pdso);
+ // rt_loadLibrary will run tls ctors, so do this only for dlopen
+ immutable runTlsCtors = !_rtLoading;
+ runModuleConstructors(pdso, runTlsCtors);
+ }
+ }
+ // has backlink => unregister
+ else
+ {
+ DSO* pdso = cast(DSO*)*data._slot;
+ *data._slot = null;
+
+ // don't finalizes modules after rt_term was called (see Bugzilla 11378)
+ if (_isRuntimeInitialized)
+ {
+ // rt_unloadLibrary already ran tls dtors, so do this only for dlclose
+ immutable runTlsDtors = !_rtLoading;
+ runModuleDestructors(pdso, runTlsDtors);
+ unregisterGCRanges(pdso);
+ // run finalizers after module dtors (same order as in rt_term)
+ version (Shared) runFinalizers(pdso);
+ }
+
+ version (Shared)
+ {
+ if (!_rtLoading)
+ {
+ /* This DSO was not unloaded by rt_unloadLibrary so we
+ * have to remove it from _loadedDSOs here.
+ */
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ if (tdso._pdso == pdso)
+ {
+ _loadedDSOs.remove(i);
+ break;
+ }
+ }
+ }
+
+ unsetDSOForHandle(pdso, pdso._handle);
+ }
+ else
+ {
+ // static DSOs are unloaded in reverse order
+ safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
+ _loadedDSOs.popBack();
+ }
+
+ freeDSO(pdso);
+
+ // last DSO being unloaded => shutdown registry
+ if (_loadedDSOs.empty)
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_destroy();
+ version (Shared)
+ {
+ safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+ _handleToDSO.reset();
+ }
+ finiLocks();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dynamic loading
+///////////////////////////////////////////////////////////////////////////////
+
+// Shared D libraries are only supported when linking against a shared druntime library.
+
+version (Shared)
+{
+ ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc
+ {
+ foreach (ref tdata; _loadedDSOs)
+ if (tdata._pdso == pdso) return &tdata;
+ return null;
+ }
+
+ void incThreadRef(DSO* pdso, bool incAdd)
+ {
+ if (auto tdata = findThreadDSO(pdso)) // already initialized
+ {
+ if (incAdd && ++tdata._addCnt > 1) return;
+ ++tdata._refCnt;
+ }
+ else
+ {
+ foreach (dep; pdso._deps)
+ incThreadRef(dep, false);
+ immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ pdso._moduleGroup.runTlsCtors();
+ }
+ }
+
+ void decThreadRef(DSO* pdso, bool decAdd)
+ {
+ auto tdata = findThreadDSO(pdso);
+ 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;
+
+ pdso._moduleGroup.runTlsDtors();
+ foreach (i, ref td; _loadedDSOs)
+ if (td._pdso == pdso) _loadedDSOs.remove(i);
+ foreach (dep; pdso._deps)
+ decThreadRef(dep, false);
+ }
+}
+
+/***********************************
+ * These are a temporary means of providing a GC hook for DLL use. They may be
+ * replaced with some other similar functionality later.
+ */
+extern (C)
+{
+ void* gc_getProxy();
+ void gc_setProxy(void* p);
+ void gc_clrProxy();
+
+ alias void function(void*) gcSetFn;
+ alias void function() gcClrFn;
+}
+
+/*******************************************
+ * Loads a DLL written in D with the name 'name'.
+ * Returns:
+ * opaque handle to the DLL if successfully loaded
+ * null if failure
+ */
+extern(C) void* rt_loadLibrary(const char* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryA(name));
+}
+
+extern (C) void* rt_loadLibraryW(const wchar_t* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryW(name));
+}
+
+void* initLibrary(void* handle)
+{
+ if (handle is null)
+ return null;
+
+ version (Shared)
+ {
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ incThreadRef(pdso, true);
+ }
+ gcSetFn gcSet = cast(gcSetFn) GetProcAddress(handle, "gc_setProxy");
+ if (gcSet !is null)
+ {
+ // BUG: Set proxy, but too late
+ gcSet(gc_getProxy());
+ }
+ return handle;
+}
+
+/*************************************
+ * Unloads DLL that was previously loaded by rt_loadLibrary().
+ * Input:
+ * handle the handle returned by rt_loadLibrary()
+ * Returns:
+ * 1 succeeded
+ * 0 some failure happened
+ */
+extern(C) int rt_unloadLibrary(void* handle)
+{
+ if (handle is null)
+ return false;
+
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ decThreadRef(pdso, true);
+ }
+ gcClrFn gcClr = cast(gcClrFn) GetProcAddress(handle, "gc_clrProxy");
+ if (gcClr !is null)
+ gcClr();
+ return .FreeLibrary(handle) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// helper functions
+///////////////////////////////////////////////////////////////////////////////
+
+void initLocks() nothrow @nogc
+{
+ version (Shared)
+ InitializeCriticalSection(&_handleToDSOMutex);
+}
+
+void finiLocks() nothrow @nogc
+{
+ version (Shared)
+ DeleteCriticalSection(&_handleToDSOMutex);
+}
+
+void runModuleConstructors(DSO* pdso, bool runTlsCtors)
+{
+ pdso._moduleGroup.sortCtors();
+ pdso._moduleGroup.runCtors();
+ if (runTlsCtors) pdso._moduleGroup.runTlsCtors();
+}
+
+void runModuleDestructors(DSO* pdso, bool runTlsDtors)
+{
+ if (runTlsDtors) pdso._moduleGroup.runTlsDtors();
+ pdso._moduleGroup.runDtors();
+}
+
+void registerGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.addRange(rng.ptr, rng.length);
+}
+
+void unregisterGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.removeRange(rng.ptr);
+}
+
+version (Shared) void runFinalizers(DSO* pdso)
+{
+ foreach (seg; pdso._codeSegments)
+ GC.runFinalizers(seg);
+}
+
+void freeDSO(DSO* pdso) nothrow @nogc
+{
+ pdso._gcRanges.reset();
+ version (Shared)
+ {
+ pdso._codeSegments.reset();
+ pdso._deps.reset();
+ pdso._handle = null;
+ }
+ .free(pdso);
+}
+
+version (Shared)
+{
+@nogc nothrow:
+ const(char)* nameForDSO(DSO* pdso, ref char[] buffer)
+ {
+ const success = GetModuleFileNameA(pdso._handle, buffer.ptr, cast(DWORD)buffer.length) != 0;
+ safeAssert(success, "Failed to get DLL name.");
+ return buffer.ptr;
+ }
+
+ DSO* dsoForHandle(in void* handle)
+ {
+ DSO* pdso;
+ .EnterCriticalSection(&_handleToDSOMutex);
+ if (auto ppdso = handle in _handleToDSO)
+ pdso = *ppdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ return pdso;
+ }
+
+ void setDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(handle !in _handleToDSO, "DSO already registered.");
+ _handleToDSO[handle] = pdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void unsetDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
+ _handleToDSO.remove(handle);
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void getDependencies(in HMODULE handle, ref Array!(DSO*) deps)
+ {
+ auto nthdr = getNTHeader(handle);
+ auto import_entry = nthdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ auto addr = import_entry.VirtualAddress;
+ auto datasize = import_entry.Size;
+
+ if (addr == 0 && datasize == 0)
+ {
+ // Maybe the optional header isn't there, look for the section.
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ addr = section.VirtualAddress;
+ datasize = section.Misc.VirtualSize;
+ break;
+ }
+ if (datasize == 0)
+ return;
+ }
+ else
+ {
+ bool foundSection = false;
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ // Section containing import table has no contents.
+ if (section.Misc.VirtualSize == 0)
+ return;
+ foundSection = true;
+ break;
+ }
+ // There is an import table, but the section containing it could not be found
+ if (!foundSection)
+ return;
+ }
+
+ // Get the names of each DLL
+ for (uint i = 0; i + IMAGE_IMPORT_DESCRIPTOR.sizeof <= datasize;
+ i += IMAGE_IMPORT_DESCRIPTOR.sizeof)
+ {
+ const data = cast(PIMAGE_IMPORT_DESCRIPTOR)(handle + addr + i);
+ if (data.Name == 0)
+ break;
+
+ // dll name of dependency
+ auto name = cast(char*)(handle + data.Name);
+ // get handle without loading the library
+ auto libhandle = handleForName(name);
+ // the runtime linker has already loaded all dependencies
+ 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)
+ {
+ return GetModuleHandleA(name);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PE/COFF program header iteration
+///////////////////////////////////////////////////////////////////////////////
+
+bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
+{
+ if (name[] != cast(char[])section.Name[0 .. name.length])
+ return false;
+ return name.length == 8 || section.Name[name.length] == 0;
+}
+
+/************
+ * Scan segments in the image header and store
+ * the writeable data segments in *pdso.
+ */
+
+void scanSegments(in HMODULE handle, DSO* pdso) nothrow @nogc
+{
+ foreach (section; getSectionHeader(handle))
+ {
+ // the ".data" image section includes both object file sections ".data" and ".bss"
+ if (compareSectionName(section, ".data"))
+ {
+ auto data = cast(void*)handle + section.VirtualAddress;
+ pdso._gcRanges.insertBack(data[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+
+ version (Shared)
+ {
+ if (compareSectionName(section, ".text"))
+ {
+ auto text = cast(void*)handle + section.VirtualAddress;
+ pdso._codeSegments.insertBack(text[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+ }
+ }
+}
+
+/**************************
+ * Input:
+ * handle where the output is to be written
+ * Returns:
+ * true if found, and *handle is filled in
+ */
+
+bool findModuleHandleForAddr(in void* addr, out HMODULE handle) nothrow @nogc
+{
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ cast(const(wchar)*) addr, &handle))
+ return true;
+
+ return false;
+}
+
+/**
+ * Returns the image NT header for the HMODULE handle passed,
+ * or null if not found.
+ */
+PIMAGE_NT_HEADERS getNTHeader(in HMODULE handle) nothrow @nogc
+{
+ auto doshdr = cast(PIMAGE_DOS_HEADER)handle;
+ if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
+ return null;
+
+ return cast(typeof(return))(cast(void*)doshdr + doshdr.e_lfanew);
+}
+
+/**
+ * Returns the image section header for the HMODULE handle passed,
+ * or null if not found.
+ */
+IMAGE_SECTION_HEADER[] getSectionHeader(in HMODULE handle) nothrow @nogc
+{
+ if (auto nthdr = getNTHeader(handle))
+ {
+ const void* opthdr = &nthdr.OptionalHeader;
+ const offset = nthdr.FileHeader.SizeOfOptionalHeader;
+ const length = nthdr.FileHeader.NumberOfSections;
+ return (cast(PIMAGE_SECTION_HEADER)(opthdr + offset))[0 .. length];
+ }
+ return null;
+}
diff --git a/libphobos/libdruntime/gcc/sections/win32.d b/libphobos/libdruntime/gcc/sections/win32.d
deleted file mode 100644
index b355dfc5068..00000000000
--- a/libphobos/libdruntime/gcc/sections/win32.d
+++ /dev/null
@@ -1,183 +0,0 @@
-// Win32-specific support for sections.
-// Copyright (C) 2019-2021 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):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import rt.minfo;
-import core.stdc.stdlib : malloc, free;
-
-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 inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][] _gcRanges;
-}
-
-shared(bool) conservative;
-
-void initSections() nothrow @nogc
-{
- _sections._moduleGroup = ModuleGroup(getModuleInfos());
-
- import rt.sections;
- conservative = !scanDataSegPrecisely();
-
- if (conservative)
- {
- _sections._gcRanges = (cast(void[]*) malloc(2 * (void[]).sizeof))[0..2];
-
- auto databeg = cast(void*)&_xi_a;
- auto dataend = cast(void*)_moduleinfo_array.ptr;
- _sections._gcRanges[0] = databeg[0 .. dataend - databeg];
-
- // skip module info and CONST segment
- auto bssbeg = cast(void*)&_edata;
- auto bssend = cast(void*)&_end;
- _sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];
- }
- else
- {
- size_t count = &_DPend - &_DPbegin;
- auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);
- size_t r = 0;
- void* prev = null;
- for (size_t i = 0; i < count; i++)
- {
- void* addr = (&_DPbegin)[i];
- if (prev + (void*).sizeof == addr)
- ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];
- else
- ranges[r++] = (cast(void**)addr)[0..1];
- prev = addr;
- }
- _sections._gcRanges = ranges[0..r];
- }
-}
-
-void finiSections() nothrow @nogc
-{
- free(_sections._gcRanges.ptr);
-}
-
-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
-{
- if (conservative)
- {
- dg(rng.ptr, rng.ptr + rng.length);
- }
- else
- {
- for (auto p = &_TPbegin; p < &_TPend; )
- {
- uint beg = *p++;
- uint end = beg + cast(uint)((void*).sizeof);
- while (p < &_TPend && *p == end)
- {
- end += (void*).sizeof;
- p++;
- }
- dg(rng.ptr + beg, rng.ptr + end);
- }
- }
-}
-
-private:
-
-__gshared SectionGroup _sections;
-
-// Windows: this gets initialized by minit.asm
-extern(C) __gshared immutable(ModuleInfo*)[] _moduleinfo_array;
-extern(C) void _minit() nothrow @nogc;
-
-immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
-out (result)
-{
- foreach (m; result)
- assert(m !is null);
-}
-body
-{
- // _minit directly alters the global _moduleinfo_array
- _minit();
- return _moduleinfo_array;
-}
-
-extern(C)
-{
- extern __gshared
- {
- int _xi_a; // &_xi_a just happens to be start of data segment
- int _edata; // &_edata is start of BSS segment
- int _end; // &_end is past end of BSS
-
- void* _DPbegin; // first entry in the array of pointers addresses
- void* _DPend; // &_DPend points after last entry of array
- uint _TPbegin; // first entry in the array of TLS offsets of pointers
- uint _TPend; // &_DPend points after last entry of array
- }
-
- extern
- {
- int _tlsstart;
- int _tlsend;
- }
-}
diff --git a/libphobos/libdruntime/gcc/sections/win64.d b/libphobos/libdruntime/gcc/sections/win64.d
index 357940ba821..512693c071d 100644
--- a/libphobos/libdruntime/gcc/sections/win64.d
+++ b/libphobos/libdruntime/gcc/sections/win64.d
@@ -51,14 +51,6 @@ struct SectionGroup
return _moduleGroup;
}
- version (Win64)
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;
- auto pend = cast(immutable(FuncTable)*)&_deh_end;
- return pbeg[0 .. pend - pbeg];
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d
index 5315739f82f..592b3afcb71 100644
--- a/libphobos/libdruntime/gcc/unwind/generic.d
+++ b/libphobos/libdruntime/gcc/unwind/generic.d
@@ -269,6 +269,6 @@ version (GNU_SEH_Exceptions)
ExceptionCollidedUnwind
}
- extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,
+ extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*, void*,
_Unwind_Personality_Fn);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 3d5ba299863..e4a2c6571d4 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -70,70 +70,6 @@ version (CRuntime_Microsoft)
extern(C) void init_msvc();
}
-/***********************************
- * These are a temporary means of providing a GC hook for DLL use. They may be
- * replaced with some other similar functionality later.
- */
-extern (C)
-{
- void* gc_getProxy();
- void gc_setProxy(void* p);
- void gc_clrProxy();
-
- alias void* function() gcGetFn;
- alias void function(void*) gcSetFn;
- alias void function() gcClrFn;
-}
-
-version (Windows)
-{
- /*******************************************
- * Loads a DLL written in D with the name 'name'.
- * Returns:
- * opaque handle to the DLL if successfully loaded
- * null if failure
- */
- extern (C) void* rt_loadLibrary(const char* name)
- {
- return initLibrary(.LoadLibraryA(name));
- }
-
- extern (C) void* rt_loadLibraryW(const wchar_t* name)
- {
- return initLibrary(.LoadLibraryW(name));
- }
-
- void* initLibrary(void* mod)
- {
- // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
- // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
- if (mod is null)
- return mod;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, "gc_setProxy");
- if (gcSet !is null)
- { // BUG: Set proxy, but too late
- gcSet(gc_getProxy());
- }
- return mod;
- }
-
- /*************************************
- * Unloads DLL that was previously loaded by rt_loadLibrary().
- * Input:
- * ptr the handle returned by rt_loadLibrary()
- * Returns:
- * 1 succeeded
- * 0 some failure happened
- */
- extern (C) int rt_unloadLibrary(void* ptr)
- {
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
- if (gcClr !is null)
- gcClr();
- return FreeLibrary(ptr) != 0;
- }
-}
-
/* To get out-of-band access to the args[] passed to main().
*/
diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am
index 2de8ab951b4..0dc2a2625a9 100644
--- a/libphobos/src/Makefile.am
+++ b/libphobos/src/Makefile.am
@@ -24,7 +24,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 2e721783d06..33453517153 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -414,6 +414,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -443,6 +445,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -477,7 +480,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index c38a4688258..51eb4efc79d 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -242,6 +242,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -271,6 +273,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gcc(refs/users/ibuclaw/heads/mingw)] More MSVC support
@ 2021-03-24 16:06 Iain Buclaw
0 siblings, 0 replies; 5+ messages in thread
From: Iain Buclaw @ 2021-03-24 16:06 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:867af327bc497d39e3b26f19685ee7cf7a669d25
commit 867af327bc497d39e3b26f19685ee7cf7a669d25
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Wed Mar 24 16:24:04 2021 +0100
More MSVC support
Diff:
---
gcc/config/aarch64/aarch64-d.c | 2 +
gcc/config/arm/arm-d.c | 2 +
gcc/config/i386/cygming.h | 2 +
gcc/config/i386/i386-d.c | 13 +
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/i386/winnt-d.c | 7 +
gcc/config/mips/mips-d.c | 2 +
gcc/config/pa/pa-d.c | 2 +
gcc/config/riscv/riscv-d.c | 2 +
gcc/config/rs6000/rs6000-d.c | 2 +
gcc/config/s390/s390-d.c | 2 +
gcc/config/sparc/sparc-d.c | 2 +
gcc/d/d-target.cc | 5 +-
gcc/d/d-target.def | 10 +
gcc/doc/tm.texi | 7 +
gcc/doc/tm.texi.in | 2 +
libphobos/Makefile.in | 3 +
libphobos/configure | 24 +-
libphobos/configure.ac | 17 +-
libphobos/libdruntime/Makefile.am | 7 +-
libphobos/libdruntime/Makefile.in | 68 +-
libphobos/libdruntime/config/mingw/msvc.c | 54 ++
libphobos/libdruntime/config/mingw/switchcontext.S | 12 +-
libphobos/libdruntime/core/stdc/stdlib.d | 27 +-
libphobos/libdruntime/core/stdc/tgmath.d | 11 +-
libphobos/libdruntime/core/sys/windows/com.d | 4 +-
libphobos/libdruntime/core/sys/windows/dbghelp.d | 2 +-
libphobos/libdruntime/core/sys/windows/dll.d | 12 +-
libphobos/libdruntime/core/thread/osthread.d | 4 +-
libphobos/libdruntime/gcc/deh.d | 2 +-
libphobos/libdruntime/gcc/gthread.d | 6 +-
libphobos/libdruntime/gcc/sections/package.d | 28 +-
libphobos/libdruntime/gcc/sections/pecoff.d | 830 +++++++++++++++++++++
libphobos/libdruntime/gcc/sections/win32.d | 183 -----
libphobos/libdruntime/gcc/sections/win64.d | 8 -
libphobos/libdruntime/gcc/unwind/generic.d | 2 +-
libphobos/libdruntime/rt/dmain2.d | 64 --
libphobos/src/Makefile.am | 2 +-
libphobos/src/Makefile.in | 5 +-
libphobos/testsuite/Makefile.in | 3 +
41 files changed, 1085 insertions(+), 359 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..4fce593ac27 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..2cb9f4bd899 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index cfbca34f996..59eb812c1cf 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -209,6 +209,8 @@ along with GCC; see the file COPYING3. If not see
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
flag_pic = TARGET_64BIT ? 1 : 0; \
+ if (!global_options_set.x_dwarf_version) \
+ dwarf_version = 4; \
} while (0)
/* Define this macro if references to a symbol must be treated
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..34f53ba046d 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -42,3 +44,14 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Implement TARGET_D_EXTERN_SYSTEM_LINKAGE for x86 targets. */
+
+int
+ix86_d_extern_system_linkage (void)
+{
+ if (ix86_abi == MS_ABI)
+ return LINKwindows;
+
+ return LINKc;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..d07bf09bc65 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern int ix86_d_extern_system_linkage (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 058c1cc25b2..10954fb0aab 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_EXTERN_SYSTEM_LINKAGE ix86_d_extern_system_linkage
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index 3b5791a7bff..d05ea8a92bf 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -30,6 +32,11 @@ winnt_d_os_builtins (void)
{
d_add_builtin_version ("Windows");
+ if (ix86_abi == SYSV_ABI)
+ d_add_builtin_version ("SYSV_ABI");
+ else
+ d_add_builtin_version ("MS_ABI");
+
#define builtin_version(TXT) d_add_builtin_version (TXT)
#ifdef EXTRA_TARGET_D_OS_VERSIONS
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..dc57127791c 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..663e749995a 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..b20b778bd35 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..6bfe8130dd3 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..2f945ebfa12 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..0eb663bb132 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..e95dd01b0ee 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -417,11 +417,14 @@ TargetCPP::fundamentalType (const Type *, bool &)
return false;
}
-/* Return the default system linkage for the target. */
+/* Return the default `extern (System)` linkage for the target. */
LINK
Target::systemLinkage (void)
{
+ if (targetdm.d_extern_system_linkage)
+ return (LINK) targetdm.d_extern_system_linkage ();
+
return LINKc;
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..889299fffe4 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,16 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* */
+DEFHOOK
+(d_extern_system_linkage,
+ "If defined, this hook returns the extern linkage which should be applied\n\
+ for all declarations annotated with @code{extern(System)}. Typically,\n\
+ @code{extern(System)} is the same as @code{extern(Windows)} on Microsoft\n\
+ Windows platforms, and @code{extern(C)} on other platforms.",
+ int, (void),
+ NULL)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..76c9fe0d173 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,13 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} int TARGET_D_EXTERN_SYSTEM_LINKAGE (void)
+If defined, this hook returns the extern linkage which should be applied
+ for all declarations annotated with @code{extern(System)}. Typically,
+ @code{extern(System)} is the same as @code{extern(Windows)} on Microsoft
+ Windows platforms, and @code{extern(C)} on other platforms.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..ef15417a791 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,8 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_EXTERN_SYSTEM_LINKAGE
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index d42248405a2..eab12688867 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -298,6 +298,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -327,6 +329,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
diff --git a/libphobos/configure b/libphobos/configure
index c940a404be4..59ca64aa1e0 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -705,6 +705,9 @@ libphobos_builddir
get_gcc_base_ver
phobos_compiler_shared_flag
phobos_compiler_pic_flag
+phobos_lt_pic_flag
+enable_static
+enable_shared
OTOOL64
OTOOL
LIPO
@@ -11746,7 +11749,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11749 "configure"
+#line 11752 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11852,7 +11855,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11855 "configure"
+#line 11858 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13997,8 +14000,14 @@ CFLAGS=$lt_save_CFLAGS
GDCFLAGS=$gdc_save_DFLAGS
+
+
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -14010,26 +14019,23 @@ CFLAGS=$lt_save_CFLAGS
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index cc9af29754f..248d0ebbc19 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -91,9 +91,15 @@ AC_SUBST(CFLAGS_FOR_BUILD)
LT_INIT(dlopen)
AM_PROG_LIBTOOL
WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
# libtool variables for Phobos shared and position-independent compiles.
#
+# Use phobos_lt_pic_flag to designate the automake variable
+# used to encapsulate the default libtool approach to creating objects
+# with position-independent code. Default: -prefer-pic.
+#
# Use phobos_compiler_shared_flag to designate the compile-time flags for
# creating shared objects. Default: -fversion=Shared.
#
@@ -105,26 +111,23 @@ WITH_LOCAL_DRUNTIME([LT_LANG([D])], [])
# libtool, and so we make it here. How it is handled is that in shared
# compilations the `lt_prog_compiler_pic_D' variable is used to instead
# ensure that conditional compilation of shared runtime code is compiled in.
-# The original PIC flags are then used in the compilation of every object.
-#
-# Why are objects destined for libgphobos.a compiled with -fPIC?
-# Because -fPIC is not harmful to use for objects destined for static
-# libraries. In addition, using -fPIC will allow the use of static
-# libgphobos.a in the creation of other D shared libraries.
if test "$enable_shared" = yes; then
+ phobos_lt_pic_flag="-prefer-pic"
phobos_compiler_pic_flag="$lt_prog_compiler_pic_D"
phobos_compiler_shared_flag="-fversion=Shared"
else
+ phobos_lt_pic_flag=
phobos_compiler_pic_flag=
phobos_compiler_shared_flag=
fi
+AC_SUBST(phobos_lt_pic_flag)
AC_SUBST(phobos_compiler_pic_flag)
AC_SUBST(phobos_compiler_shared_flag)
# Override the libtool's pic_flag and pic_mode.
# Do this step after AM_PROG_LIBTOOL, but before AC_OUTPUT.
# NB: this impacts --with-pic and --without-pic.
-lt_prog_compiler_pic_D="$phobos_compiler_shared_flag"
+lt_prog_compiler_pic_D="$phobos_compiler_pic_flag $phobos_compiler_shared_flag"
pic_mode='default'
# Determine what GCC version number to use in filesystem paths.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 945271e028f..bedd7a325ec 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -23,7 +23,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
@@ -69,7 +69,8 @@ if DRUNTIME_OS_LINUX
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_LINUX)
endif
if DRUNTIME_OS_MINGW
- DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS)
+ DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_WINDOWS) \
+ config/mingw/msvc.c
endif
if DRUNTIME_OS_SOLARIS
DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_SOLARIS)
@@ -187,7 +188,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/backtrace.d \
gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 06c02961c86..665af30e09d 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -117,7 +117,9 @@ target_triplet = @target@
@DRUNTIME_OS_NETBSD_TRUE@am__append_6 = $(DRUNTIME_DSOURCES_NETBSD)
@DRUNTIME_OS_OPENBSD_TRUE@am__append_7 = $(DRUNTIME_DSOURCES_OPENBSD)
@DRUNTIME_OS_LINUX_TRUE@am__append_8 = $(DRUNTIME_DSOURCES_LINUX)
-@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS)
+@DRUNTIME_OS_MINGW_TRUE@am__append_9 = $(DRUNTIME_DSOURCES_WINDOWS) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/msvc.c
+
@DRUNTIME_OS_SOLARIS_TRUE@am__append_10 = $(DRUNTIME_DSOURCES_SOLARIS)
# CPU specific sources
@DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S
@@ -213,7 +215,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
gcc/builtins.lo gcc/deh.lo gcc/emutls.lo gcc/gthread.lo \
gcc/sections/android.lo gcc/sections/elf_shared.lo \
gcc/sections/osx.lo gcc/sections/package.lo \
- gcc/sections/win32.lo gcc/sections/win64.lo gcc/unwind/arm.lo \
+ gcc/sections/pecoff.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 \
@@ -425,7 +427,8 @@ am__objects_19 = core/sys/windows/accctrl.lo \
core/sys/windows/winspool.lo core/sys/windows/winsvc.lo \
core/sys/windows/winuser.lo core/sys/windows/winver.lo \
core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo
-@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19)
+@DRUNTIME_OS_MINGW_TRUE@am__objects_20 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \
core/sys/solaris/libelf.lo core/sys/solaris/link.lo \
@@ -460,24 +463,26 @@ am_libgdruntime_la_OBJECTS = $(am__objects_33)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__objects_34 = core/stdc/libgdruntime_convenience_la-errno_.lo
-@DRUNTIME_CPU_AARCH64_TRUE@am__objects_35 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_ARM_TRUE@am__objects_36 = config/arm/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_MIPS_TRUE@am__objects_37 = config/mips/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_38 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_39 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_40 = config/x86/libgdruntime_convenience_la-switchcontext.lo
-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_41 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
-@DRUNTIME_CPU_S390_TRUE@am__objects_42 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
-am__objects_43 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
+@DRUNTIME_OS_MINGW_TRUE@am__objects_35 = $(am__objects_19) \
+@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
+@DRUNTIME_CPU_AARCH64_TRUE@am__objects_36 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_ARM_TRUE@am__objects_37 = config/arm/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_MIPS_TRUE@am__objects_38 = config/mips/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_POWERPC_TRUE@am__objects_39 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_40 = config/mingw/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_41 = config/x86/libgdruntime_convenience_la-switchcontext.lo
+@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_42 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo
+@DRUNTIME_CPU_S390_TRUE@am__objects_43 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo
+am__objects_44 = $(am__objects_4) $(am__objects_6) $(am__objects_8) \
$(am__objects_10) $(am__objects_12) $(am__objects_14) \
- $(am__objects_16) $(am__objects_18) $(am__objects_20) \
- $(am__objects_22) $(am__objects_35) $(am__objects_36) \
- $(am__objects_37) $(am__objects_38) $(am__objects_39) \
- $(am__objects_40) $(am__objects_41) $(am__objects_42)
-am__objects_44 = $(am__objects_1) $(am__objects_34) $(am__objects_43) \
+ $(am__objects_16) $(am__objects_18) $(am__objects_35) \
+ $(am__objects_22) $(am__objects_36) $(am__objects_37) \
+ $(am__objects_38) $(am__objects_39) $(am__objects_40) \
+ $(am__objects_41) $(am__objects_42) $(am__objects_43)
+am__objects_45 = $(am__objects_1) $(am__objects_34) $(am__objects_44) \
$(am__objects_32)
-am__objects_45 = $(am__objects_44)
-am_libgdruntime_convenience_la_OBJECTS = $(am__objects_45)
+am__objects_46 = $(am__objects_45)
+am_libgdruntime_convenience_la_OBJECTS = $(am__objects_46)
libgdruntime_convenience_la_OBJECTS = \
$(am_libgdruntime_convenience_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
@@ -659,6 +664,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -688,6 +695,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -720,7 +728,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) -I .
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
@@ -813,7 +821,7 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
gc/pooltable.d gc/proxy.d gcc/attribute.d gcc/backtrace.d \
gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
gcc/sections/android.d gcc/sections/elf_shared.d gcc/sections/osx.d \
- gcc/sections/package.d gcc/sections/win32.d gcc/sections/win64.d \
+ gcc/sections/package.d gcc/sections/pecoff.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 \
@@ -1213,8 +1221,7 @@ 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/win32.lo: gcc/sections/$(am__dirstamp)
-gcc/sections/win64.lo: gcc/sections/$(am__dirstamp)
+gcc/sections/pecoff.lo: gcc/sections/$(am__dirstamp)
gcc/unwind/$(am__dirstamp):
@$(MKDIR_P) gcc/unwind
@: > gcc/unwind/$(am__dirstamp)
@@ -1720,6 +1727,10 @@ core/sys/windows/winuser.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/winver.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtsapi32.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/wtypes.lo: core/sys/windows/$(am__dirstamp)
+config/mingw/$(am__dirstamp):
+ @$(MKDIR_P) config/mingw
+ @: > config/mingw/$(am__dirstamp)
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/$(am__dirstamp)
core/sys/solaris/$(am__dirstamp):
@$(MKDIR_P) core/sys/solaris
@: > core/sys/solaris/$(am__dirstamp)
@@ -1769,9 +1780,6 @@ config/powerpc/$(am__dirstamp):
@: > config/powerpc/$(am__dirstamp)
config/powerpc/libgdruntime_la-switchcontext.lo: \
config/powerpc/$(am__dirstamp)
-config/mingw/$(am__dirstamp):
- @$(MKDIR_P) config/mingw
- @: > config/mingw/$(am__dirstamp)
config/mingw/libgdruntime_la-switchcontext.lo: \
config/mingw/$(am__dirstamp)
config/x86/$(am__dirstamp):
@@ -1796,6 +1804,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+config/mingw/libgdruntime_convenience_la-msvc.lo: \
+ config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
config/aarch64/$(am__dirstamp)
config/arm/libgdruntime_convenience_la-switchcontext.lo: \
@@ -1991,9 +2001,15 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
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
+config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.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 config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/libphobos/libdruntime/config/mingw/msvc.c b/libphobos/libdruntime/config/mingw/msvc.c
new file mode 100644
index 00000000000..25b15a06950
--- /dev/null
+++ b/libphobos/libdruntime/config/mingw/msvc.c
@@ -0,0 +1,54 @@
+/* Windows support code to wrap differences between different
+ versions of the Microsoft C libaries.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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/>. */
+
+#include <stdio.h>
+
+/* The symbols for stdin, stdout, and stderr are defined for D in the
+ core.stdc.stdio module. Save the macros and redeclare them here. */
+#define c_stdin stdin
+#undef stdin
+extern FILE *stdin;
+
+#define c_stdout stdout
+#undef stdout
+extern FILE *stdout;
+
+#define c_stderr stderr
+#undef stderr
+extern FILE *stderr;
+
+/* Set to 1 if run-time is using ucrtbase.dll. */
+unsigned char msvcUsesUCRT;
+
+void init_msvc()
+{
+#if __MSVCRT_VERSION__ >= 0x1400
+ msvcUsedUCRT = 1;
+#endif
+
+ stdin = c_stdin;
+ stdout = c_stdout;
+ stderr = c_stderr;
+}
diff --git a/libphobos/libdruntime/config/mingw/switchcontext.S b/libphobos/libdruntime/config/mingw/switchcontext.S
index 6592ff604bc..0cb8b015bfc 100644
--- a/libphobos/libdruntime/config/mingw/switchcontext.S
+++ b/libphobos/libdruntime/config/mingw/switchcontext.S
@@ -28,7 +28,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -63,13 +66,15 @@ CSYM(fiber_switchContext):
popq %RCX;
jmp *%RCX;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#elif defined(_X86_)
.text
.globl CSYM(fiber_switchContext)
- .type CSYM(fiber_switchContext), @function
+ .def CSYM(fiber_switchContext)
+ .scl 2
+ .type 32
+ .endef
.align 16
CSYM(fiber_switchContext):
.cfi_startproc
@@ -104,6 +109,5 @@ CSYM(fiber_switchContext):
// 'return' to complete switch
ret;
.cfi_endproc
- .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
#endif
diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d
index 7caef4c1339..b048a944a88 100644
--- a/libphobos/libdruntime/core/stdc/stdlib.d
+++ b/libphobos/libdruntime/core/stdc/stdlib.d
@@ -121,19 +121,22 @@ ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
version (CRuntime_Microsoft)
{
- // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
- ///
- extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
- { // Fake it 'till we make it
- return strtod(nptr, endptr);
+ version (MinGW)
+ {
+ ///
+ real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
+ ///
+ alias __mingw_strtold strtold;
+ }
+ else
+ {
+ // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
+ ///
+ extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
+ { // Fake it 'till we make it
+ return strtod(nptr, endptr);
+ }
}
-}
-else version (MinGW)
-{
- ///
- real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
- ///
- alias __mingw_strtold strtold;
}
else
{
diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d
index 4dd1b3ccc66..9a351db3861 100644
--- a/libphobos/libdruntime/core/stdc/tgmath.d
+++ b/libphobos/libdruntime/core/stdc/tgmath.d
@@ -1409,13 +1409,20 @@ else
alias core.stdc.math.fabs fabs;
version (CRuntime_Microsoft)
{
+ version (MinGW)
+ {
+ ///
+ alias core.stdc.math.fabsf fabs;
+ ///
+ alias core.stdc.math.fabsl fabs;
+ }
}
else
{
///
- alias core.stdc.math.fabsf fabs;
+ alias core.stdc.math.fabsf fabs;
///
- alias core.stdc.math.fabsl fabs;
+ alias core.stdc.math.fabsl fabs;
}
///
diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d
index 90a294343fc..2808a6c59fc 100644
--- a/libphobos/libdruntime/core/sys/windows/com.d
+++ b/libphobos/libdruntime/core/sys/windows/com.d
@@ -57,12 +57,12 @@ alias COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
public import core.sys.windows.uuid;
-extern (System)
+extern (Windows)
{
class ComObject : IUnknown
{
-extern (System):
+extern (Windows):
HRESULT QueryInterface(const(IID)* riid, void** ppv)
{
if (*riid == IID_IUnknown)
diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d
index 8c9827034e9..9848fb99115 100644
--- a/libphobos/libdruntime/core/sys/windows/dbghelp.d
+++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d
@@ -18,7 +18,7 @@ import core.sys.windows.windef;
public import core.sys.windows.dbghelp_types;
-extern(System)
+extern(Windows)
{
alias BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 9f36ac389a6..3df0d7fd41b 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -31,17 +31,7 @@ public import core.sys.windows.threadaux;
// not access tls_array[tls_index] as needed for thread local _tlsstart and _tlsend
extern (C)
{
- version (MinGW)
- {
- extern __gshared void* _tls_start;
- extern __gshared void* _tls_end;
- extern __gshared void* __xl_a;
-
- alias _tls_start _tlsstart;
- alias _tls_end _tlsend;
- alias __xl_a _tls_callbacks_a;
- }
- else version (Win32)
+ version (Win32)
{
version (CRuntime_DigitalMars)
{
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index defdc9586f1..638eada3e43 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -1539,9 +1539,9 @@ package extern(D) void* getStackBottom() nothrow @nogc
void *bottom;
version (X86)
- asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movl %%fs:4, %0;" : "=r" (bottom); }
else version (X86_64)
- asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" bottom; }
+ asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
else
static assert(false, "Platform not supported.");
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index c747b5132d1..7e02dabd221 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -805,7 +805,7 @@ version (GNU_SEH_Exceptions)
void* ms_orig_context, void* ms_disp)
{
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
- ms_disp, &__gdc_personality_imp);
+ ms_disp, &gdc_personality);
}
}
else version (GNU_SjLj_Exceptions)
diff --git a/libphobos/libdruntime/gcc/gthread.d b/libphobos/libdruntime/gcc/gthread.d
index ef35a3c27ec..5003637b9ea 100644
--- a/libphobos/libdruntime/gcc/gthread.d
+++ b/libphobos/libdruntime/gcc/gthread.d
@@ -86,10 +86,12 @@ else static if (GNU_Thread_Model == ThreadModel.Single)
}
else static if (GNU_Thread_Model == ThreadModel.Win32)
{
+ import core.stdc.config;
+
struct __gthread_once_t
{
- INT done;
- LONG started;
+ int done;
+ c_long started;
}
int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor);
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
index fdaf039fcfa..5d76072af25 100644
--- a/libphobos/libdruntime/gcc/sections/package.d
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -22,26 +22,20 @@
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)
+version (CRuntime_Glibc) version = ElfShared;
+version (CRuntime_Musl) version = ElfShared;
+version (CRuntime_UClibc) version = ElfShared;
+version (FreeBSD) version = ElfShared;
+version (NetBSD) version = ElfShared;
+version (DragonFlyBSD) version = ElfShared;
+version (Solaris) version = ElfShared;
+
+version (ElfShared)
public import gcc.sections.elf_shared;
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 (Windows)
+ public import gcc.sections.pecoff;
else version (CRuntime_Bionic)
public import gcc.sections.android;
else
diff --git a/libphobos/libdruntime/gcc/sections/pecoff.d b/libphobos/libdruntime/gcc/sections/pecoff.d
new file mode 100644
index 00000000000..5fa1df2ac54
--- /dev/null
+++ b/libphobos/libdruntime/gcc/sections/pecoff.d
@@ -0,0 +1,830 @@
+// PE/COFF-specific support for sections.
+// Copyright (C) 2021 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.pecoff;
+
+version (Windows):
+
+import core.memory;
+import core.stdc.stdlib;
+import core.sys.windows.winbase;
+import core.sys.windows.windef;
+import core.sys.windows.winnt;
+import rt.minfo;
+import rt.util.container.array;
+import rt.util.container.hashtab;
+
+version (GNU_EMUTLS)
+ import gcc.emutls;
+
+/****
+ * 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.).
+ */
+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
+{
+ static int opApply(scope int delegate(ref DSO) dg)
+ {
+ foreach (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ static int opApplyReverse(scope int delegate(ref DSO) dg)
+ {
+ foreach_reverse (dso; _loadedDSOs)
+ {
+ if (auto res = dg(*dso))
+ return res;
+ }
+ return 0;
+ }
+
+ @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
+ {
+ return _moduleGroup.modules;
+ }
+
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
+ {
+ return _moduleGroup;
+ }
+
+ @property inout(void[])[] gcRanges() inout nothrow @nogc
+ {
+ return _gcRanges[];
+ }
+
+private:
+
+ invariant()
+ {
+ safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO.");
+ }
+
+ void** _slot;
+ ModuleGroup _moduleGroup;
+ Array!(void[]) _gcRanges;
+
+ version (Shared)
+ {
+ Array!(void[]) _codeSegments; // array of code segments
+ Array!(DSO*) _deps; // D libraries needed by this DSO
+ void* _handle; // corresponding handle
+ }
+}
+
+/****
+ * Boolean flag set to true while the runtime is initialized.
+ */
+__gshared bool _isRuntimeInitialized;
+
+/****
+ * Gets called on program startup just before GC is initialized.
+ */
+void initSections() nothrow @nogc
+{
+ _isRuntimeInitialized = true;
+}
+
+/***
+ * Gets called on program shutdown just after GC is terminated.
+ */
+void finiSections() nothrow @nogc
+{
+ _isRuntimeInitialized = false;
+}
+
+alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
+
+version (Shared)
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(ThreadDSO)* initTLSRanges() @nogc nothrow
+ {
+ return &_loadedDSOs();
+ }
+
+ void finiTLSRanges(Array!(ThreadDSO)* tdsos) @nogc nothrow
+ {
+ // Nothing to do here. tdsos used to point to the _loadedDSOs instance
+ // in the dying thread's TLS segment and as such is not valid anymore.
+ // The memory for the array contents was already reclaimed in
+ // cleanupLoadedLibraries().
+ }
+
+ void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+
+ // interface for core.thread to inherit loaded libraries
+ void* pinLoadedLibraries() nothrow @nogc
+ {
+ auto res = cast(Array!(ThreadDSO)*)calloc(1, Array!(ThreadDSO).sizeof);
+ res.length = _loadedDSOs.length;
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ (*res)[i] = tdso;
+ if (tdso._addCnt)
+ {
+ // Increment the DLL ref for explicitly loaded libraries to pin them.
+ char[MAX_PATH] buf;
+ char[] buffer = buf[];
+ const success = .LoadLibraryA(nameForDSO(tdso._pdso, buffer)) !is null;
+ safeAssert(success, "Failed to increment DLL ref.");
+ (*res)[i]._addCnt = 1; // new array takes over the additional ref count
+ }
+ }
+ return res;
+ }
+
+ void unpinLoadedLibraries(void* p) nothrow @nogc
+ {
+ auto pary = cast(Array!(ThreadDSO)*)p;
+ // In case something failed we need to undo the pinning.
+ foreach (ref tdso; *pary)
+ {
+ if (tdso._addCnt)
+ {
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid library handle.");
+ .FreeLibrary(handle);
+ }
+ }
+ pary.reset();
+ .free(pary);
+ }
+
+ // Called before TLS ctors are ran, copy over the loaded libraries
+ // of the parent thread.
+ void inheritLoadedLibraries(void* p) nothrow @nogc
+ {
+ safeAssert(_loadedDSOs.empty, "DSOs have already been registered for this thread.");
+ _loadedDSOs.swap(*cast(Array!(ThreadDSO)*)p);
+ .free(p);
+ }
+
+ // Called after all TLS dtors ran, decrements all remaining DLL refs.
+ void cleanupLoadedLibraries() nothrow @nogc
+ {
+ foreach (ref tdso; _loadedDSOs)
+ {
+ if (tdso._addCnt == 0) continue;
+
+ auto handle = tdso._pdso._handle;
+ safeAssert(handle !is null, "Invalid DSO handle.");
+ for (; tdso._addCnt > 0; --tdso._addCnt)
+ .FreeLibrary(handle);
+ }
+
+ // Free the memory for the array contents.
+ _loadedDSOs.reset();
+ }
+}
+else
+{
+ /***
+ * Called once per thread; returns array of thread local storage ranges
+ */
+ Array!(void[])* initTLSRanges() nothrow @nogc
+ {
+ return null;
+ }
+
+ void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
+ {
+ }
+
+ void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_scan(dg);
+ else
+ static assert(0, "Native TLS unimplemented");
+ }
+}
+
+private:
+
+version (Shared)
+{
+ /*
+ * Array of thread local DSO metadata for all libraries loaded and
+ * initialized in this thread.
+ *
+ * Note:
+ * A newly spawned thread will inherit these libraries.
+ * Note:
+ * We use an array here to preserve the order of
+ * initialization. If that became a performance issue, we
+ * could use a hash table and enumerate the DSOs during
+ * loading so that the hash table values could be sorted when
+ * necessary.
+ */
+ struct ThreadDSO
+ {
+ DSO* _pdso;
+ static if (_pdso.sizeof == 8) uint _refCnt, _addCnt;
+ else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt;
+ else static assert(0, "unimplemented");
+ alias _pdso this;
+ }
+
+ @property ref Array!(ThreadDSO) _loadedDSOs() @nogc nothrow
+ {
+ static Array!(ThreadDSO) x;
+ return x;
+ }
+
+ /*
+ * Set to true during rt_loadLibrary/rt_unloadLibrary calls.
+ */
+ bool _rtLoading;
+
+ /*
+ * Hash table to map the native handle (as returned by dlopen)
+ * to the corresponding DSO*, protected by a mutex.
+ */
+ __gshared CRITICAL_SECTION _handleToDSOMutex;
+ @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow
+ {
+ __gshared HashTab!(void*, DSO*) x;
+ return x;
+ }
+}
+else
+{
+ /*
+ * Static DSOs loaded by the runtime linker. This includes the
+ * executable. These can't be unloaded.
+ */
+ @property ref Array!(DSO*) _loadedDSOs() @nogc nothrow
+ {
+ __gshared Array!(DSO*) x;
+ return x;
+ }
+
+ enum _rtLoading = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Compiler to runtime interface.
+///////////////////////////////////////////////////////////////////////////////
+
+/****
+ * This data structure is generated by the compiler, and then passed to
+ * _d_dso_registry().
+ */
+struct CompilerDSOData
+{
+ size_t _version; // currently 1
+ void** _slot; // can be used to store runtime data
+ immutable(object.ModuleInfo*)* _minfo_beg, _minfo_end; // array of modules in this object file
+}
+
+T[] toRange(T)(T* beg, T* end) { return beg[0 .. end - beg]; }
+
+/* For each shared library and executable, the compiler generates code that
+ * sets up CompilerDSOData and calls _d_dso_registry().
+ * A pointer to that code is inserted into both the .ctors and .dtors
+ * segment so it gets called by the loader on startup and shutdown.
+ */
+extern(C) void _d_dso_registry(CompilerDSOData* data)
+{
+ // only one supported currently
+ safeAssert(data._version >= 1, "Incompatible compiler-generated DSO data version.");
+
+ // no backlink => register
+ if (*data._slot is null)
+ {
+ immutable firstDSO = _loadedDSOs.empty;
+ if (firstDSO) initLocks();
+
+ DSO* pdso = cast(DSO*).calloc(1, DSO.sizeof);
+ assert(typeid(DSO).initializer().ptr is null);
+ pdso._slot = data._slot;
+ *data._slot = pdso; // store backlink in library record
+
+ pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end));
+
+ HMODULE handle = void;
+ const moduleFound = findModuleHandleForAddr(data._slot, handle);
+ safeAssert(moduleFound, "Failed to find image header.");
+
+ scanSegments(handle, pdso);
+
+ version (Shared)
+ {
+ getDependencies(handle, pdso._deps);
+ pdso._handle = handle;
+ setDSOForHandle(pdso, pdso._handle);
+
+ if (!_rtLoading)
+ {
+ /* This DSO was not loaded by rt_loadLibrary which
+ * happens for all dependencies of an executable or
+ * the first dlopen call from a C program.
+ * In this case we add the DSO to the _loadedDSOs of this
+ * thread with a refCnt of 1 and call the TlsCtors.
+ */
+ immutable ushort refCnt = 1, addCnt = 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ }
+ }
+ else
+ {
+ foreach (p; _loadedDSOs)
+ safeAssert(p !is pdso, "DSO already registered.");
+ _loadedDSOs.insertBack(pdso);
+ }
+
+ // don't initialize modules before rt_init was called
+ if (_isRuntimeInitialized)
+ {
+ registerGCRanges(pdso);
+ // rt_loadLibrary will run tls ctors, so do this only for dlopen
+ immutable runTlsCtors = !_rtLoading;
+ runModuleConstructors(pdso, runTlsCtors);
+ }
+ }
+ // has backlink => unregister
+ else
+ {
+ DSO* pdso = cast(DSO*)*data._slot;
+ *data._slot = null;
+
+ // don't finalizes modules after rt_term was called (see Bugzilla 11378)
+ if (_isRuntimeInitialized)
+ {
+ // rt_unloadLibrary already ran tls dtors, so do this only for dlclose
+ immutable runTlsDtors = !_rtLoading;
+ runModuleDestructors(pdso, runTlsDtors);
+ unregisterGCRanges(pdso);
+ // run finalizers after module dtors (same order as in rt_term)
+ version (Shared) runFinalizers(pdso);
+ }
+
+ version (Shared)
+ {
+ if (!_rtLoading)
+ {
+ /* This DSO was not unloaded by rt_unloadLibrary so we
+ * have to remove it from _loadedDSOs here.
+ */
+ foreach (i, ref tdso; _loadedDSOs)
+ {
+ if (tdso._pdso == pdso)
+ {
+ _loadedDSOs.remove(i);
+ break;
+ }
+ }
+ }
+
+ unsetDSOForHandle(pdso, pdso._handle);
+ }
+ else
+ {
+ // static DSOs are unloaded in reverse order
+ safeAssert(pdso == _loadedDSOs.back, "DSO being unregistered isn't current last one.");
+ _loadedDSOs.popBack();
+ }
+
+ freeDSO(pdso);
+
+ // last DSO being unloaded => shutdown registry
+ if (_loadedDSOs.empty)
+ {
+ version (GNU_EMUTLS)
+ _d_emutls_destroy();
+ version (Shared)
+ {
+ safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs.");
+ _handleToDSO.reset();
+ }
+ finiLocks();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dynamic loading
+///////////////////////////////////////////////////////////////////////////////
+
+// Shared D libraries are only supported when linking against a shared druntime library.
+
+version (Shared)
+{
+ ThreadDSO* findThreadDSO(DSO* pdso) nothrow @nogc
+ {
+ foreach (ref tdata; _loadedDSOs)
+ if (tdata._pdso == pdso) return &tdata;
+ return null;
+ }
+
+ void incThreadRef(DSO* pdso, bool incAdd)
+ {
+ if (auto tdata = findThreadDSO(pdso)) // already initialized
+ {
+ if (incAdd && ++tdata._addCnt > 1) return;
+ ++tdata._refCnt;
+ }
+ else
+ {
+ foreach (dep; pdso._deps)
+ incThreadRef(dep, false);
+ immutable ushort refCnt = 1, addCnt = incAdd ? 1 : 0;
+ _loadedDSOs.insertBack(ThreadDSO(pdso, refCnt, addCnt));
+ pdso._moduleGroup.runTlsCtors();
+ }
+ }
+
+ void decThreadRef(DSO* pdso, bool decAdd)
+ {
+ auto tdata = findThreadDSO(pdso);
+ 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;
+
+ pdso._moduleGroup.runTlsDtors();
+ foreach (i, ref td; _loadedDSOs)
+ if (td._pdso == pdso) _loadedDSOs.remove(i);
+ foreach (dep; pdso._deps)
+ decThreadRef(dep, false);
+ }
+}
+
+/***********************************
+ * These are a temporary means of providing a GC hook for DLL use. They may be
+ * replaced with some other similar functionality later.
+ */
+extern (C)
+{
+ void* gc_getProxy();
+ void gc_setProxy(void* p);
+ void gc_clrProxy();
+
+ alias void function(void*) gcSetFn;
+ alias void function() gcClrFn;
+}
+
+/*******************************************
+ * Loads a DLL written in D with the name 'name'.
+ * Returns:
+ * opaque handle to the DLL if successfully loaded
+ * null if failure
+ */
+extern(C) void* rt_loadLibrary(const char* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryA(name));
+}
+
+extern (C) void* rt_loadLibraryW(const wchar_t* name)
+{
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+ }
+ return initLibrary(.LoadLibraryW(name));
+}
+
+void* initLibrary(void* handle)
+{
+ if (handle is null)
+ return null;
+
+ version (Shared)
+ {
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ incThreadRef(pdso, true);
+ }
+ gcSetFn gcSet = cast(gcSetFn) GetProcAddress(handle, "gc_setProxy");
+ if (gcSet !is null)
+ {
+ // BUG: Set proxy, but too late
+ gcSet(gc_getProxy());
+ }
+ return handle;
+}
+
+/*************************************
+ * Unloads DLL that was previously loaded by rt_loadLibrary().
+ * Input:
+ * handle the handle returned by rt_loadLibrary()
+ * Returns:
+ * 1 succeeded
+ * 0 some failure happened
+ */
+extern(C) int rt_unloadLibrary(void* handle)
+{
+ if (handle is null)
+ return false;
+
+ version (Shared)
+ {
+ immutable save = _rtLoading;
+ _rtLoading = true;
+ scope (exit) _rtLoading = save;
+
+ // if it's a D library
+ if (auto pdso = dsoForHandle(handle))
+ decThreadRef(pdso, true);
+ }
+ gcClrFn gcClr = cast(gcClrFn) GetProcAddress(handle, "gc_clrProxy");
+ if (gcClr !is null)
+ gcClr();
+ return .FreeLibrary(handle) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// helper functions
+///////////////////////////////////////////////////////////////////////////////
+
+void initLocks() nothrow @nogc
+{
+ version (Shared)
+ InitializeCriticalSection(&_handleToDSOMutex);
+}
+
+void finiLocks() nothrow @nogc
+{
+ version (Shared)
+ DeleteCriticalSection(&_handleToDSOMutex);
+}
+
+void runModuleConstructors(DSO* pdso, bool runTlsCtors)
+{
+ pdso._moduleGroup.sortCtors();
+ pdso._moduleGroup.runCtors();
+ if (runTlsCtors) pdso._moduleGroup.runTlsCtors();
+}
+
+void runModuleDestructors(DSO* pdso, bool runTlsDtors)
+{
+ if (runTlsDtors) pdso._moduleGroup.runTlsDtors();
+ pdso._moduleGroup.runDtors();
+}
+
+void registerGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.addRange(rng.ptr, rng.length);
+}
+
+void unregisterGCRanges(DSO* pdso) nothrow @nogc
+{
+ foreach (rng; pdso._gcRanges)
+ GC.removeRange(rng.ptr);
+}
+
+version (Shared) void runFinalizers(DSO* pdso)
+{
+ foreach (seg; pdso._codeSegments)
+ GC.runFinalizers(seg);
+}
+
+void freeDSO(DSO* pdso) nothrow @nogc
+{
+ pdso._gcRanges.reset();
+ version (Shared)
+ {
+ pdso._codeSegments.reset();
+ pdso._deps.reset();
+ pdso._handle = null;
+ }
+ .free(pdso);
+}
+
+version (Shared)
+{
+@nogc nothrow:
+ const(char)* nameForDSO(DSO* pdso, ref char[] buffer)
+ {
+ const success = GetModuleFileNameA(pdso._handle, buffer.ptr, cast(DWORD)buffer.length) != 0;
+ safeAssert(success, "Failed to get DLL name.");
+ return buffer.ptr;
+ }
+
+ DSO* dsoForHandle(in void* handle)
+ {
+ DSO* pdso;
+ .EnterCriticalSection(&_handleToDSOMutex);
+ if (auto ppdso = handle in _handleToDSO)
+ pdso = *ppdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ return pdso;
+ }
+
+ void setDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(handle !in _handleToDSO, "DSO already registered.");
+ _handleToDSO[handle] = pdso;
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void unsetDSOForHandle(DSO* pdso, void* handle)
+ {
+ .EnterCriticalSection(&_handleToDSOMutex);
+ safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO.");
+ _handleToDSO.remove(handle);
+ .LeaveCriticalSection(&_handleToDSOMutex);
+ }
+
+ void getDependencies(in HMODULE handle, ref Array!(DSO*) deps)
+ {
+ auto nthdr = getNTHeader(handle);
+ auto import_entry = nthdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ auto addr = import_entry.VirtualAddress;
+ auto datasize = import_entry.Size;
+
+ if (addr == 0 && datasize == 0)
+ {
+ // Maybe the optional header isn't there, look for the section.
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ addr = section.VirtualAddress;
+ datasize = section.Misc.VirtualSize;
+ break;
+ }
+ if (datasize == 0)
+ return;
+ }
+ else
+ {
+ bool foundSection = false;
+ foreach (section; getSectionHeader(handle))
+ {
+ if (!compareSectionName(section, ".idata"))
+ continue;
+ // Section containing import table has no contents.
+ if (section.Misc.VirtualSize == 0)
+ return;
+ foundSection = true;
+ break;
+ }
+ // There is an import table, but the section containing it could not be found
+ if (!foundSection)
+ return;
+ }
+
+ // Get the names of each DLL
+ for (uint i = 0; i + IMAGE_IMPORT_DESCRIPTOR.sizeof <= datasize;
+ i += IMAGE_IMPORT_DESCRIPTOR.sizeof)
+ {
+ const data = cast(PIMAGE_IMPORT_DESCRIPTOR)(handle + addr + i);
+ if (data.Name == 0)
+ break;
+
+ // dll name of dependency
+ auto name = cast(char*)(handle + data.Name);
+ // get handle without loading the library
+ auto libhandle = handleForName(name);
+ // the runtime linker has already loaded all dependencies
+ 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)
+ {
+ return GetModuleHandleA(name);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PE/COFF program header iteration
+///////////////////////////////////////////////////////////////////////////////
+
+bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
+{
+ if (name[] != cast(char[])section.Name[0 .. name.length])
+ return false;
+ return name.length == 8 || section.Name[name.length] == 0;
+}
+
+/************
+ * Scan segments in the image header and store
+ * the writeable data segments in *pdso.
+ */
+
+void scanSegments(in HMODULE handle, DSO* pdso) nothrow @nogc
+{
+ foreach (section; getSectionHeader(handle))
+ {
+ // the ".data" image section includes both object file sections ".data" and ".bss"
+ if (compareSectionName(section, ".data"))
+ {
+ auto data = cast(void*)handle + section.VirtualAddress;
+ pdso._gcRanges.insertBack(data[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+
+ version (Shared)
+ {
+ if (compareSectionName(section, ".text"))
+ {
+ auto text = cast(void*)handle + section.VirtualAddress;
+ pdso._codeSegments.insertBack(text[0 .. section.Misc.VirtualSize]);
+ continue;
+ }
+ }
+ }
+}
+
+/**************************
+ * Input:
+ * handle where the output is to be written
+ * Returns:
+ * true if found, and *handle is filled in
+ */
+
+bool findModuleHandleForAddr(in void* addr, out HMODULE handle) nothrow @nogc
+{
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ cast(const(wchar)*) addr, &handle))
+ return true;
+
+ return false;
+}
+
+/**
+ * Returns the image NT header for the HMODULE handle passed,
+ * or null if not found.
+ */
+PIMAGE_NT_HEADERS getNTHeader(in HMODULE handle) nothrow @nogc
+{
+ auto doshdr = cast(PIMAGE_DOS_HEADER)handle;
+ if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
+ return null;
+
+ return cast(typeof(return))(cast(void*)doshdr + doshdr.e_lfanew);
+}
+
+/**
+ * Returns the image section header for the HMODULE handle passed,
+ * or null if not found.
+ */
+IMAGE_SECTION_HEADER[] getSectionHeader(in HMODULE handle) nothrow @nogc
+{
+ if (auto nthdr = getNTHeader(handle))
+ {
+ const void* opthdr = &nthdr.OptionalHeader;
+ const offset = nthdr.FileHeader.SizeOfOptionalHeader;
+ const length = nthdr.FileHeader.NumberOfSections;
+ return (cast(PIMAGE_SECTION_HEADER)(opthdr + offset))[0 .. length];
+ }
+ return null;
+}
diff --git a/libphobos/libdruntime/gcc/sections/win32.d b/libphobos/libdruntime/gcc/sections/win32.d
deleted file mode 100644
index b355dfc5068..00000000000
--- a/libphobos/libdruntime/gcc/sections/win32.d
+++ /dev/null
@@ -1,183 +0,0 @@
-// Win32-specific support for sections.
-// Copyright (C) 2019-2021 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):
-
-// debug = PRINTF;
-debug(PRINTF) import core.stdc.stdio;
-import rt.minfo;
-import core.stdc.stdlib : malloc, free;
-
-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 inout(void[])[] gcRanges() inout nothrow @nogc
- {
- return _gcRanges[];
- }
-
-private:
- ModuleGroup _moduleGroup;
- void[][] _gcRanges;
-}
-
-shared(bool) conservative;
-
-void initSections() nothrow @nogc
-{
- _sections._moduleGroup = ModuleGroup(getModuleInfos());
-
- import rt.sections;
- conservative = !scanDataSegPrecisely();
-
- if (conservative)
- {
- _sections._gcRanges = (cast(void[]*) malloc(2 * (void[]).sizeof))[0..2];
-
- auto databeg = cast(void*)&_xi_a;
- auto dataend = cast(void*)_moduleinfo_array.ptr;
- _sections._gcRanges[0] = databeg[0 .. dataend - databeg];
-
- // skip module info and CONST segment
- auto bssbeg = cast(void*)&_edata;
- auto bssend = cast(void*)&_end;
- _sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];
- }
- else
- {
- size_t count = &_DPend - &_DPbegin;
- auto ranges = cast(void[]*) malloc(count * (void[]).sizeof);
- size_t r = 0;
- void* prev = null;
- for (size_t i = 0; i < count; i++)
- {
- void* addr = (&_DPbegin)[i];
- if (prev + (void*).sizeof == addr)
- ranges[r-1] = ranges[r-1].ptr[0 .. ranges[r-1].length + (void*).sizeof];
- else
- ranges[r++] = (cast(void**)addr)[0..1];
- prev = addr;
- }
- _sections._gcRanges = ranges[0..r];
- }
-}
-
-void finiSections() nothrow @nogc
-{
- free(_sections._gcRanges.ptr);
-}
-
-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
-{
- if (conservative)
- {
- dg(rng.ptr, rng.ptr + rng.length);
- }
- else
- {
- for (auto p = &_TPbegin; p < &_TPend; )
- {
- uint beg = *p++;
- uint end = beg + cast(uint)((void*).sizeof);
- while (p < &_TPend && *p == end)
- {
- end += (void*).sizeof;
- p++;
- }
- dg(rng.ptr + beg, rng.ptr + end);
- }
- }
-}
-
-private:
-
-__gshared SectionGroup _sections;
-
-// Windows: this gets initialized by minit.asm
-extern(C) __gshared immutable(ModuleInfo*)[] _moduleinfo_array;
-extern(C) void _minit() nothrow @nogc;
-
-immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
-out (result)
-{
- foreach (m; result)
- assert(m !is null);
-}
-body
-{
- // _minit directly alters the global _moduleinfo_array
- _minit();
- return _moduleinfo_array;
-}
-
-extern(C)
-{
- extern __gshared
- {
- int _xi_a; // &_xi_a just happens to be start of data segment
- int _edata; // &_edata is start of BSS segment
- int _end; // &_end is past end of BSS
-
- void* _DPbegin; // first entry in the array of pointers addresses
- void* _DPend; // &_DPend points after last entry of array
- uint _TPbegin; // first entry in the array of TLS offsets of pointers
- uint _TPend; // &_DPend points after last entry of array
- }
-
- extern
- {
- int _tlsstart;
- int _tlsend;
- }
-}
diff --git a/libphobos/libdruntime/gcc/sections/win64.d b/libphobos/libdruntime/gcc/sections/win64.d
index 357940ba821..512693c071d 100644
--- a/libphobos/libdruntime/gcc/sections/win64.d
+++ b/libphobos/libdruntime/gcc/sections/win64.d
@@ -51,14 +51,6 @@ struct SectionGroup
return _moduleGroup;
}
- version (Win64)
- @property immutable(FuncTable)[] ehTables() const nothrow @nogc
- {
- auto pbeg = cast(immutable(FuncTable)*)&_deh_beg;
- auto pend = cast(immutable(FuncTable)*)&_deh_end;
- return pbeg[0 .. pend - pbeg];
- }
-
@property inout(void[])[] gcRanges() inout nothrow @nogc
{
return _gcRanges[];
diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d
index 5315739f82f..592b3afcb71 100644
--- a/libphobos/libdruntime/gcc/unwind/generic.d
+++ b/libphobos/libdruntime/gcc/unwind/generic.d
@@ -269,6 +269,6 @@ version (GNU_SEH_Exceptions)
ExceptionCollidedUnwind
}
- extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*,
+ extern(C) EXCEPTION_DISPOSITION _GCC_specific_handler(void*, void*, void*, void*,
_Unwind_Personality_Fn);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 3d5ba299863..e4a2c6571d4 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -70,70 +70,6 @@ version (CRuntime_Microsoft)
extern(C) void init_msvc();
}
-/***********************************
- * These are a temporary means of providing a GC hook for DLL use. They may be
- * replaced with some other similar functionality later.
- */
-extern (C)
-{
- void* gc_getProxy();
- void gc_setProxy(void* p);
- void gc_clrProxy();
-
- alias void* function() gcGetFn;
- alias void function(void*) gcSetFn;
- alias void function() gcClrFn;
-}
-
-version (Windows)
-{
- /*******************************************
- * Loads a DLL written in D with the name 'name'.
- * Returns:
- * opaque handle to the DLL if successfully loaded
- * null if failure
- */
- extern (C) void* rt_loadLibrary(const char* name)
- {
- return initLibrary(.LoadLibraryA(name));
- }
-
- extern (C) void* rt_loadLibraryW(const wchar_t* name)
- {
- return initLibrary(.LoadLibraryW(name));
- }
-
- void* initLibrary(void* mod)
- {
- // BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
- // (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
- if (mod is null)
- return mod;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(mod, "gc_setProxy");
- if (gcSet !is null)
- { // BUG: Set proxy, but too late
- gcSet(gc_getProxy());
- }
- return mod;
- }
-
- /*************************************
- * Unloads DLL that was previously loaded by rt_loadLibrary().
- * Input:
- * ptr the handle returned by rt_loadLibrary()
- * Returns:
- * 1 succeeded
- * 0 some failure happened
- */
- extern (C) int rt_unloadLibrary(void* ptr)
- {
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
- if (gcClr !is null)
- gcClr();
- return FreeLibrary(ptr) != 0;
- }
-}
-
/* To get out-of-band access to the args[] passed to main().
*/
diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am
index 2de8ab951b4..0dc2a2625a9 100644
--- a/libphobos/src/Makefile.am
+++ b/libphobos/src/Makefile.am
@@ -24,7 +24,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS= \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
# Flags for other kinds of sources
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 2e721783d06..33453517153 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -414,6 +414,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -443,6 +445,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -477,7 +480,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) \
# D flags for compilation
AM_DFLAGS = \
- $(phobos_compiler_pic_flag) \
+ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \
$(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS)
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index c38a4688258..51eb4efc79d 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -242,6 +242,8 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
exec_prefix = @exec_prefix@
gcc_version = @gcc_version@
gdc_include_dir = @gdc_include_dir@
@@ -271,6 +273,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
phobos_compiler_pic_flag = @phobos_compiler_pic_flag@
phobos_compiler_shared_flag = @phobos_compiler_shared_flag@
+phobos_lt_pic_flag = @phobos_lt_pic_flag@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-04-10 15:22 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-24 15:25 [gcc(refs/users/ibuclaw/heads/mingw)] More MSVC support Iain Buclaw
2021-03-24 16:06 Iain Buclaw
2021-03-24 16:10 Iain Buclaw
2021-04-08 13:35 Iain Buclaw
2021-04-10 15:22 Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).