From b66e72b43e1e8f402dc958ce3cca35f7c273340d Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 19 Apr 2021 14:36:14 +0200 Subject: [PATCH] libphobos: Add D runtime support code for MinGW (PR99794) libphobos/ChangeLog: PR d/99794 * libdruntime/Makefile.am (DRUNTIME_SOURCES_CONFIGURED): Add config/mingw/msvc.c on DRUNTIME_OS_MINGW. * libdruntime/Makefile.in: Regenerate. * libdruntime/config/mingw/msvc.c: New file. * libdruntime/config/mingw/switchcontext.S (fiber_switchContext): Fix function definition. * libdruntime/gcc/deh.d (__gdc_personality_seh0): Fix call to _GCC_specific_handler. * libdruntime/gcc/gthread.d (__gthread_once_t): Fix definition. * libdruntime/gcc/unwind/generic.d (_GCC_specific_handler): Fix declaration. * libdruntime/rt/dmain2.d (rt_loadLibrary): Remove function. (rt_loadLibraryW): Remove function. (initLibrary): Remove function. (rt_unloadLibrary): Remove function. --- libphobos/libdruntime/Makefile.am | 3 +- libphobos/libdruntime/Makefile.in | 56 ++++--- libphobos/libdruntime/config/mingw/msvc.c | 169 +++++++++++++++++++++ libphobos/libdruntime/config/mingw/switchcontext.S | 12 +- libphobos/libdruntime/gcc/deh.d | 2 +- libphobos/libdruntime/gcc/gthread.d | 6 +- libphobos/libdruntime/gcc/unwind/generic.d | 2 +- libphobos/libdruntime/rt/dmain2.d | 67 +------- 8 files changed, 223 insertions(+), 94 deletions(-) create mode 100644 libphobos/libdruntime/config/mingw/msvc.c 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..da40718e3ed --- /dev/null +++ b/libphobos/libdruntime/config/mingw/msvc.c @@ -0,0 +1,169 @@ +/* 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 +. */ + +#ifdef __MINGW32__ +#include <_mingw.h> +#endif +#include + +/* The D runtime library defines stdin, stdout, and stderr as extern(C) symbols + in the core.stdc.stdio module, and require initializing at start-up. */ +__attribute__((weakref ("stdin"))) +static FILE *core_stdc_stdin; + +__attribute__((weakref ("stdout"))) +static FILE *core_stdc_stdout; + +__attribute__((weakref ("stderr"))) +static FILE *core_stdc_stderr; + +/* Set to 1 if runtime is using libucrt.dll. */ +unsigned char msvcUsesUCRT; + +void +init_msvc (void) +{ + core_stdc_stdin = stdin; + core_stdc_stdout = stdout; + core_stdc_stderr = stderr; + +#if __MSVCRT_VERSION__ >= 0xE00 + msvcUsedUCRT = 1; +#endif +} + +/* Phobos std.stdio module assumes these functions are present at link time, + and not absent or macros. */ +#ifdef _fgetc_nolock +#undef _fgetc_nolock + +int +_fgetc_nolock (FILE *fp) +{ + fp->_cnt--; + if (fp->_cnt >= 0) + { + const int c = *fp->_ptr; + fp->_ptr++; + return c & 0xff; + } + else + return _filbuf (fp); +} + +#endif /* _fgetc_nolock */ + +#ifdef _fputc_nolock +#undef _fputc_nolock + +int +_fputc_nolock (int c, FILE *fp) +{ + fp->_cnt--; + if (fp->_cnt >= 0) + { + *fp->_ptr = (char) c; + fp->_ptr++; + return c & 0xff; + } + else + return _flsbuf (c, fp); +} + +#endif /* _fputc_nolock */ + +#ifdef rewind +#undef rewind + +void +rewind (FILE *fp) +{ + fseek (fp, 0, SEEK_SET); + fp->_flag &= ~_IOERR; +} + +#endif /* rewind */ + +#ifdef clearerr +#undef clearerr + +void +clearerr (FILE *fp) +{ + fp->_flag &= ~(_IOERR | _IOEOF); +} + +#endif /* clearerr */ + +#ifdef feof +#undef feof + +int +feof (FILE *fp) +{ + return fp->_flag & _IOEOF; +} + +#endif /* feof */ + +#ifdef ferror +#undef ferror + +int +ferror (FILE *fp) +{ + return fp->_flag & _IOERR; +} + +#endif /* ferror */ + +#ifdef fileno +#undef fileno + +int +fileno (FILE *fp) +{ + return fp->_file; +} + +#endif /* fileno */ + +/* Phobos std.stdio module has a dependency on the UCRT library, so provide + stubs that forward to the nearest equivalent. */ +#if __MSVCRT_VERSION__ < 0x800 + +wint_t +_fgetwc_nolock (FILE *fp) +{ + return fgetwc (fp); +} + +wint_t +_fputwc_nolock (wchar_t c, FILE *fp) +{ + return fputwc(c, fp); +} + +#endif /* __MSVCRT_VERSION__ < 0x800*/ 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/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..e6acbd5105f 100644 --- a/libphobos/libdruntime/rt/dmain2.d +++ b/libphobos/libdruntime/rt/dmain2.d @@ -9,6 +9,9 @@ * Source: $(DRUNTIMESRC src/rt/_dmain2.d) */ +/* NOTE: This file has been patched from the original DMD distribution to + * work with the GDC compiler. + */ module rt.dmain2; private @@ -70,70 +73,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(). */ -- 2.11.4.GIT