From fdfcb5353cc2b06fc80205cfcb3bc5ba25556264 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 26 Mar 2021 15:46:24 +0100 Subject: libphobos: Build all modules with -fversion=Shared when configured with --enable-shared The libgdruntime_convenience library was built with `-fversion=Shared', but the libphobos part wasn't when creating the static library. As there are no issues compiling in Shared code into the static library, to avoid mismatches the flag is now always present when --enable-shared is turned on. Libtool's compiler PIC D flag is now the combination of compiler PIC and D Shared flags, and AM_DFLAGS passes `-prefer-pic' to libtool unless --enable-shared is turned off. libphobos/ChangeLog: * Makefile.in: Regenerate. * configure: Regenerate. * configure.ac: Substitute enable_shared, enable_static, and phobos_lt_pic_flag. * libdruntime/Makefile.am (AM_DFLAGS): Replace phobos_compiler_pic_flag with phobos_lt_pic_flags, and phobos_compiler_shared_flag. * libdruntime/Makefile.in: Regenerate. * src/Makefile.am (AM_DFLAGS): Replace phobos_compiler_pic_flag with phobos_lt_pic_flag, and phobos_compiler_shared_flag. * src/Makefile.in: Regenerate. * testsuite/Makefile.in: Regenerate. * testsuite/libphobos.druntime_shared/druntime_shared.exp: Remove -fversion=Shared and -fno-moduleinfo from default extra test flags. * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise. * testsuite/testsuite_flags.in: Add phobos_compiler_shared_flag to --gdcflags. --- libphobos/Makefile.in | 3 +++ libphobos/configure | 24 ++++++++++++++-------- libphobos/configure.ac | 17 ++++++++------- libphobos/libdruntime/Makefile.am | 2 +- libphobos/libdruntime/Makefile.in | 5 ++++- libphobos/src/Makefile.am | 2 +- libphobos/src/Makefile.in | 5 ++++- libphobos/testsuite/Makefile.in | 3 +++ .../libphobos.druntime_shared/druntime_shared.exp | 4 ++-- .../libphobos.phobos_shared/phobos_shared.exp | 4 ++-- libphobos/testsuite/testsuite_flags.in | 3 ++- 11 files changed, 47 insertions(+), 25 deletions(-) (limited to 'libphobos') diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in index d422484..eab1268 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 c940a40..59ca64a 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 cc9af29..248d0eb 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 945271e..535ca26 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 diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 06c0296..7960add 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -659,6 +659,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 +690,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 +723,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) diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am index 2de8ab9..0dc2a26 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 2e72178..3345351 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 c38a468..51eb4ef 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@ diff --git a/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp b/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp index 6ca62a3..2b25613 100644 --- a/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp +++ b/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp @@ -34,8 +34,8 @@ dg-init # Main loop. foreach test $tests { set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../libdruntime $test]" - dg-runtest $test "-fversion=Shared -shared-libphobos" \ - "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags" + dg-runtest $test "-shared-libphobos" \ + "-fmain -fbuilding-libphobos-tests $version_flags" set libphobos_test_name "" } diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp index da31304..3a847e7 100644 --- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp +++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp @@ -45,8 +45,8 @@ dg-init # Main loop. foreach test $tests { set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]" - dg-runtest $test "-fversion=Shared -shared-libphobos" \ - "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags" + dg-runtest $test "-shared-libphobos" \ + "-fmain -fbuilding-libphobos-tests $version_flags" set libphobos_test_name "" } diff --git a/libphobos/testsuite/testsuite_flags.in b/libphobos/testsuite/testsuite_flags.in index 6a2d79f..bafd5ad4 100755 --- a/libphobos/testsuite/testsuite_flags.in +++ b/libphobos/testsuite/testsuite_flags.in @@ -28,7 +28,8 @@ case ${query} in ;; --gdcflags) GDCFLAGS_default="-fmessage-length=0 -fno-show-column" - GDCFLAGS_config="@WARN_DFLAGS@ @GDCFLAGS@ @CET_DFLAGS@ -fno-release -funittest" + GDCFLAGS_config="@WARN_DFLAGS@ @GDCFLAGS@ @CET_DFLAGS@ + @phobos_compiler_shared_flag@ -fno-release -funittest" echo ${GDCFLAGS_default} ${GDCFLAGS_config} ;; --gdcpaths) -- cgit v1.1 From 651684b462f979a4e70a668c4c9767a5fd7d223a Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 27 Mar 2021 00:16:27 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 235af5b..e58bd3c 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,23 @@ +2021-03-26 Iain Buclaw + + * Makefile.in: Regenerate. + * configure: Regenerate. + * configure.ac: Substitute enable_shared, enable_static, and + phobos_lt_pic_flag. + * libdruntime/Makefile.am (AM_DFLAGS): Replace + phobos_compiler_pic_flag with phobos_lt_pic_flags, and + phobos_compiler_shared_flag. + * libdruntime/Makefile.in: Regenerate. + * src/Makefile.am (AM_DFLAGS): Replace phobos_compiler_pic_flag + with phobos_lt_pic_flag, and phobos_compiler_shared_flag. + * src/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * testsuite/libphobos.druntime_shared/druntime_shared.exp: Remove + -fversion=Shared and -fno-moduleinfo from default extra test flags. + * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise. + * testsuite/testsuite_flags.in: Add phobos_compiler_shared_flag to + --gdcflags. + 2021-02-04 Iain Buclaw PR d/98910 -- cgit v1.1 From 5a0aa603b2452dca48ad86d97d4b918187d259fc Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 2 Apr 2021 13:29:22 +0200 Subject: d: Merge upstream dmd 3b808e838, druntime 483bc129, phobos f89dc217a D front-end changes: - Explicit package visibility attribute is now always applied to introducing scopes. - Added `__traits(totype, string)' to convert mangled type string to an existing type. - Printf-like and scanf-like functions are now detected by prefixing them with `pragma(printf)' for printf-like functions or `pragma(scanf)' for scanf-like functions. - Added `__c_wchar_t', `__c_complex_float', `__c_complex_double', and `__c_complex_real' types for interfacing with C and C++. - Template alias parameters can now be instantiated with basic types, such as `int` or `void function()`. - Mixins can now be used as types in the form `mixin(string) var'. - Mixin expressions can take an argument list, same as `pragma(msg)'. - Implement DIP1034, add `typeof(*null)' types to represent `noreturn'. - `pragma(msg)' can print expressions of type `void'. - It is now an error to use private variables selectively imported from other modules. Due to a bug, some imported private members were visible from other modules, violating the specification. - Added new syntax to declare an alias to a function type using the `alias' syntax based on the assignment operator. - Function literals can now return a value by reference. Phobos changes: - Synchronize C bindings with the latest port fixes in upstream druntime. - Added alias for a `noreturn' type in object.d - Make use of the new `pragma(printf)' and `pragma(scanf)' pragmas, fix all code that got flagged as being incorrect. - Fixed code that relied on bugs in the D import package system. Reviewed-on: https://github.com/dlang/dmd/pull/12339 https://github.com/dlang/druntime/pull/3422 https://github.com/dlang/phobos/pull/7932 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 3b808e838. * Make-lang.in (D_FRONTEND_OBJS): Add d/chkformat.o. * d-codegen.cc (build_struct_literal): Handle special enums. * d-convert.cc (convert_expr): Handle noreturn type. (convert_for_condition): Likewise. * d-target.cc (Target::_init): Set type for wchar_t. (TargetCPP::derivedClassOffset): New method. (Target::libraryObjectMonitors): New method. * decl.cc (get_symbol_decl): Set TREE_THIS_VOLATILE for functions of type noreturn. * toir.cc (IRVisitor::visit (ReturnStatement *)): Handle returning noreturn types. * types.cc (TypeVisitor::visit (TypeNoreturn *)): New method. (TypeVisitor::visit (TypeEnum *)): Handle special enums. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 483bc129. * libdruntime/Makefile.am (DRUNTIME_DSOURCES_DARWIN): Add core/sys/darwin/fcntl.d. (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/unistd.d. (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/stdc/malloc.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos f89dc217a. * src/Makefile.am (PHOBOS_DSOURCES): Add std/regex/internal/tests2.d. * src/Makefile.in: Regenerate. * testsuite/libphobos.exceptions/chain.d: Fix format arguments. * testsuite/libphobos.exceptions/line_trace.d: Likewise. --- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/Makefile.am | 58 +- libphobos/libdruntime/Makefile.in | 105 ++-- libphobos/libdruntime/core/stdc/complex.d | 70 +-- libphobos/libdruntime/core/stdc/config.d | 43 ++ libphobos/libdruntime/core/stdc/errno.d | 16 +- libphobos/libdruntime/core/stdc/math.d | 400 +++++-------- libphobos/libdruntime/core/stdc/stdio.d | 61 +- libphobos/libdruntime/core/stdc/stdlib.d | 6 +- libphobos/libdruntime/core/stdc/tgmath.d | 653 ++++++++------------ libphobos/libdruntime/core/stdc/wchar_.d | 9 +- libphobos/libdruntime/core/sys/darwin/fcntl.d | 20 + libphobos/libdruntime/core/sys/linux/epoll.d | 88 ++- libphobos/libdruntime/core/sys/openbsd/string.d | 2 + libphobos/libdruntime/core/sys/openbsd/unistd.d | 17 + libphobos/libdruntime/core/sys/posix/config.d | 1 + libphobos/libdruntime/core/sys/posix/dlfcn.d | 11 +- libphobos/libdruntime/core/sys/posix/signal.d | 14 +- libphobos/libdruntime/core/sys/posix/unistd.d | 48 ++ libphobos/libdruntime/core/sys/windows/com.d | 20 +- libphobos/libdruntime/core/sys/windows/dll.d | 12 +- .../libdruntime/core/sys/windows/stdc/malloc.d | 26 + libphobos/libdruntime/gc/impl/conservative/gc.d | 4 +- libphobos/libdruntime/object.d | 7 +- libphobos/src/MERGE | 2 +- libphobos/src/Makefile.am | 12 +- libphobos/src/Makefile.in | 14 +- libphobos/src/std/algorithm/iteration.d | 8 +- libphobos/src/std/algorithm/searching.d | 4 +- libphobos/src/std/container/rbtree.d | 4 +- libphobos/src/std/conv.d | 2 +- libphobos/src/std/datetime/systime.d | 4 +- libphobos/src/std/experimental/logger/nulllogger.d | 2 +- libphobos/src/std/experimental/typecons.d | 6 +- libphobos/src/std/file.d | 5 +- libphobos/src/std/format.d | 4 +- libphobos/src/std/internal/math/biguintcore.d | 4 +- libphobos/src/std/math.d | 4 +- libphobos/src/std/parallelism.d | 4 +- libphobos/src/std/range/package.d | 1 - libphobos/src/std/regex/internal/tests.d | 653 +------------------- libphobos/src/std/regex/internal/tests2.d | 662 +++++++++++++++++++++ libphobos/src/std/socket.d | 2 +- libphobos/src/std/typecons.d | 10 +- libphobos/src/std/zip.d | 6 +- libphobos/testsuite/libphobos.exceptions/chain.d | 4 +- .../testsuite/libphobos.exceptions/line_trace.d | 2 +- 47 files changed, 1568 insertions(+), 1544 deletions(-) create mode 100644 libphobos/libdruntime/core/sys/darwin/fcntl.d create mode 100644 libphobos/libdruntime/core/sys/openbsd/unistd.d create mode 100644 libphobos/libdruntime/core/sys/windows/stdc/malloc.d create mode 100644 libphobos/src/std/regex/internal/tests2.d (limited to 'libphobos') diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index a4a9a94..b797682 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -0fd4364c4a4eb2ce0ebb8f613092c5bed7a63bf9 +483bc12977af3c1288fd52e7b4fa14b716896c5a The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 535ca26..2a5c793 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -208,16 +208,17 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \ DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \ core/sys/darwin/dlfcn.d core/sys/darwin/err.d \ - core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \ - core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \ - core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \ - core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \ - core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \ - core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \ - core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \ - core/sys/darwin/string.d core/sys/darwin/sys/attr.d \ - core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \ - core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d + core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \ + core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \ + core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \ + core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \ + core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \ + core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \ + core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \ + core/sys/darwin/stdlib.d core/sys/darwin/string.d \ + core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \ + core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \ + core/sys/darwin/sys/sysctl.d DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \ core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \ @@ -275,7 +276,8 @@ DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \ core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \ core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \ - core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d + core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \ + core/sys/openbsd/unistd.d DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ core/sys/posix/arpa/inet.d core/sys/posix/config.d \ @@ -382,22 +384,22 @@ DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \ core/sys/windows/sqlext.d core/sys/windows/sqltypes.d \ core/sys/windows/sqlucode.d core/sys/windows/sspi.d \ core/sys/windows/stacktrace.d core/sys/windows/stat.d \ - core/sys/windows/stdc/time.d core/sys/windows/subauth.d \ - core/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \ - core/sys/windows/tmschema.d core/sys/windows/unknwn.d \ - core/sys/windows/uuid.d core/sys/windows/vfw.d \ - core/sys/windows/w32api.d core/sys/windows/winbase.d \ - core/sys/windows/winber.d core/sys/windows/wincon.d \ - core/sys/windows/wincrypt.d core/sys/windows/windef.d \ - core/sys/windows/windows.d core/sys/windows/winerror.d \ - core/sys/windows/wingdi.d core/sys/windows/winhttp.d \ - core/sys/windows/wininet.d core/sys/windows/winioctl.d \ - core/sys/windows/winldap.d core/sys/windows/winnetwk.d \ - core/sys/windows/winnls.d core/sys/windows/winnt.d \ - core/sys/windows/winperf.d core/sys/windows/winreg.d \ - core/sys/windows/winsock2.d core/sys/windows/winspool.d \ - core/sys/windows/winsvc.d core/sys/windows/winuser.d \ - core/sys/windows/winver.d core/sys/windows/wtsapi32.d \ - core/sys/windows/wtypes.d + core/sys/windows/stdc/malloc.d core/sys/windows/stdc/time.d \ + core/sys/windows/subauth.d core/sys/windows/threadaux.d \ + core/sys/windows/tlhelp32.d core/sys/windows/tmschema.d \ + core/sys/windows/unknwn.d core/sys/windows/uuid.d \ + core/sys/windows/vfw.d core/sys/windows/w32api.d \ + core/sys/windows/winbase.d core/sys/windows/winber.d \ + core/sys/windows/wincon.d core/sys/windows/wincrypt.d \ + core/sys/windows/windef.d core/sys/windows/windows.d \ + core/sys/windows/winerror.d core/sys/windows/wingdi.d \ + core/sys/windows/winhttp.d core/sys/windows/wininet.d \ + core/sys/windows/winioctl.d core/sys/windows/winldap.d \ + core/sys/windows/winnetwk.d core/sys/windows/winnls.d \ + core/sys/windows/winnt.d core/sys/windows/winperf.d \ + core/sys/windows/winreg.d core/sys/windows/winsock2.d \ + core/sys/windows/winspool.d core/sys/windows/winsvc.d \ + core/sys/windows/winuser.d core/sys/windows/winver.d \ + core/sys/windows/wtsapi32.d core/sys/windows/wtypes.d DRUNTIME_DISOURCES = __entrypoint.di __main.di diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 7960add..b00fe02 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -256,8 +256,9 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \ @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3) am__objects_5 = core/sys/darwin/crt_externs.lo \ core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \ - core/sys/darwin/execinfo.lo core/sys/darwin/ifaddrs.lo \ - core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \ + core/sys/darwin/execinfo.lo core/sys/darwin/fcntl.lo \ + core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \ + core/sys/darwin/mach/getsect.lo \ core/sys/darwin/mach/kern_return.lo \ core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \ core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \ @@ -322,7 +323,8 @@ am__objects_15 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/err.lo \ core/sys/openbsd/sys/elf32.lo core/sys/openbsd/sys/elf64.lo \ core/sys/openbsd/sys/elf_common.lo \ core/sys/openbsd/sys/link_elf.lo core/sys/openbsd/sys/mman.lo \ - core/sys/openbsd/sys/sysctl.lo core/sys/openbsd/time.lo + core/sys/openbsd/sys/sysctl.lo core/sys/openbsd/time.lo \ + core/sys/openbsd/unistd.lo @DRUNTIME_OS_OPENBSD_TRUE@am__objects_16 = $(am__objects_15) am__objects_17 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \ core/sys/linux/elf.lo core/sys/linux/epoll.lo \ @@ -408,23 +410,24 @@ am__objects_19 = core/sys/windows/accctrl.lo \ core/sys/windows/sql.lo core/sys/windows/sqlext.lo \ core/sys/windows/sqltypes.lo core/sys/windows/sqlucode.lo \ core/sys/windows/sspi.lo core/sys/windows/stacktrace.lo \ - core/sys/windows/stat.lo core/sys/windows/stdc/time.lo \ - core/sys/windows/subauth.lo core/sys/windows/threadaux.lo \ - core/sys/windows/tlhelp32.lo core/sys/windows/tmschema.lo \ - core/sys/windows/unknwn.lo core/sys/windows/uuid.lo \ - core/sys/windows/vfw.lo core/sys/windows/w32api.lo \ - core/sys/windows/winbase.lo core/sys/windows/winber.lo \ - core/sys/windows/wincon.lo core/sys/windows/wincrypt.lo \ - core/sys/windows/windef.lo core/sys/windows/windows.lo \ - core/sys/windows/winerror.lo core/sys/windows/wingdi.lo \ - core/sys/windows/winhttp.lo core/sys/windows/wininet.lo \ - core/sys/windows/winioctl.lo core/sys/windows/winldap.lo \ - core/sys/windows/winnetwk.lo core/sys/windows/winnls.lo \ - core/sys/windows/winnt.lo core/sys/windows/winperf.lo \ - core/sys/windows/winreg.lo core/sys/windows/winsock2.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 + core/sys/windows/stat.lo core/sys/windows/stdc/malloc.lo \ + core/sys/windows/stdc/time.lo core/sys/windows/subauth.lo \ + core/sys/windows/threadaux.lo core/sys/windows/tlhelp32.lo \ + core/sys/windows/tmschema.lo core/sys/windows/unknwn.lo \ + core/sys/windows/uuid.lo core/sys/windows/vfw.lo \ + core/sys/windows/w32api.lo core/sys/windows/winbase.lo \ + core/sys/windows/winber.lo core/sys/windows/wincon.lo \ + core/sys/windows/wincrypt.lo core/sys/windows/windef.lo \ + core/sys/windows/windows.lo core/sys/windows/winerror.lo \ + core/sys/windows/wingdi.lo core/sys/windows/winhttp.lo \ + core/sys/windows/wininet.lo core/sys/windows/winioctl.lo \ + core/sys/windows/winldap.lo core/sys/windows/winnetwk.lo \ + core/sys/windows/winnls.lo core/sys/windows/winnt.lo \ + core/sys/windows/winperf.lo core/sys/windows/winreg.lo \ + core/sys/windows/winsock2.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) am__objects_21 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \ core/sys/solaris/err.lo core/sys/solaris/execinfo.lo \ @@ -837,16 +840,17 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \ DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \ core/sys/darwin/dlfcn.d core/sys/darwin/err.d \ - core/sys/darwin/execinfo.d core/sys/darwin/ifaddrs.d \ - core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \ - core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \ - core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \ - core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \ - core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \ - core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \ - core/sys/darwin/string.d core/sys/darwin/sys/attr.d \ - core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \ - core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d + core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \ + core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \ + core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \ + core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \ + core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \ + core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \ + core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \ + core/sys/darwin/stdlib.d core/sys/darwin/string.d \ + core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \ + core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \ + core/sys/darwin/sys/sysctl.d DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \ core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \ @@ -904,7 +908,8 @@ DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \ core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \ core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \ - core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d + core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \ + core/sys/openbsd/unistd.d DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ core/sys/posix/arpa/inet.d core/sys/posix/config.d \ @@ -1011,23 +1016,23 @@ DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \ core/sys/windows/sqlext.d core/sys/windows/sqltypes.d \ core/sys/windows/sqlucode.d core/sys/windows/sspi.d \ core/sys/windows/stacktrace.d core/sys/windows/stat.d \ - core/sys/windows/stdc/time.d core/sys/windows/subauth.d \ - core/sys/windows/threadaux.d core/sys/windows/tlhelp32.d \ - core/sys/windows/tmschema.d core/sys/windows/unknwn.d \ - core/sys/windows/uuid.d core/sys/windows/vfw.d \ - core/sys/windows/w32api.d core/sys/windows/winbase.d \ - core/sys/windows/winber.d core/sys/windows/wincon.d \ - core/sys/windows/wincrypt.d core/sys/windows/windef.d \ - core/sys/windows/windows.d core/sys/windows/winerror.d \ - core/sys/windows/wingdi.d core/sys/windows/winhttp.d \ - core/sys/windows/wininet.d core/sys/windows/winioctl.d \ - core/sys/windows/winldap.d core/sys/windows/winnetwk.d \ - core/sys/windows/winnls.d core/sys/windows/winnt.d \ - core/sys/windows/winperf.d core/sys/windows/winreg.d \ - core/sys/windows/winsock2.d core/sys/windows/winspool.d \ - core/sys/windows/winsvc.d core/sys/windows/winuser.d \ - core/sys/windows/winver.d core/sys/windows/wtsapi32.d \ - core/sys/windows/wtypes.d + core/sys/windows/stdc/malloc.d core/sys/windows/stdc/time.d \ + core/sys/windows/subauth.d core/sys/windows/threadaux.d \ + core/sys/windows/tlhelp32.d core/sys/windows/tmschema.d \ + core/sys/windows/unknwn.d core/sys/windows/uuid.d \ + core/sys/windows/vfw.d core/sys/windows/w32api.d \ + core/sys/windows/winbase.d core/sys/windows/winber.d \ + core/sys/windows/wincon.d core/sys/windows/wincrypt.d \ + core/sys/windows/windef.d core/sys/windows/windows.d \ + core/sys/windows/winerror.d core/sys/windows/wingdi.d \ + core/sys/windows/winhttp.d core/sys/windows/wininet.d \ + core/sys/windows/winioctl.d core/sys/windows/winldap.d \ + core/sys/windows/winnetwk.d core/sys/windows/winnls.d \ + core/sys/windows/winnt.d core/sys/windows/winperf.d \ + core/sys/windows/winreg.d core/sys/windows/winsock2.d \ + core/sys/windows/winspool.d core/sys/windows/winsvc.d \ + core/sys/windows/winuser.d core/sys/windows/winver.d \ + core/sys/windows/wtsapi32.d core/sys/windows/wtypes.d DRUNTIME_DISOURCES = __entrypoint.di __main.di all: all-am @@ -1346,6 +1351,7 @@ core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/execinfo.lo: core/sys/darwin/$(am__dirstamp) +core/sys/darwin/fcntl.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/ifaddrs.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/mach/$(am__dirstamp): @$(MKDIR_P) core/sys/darwin/mach @@ -1510,6 +1516,7 @@ core/sys/openbsd/sys/link_elf.lo: \ core/sys/openbsd/sys/mman.lo: core/sys/openbsd/sys/$(am__dirstamp) core/sys/openbsd/sys/sysctl.lo: core/sys/openbsd/sys/$(am__dirstamp) core/sys/openbsd/time.lo: core/sys/openbsd/$(am__dirstamp) +core/sys/openbsd/unistd.lo: core/sys/openbsd/$(am__dirstamp) core/sys/linux/$(am__dirstamp): @$(MKDIR_P) core/sys/linux @: > core/sys/linux/$(am__dirstamp) @@ -1690,6 +1697,8 @@ core/sys/windows/stat.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/stdc/$(am__dirstamp): @$(MKDIR_P) core/sys/windows/stdc @: > core/sys/windows/stdc/$(am__dirstamp) +core/sys/windows/stdc/malloc.lo: \ + core/sys/windows/stdc/$(am__dirstamp) core/sys/windows/stdc/time.lo: core/sys/windows/stdc/$(am__dirstamp) core/sys/windows/subauth.lo: core/sys/windows/$(am__dirstamp) core/sys/windows/threadaux.lo: core/sys/windows/$(am__dirstamp) diff --git a/libphobos/libdruntime/core/stdc/complex.d b/libphobos/libdruntime/core/stdc/complex.d index d878366..b84651f 100644 --- a/libphobos/libdruntime/core/stdc/complex.d +++ b/libphobos/libdruntime/core/stdc/complex.d @@ -19,163 +19,97 @@ extern (C): nothrow: @nogc: -/// +// @@@DEPRECATED_2.105@@@ +deprecated: alias creal complex; -/// alias ireal imaginary; -/// cdouble cacos(cdouble z); -/// cfloat cacosf(cfloat z); -/// creal cacosl(creal z); -/// cdouble casin(cdouble z); -/// cfloat casinf(cfloat z); -/// creal casinl(creal z); -/// cdouble catan(cdouble z); -/// cfloat catanf(cfloat z); -/// creal catanl(creal z); -/// cdouble ccos(cdouble z); -/// cfloat ccosf(cfloat z); -/// creal ccosl(creal z); -/// cdouble csin(cdouble z); -/// cfloat csinf(cfloat z); -/// creal csinl(creal z); -/// cdouble ctan(cdouble z); -/// cfloat ctanf(cfloat z); -/// creal ctanl(creal z); -/// cdouble cacosh(cdouble z); -/// cfloat cacoshf(cfloat z); -/// creal cacoshl(creal z); -/// cdouble casinh(cdouble z); -/// cfloat casinhf(cfloat z); -/// creal casinhl(creal z); -/// cdouble catanh(cdouble z); -/// cfloat catanhf(cfloat z); -/// creal catanhl(creal z); -/// cdouble ccosh(cdouble z); -/// cfloat ccoshf(cfloat z); -/// creal ccoshl(creal z); -/// cdouble csinh(cdouble z); -/// cfloat csinhf(cfloat z); -/// creal csinhl(creal z); -/// cdouble ctanh(cdouble z); -/// cfloat ctanhf(cfloat z); -/// creal ctanhl(creal z); -/// cdouble cexp(cdouble z); -/// cfloat cexpf(cfloat z); -/// creal cexpl(creal z); -/// cdouble clog(cdouble z); -/// cfloat clogf(cfloat z); -/// creal clogl(creal z); -/// double cabs(cdouble z); - /// float cabsf(cfloat z); - /// real cabsl(creal z); - /// cdouble cpow(cdouble x, cdouble y); -/// cfloat cpowf(cfloat x, cfloat y); -/// creal cpowl(creal x, creal y); -/// cdouble csqrt(cdouble z); -/// cfloat csqrtf(cfloat z); -/// creal csqrtl(creal z); -/// double carg(cdouble z); - /// float cargf(cfloat z); - /// real cargl(creal z); -/// pragma(inline, true) double cimag(cdouble z) { return z.im; } -/// pragma(inline, true) float cimagf(cfloat z) { return z.im; } -/// pragma(inline, true) real cimagl(creal z) { return z.im; } -/// cdouble conj(cdouble z); -/// cfloat conjf(cfloat z); -/// creal conjl(creal z); -/// cdouble cproj(cdouble z); -/// cfloat cprojf(cfloat z); -/// creal cprojl(creal z); // Note: `creal` is a keyword in D and so this function is inaccessible, use `creald` instead //pragma(inline, true) double creal(cdouble z) { return z.re; } -/// pragma(inline, true) double creald(cdouble z) { return z.re; } -/// pragma(inline, true) float crealf(cfloat z) { return z.re; } -/// pragma(inline, true) real creall(creal z) { return z.re; } diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d index cdb987f..802f5b6 100644 --- a/libphobos/libdruntime/core/stdc/config.d +++ b/libphobos/libdruntime/core/stdc/config.d @@ -34,6 +34,7 @@ version (StdDdoc) alias ddoc_long = int; alias ddoc_ulong = uint; } + struct ddoc_complex(T) { T re; T im; }; } /*** @@ -89,6 +90,24 @@ version (StdDdoc) * C++ compiler's `ptrdiff_t` type. */ alias cpp_ptrdiff_t = ptrdiff_t; + + /*** + * Used for a complex floating point type that corresponds in size and ABI to the associated + * C compiler's `_Complex float` type. + */ + alias c_complex_float = ddoc_complex!float; + + /*** + * Used for a complex floating point type that corresponds in size and ABI to the associated + * C compiler's `_Complex double` type. + */ + alias c_complex_double = ddoc_complex!double; + + /*** + * Used for a complex floating point type that corresponds in size and ABI to the associated + * C compiler's `_Complex long double` type. + */ + alias c_complex_real = ddoc_complex!real; } else { @@ -230,4 +249,28 @@ else alias cpp_size_t = size_t; alias cpp_ptrdiff_t = ptrdiff_t; } + +// ABI layout of native complex types. +private struct _Complex(T) +{ + T re; + T im; +} + +version (Posix) +{ + align(float.alignof) enum __c_complex_float : _Complex!float; + align(double.alignof) enum __c_complex_double : _Complex!double; + align(real.alignof) enum __c_complex_real : _Complex!real; +} +else +{ + align(float.sizeof * 2) enum __c_complex_float : _Complex!float; + align(double.sizeof * 2) enum __c_complex_double : _Complex!double; + align(real.alignof) enum __c_complex_real : _Complex!real; +} + +alias c_complex_float = __c_complex_float; +alias c_complex_double = __c_complex_double; +alias c_complex_real = __c_complex_real; } diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d index 31f7d11..57bc15d 100644 --- a/libphobos/libdruntime/core/stdc/errno.d +++ b/libphobos/libdruntime/core/stdc/errno.d @@ -156,15 +156,9 @@ else version (Haiku) else { /// - @property int errno() { return getErrno(); } + extern(C) pragma(mangle, "getErrno") @property int errno(); /// - @property int errno(int n) { return setErrno(n); } - - extern (C) - { - private int getErrno(); // for internal use - private int setErrno(int); // for internal use - } + extern(C) pragma(mangle, "setErrno") @property int errno(int n); } extern (C): @@ -1532,7 +1526,11 @@ else version (OpenBSD) enum EIDRM = 89; /// Identifier removed enum ENOMSG = 90; /// No message of desired type enum ENOTSUP = 91; /// Not supported - enum ELAST = 91; /// Must be equal largest errno + enum EBADMSG = 92; /// Bad message + enum ENOTRECOVERABLE = 93; /// State not recoverable + enum EOWNERDEAD = 94; /// Previous owner died + enum EPROTO = 95; /// Protocol error + enum ELAST = 95; /// Must be equal largest errno } else version (DragonFlyBSD) { diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d index e8d1fa8..fba78ee 100644 --- a/libphobos/libdruntime/core/stdc/math.d +++ b/libphobos/libdruntime/core/stdc/math.d @@ -319,16 +319,12 @@ version (CRuntime_DigitalMars) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassify_f(x); } + extern(C) pragma(mangle, "__fpclassify_f") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassify_d(x); } + extern(C) pragma(mangle, "__fpclassify_d") pure int fpclassify(double x); /// - pure int fpclassify(real x) - { - return (real.sizeof == double.sizeof) - ? __fpclassify_d(x) - : __fpclassify_ld(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify_d" : "__fpclassify_ld") + pure int fpclassify(real x); //int isfinite(real-floating x); /// @@ -442,24 +438,18 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o FP_NAN = 2, } - pure private short _fdclass(float x); - pure private short _dclass(double x); - - pure private int _fdsign(float x); - pure private int _dsign(double x); - extern(D) { //int fpclassify(real-floating x); /// - pure int fpclassify()(float x) { return _fdclass(x); } + extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x); /// - pure int fpclassify()(double x) { return _dclass(x); } + extern(C) pragma(mangle, "_dclass") pure int fpclassify(double x); /// pure int fpclassify()(real x) { static if (real.sizeof == double.sizeof) - return _dclass(cast(double) x); + return fpclassify(cast(double) x); else static assert(false, "fpclassify(real) not supported by MS C runtime"); } @@ -495,7 +485,7 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o /// pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); } /// - pure int isnan(double x) { return _isnan(x); } + extern(C) pragma(mangle, "_isnan") pure int isnan(double x); /// pure int isnan(real x) { return _isnan(cast(double) x); } } @@ -510,14 +500,14 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o //int signbit(real-floating x); /// - pure int signbit()(float x) { return _fdsign(x); } + extern(C) pragma(mangle, "_fdsign") pure int signbit(float x); /// - pure int signbit()(double x) { return _dsign(x); } + extern(C) pragma(mangle, "_dsign") pure int signbit(double x); /// pure int signbit()(real x) { static if (real.sizeof == double.sizeof) - return _dsign(cast(double) x); + return signbit(cast(double) x); else return (cast(short*)&(x))[4] & 0x8000; } @@ -573,55 +563,39 @@ else version (CRuntime_Glibc) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassify(x); } + extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x); /// - pure int fpclassify(real x) - { - return (real.sizeof == double.sizeof) - ? __fpclassify(x) - : __fpclassifyl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl") + pure int fpclassify(real x); //int isfinite(real-floating x); /// - pure int isfinite(float x) { return __finitef(x); } + extern(C) pragma(mangle, "__finitef") pure int isfinite(float x); /// - pure int isfinite(double x) { return __finite(x); } + extern(C) pragma(mangle, "__finite") pure int isfinite(double x); /// - pure int isfinite(real x) - { - return (real.sizeof == double.sizeof) - ? __finite(x) - : __finitel(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__finite" : "__finitel") + pure int isfinite(real x); //int isinf(real-floating x); /// - pure int isinf(float x) { return __isinff(x); } + extern(C) pragma(mangle, "__isinff") pure int isinf(float x); /// - pure int isinf(double x) { return __isinf(x); } + extern(C) pragma(mangle, "__isinf") pure int isinf(double x); /// - pure int isinf(real x) - { - return (real.sizeof == double.sizeof) - ? __isinf(x) - : __isinfl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isinf" : "__isinfl") + pure int isinf(real x); //int isnan(real-floating x); /// - pure int isnan(float x) { return __isnanf(x); } + extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); /// - pure int isnan(double x) { return __isnan(x); } + extern(C) pragma(mangle, "__isnan") pure int isnan(double x); /// - pure int isnan(real x) - { - return (real.sizeof == double.sizeof) - ? __isnan(x) - : __isnanl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") + pure int isnan(real x); //int isnormal(real-floating x); /// @@ -633,16 +607,12 @@ else version (CRuntime_Glibc) //int signbit(real-floating x); /// - pure int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); /// - pure int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); /// - pure int signbit(real x) - { - return (real.sizeof == double.sizeof) - ? __signbit(x) - : __signbitl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl") + pure int signbit(real x); } } else version (CRuntime_Musl) @@ -685,16 +655,12 @@ else version (CRuntime_Musl) { //int fpclassify(real-floating x); /// - int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") int fpclassify(float x); /// - int fpclassify(double x) { return __fpclassify(x); } + extern(C) pragma(mangle, "__fpclassify") int fpclassify(double x); /// - int fpclassify(real x) - { - return (real.sizeof == double.sizeof) - ? __fpclassify(x) - : __fpclassifyl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl") + int fpclassify(real x); private uint __FLOAT_BITS(float __f) { union __u_t { @@ -765,16 +731,12 @@ else version (CRuntime_Musl) //int signbit(real-floating x); /// - int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") int signbit(float x); /// - int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") int signbit(double x); /// - int signbit(real x) - { - return (real.sizeof == double.sizeof) - ? __signbit(x) - : __signbitl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl") + int signbit(real x); } } else version (CRuntime_UClibc) @@ -826,52 +788,36 @@ else version (CRuntime_UClibc) extern (D) { /// - int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") int fpclassify(float x); /// - int fpclassify(double x) { return __fpclassify(x); } + extern(C) pragma(mangle, "__fpclassify") int fpclassify(double x); /// - int fpclassify(real x) - { - return (real.sizeof == double.sizeof) - ? __fpclassify(x) - : __fpclassifyl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl") + int fpclassify(real x); /// - int isfinite(float x) { return __finitef(x); } + extern(C) pragma(mangle, "__finitef") int isfinite(float x); /// - int isfinite(double x) { return __finite(x); } + extern(C) pragma(mangle, "__finite") int isfinite(double x); /// - int isfinite(real x) - { - return (real.sizeof == double.sizeof) - ? __finite(x) - : __finitel(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__finite" : "__finitel") + int isfinite(real x); /// - int isinf(float x) { return __isinff(x); } + extern(C) pragma(mangle, "__isinff") int isinf(float x); /// - int isinf(double x) { return __isinf(x); } + extern(C) pragma(mangle, "__isinf") int isinf(double x); /// - int isinf(real x) - { - return (real.sizeof == double.sizeof) - ? __isinf(x) - : __isinfl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isinf" : "__isinfl") + int isinf(real x); /// - int isnan(float x) { return __isnanf(x); } + extern(C) pragma(mangle, "__isnanf") int isnan(float x); /// - int isnan(double x) { return __isnan(x); } + extern(C) pragma(mangle, "__isnan") int isnan(double x); /// - int isnan(real x) - { - return (real.sizeof == double.sizeof) - ? __isnan(x) - : __isnanl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") + int isnan(real x); /// int isnormal(float x) { return fpclassify(x) == FP_NORMAL; } @@ -881,16 +827,12 @@ else version (CRuntime_UClibc) int isnormal(real x) { return fpclassify(x) == FP_NORMAL; } /// - int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") int signbit(float x); /// - int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") int signbit(double x); /// - int signbit(real x) - { - return (real.sizeof == double.sizeof) - ? __signbit(x) - : __signbitl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl") + int signbit(real x); } } else version (MinGW) @@ -925,16 +867,12 @@ else version (MinGW) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassify(x); } + extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x); /// - pure int fpclassify(real x) - { - return (real.sizeof == double.sizeof) - ? __fpclassify(x) - : __fpclassifyl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl") + pure int fpclassify(real x); //int isfinite(real-floating x); /// @@ -954,16 +892,12 @@ else version (MinGW) //int isnan(real-floating x); /// - pure int isnan(float x) { return __isnanf(x); } + extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); /// - pure int isnan(double x) { return __isnan(x); } + extern(C) pragma(mangle, "__isnan") pure int isnan(double x); /// - pure int isnan(real x) - { - return (real.sizeof == double.sizeof) - ? __isnan(x) - : __isnanl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") + pure int isnan(real x); //int isnormal(real-floating x); /// @@ -975,16 +909,12 @@ else version (MinGW) //int signbit(real-floating x); /// - int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); /// - int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); /// - int signbit(real x) - { - return (real.sizeof == double.sizeof) - ? __signbit(x) - : __signbitl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl") + int signbit(real x); } } else version (Darwin) @@ -1070,35 +1000,35 @@ else version (Darwin) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassifyd(x); } + extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); /// - pure int fpclassify(real x) { return __fpclassifyl(x); } + extern(C) pragma(mangle, __fpclassifyl.mangleof) pure int fpclassify(real x); //int isfinite(real-floating x); /// - pure int isfinite(float x) { return __isfinitef(x); } + extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x); /// - pure int isfinite(double x) { return __isfinited(x); } + extern(C) pragma(mangle, "__isfinited") pure int isfinite(double x); /// - pure int isfinite(real x) { return __isfinitel(x); } + extern(C) pragma(mangle, __isfinitel.mangleof) pure int isfinite(real x); //int isinf(real-floating x); /// - pure int isinf(float x) { return __isinff(x); } + extern(C) pragma(mangle, "__isinff") pure int isinf(float x); /// - pure int isinf(double x) { return __isinfd(x); } + extern(C) pragma(mangle, "__isinfd") pure int isinf(double x); /// - pure int isinf(real x) { return __isinfl(x); } + extern(C) pragma(mangle, __isinfl.mangleof) pure int isinf(real x); //int isnan(real-floating x); /// - pure int isnan(float x) { return __isnanf(x); } + extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); /// - pure int isnan(double x) { return __isnand(x); } + extern(C) pragma(mangle, "__isnand") pure int isnan(double x); /// - pure int isnan(real x) { return __isnanl(x); } + extern(C) pragma(mangle, __isnanl.mangleof) pure int isnan(real x); //int isnormal(real-floating x); /// @@ -1110,11 +1040,11 @@ else version (Darwin) //int signbit(real-floating x); /// - pure int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); /// - pure int signbit(double x) { return __signbitd(x); } + extern(C) pragma(mangle, "__signbitd") pure int signbit(double x); /// - pure int signbit(real x) { return __signbitl(x); } + extern(C) pragma(mangle, "__signbitl") pure int signbit(real x); } } else version (FreeBSD) @@ -1163,27 +1093,27 @@ else version (FreeBSD) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassifyd(x); } + extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); /// - pure int fpclassify(real x) { return __fpclassifyl(x); } + extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x); //int isfinite(real-floating x); /// - pure int isfinite(float x) { return __isfinitef(x); } + extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x); /// - pure int isfinite(double x) { return __isfinite(x); } + extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x); /// - pure int isfinite(real x) { return __isfinitel(x); } + extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x); //int isinf(real-floating x); /// - pure int isinf(float x) { return __isinff(x); } + extern(C) pragma(mangle, "__isinff") pure int isinf(float x); /// pure int isinf(double x) { return __isinfl(x); } /// - pure int isinf(real x) { return __isinfl(x); } + extern(C) pragma(mangle, "__isinfl") pure int isinf(real x); //int isnan(real-floating x); /// @@ -1191,21 +1121,21 @@ else version (FreeBSD) /// pure int isnan(double x) { return __isnanl(x); } /// - pure int isnan(real x) { return __isnanl(x); } + extern(C) pragma(mangle, "__isnanl") pure int isnan(real x); //int isnormal(real-floating x); /// - pure int isnormal(float x) { return __isnormalf(x); } + extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x); /// - pure int isnormal(double x) { return __isnormal(x); } + extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x); /// - pure int isnormal(real x) { return __isnormall(x); } + extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x); //int signbit(real-floating x); /// - pure int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); /// - pure int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); /// pure int signbit(real x) { return __signbit(x); } } @@ -1256,27 +1186,27 @@ else version (OpenBSD) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassifyd(x); } + extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); /// - pure int fpclassify(real x) { return __fpclassifyl(x); } + extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x); //int isfinite(real-floating x); /// - pure int isfinite(float x) { return __isfinitef(x); } + extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x); /// - pure int isfinite(double x) { return __isfinite(x); } + extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x); /// - pure int isfinite(real x) { return __isfinitel(x); } + extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x); //int isinf(real-floating x); /// - pure int isinf(float x) { return __isinff(x); } + extern(C) pragma(mangle, "__isinff") pure int isinf(float x); /// pure int isinf(double x) { return __isinfl(x); } /// - pure int isinf(real x) { return __isinfl(x); } + extern(C) pragma(mangle, "__isinfl") pure int isinf(real x); //int isnan(real-floating x); /// @@ -1284,21 +1214,21 @@ else version (OpenBSD) /// pure int isnan(double x) { return __isnanl(x); } /// - pure int isnan(real x) { return __isnanl(x); } + extern(C) pragma(mangle, "__isnanl") pure int isnan(real x); //int isnormal(real-floating x); /// - pure int isnormal(float x) { return __isnormalf(x); } + extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x); /// - pure int isnormal(double x) { return __isnormal(x); } + extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x); /// - pure int isnormal(real x) { return __isnormall(x); } + extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x); //int signbit(real-floating x); /// - pure int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); /// - pure int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); /// pure int signbit(real x) { return __signbit(x); } } @@ -1337,16 +1267,12 @@ else version (NetBSD) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassifyd(x); } + extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); /// - pure int fpclassify(real x) - { - return (real.sizeof == double.sizeof) - ? __fpclassifyd(x) - : __fpclassifyl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassifyd" : "__fpclassifyl") + pure int fpclassify(real x); //int isfinite(real-floating x); /// @@ -1433,29 +1359,29 @@ else version (DragonFlyBSD) extern (D) { - pure int fpclassify(float x) { return __fpclassifyf(x); } - pure int fpclassify(double x) { return __fpclassifyd(x); } - pure int fpclassify(real x) { return __fpclassifyl(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); + extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); + extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x); - pure int isfinite(float x) { return __isfinitef(x); } - pure int isfinite(double x) { return __isfinite(x); } - pure int isfinite(real x) { return __isfinitel(x); } + extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x); + extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x); + extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x); - pure int isinf(float x) { return __isinff(x); } - pure int isinf(double x) { return __isinf(x); } - pure int isinf(real x) { return __isinfl(x); } + extern(C) pragma(mangle, "__isinff") pure int isinf(float x); + extern(C) pragma(mangle, "__isinf") pure int isinf(double x); + extern(C) pragma(mangle, "__isinfl") pure int isinf(real x); - pure int isnan(float x) { return __isnanf(x); } - pure int isnan(double x) { return __isnan(x); } - pure int isnan(real x) { return __isnanl(x); } + extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); + extern(C) pragma(mangle, "__isnan") pure int isnan(double x); + extern(C) pragma(mangle, "__isnanl") pure int isnan(real x); - pure int isnormal(float x) { return __isnormalf(x); } - pure int isnormal(double x) { return __isnormal(x); } - pure int isnormal(real x) { return __isnormall(x); } + extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x); + extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x); + extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x); - pure int signbit(float x) { return __signbitf(x); } - pure int signbit(double x) { return __signbit(x); } - pure int signbit(real x) { return __signbitl(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); + extern(C) pragma(mangle, "__signbitl") pure int signbit(real x); } } else version (Solaris) @@ -1468,16 +1394,12 @@ else version (Solaris) { //int isnan(real-floating x); /// - pure int isnan(float x) { return __isnanf(x); } + extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); /// - pure int isnan(double x) { return __isnan(x); } + extern(C) pragma(mangle, "__isnan") pure int isnan(double x); /// - pure int isnan(real x) - { - return (real.sizeof == double.sizeof) - ? __isnan(x) - : __isnanl(x); - } + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") + pure int isnan(real x); } } else version (CRuntime_Bionic) @@ -1527,49 +1449,49 @@ else version (CRuntime_Bionic) { //int fpclassify(real-floating x); /// - pure int fpclassify(float x) { return __fpclassifyf(x); } + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - pure int fpclassify(double x) { return __fpclassifyd(x); } + extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); /// - pure int fpclassify(real x) { return __fpclassifyl(x); } + extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x); //int isfinite(real-floating x); /// - pure int isfinite(float x) { return __isfinitef(x); } + extern(C) pragma(mangle, "__isfinitef") pure int isfinite(float x); /// - pure int isfinite(double x) { return __isfinite(x); } + extern(C) pragma(mangle, "__isfinite") pure int isfinite(double x); /// - pure int isfinite(real x) { return __isfinitel(x); } + extern(C) pragma(mangle, "__isfinitel") pure int isfinite(real x); //int isinf(real-floating x); /// - pure int isinf(float x) { return __isinff(x); } + extern(C) pragma(mangle, "__isinff") pure int isinf(float x); /// - pure int isinf(double x) { return __isinf(x); } + extern(C) pragma(mangle, "__isinf") pure int isinf(double x); /// - pure int isinf(real x) { return __isinfl(x); } + extern(C) pragma(mangle, "__isinfl") pure int isinf(real x); //int isnan(real-floating x); /// - pure int isnan(float x) { return isnanf(x); } + extern(C) pragma(mangle, "isnanf") pure int isnan(float x); /// - pure int isnan(real x) { return __isnanl(x); } + extern(C) pragma(mangle, "__isnanl") pure int isnan(real x); //int isnormal(real-floating x); /// - pure int isnormal(float x) { return __isnormalf(x); } + extern(C) pragma(mangle, "__isnormalf") pure int isnormal(float x); /// - pure int isnormal(double x) { return __isnormal(x); } + extern(C) pragma(mangle, "__isnormal") pure int isnormal(double x); /// - pure int isnormal(real x) { return __isnormall(x); } + extern(C) pragma(mangle, "__isnormall") pure int isnormal(real x); //int signbit(real-floating x); /// - pure int signbit(float x) { return __signbitf(x); } + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); /// - pure int signbit(double x) { return __signbit(x); } + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); /// - pure int signbit(real x) { return __signbitl(x); } + extern(C) pragma(mangle, "__signbitl") pure int signbit(real x); } } @@ -1841,14 +1763,12 @@ version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only /// extern(D) pure real fabsl()(real x) { return fabs(cast(double) x); } - private double _hypot(double x, double y); - private float _hypotf(float x, float y); /// - extern(D) double hypot(double x, double y) { return _hypot(x, y); } + extern(C) pragma(mangle, "_hypot") double hypot(double x, double y); /// - extern(D) float hypotf(float x, float y) { return _hypotf(x, y); } + extern(C) pragma(mangle, "_hypotf") float hypotf(float x, float y); /// - extern(D) real hypotl(real x, real y) { return _hypot(cast(double) x, cast(double) y); } + extern(D) real hypotl(real x, real y) { return hypot(cast(double) x, cast(double) y); } /// double pow(double x, double y); diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index 6701159..532a080 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -1166,61 +1166,73 @@ version (MinGW) // Prefer the MinGW versions over the MSVC ones, as the latter don't handle // reals at all. /// + pragma(printf) int __mingw_fprintf(FILE* stream, scope const char* format, scope const ...); /// alias __mingw_fprintf fprintf; /// + pragma(scanf) int __mingw_fscanf(FILE* stream, scope const char* format, scope ...); /// alias __mingw_fscanf fscanf; /// + pragma(printf) int __mingw_sprintf(scope char* s, scope const char* format, scope const ...); /// alias __mingw_sprintf sprintf; /// + pragma(scanf) int __mingw_sscanf(scope const char* s, scope const char* format, scope ...); /// alias __mingw_sscanf sscanf; /// + pragma(printf) int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg); /// alias __mingw_vfprintf vfprintf; /// + pragma(scanf) int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg); /// alias __mingw_vfscanf vfscanf; /// + pragma(printf) int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg); /// alias __mingw_vsprintf vsprintf; /// + pragma(scanf) int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg); /// alias __mingw_vsscanf vsscanf; /// + pragma(printf) int __mingw_vprintf(scope const char* format, va_list arg); /// alias __mingw_vprintf vprintf; /// + pragma(scanf) int __mingw_vscanf(scope const char* format, va_list arg); /// alias __mingw_vscanf vscanf; /// + pragma(printf) int __mingw_printf(scope const char* format, scope const ...); /// alias __mingw_printf printf; /// + pragma(scanf) int __mingw_scanf(scope const char* format, scope ...); /// alias __mingw_scanf scanf; @@ -1228,28 +1240,40 @@ version (MinGW) else { /// + pragma(printf) int fprintf(FILE* stream, scope const char* format, scope const ...); /// + pragma(scanf) int fscanf(FILE* stream, scope const char* format, scope ...); /// + pragma(printf) int sprintf(scope char* s, scope const char* format, scope const ...); /// + pragma(scanf) int sscanf(scope const char* s, scope const char* format, scope ...); /// + pragma(printf) int vfprintf(FILE* stream, scope const char* format, va_list arg); /// + pragma(scanf) int vfscanf(FILE* stream, scope const char* format, va_list arg); /// + pragma(printf) int vsprintf(scope char* s, scope const char* format, va_list arg); /// + pragma(scanf) int vsscanf(scope const char* s, scope const char* format, va_list arg); /// + pragma(printf) int vprintf(scope const char* format, va_list arg); /// + pragma(scanf) int vscanf(scope const char* format, va_list arg); /// + pragma(printf) int printf(scope const char* format, scope const ...); /// + pragma(scanf) int scanf(scope const char* format, scope ...); } @@ -1278,13 +1302,14 @@ extern (D) @trusted int getchar()() { return getc(stdin); } /// int putchar()(int c) { return putc(c,stdout); } - /// - int getc()(FILE* stream) { return fgetc(stream); } - /// - int putc()(int c, FILE* stream) { return fputc(c,stream); } } /// +alias getc = fgetc; +/// +alias putc = fputc; + +/// @trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation. /// @@ -1323,11 +1348,13 @@ version (CRuntime_DigitalMars) pure int fileno()(FILE* stream) { return stream._file; } } /// + pragma(printf) int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// alias _snprintf snprintf; /// + pragma(printf) int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// alias _vsnprintf vsnprintf; @@ -1351,6 +1378,7 @@ else version (CRuntime_Microsoft) version (MinGW) { + pragma(printf) int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// alias __mingw_snprintf _snprintf; @@ -1358,6 +1386,7 @@ else version (CRuntime_Microsoft) alias __mingw_snprintf snprintf; /// + pragma(printf) int __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// alias __mingw_vsnprintf _vsnprintf; @@ -1367,13 +1396,17 @@ else version (CRuntime_Microsoft) else { /// + pragma(printf) int _snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } @@ -1410,8 +1443,10 @@ else version (CRuntime_Glibc) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (Darwin) @@ -1432,8 +1467,10 @@ else version (Darwin) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (FreeBSD) @@ -1454,8 +1491,10 @@ else version (FreeBSD) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (NetBSD) @@ -1476,8 +1515,10 @@ else version (NetBSD) } /// + pragma(printf) int snprintf(char* s, size_t n, const scope char* format, scope const ...); /// + pragma(printf) int vsnprintf(char* s, size_t n, const scope char* format, va_list arg); } else version (OpenBSD) @@ -1567,8 +1608,10 @@ else version (OpenBSD) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (DragonFlyBSD) @@ -1599,7 +1642,9 @@ else version (DragonFlyBSD) enum __SALC = 0x4000; enum __SIGN = 0x8000; + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (Solaris) @@ -1620,8 +1665,10 @@ else version (Solaris) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (CRuntime_Bionic) @@ -1642,8 +1689,10 @@ else version (CRuntime_Bionic) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (CRuntime_Musl) @@ -1663,8 +1712,10 @@ else version (CRuntime_Musl) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (CRuntime_UClibc) @@ -1685,8 +1736,10 @@ else version (CRuntime_UClibc) } /// + pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// + pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 7caef4c..5d69b88 100644 --- a/libphobos/libdruntime/core/stdc/stdlib.d +++ b/libphobos/libdruntime/core/stdc/stdlib.d @@ -164,13 +164,13 @@ void* realloc(void* ptr, size_t size); void free(void* ptr); /// -void abort() @safe; +noreturn abort() @safe; /// -void exit(int status); +noreturn exit(int status); /// int atexit(void function() func); /// -void _Exit(int status); +noreturn _Exit(int status); /// char* getenv(scope const char* name); diff --git a/libphobos/libdruntime/core/stdc/tgmath.d b/libphobos/libdruntime/core/stdc/tgmath.d index 4dd1b3c..2ff1522 100644 --- a/libphobos/libdruntime/core/stdc/tgmath.d +++ b/libphobos/libdruntime/core/stdc/tgmath.d @@ -32,12 +32,10 @@ version (NetBSD) /// alias core.stdc.math.acosl acos; - /// - alias core.stdc.complex.cacos acos; - /// - alias core.stdc.complex.cacosf acos; - /// - alias core.stdc.complex.cacosl acos; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cacos acos; + deprecated alias core.stdc.complex.cacosf acos; + deprecated alias core.stdc.complex.cacosl acos; /// alias core.stdc.math.asin asin; @@ -46,12 +44,10 @@ version (NetBSD) /// alias core.stdc.math.asinl asin; - /// - alias core.stdc.complex.casin asin; - /// - alias core.stdc.complex.casinf asin; - /// - alias core.stdc.complex.casinl asin; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.casin asin; + deprecated alias core.stdc.complex.casinf asin; + deprecated alias core.stdc.complex.casinl asin; /// alias core.stdc.math.atan atan; @@ -60,12 +56,10 @@ version (NetBSD) /// alias core.stdc.math.atanl atan; - /// - alias core.stdc.complex.catan atan; - /// - alias core.stdc.complex.catanf atan; - /// - alias core.stdc.complex.catanl atan; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.catan atan; + deprecated alias core.stdc.complex.catanf atan; + deprecated alias core.stdc.complex.catanl atan; /// alias core.stdc.math.atan2 atan2; @@ -81,12 +75,10 @@ version (NetBSD) /// alias core.stdc.math.cosl cos; - /// - alias core.stdc.complex.ccos cos; - /// - alias core.stdc.complex.ccosf cos; - /// - alias core.stdc.complex.ccosl cos; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ccos cos; + deprecated alias core.stdc.complex.ccosf cos; + deprecated alias core.stdc.complex.ccosl cos; /// alias core.stdc.math.sin sin; @@ -95,12 +87,10 @@ version (NetBSD) /// alias core.stdc.math.sinl sin; - /// - alias core.stdc.complex.csin csin; - /// - alias core.stdc.complex.csinf csin; - /// - alias core.stdc.complex.csinl csin; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csin csin; + deprecated alias core.stdc.complex.csinf csin; + deprecated alias core.stdc.complex.csinl csin; /// alias core.stdc.math.tan tan; @@ -109,12 +99,10 @@ version (NetBSD) /// alias core.stdc.math.tanl tan; - /// - alias core.stdc.complex.ctan tan; - /// - alias core.stdc.complex.ctanf tan; - /// - alias core.stdc.complex.ctanl tan; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ctan tan; + deprecated alias core.stdc.complex.ctanf tan; + deprecated alias core.stdc.complex.ctanl tan; /// alias core.stdc.math.acosh acosh; @@ -123,12 +111,10 @@ version (NetBSD) /// alias core.stdc.math.acoshl acosh; - /// - alias core.stdc.complex.cacosh acosh; - /// - alias core.stdc.complex.cacoshf acosh; - /// - alias core.stdc.complex.cacoshl acosh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cacosh acosh; + deprecated alias core.stdc.complex.cacoshf acosh; + deprecated alias core.stdc.complex.cacoshl acosh; /// alias core.stdc.math.asinh asinh; @@ -137,12 +123,10 @@ version (NetBSD) /// alias core.stdc.math.asinhl asinh; - /// - alias core.stdc.complex.casinh asinh; - /// - alias core.stdc.complex.casinhf asinh; - /// - alias core.stdc.complex.casinhl asinh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.casinh asinh; + deprecated alias core.stdc.complex.casinhf asinh; + deprecated alias core.stdc.complex.casinhl asinh; /// alias core.stdc.math.atanh atanh; @@ -151,12 +135,10 @@ version (NetBSD) /// alias core.stdc.math.atanhl atanh; - /// - alias core.stdc.complex.catanh atanh; - /// - alias core.stdc.complex.catanhf atanh; - /// - alias core.stdc.complex.catanhl atanh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.catanh atanh; + deprecated alias core.stdc.complex.catanhf atanh; + deprecated alias core.stdc.complex.catanhl atanh; /// alias core.stdc.math.cosh cosh; @@ -165,12 +147,10 @@ version (NetBSD) /// alias core.stdc.math.coshl cosh; - /// - alias core.stdc.complex.ccosh cosh; - /// - alias core.stdc.complex.ccoshf cosh; - /// - alias core.stdc.complex.ccoshl cosh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ccosh cosh; + deprecated alias core.stdc.complex.ccoshf cosh; + deprecated alias core.stdc.complex.ccoshl cosh; /// alias core.stdc.math.sinh sinh; @@ -179,12 +159,10 @@ version (NetBSD) /// alias core.stdc.math.sinhl sinh; - /// - alias core.stdc.complex.csinh sinh; - /// - alias core.stdc.complex.csinhf sinh; - /// - alias core.stdc.complex.csinhl sinh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csinh sinh; + deprecated alias core.stdc.complex.csinhf sinh; + deprecated alias core.stdc.complex.csinhl sinh; /// alias core.stdc.math.tanh tanh; @@ -193,12 +171,10 @@ version (NetBSD) /// alias core.stdc.math.tanhl tanh; - /// - alias core.stdc.complex.ctanh tanh; - /// - alias core.stdc.complex.ctanhf tanh; - /// - alias core.stdc.complex.ctanhl tanh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ctanh tanh; + deprecated alias core.stdc.complex.ctanhf tanh; + deprecated alias core.stdc.complex.ctanhl tanh; /// alias core.stdc.math.exp exp; @@ -207,12 +183,10 @@ version (NetBSD) /// alias core.stdc.math.expl exp; - /// - alias core.stdc.complex.cexp exp; - /// - alias core.stdc.complex.cexpf exp; - /// - alias core.stdc.complex.cexpl exp; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cexp exp; + deprecated alias core.stdc.complex.cexpf exp; + deprecated alias core.stdc.complex.cexpl exp; /// alias core.stdc.math.exp2 exp2; @@ -256,12 +230,10 @@ version (NetBSD) /// alias core.stdc.math.logl log; - /// - alias core.stdc.complex.clog log; - /// - alias core.stdc.complex.clogf log; - /// - alias core.stdc.complex.clogl log; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.clog log; + deprecated alias core.stdc.complex.clogf log; + deprecated alias core.stdc.complex.clogl log; /// alias core.stdc.math.log10 log10; @@ -325,12 +297,10 @@ version (NetBSD) /// alias core.stdc.math.fabsl fabs; - /// - alias core.stdc.complex.cabs fabs; - /// - alias core.stdc.complex.cabsf fabs; - /// - alias core.stdc.complex.cabsl fabs; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cabs fabs; + deprecated alias core.stdc.complex.cabsf fabs; + deprecated alias core.stdc.complex.cabsl fabs; /// alias core.stdc.math.hypot hypot; @@ -346,12 +316,10 @@ version (NetBSD) /// alias core.stdc.math.powl pow; - /// - alias core.stdc.complex.cpow pow; - /// - alias core.stdc.complex.cpowf pow; - /// - alias core.stdc.complex.cpowl pow; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cpow pow; + deprecated alias core.stdc.complex.cpowf pow; + deprecated alias core.stdc.complex.cpowl pow; /// alias core.stdc.math.sqrt sqrt; @@ -360,12 +328,10 @@ version (NetBSD) /// alias core.stdc.math.sqrtl sqrt; - /// - alias core.stdc.complex.csqrt sqrt; - /// - alias core.stdc.complex.csqrtf sqrt; - /// - alias core.stdc.complex.csqrtl sqrt; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csqrt sqrt; + deprecated alias core.stdc.complex.csqrtf sqrt; + deprecated alias core.stdc.complex.csqrtl sqrt; /// alias core.stdc.math.erf erf; @@ -539,37 +505,23 @@ version (NetBSD) /// alias core.stdc.math.fmal fma; - /// - alias core.stdc.complex.carg carg; - /// - alias core.stdc.complex.cargf carg; - /// - alias core.stdc.complex.cargl carg; - - /// - alias core.stdc.complex.cimag cimag; - /// - alias core.stdc.complex.cimagf cimag; - /// - alias core.stdc.complex.cimagl cimag; - - /// - alias core.stdc.complex.conj conj; - /// - alias core.stdc.complex.conjf conj; - /// - alias core.stdc.complex.conjl conj; - - /// - alias core.stdc.complex.cproj cproj; - /// - alias core.stdc.complex.cprojf cproj; - /// - alias core.stdc.complex.cprojl cproj; - -// alias core.stdc.complex.creal creal; -// alias core.stdc.complex.crealf creal; -// alias core.stdc.complex.creall creal; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.carg carg; + deprecated alias core.stdc.complex.cargf carg; + deprecated alias core.stdc.complex.cargl carg; + deprecated alias core.stdc.complex.cimag cimag; + deprecated alias core.stdc.complex.cimagf cimag; + deprecated alias core.stdc.complex.cimagl cimag; + deprecated alias core.stdc.complex.conj conj; + deprecated alias core.stdc.complex.conjf conj; + deprecated alias core.stdc.complex.conjl conj; + deprecated alias core.stdc.complex.cproj cproj; + deprecated alias core.stdc.complex.cprojf cproj; + deprecated alias core.stdc.complex.cprojl cproj; + +// deprecated alias core.stdc.complex.creal creal; +// deprecated alias core.stdc.complex.crealf creal; +// deprecated alias core.stdc.complex.creall creal; } else version (OpenBSD) { @@ -580,12 +532,10 @@ else version (OpenBSD) /// alias core.stdc.math.acosl acos; - /// - alias core.stdc.complex.cacos acos; - /// - alias core.stdc.complex.cacosf acos; - /// - alias core.stdc.complex.cacosl acos; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cacos acos; + deprecated alias core.stdc.complex.cacosf acos; + deprecated alias core.stdc.complex.cacosl acos; /// alias core.stdc.math.asin asin; @@ -594,12 +544,10 @@ else version (OpenBSD) /// alias core.stdc.math.asinl asin; - /// - alias core.stdc.complex.casin asin; - /// - alias core.stdc.complex.casinf asin; - /// - alias core.stdc.complex.casinl asin; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.casin asin; + deprecated alias core.stdc.complex.casinf asin; + deprecated alias core.stdc.complex.casinl asin; /// alias core.stdc.math.atan atan; @@ -608,12 +556,10 @@ else version (OpenBSD) /// alias core.stdc.math.atanl atan; - /// - alias core.stdc.complex.catan atan; - /// - alias core.stdc.complex.catanf atan; - /// - alias core.stdc.complex.catanl atan; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.catan atan; + deprecated alias core.stdc.complex.catanf atan; + deprecated alias core.stdc.complex.catanl atan; /// alias core.stdc.math.atan2 atan2; @@ -629,12 +575,10 @@ else version (OpenBSD) /// alias core.stdc.math.cosl cos; - /// - alias core.stdc.complex.ccos cos; - /// - alias core.stdc.complex.ccosf cos; - /// - alias core.stdc.complex.ccosl cos; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ccos cos; + deprecated alias core.stdc.complex.ccosf cos; + deprecated alias core.stdc.complex.ccosl cos; /// alias core.stdc.math.sin sin; @@ -643,12 +587,10 @@ else version (OpenBSD) /// alias core.stdc.math.sinl sin; - /// - alias core.stdc.complex.csin csin; - /// - alias core.stdc.complex.csinf csin; - /// - alias core.stdc.complex.csinl csin; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csin csin; + deprecated alias core.stdc.complex.csinf csin; + deprecated alias core.stdc.complex.csinl csin; /// alias core.stdc.math.tan tan; @@ -657,12 +599,10 @@ else version (OpenBSD) /// alias core.stdc.math.tanl tan; - /// - alias core.stdc.complex.ctan tan; - /// - alias core.stdc.complex.ctanf tan; - /// - alias core.stdc.complex.ctanl tan; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ctan tan; + deprecated alias core.stdc.complex.ctanf tan; + deprecated alias core.stdc.complex.ctanl tan; /// alias core.stdc.math.acosh acosh; @@ -671,12 +611,10 @@ else version (OpenBSD) /// alias core.stdc.math.acoshl acosh; - /// - alias core.stdc.complex.cacosh acosh; - /// - alias core.stdc.complex.cacoshf acosh; - /// - alias core.stdc.complex.cacoshl acosh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cacosh acosh; + deprecated alias core.stdc.complex.cacoshf acosh; + deprecated alias core.stdc.complex.cacoshl acosh; /// alias core.stdc.math.asinh asinh; @@ -685,12 +623,10 @@ else version (OpenBSD) /// alias core.stdc.math.asinhl asinh; - /// - alias core.stdc.complex.casinh asinh; - /// - alias core.stdc.complex.casinhf asinh; - /// - alias core.stdc.complex.casinhl asinh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.casinh asinh; + deprecated alias core.stdc.complex.casinhf asinh; + deprecated alias core.stdc.complex.casinhl asinh; /// alias core.stdc.math.atanh atanh; @@ -699,12 +635,10 @@ else version (OpenBSD) /// alias core.stdc.math.atanhl atanh; - /// - alias core.stdc.complex.catanh atanh; - /// - alias core.stdc.complex.catanhf atanh; - /// - alias core.stdc.complex.catanhl atanh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.catanh atanh; + deprecated alias core.stdc.complex.catanhf atanh; + deprecated alias core.stdc.complex.catanhl atanh; /// alias core.stdc.math.cosh cosh; @@ -713,12 +647,10 @@ else version (OpenBSD) /// alias core.stdc.math.coshl cosh; - /// - alias core.stdc.complex.ccosh cosh; - /// - alias core.stdc.complex.ccoshf cosh; - /// - alias core.stdc.complex.ccoshl cosh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ccosh cosh; + deprecated alias core.stdc.complex.ccoshf cosh; + deprecated alias core.stdc.complex.ccoshl cosh; /// alias core.stdc.math.sinh sinh; @@ -727,12 +659,10 @@ else version (OpenBSD) /// alias core.stdc.math.sinhl sinh; - /// - alias core.stdc.complex.csinh sinh; - /// - alias core.stdc.complex.csinhf sinh; - /// - alias core.stdc.complex.csinhl sinh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csinh sinh; + deprecated alias core.stdc.complex.csinhf sinh; + deprecated alias core.stdc.complex.csinhl sinh; /// alias core.stdc.math.tanh tanh; @@ -741,12 +671,10 @@ else version (OpenBSD) /// alias core.stdc.math.tanhl tanh; - /// - alias core.stdc.complex.ctanh tanh; - /// - alias core.stdc.complex.ctanhf tanh; - /// - alias core.stdc.complex.ctanhl tanh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ctanh tanh; + deprecated alias core.stdc.complex.ctanhf tanh; + deprecated alias core.stdc.complex.ctanhl tanh; /// alias core.stdc.math.exp exp; @@ -755,12 +683,10 @@ else version (OpenBSD) /// alias core.stdc.math.expl exp; - /// - alias core.stdc.complex.cexp exp; - /// - alias core.stdc.complex.cexpf exp; - /// - alias core.stdc.complex.cexpl exp; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cexp exp; + deprecated alias core.stdc.complex.cexpf exp; + deprecated alias core.stdc.complex.cexpl exp; /// alias core.stdc.math.exp2 exp2; @@ -804,12 +730,10 @@ else version (OpenBSD) /// alias core.stdc.math.logl log; - /// - alias core.stdc.complex.clog log; - /// - alias core.stdc.complex.clogf log; - /// - alias core.stdc.complex.clogl log; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.clog log; + deprecated alias core.stdc.complex.clogf log; + deprecated alias core.stdc.complex.clogl log; /// alias core.stdc.math.log10 log10; @@ -874,12 +798,10 @@ else version (OpenBSD) /// alias core.stdc.math.fabsl fabs; - /// - alias core.stdc.complex.cabs fabs; - /// - alias core.stdc.complex.cabsf fabs; - /// - alias core.stdc.complex.cabsl fabs; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cabs fabs; + deprecated alias core.stdc.complex.cabsf fabs; + deprecated alias core.stdc.complex.cabsl fabs; /// alias core.stdc.math.hypot hypot; @@ -895,12 +817,10 @@ else version (OpenBSD) /// alias core.stdc.math.powl pow; - /// - alias core.stdc.complex.cpow pow; - /// - alias core.stdc.complex.cpowf pow; - /// - alias core.stdc.complex.cpowl pow; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cpow pow; + deprecated alias core.stdc.complex.cpowf pow; + deprecated alias core.stdc.complex.cpowl pow; /// alias core.stdc.math.sqrt sqrt; @@ -909,12 +829,10 @@ else version (OpenBSD) /// alias core.stdc.math.sqrtl sqrt; - /// - alias core.stdc.complex.csqrt sqrt; - /// - alias core.stdc.complex.csqrtf sqrt; - /// - alias core.stdc.complex.csqrtl sqrt; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csqrt sqrt; + deprecated alias core.stdc.complex.csqrtf sqrt; + deprecated alias core.stdc.complex.csqrtl sqrt; /// alias core.stdc.math.erf erf; @@ -1077,37 +995,23 @@ else version (OpenBSD) /// alias core.stdc.math.fmal fma; - /// - alias core.stdc.complex.carg carg; - /// - alias core.stdc.complex.cargf carg; - /// - alias core.stdc.complex.cargl carg; - - /// - alias core.stdc.complex.cimag cimag; - /// - alias core.stdc.complex.cimagf cimag; - /// - alias core.stdc.complex.cimagl cimag; - - /// - alias core.stdc.complex.conj conj; - /// - alias core.stdc.complex.conjf conj; - /// - alias core.stdc.complex.conjl conj; - - /// - alias core.stdc.complex.cproj cproj; - /// - alias core.stdc.complex.cprojf cproj; - /// - alias core.stdc.complex.cprojl cproj; - -// alias core.stdc.complex.creal creal; -// alias core.stdc.complex.crealf creal; -// alias core.stdc.complex.creall creal; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.carg carg; + deprecated alias core.stdc.complex.cargf carg; + deprecated alias core.stdc.complex.cargl carg; + deprecated alias core.stdc.complex.cimag cimag; + deprecated alias core.stdc.complex.cimagf cimag; + deprecated alias core.stdc.complex.cimagl cimag; + deprecated alias core.stdc.complex.conj conj; + deprecated alias core.stdc.complex.conjf conj; + deprecated alias core.stdc.complex.conjl conj; + deprecated alias core.stdc.complex.cproj cproj; + deprecated alias core.stdc.complex.cprojf cproj; + deprecated alias core.stdc.complex.cprojl cproj; + +// deprecated alias core.stdc.complex.creal creal; +// deprecated alias core.stdc.complex.crealf creal; +// deprecated alias core.stdc.complex.creall creal; } else { @@ -1118,12 +1022,10 @@ else /// alias core.stdc.math.acosl acos; - /// - alias core.stdc.complex.cacos acos; - /// - alias core.stdc.complex.cacosf acos; - /// - alias core.stdc.complex.cacosl acos; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cacos acos; + deprecated alias core.stdc.complex.cacosf acos; + deprecated alias core.stdc.complex.cacosl acos; /// alias core.stdc.math.asin asin; @@ -1132,12 +1034,10 @@ else /// alias core.stdc.math.asinl asin; - /// - alias core.stdc.complex.casin asin; - /// - alias core.stdc.complex.casinf asin; - /// - alias core.stdc.complex.casinl asin; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.casin asin; + deprecated alias core.stdc.complex.casinf asin; + deprecated alias core.stdc.complex.casinl asin; /// alias core.stdc.math.atan atan; @@ -1146,12 +1046,10 @@ else /// alias core.stdc.math.atanl atan; - /// - alias core.stdc.complex.catan atan; - /// - alias core.stdc.complex.catanf atan; - /// - alias core.stdc.complex.catanl atan; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.catan atan; + deprecated alias core.stdc.complex.catanf atan; + deprecated alias core.stdc.complex.catanl atan; /// alias core.stdc.math.atan2 atan2; @@ -1167,12 +1065,10 @@ else /// alias core.stdc.math.cosl cos; - /// - alias core.stdc.complex.ccos cos; - /// - alias core.stdc.complex.ccosf cos; - /// - alias core.stdc.complex.ccosl cos; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ccos cos; + deprecated alias core.stdc.complex.ccosf cos; + deprecated alias core.stdc.complex.ccosl cos; /// alias core.stdc.math.sin sin; @@ -1181,12 +1077,10 @@ else /// alias core.stdc.math.sinl sin; - /// - alias core.stdc.complex.csin csin; - /// - alias core.stdc.complex.csinf csin; - /// - alias core.stdc.complex.csinl csin; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csin csin; + deprecated alias core.stdc.complex.csinf csin; + deprecated alias core.stdc.complex.csinl csin; /// alias core.stdc.math.tan tan; @@ -1195,12 +1089,10 @@ else /// alias core.stdc.math.tanl tan; - /// - alias core.stdc.complex.ctan tan; - /// - alias core.stdc.complex.ctanf tan; - /// - alias core.stdc.complex.ctanl tan; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ctan tan; + deprecated alias core.stdc.complex.ctanf tan; + deprecated alias core.stdc.complex.ctanl tan; /// alias core.stdc.math.acosh acosh; @@ -1209,12 +1101,10 @@ else /// alias core.stdc.math.acoshl acosh; - /// - alias core.stdc.complex.cacosh acosh; - /// - alias core.stdc.complex.cacoshf acosh; - /// - alias core.stdc.complex.cacoshl acosh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cacosh acosh; + deprecated alias core.stdc.complex.cacoshf acosh; + deprecated alias core.stdc.complex.cacoshl acosh; /// alias core.stdc.math.asinh asinh; @@ -1223,12 +1113,10 @@ else /// alias core.stdc.math.asinhl asinh; - /// - alias core.stdc.complex.casinh asinh; - /// - alias core.stdc.complex.casinhf asinh; - /// - alias core.stdc.complex.casinhl asinh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.casinh asinh; + deprecated alias core.stdc.complex.casinhf asinh; + deprecated alias core.stdc.complex.casinhl asinh; /// alias core.stdc.math.atanh atanh; @@ -1237,12 +1125,10 @@ else /// alias core.stdc.math.atanhl atanh; - /// - alias core.stdc.complex.catanh atanh; - /// - alias core.stdc.complex.catanhf atanh; - /// - alias core.stdc.complex.catanhl atanh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.catanh atanh; + deprecated alias core.stdc.complex.catanhf atanh; + deprecated alias core.stdc.complex.catanhl atanh; /// alias core.stdc.math.cosh cosh; @@ -1251,12 +1137,10 @@ else /// alias core.stdc.math.coshl cosh; - /// - alias core.stdc.complex.ccosh cosh; - /// - alias core.stdc.complex.ccoshf cosh; - /// - alias core.stdc.complex.ccoshl cosh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ccosh cosh; + deprecated alias core.stdc.complex.ccoshf cosh; + deprecated alias core.stdc.complex.ccoshl cosh; /// alias core.stdc.math.sinh sinh; @@ -1265,12 +1149,10 @@ else /// alias core.stdc.math.sinhl sinh; - /// - alias core.stdc.complex.csinh sinh; - /// - alias core.stdc.complex.csinhf sinh; - /// - alias core.stdc.complex.csinhl sinh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csinh sinh; + deprecated alias core.stdc.complex.csinhf sinh; + deprecated alias core.stdc.complex.csinhl sinh; /// alias core.stdc.math.tanh tanh; @@ -1279,12 +1161,10 @@ else /// alias core.stdc.math.tanhl tanh; - /// - alias core.stdc.complex.ctanh tanh; - /// - alias core.stdc.complex.ctanhf tanh; - /// - alias core.stdc.complex.ctanhl tanh; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.ctanh tanh; + deprecated alias core.stdc.complex.ctanhf tanh; + deprecated alias core.stdc.complex.ctanhl tanh; /// alias core.stdc.math.exp exp; @@ -1293,12 +1173,10 @@ else /// alias core.stdc.math.expl exp; - /// - alias core.stdc.complex.cexp exp; - /// - alias core.stdc.complex.cexpf exp; - /// - alias core.stdc.complex.cexpl exp; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cexp exp; + deprecated alias core.stdc.complex.cexpf exp; + deprecated alias core.stdc.complex.cexpl exp; /// alias core.stdc.math.exp2 exp2; @@ -1342,12 +1220,10 @@ else /// alias core.stdc.math.logl log; - /// - alias core.stdc.complex.clog log; - /// - alias core.stdc.complex.clogf log; - /// - alias core.stdc.complex.clogl log; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.clog log; + deprecated alias core.stdc.complex.clogf log; + deprecated alias core.stdc.complex.clogl log; /// alias core.stdc.math.log10 log10; @@ -1418,12 +1294,10 @@ else alias core.stdc.math.fabsl fabs; } - /// - alias core.stdc.complex.cabs fabs; - /// - alias core.stdc.complex.cabsf fabs; - /// - alias core.stdc.complex.cabsl fabs; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cabs fabs; + deprecated alias core.stdc.complex.cabsf fabs; + deprecated alias core.stdc.complex.cabsl fabs; /// alias core.stdc.math.hypot hypot; @@ -1439,12 +1313,10 @@ else /// alias core.stdc.math.powl pow; - /// - alias core.stdc.complex.cpow pow; - /// - alias core.stdc.complex.cpowf pow; - /// - alias core.stdc.complex.cpowl pow; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.cpow pow; + deprecated alias core.stdc.complex.cpowf pow; + deprecated alias core.stdc.complex.cpowl pow; /// alias core.stdc.math.sqrt sqrt; @@ -1453,12 +1325,10 @@ else /// alias core.stdc.math.sqrtl sqrt; - /// - alias core.stdc.complex.csqrt sqrt; - /// - alias core.stdc.complex.csqrtf sqrt; - /// - alias core.stdc.complex.csqrtl sqrt; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.csqrt sqrt; + deprecated alias core.stdc.complex.csqrtf sqrt; + deprecated alias core.stdc.complex.csqrtl sqrt; /// alias core.stdc.math.erf erf; @@ -1635,35 +1505,20 @@ else /// alias core.stdc.math.fmal fma; - /// - alias core.stdc.complex.carg carg; - /// - alias core.stdc.complex.cargf carg; - /// - alias core.stdc.complex.cargl carg; - - /// - alias core.stdc.complex.cimag cimag; - /// - alias core.stdc.complex.cimagf cimag; - /// - alias core.stdc.complex.cimagl cimag; - - /// - alias core.stdc.complex.conj conj; - /// - alias core.stdc.complex.conjf conj; - /// - alias core.stdc.complex.conjl conj; - - /// - alias core.stdc.complex.cproj cproj; - /// - alias core.stdc.complex.cprojf cproj; - /// - alias core.stdc.complex.cprojl cproj; - -// alias core.stdc.complex.creal creal; -// alias core.stdc.complex.crealf creal; -// alias core.stdc.complex.creall creal; + // @@@DEPRECATED_2.105@@@ + deprecated alias core.stdc.complex.carg carg; + deprecated alias core.stdc.complex.cargf carg; + deprecated alias core.stdc.complex.cargl carg; + deprecated alias core.stdc.complex.cimag cimag; + deprecated alias core.stdc.complex.cimagf cimag; + deprecated alias core.stdc.complex.cimagl cimag; + deprecated alias core.stdc.complex.conj conj; + deprecated alias core.stdc.complex.conjf conj; + deprecated alias core.stdc.complex.conjl conj; + deprecated alias core.stdc.complex.cproj cproj; + deprecated alias core.stdc.complex.cprojf cproj; + deprecated alias core.stdc.complex.cprojl cproj; +// deprecated alias core.stdc.complex.creal creal; +// deprecated alias core.stdc.complex.crealf creal; +// deprecated alias core.stdc.complex.creall creal; } diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d index eecc8ef..6da5618 100644 --- a/libphobos/libdruntime/core/stdc/wchar_.d +++ b/libphobos/libdruntime/core/stdc/wchar_.d @@ -173,12 +173,13 @@ extern (D) @trusted wint_t getwchar() { return fgetwc(stdin); } /// wint_t putwchar(wchar_t c) { return fputwc(c,stdout); } - /// - wint_t getwc(FILE* stream) { return fgetwc(stream); } - /// - wint_t putwc(wchar_t c, FILE* stream) { return fputwc(c, stream); } } +/// +alias getwc = fgetwc; +/// +alias putwc = fputwc; + // No unsafe pointer manipulation. @trusted { diff --git a/libphobos/libdruntime/core/sys/darwin/fcntl.d b/libphobos/libdruntime/core/sys/darwin/fcntl.d new file mode 100644 index 0000000..47d895a --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/fcntl.d @@ -0,0 +1,20 @@ +module core.sys.darwin.fcntl; + +public import core.sys.posix.fcntl; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (Darwin): +extern (C): +nothrow: +@nogc: +@system: + +enum F_FULLFSYNC = 51; diff --git a/libphobos/libdruntime/core/sys/linux/epoll.d b/libphobos/libdruntime/core/sys/linux/epoll.d index 0c3aed9..f5ff7db 100644 --- a/libphobos/libdruntime/core/sys/linux/epoll.d +++ b/libphobos/libdruntime/core/sys/linux/epoll.d @@ -10,6 +10,8 @@ module core.sys.linux.epoll; version (linux): +import core.sys.posix.signal : sigset_t; + extern (C): @system: @nogc: @@ -52,16 +54,19 @@ enum EPOLLHUP = 0x010, EPOLLRDHUP = 0x2000, // since Linux 2.6.17 EPOLLEXCLUSIVE = 1u << 28, // since Linux 4.5 + EPOLLWAKEUP = 1u << 29, EPOLLONESHOT = 1u << 30, EPOLLET = 1u << 31 } -/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */ +/** + * Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). + */ enum { - EPOLL_CTL_ADD = 1, // Add a file descriptor to the interface. - EPOLL_CTL_DEL = 2, // Remove a file descriptor from the interface. - EPOLL_CTL_MOD = 3, // Change file descriptor epoll_event structure. + EPOLL_CTL_ADD = 1, /// Add a file descriptor to the interface. + EPOLL_CTL_DEL = 2, /// Remove a file descriptor from the interface. + EPOLL_CTL_MOD = 3, /// Change file descriptor epoll_event structure. } version (X86_Any) @@ -142,7 +147,82 @@ union epoll_data_t ulong u64; } +/** + * Creates an epoll instance. + * + * Params: + * size = a hint specifying the number of file descriptors to be associated + * with the new instance. T + * Returns: an fd for the new instance. The fd returned by epoll_create() should + * be closed with close(). + * See_also: epoll_create1 (int flags) + */ int epoll_create (int size); + +/* Same as epoll_create but with an FLAGS parameter. The unused SIZE + parameter has been dropped. */ + +/** + * Creates an epoll instance. + * + * Params: + * flags = a specified flag. If flags is 0, then, other than the fact that the + * obsolete size argument is dropped, epoll_create1() is the same as + * epoll_create(). + * Returns: an fd for the new instance. The fd returned by epoll_create() should + * be closed with close(). + * See_also: epoll_create (int size) + */ int epoll_create1 (int flags); + +/** + * Manipulate an epoll instance + * + * Params: + * epfd = an epoll file descriptor instance + * op = one of the EPOLL_CTL_* constants + * fd = target file descriptor of the operation + * event = describes which events the caller is interested in and any + * associated user dat + * Returns: 0 in case of success, -1 in case of error ( the "errno" variable + * will contain the specific error code ) + */ int epoll_ctl (int epfd, int op, int fd, epoll_event *event); + + +/** + * Wait for events on an epoll instance. + * + * + * Params: + * epfd = an epoll file descriptor instance + * events = a buffer that will contain triggered events + * maxevents = the maximum number of events to be returned ( usually size of + * "events" ) + * timeout = specifies the maximum wait time in milliseconds (-1 == infinite) + * + * Returns: the number of triggered events returned in "events" buffer. Or -1 in + * case of error with the "errno" variable set to the specific error + * code. + */ int epoll_wait (int epfd, epoll_event *events, int maxevents, int timeout); + +/** + * Wait for events on an epoll instance + * + * + * Params: + * epfd = an epoll file descriptor instance + * events = a buffer that will contain triggered events + * maxevents = the maximum number of events to be returned ( usually size of + * "events" ) + * timeout = specifies the maximum wait time in milliseconds (-1 == infinite) + * ss = a signal set. May be specified as `null`, in which case epoll_pwait() is + * equivalent to epoll_wait(). + * + * Returns: the number of triggered events returned in "events" buffer. Or -1 in + * case of error with the "errno" variable set to the specific error + * code. + */ +int epoll_pwait (int epfd, epoll_event *events, int maxevents, int timeout, + const sigset_t *ss); diff --git a/libphobos/libdruntime/core/sys/openbsd/string.d b/libphobos/libdruntime/core/sys/openbsd/string.d index 8d35b9c..cb978c8 100644 --- a/libphobos/libdruntime/core/sys/openbsd/string.d +++ b/libphobos/libdruntime/core/sys/openbsd/string.d @@ -18,4 +18,6 @@ nothrow: static if (__BSD_VISIBLE) { pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure int timingsafe_bcmp(scope const void*, scope const void*, size_t); + pure int timingsafe_memcmp(scope const void*, scope const void*, size_t); } diff --git a/libphobos/libdruntime/core/sys/openbsd/unistd.d b/libphobos/libdruntime/core/sys/openbsd/unistd.d new file mode 100644 index 0000000..ddd102c --- /dev/null +++ b/libphobos/libdruntime/core/sys/openbsd/unistd.d @@ -0,0 +1,17 @@ +/** + * D header file for OpenBSD unistd.h. + * + * Copyright: Copyright © 2021, The D Language Foundation + * License: Boost License 1.0. + * Authors: Brian Callahan + */ +module core.sys.openbsd.unistd; +public import core.sys.posix.unistd; + +version (OpenBSD): +extern (C): +nothrow: +@nogc: + +int pledge(const scope char*, const scope char*); +int unveil(const scope char*, const scope char*); diff --git a/libphobos/libdruntime/core/sys/posix/config.d b/libphobos/libdruntime/core/sys/posix/config.d index c02debff..3b575fa 100644 --- a/libphobos/libdruntime/core/sys/posix/config.d +++ b/libphobos/libdruntime/core/sys/posix/config.d @@ -117,6 +117,7 @@ else version (CRuntime_UClibc) else version (CRuntime_Bionic) { enum _GNU_SOURCE = false; + enum __USE_FILE_OFFSET64 = false; // see https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md enum __USE_GNU = _GNU_SOURCE; version (D_LP64) diff --git a/libphobos/libdruntime/core/sys/posix/dlfcn.d b/libphobos/libdruntime/core/sys/posix/dlfcn.d index e97c7ea..2477e26 100644 --- a/libphobos/libdruntime/core/sys/posix/dlfcn.d +++ b/libphobos/libdruntime/core/sys/posix/dlfcn.d @@ -139,7 +139,7 @@ else version (Darwin) char* dlerror(); void* dlopen(const scope char*, int); void* dlsym(void*, const scope char*); - int dladdr(void* addr, Dl_info* info); + int dladdr(scope const void* addr, Dl_info* info); struct Dl_info { @@ -294,6 +294,15 @@ else version (CRuntime_Musl) const(char)* dlerror(); void* dlopen(const scope char*, int); void* dlsym(void*, const scope char*); + + int dladdr(scope const void *addr, Dl_info *info); + struct Dl_info + { + const(char)* dli_fname; + void* dli_fbase; + const(char)* dli_sname; + void* dli_saddr; + } } else version (CRuntime_UClibc) { diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d index 44f45f2..0dce8c5 100644 --- a/libphobos/libdruntime/core/sys/posix/signal.d +++ b/libphobos/libdruntime/core/sys/posix/signal.d @@ -3503,7 +3503,7 @@ struct sigevent pthread_attr_t* sigev_notify_attributes; } -int sigqueue(pid_t, int, in sigval); +int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); */ @@ -3543,7 +3543,7 @@ version (CRuntime_Glibc) } _sigev_un_t _sigev_un; } - int sigqueue(pid_t, int, in sigval); + int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } @@ -3566,7 +3566,7 @@ else version (FreeBSD) } } - int sigqueue(pid_t, int, in sigval); + int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } @@ -3581,7 +3581,7 @@ else version (NetBSD) void /* pthread_attr_t */*sigev_notify_attributes; } - int sigqueue(pid_t, int, in sigval); + int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } @@ -3613,7 +3613,7 @@ else version (DragonFlyBSD) void function(_sigval_t) sigev_notify_function; } - int sigqueue(pid_t, int, in sigval); + int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } @@ -3640,7 +3640,7 @@ else version (Solaris) int __sigev_pad2; } - int sigqueue(pid_t, int, in sigval); + int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } @@ -3717,7 +3717,7 @@ else version (CRuntime_UClibc) @property void function(sigval) sigev_notify_function(ref sigevent _sigevent) { return _sigevent._sigev_un._sigev_thread._function; } @property void* sigev_notify_attributes(ref sigevent _sigevent) { return _sigevent._sigev_un._sigev_thread._attribute; } - int sigqueue(pid_t, int, in sigval); + int sigqueue(pid_t, int, const sigval); int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } diff --git a/libphobos/libdruntime/core/sys/posix/unistd.d b/libphobos/libdruntime/core/sys/posix/unistd.d index a691884..d996556 100644 --- a/libphobos/libdruntime/core/sys/posix/unistd.d +++ b/libphobos/libdruntime/core/sys/posix/unistd.d @@ -2722,3 +2722,51 @@ else version (CRuntime_UClibc) int truncate(const scope char*, off_t); } } + +// Non-standard definition to access user process environment +version (CRuntime_Glibc) +{ + extern __gshared const char** environ; +} +else version (Darwin) +{ + extern (D) @property const(char**) environ()() + { + pragma (inline, true); + import core.sys.darwin.crt_externs : _NSGetEnviron; + return *_NSGetEnviron(); + } +} +else version (FreeBSD) +{ + extern __gshared const char** environ; +} +else version (NetBSD) +{ + extern __gshared const char** environ; +} +else version (OpenBSD) +{ + extern __gshared const char** environ; +} +else version (DragonFlyBSD) +{ + extern __gshared const char** environ; +} +else version (CRuntime_Bionic) +{ + extern __gshared const char** environ; +} +else version (CRuntime_Musl) +{ + extern __gshared const char** environ; +} +else version (Solaris) +{ + extern __gshared const char** environ; +} +else version (CRuntime_UClibc) +{ + extern __gshared const char** __environ; + alias environ = __environ; +} diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d index 90a2943..88007ad 100644 --- a/libphobos/libdruntime/core/sys/windows/com.d +++ b/libphobos/libdruntime/core/sys/windows/com.d @@ -39,16 +39,16 @@ public import core.sys.windows.winerror : RPC_E_CHANGED_MODE; public import core.sys.windows.wtypes : - OLECHAR, LPOLESTR, LPCOLESTR; - -alias CLSCTX_INPROC_SERVER = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVER ; -alias CLSCTX_INPROC_HANDLER = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLER ; -alias CLSCTX_LOCAL_SERVER = core.sys.windows.wtypes.CLSCTX.CLSCTX_LOCAL_SERVER ; -alias CLSCTX_INPROC_SERVER16 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVER16 ; -alias CLSCTX_REMOTE_SERVER = core.sys.windows.wtypes.CLSCTX.CLSCTX_REMOTE_SERVER ; -alias CLSCTX_INPROC_HANDLER16 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLER16 ; -alias CLSCTX_INPROC_SERVERX86 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_SERVERX86 ; -alias CLSCTX_INPROC_HANDLERX86 = core.sys.windows.wtypes.CLSCTX.CLSCTX_INPROC_HANDLERX86; + CLSCTX, OLECHAR, LPOLESTR, LPCOLESTR; + +alias CLSCTX_INPROC_SERVER = CLSCTX.CLSCTX_INPROC_SERVER ; +alias CLSCTX_INPROC_HANDLER = CLSCTX.CLSCTX_INPROC_HANDLER ; +alias CLSCTX_LOCAL_SERVER = CLSCTX.CLSCTX_LOCAL_SERVER ; +alias CLSCTX_INPROC_SERVER16 = CLSCTX.CLSCTX_INPROC_SERVER16 ; +alias CLSCTX_REMOTE_SERVER = CLSCTX.CLSCTX_REMOTE_SERVER ; +alias CLSCTX_INPROC_HANDLER16 = CLSCTX.CLSCTX_INPROC_HANDLER16 ; +alias CLSCTX_INPROC_SERVERX86 = CLSCTX.CLSCTX_INPROC_SERVERX86 ; +alias CLSCTX_INPROC_HANDLERX86 = CLSCTX.CLSCTX_INPROC_HANDLERX86; alias COINIT_APARTMENTTHREADED = COINIT.COINIT_APARTMENTTHREADED; alias COINIT_MULTITHREADED = COINIT.COINIT_MULTITHREADED ; diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d index 9f36ac3..3df0d7f 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/sys/windows/stdc/malloc.d b/libphobos/libdruntime/core/sys/windows/stdc/malloc.d new file mode 100644 index 0000000..f52ba37 --- /dev/null +++ b/libphobos/libdruntime/core/sys/windows/stdc/malloc.d @@ -0,0 +1,26 @@ +/** + * D header file for Windows malloc.h. + * + * Translated from MinGW Windows headers + * + * Authors: Iain Buclaw + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC src/core/sys/windows/stdc/_malloc.d) + */ +module core.sys.windows.stdc.malloc; +version (CRuntime_Microsoft): +extern (C): +@system: +nothrow: +@nogc: + +export void* _recalloc(void*, size_t, size_t); + +export void _aligned_free(void*); +export void* _aligned_malloc(size_t, size_t); + +export void* _aligned_offset_malloc(size_t, size_t, size_t); +export void* _aligned_realloc(void*, size_t, size_t); +export void* _aligned_recalloc(void*, size_t, size_t, size_t); +export void* _aligned_offset_realloc(void*, size_t, size_t, size_t); +export void* _aligned_offset_recalloc(void*, size_t, size_t, size_t, size_t); diff --git a/libphobos/libdruntime/gc/impl/conservative/gc.d b/libphobos/libdruntime/gc/impl/conservative/gc.d index b7bb9b0..300a32a 100644 --- a/libphobos/libdruntime/gc/impl/conservative/gc.d +++ b/libphobos/libdruntime/gc/impl/conservative/gc.d @@ -76,7 +76,7 @@ debug(PRINTF_TO_FILE) gcStartTick = MonoTime.currTime; immutable timeElapsed = MonoTime.currTime - gcStartTick; immutable secondsAsDouble = timeElapsed.total!"hnsecs" / cast(double)convert!("seconds", "hnsecs")(1); - len = fprintf(gcx_fh, "%10.6lf: ", secondsAsDouble); + len = fprintf(gcx_fh, "%10.6f: ", secondsAsDouble); } len += fprintf(gcx_fh, fmt, args); fflush(gcx_fh); @@ -159,7 +159,7 @@ debug (LOGGING) printf(" p = %p, size = %zd, parent = %p ", p, size, parent); if (file) { - printf("%s(%u)", file, line); + printf("%s(%u)", file, cast(uint)line); } printf("\n"); } diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 04d5457..c05643b 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -19,10 +19,11 @@ private alias size_t = typeof(int.sizeof); alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0); -alias sizediff_t = ptrdiff_t; //For backwards compatibility only. +alias sizediff_t = ptrdiff_t; // For backwards compatibility only. +alias noreturn = typeof(*null); /// bottom type -alias hash_t = size_t; //For backwards compatibility only. -alias equals_t = bool; //For backwards compatibility only. +alias hash_t = size_t; // For backwards compatibility only. +alias equals_t = bool; // For backwards compatibility only. alias string = immutable(char)[]; alias wstring = immutable(wchar)[]; diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 6de04b4..4f6a168 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -9d575282edeccecbc061e615bf2486fd07e8c084 +f89dc217a680fa1a83f2999fea04b7c562f705ee The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am index 0dc2a26..2dedc74 100644 --- a/libphobos/src/Makefile.am +++ b/libphobos/src/Makefile.am @@ -135,11 +135,11 @@ PHOBOS_DSOURCES = etc/c/curl.d etc/c/sqlite3.d etc/c/zlib.d \ std/regex/internal/backtracking.d std/regex/internal/generator.d \ std/regex/internal/ir.d std/regex/internal/kickstart.d \ std/regex/internal/parser.d std/regex/internal/tests.d \ - std/regex/internal/thompson.d std/regex/package.d std/signals.d \ - std/socket.d std/stdint.d std/stdio.d std/string.d std/system.d \ - std/traits.d std/typecons.d std/typetuple.d std/uni.d std/uri.d \ - std/utf.d std/uuid.d std/variant.d std/windows/charset.d \ - std/windows/registry.d std/windows/syserror.d std/xml.d std/zip.d \ - std/zlib.d + std/regex/internal/tests2.d std/regex/internal/thompson.d \ + std/regex/package.d std/signals.d std/socket.d std/stdint.d \ + std/stdio.d std/string.d std/system.d std/traits.d std/typecons.d \ + std/typetuple.d std/uni.d std/uri.d std/utf.d std/uuid.d std/variant.d \ + std/windows/charset.d std/windows/registry.d std/windows/syserror.d \ + std/xml.d std/zip.d std/zlib.d endif diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in index 3345351..9e410e5 100644 --- a/libphobos/src/Makefile.in +++ b/libphobos/src/Makefile.in @@ -249,6 +249,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/kickstart.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/parser.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/tests.lo \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/tests2.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/thompson.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/package.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/signals.lo std/socket.lo \ @@ -572,12 +573,12 @@ libgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/backtracking.d std/regex/internal/generator.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/ir.d std/regex/internal/kickstart.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/parser.d std/regex/internal/tests.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/thompson.d std/regex/package.d std/signals.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/socket.d std/stdint.d std/stdio.d std/string.d std/system.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/traits.d std/typecons.d std/typetuple.d std/uni.d std/uri.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/utf.d std/uuid.d std/variant.d std/windows/charset.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/windows/registry.d std/windows/syserror.d std/xml.d std/zip.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/zlib.d +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/tests2.d std/regex/internal/thompson.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/package.d std/signals.d std/socket.d std/stdint.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/stdio.d std/string.d std/system.d std/traits.d std/typecons.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/typetuple.d std/uni.d std/uri.d std/utf.d std/uuid.d std/variant.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/windows/charset.d std/windows/registry.d std/windows/syserror.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/xml.d std/zip.d std/zlib.d # Source file definitions. Boring stuff, auto-generated with @@ -851,6 +852,7 @@ std/regex/internal/ir.lo: std/regex/internal/$(am__dirstamp) std/regex/internal/kickstart.lo: std/regex/internal/$(am__dirstamp) std/regex/internal/parser.lo: std/regex/internal/$(am__dirstamp) std/regex/internal/tests.lo: std/regex/internal/$(am__dirstamp) +std/regex/internal/tests2.lo: std/regex/internal/$(am__dirstamp) std/regex/internal/thompson.lo: std/regex/internal/$(am__dirstamp) std/regex/$(am__dirstamp): @$(MKDIR_P) std/regex diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d index c77792d..19cfb77 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -769,9 +769,9 @@ private struct MapResult(alias fun, Range) string s1 = "hello world!"; dstring s2 = "日本語"; dstring s3 = "hello world!"d; - auto ms1 = map!(std.ascii.toUpper)(s1); - auto ms2 = map!(std.ascii.toUpper)(s2); - auto ms3 = map!(std.ascii.toUpper)(s3); + auto ms1 = map!(toUpper)(s1); + auto ms2 = map!(toUpper)(s2); + auto ms3 = map!(toUpper)(s3); static assert(!is(ms1[0])); //narrow strings can't be indexed assert(ms2[0] == '日'); assert(ms3[0] == 'H'); @@ -4450,7 +4450,7 @@ private struct SplitterResult(alias isTerminator, Range) ["là", "dove", "terminava", "quella", "valle"] )); assert(equal( - splitter!(std.uni.isWhite)("là dove terminava quella valle"), + splitter!(isWhite)("là dove terminava quella valle"), ["là", "dove", "terminava", "quella", "valle"] )); assert(equal(splitter!"a=='本'"("日本語"), ["日", "語"])); diff --git a/libphobos/src/std/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d index 6468a87..09073f6 100644 --- a/libphobos/src/std/algorithm/searching.d +++ b/libphobos/src/std/algorithm/searching.d @@ -959,8 +959,8 @@ if (isInputRange!R && import std.ascii : isDigit; import std.uni : isWhite; - assert(countUntil!(std.uni.isWhite)("hello world") == 5); - assert(countUntil!(std.ascii.isDigit)("hello world") == -1); + assert(countUntil!(isWhite)("hello world") == 5); + assert(countUntil!(isDigit)("hello world") == -1); assert(countUntil!"a > 20"([0, 7, 12, 22, 9]) == 3); } diff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d index 861da5e..5e31ac2 100644 --- a/libphobos/src/std/container/rbtree.d +++ b/libphobos/src/std/container/rbtree.d @@ -1814,8 +1814,8 @@ assert(equal(rbt[], [5])); test!byte(); } -import std.range.primitives : isInputRange, isSomeString, ElementType; -import std.traits : isArray; +import std.range.primitives : isInputRange, ElementType; +import std.traits : isArray, isSomeString; /++ Convenience function for creating a $(D RedBlackTree!E) from a list of diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d index 31cc651..3560d13 100644 --- a/libphobos/src/std/conv.d +++ b/libphobos/src/std/conv.d @@ -3967,7 +3967,7 @@ if (isOctalLiteral(num)) /// Ditto template octal(alias decimalInteger) -if (isIntegral!(typeof(decimalInteger))) +if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger))) { enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger)); } diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d index b229191..913d360 100644 --- a/libphobos/src/std/datetime/systime.d +++ b/libphobos/src/std/datetime/systime.d @@ -9569,7 +9569,7 @@ afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); } // year - auto found = value[2 .. value.length].find!(not!(std.ascii.isDigit))(); + auto found = value[2 .. value.length].find!(not!(isDigit))(); size_t yearLen = value.length - found.length; if (found.length == 0) throw new DateTimeException("Invalid year"); @@ -9659,7 +9659,7 @@ afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); case "J": case "j": throw new DateTimeException("Invalid timezone"); default: { - if (all!(std.ascii.isAlpha)(value[0 .. tzLen])) + if (all!(isAlpha)(value[0 .. tzLen])) { tz = new immutable SimpleTimeZone(Duration.zero); break; diff --git a/libphobos/src/std/experimental/logger/nulllogger.d b/libphobos/src/std/experimental/logger/nulllogger.d index fa511be..0c55377 100644 --- a/libphobos/src/std/experimental/logger/nulllogger.d +++ b/libphobos/src/std/experimental/logger/nulllogger.d @@ -31,7 +31,7 @@ class NullLogger : Logger /// @safe unittest { - import std.experimental.logger.nulllogger : LogLevel; + import std.experimental.logger.core : LogLevel; auto nl1 = new NullLogger(LogLevel.all); nl1.info("You will never read this."); diff --git a/libphobos/src/std/experimental/typecons.d b/libphobos/src/std/experimental/typecons.d index 6906f05..07eed8f 100644 --- a/libphobos/src/std/experimental/typecons.d +++ b/libphobos/src/std/experimental/typecons.d @@ -23,8 +23,7 @@ module std.experimental.typecons; import std.meta; // : AliasSeq, allSatisfy; import std.traits; -import std.typecons : Tuple, tuple, Bind, DerivedFunctionType, - isImplicitlyConvertible, mixinAll, staticIota, +import std.typecons : Tuple, tuple, Bind, DerivedFunctionType, mixinAll, staticIota, GetOverloadedMethods; private @@ -113,7 +112,8 @@ if (Targets.length >= 1 && allSatisfy!(isMutable, Targets)) else { enum foundFunc = findCovariantFunction!(TargetMembers[i], Source, SourceMembers); - debug + version (unittest) {} + else debug { static if (foundFunc == -1) pragma(msg, "Could not locate matching function for: ", diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index 13a3db0..99530cb 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -2301,7 +2301,7 @@ if (isConvertibleToString!R) @safe unittest { - import std.path : mkdir; + import std.file : mkdir; static assert(__traits(compiles, mkdir(TestAliasedString(null)))); } @@ -4112,7 +4112,8 @@ auto dirEntries(string path, SpanMode mode, bool followSymlink = true) import std.algorithm.searching : startsWith; import std.array : array; import std.conv : to; - import std.path : dirEntries, buildPath, absolutePath; + import std.path : buildPath, absolutePath; + import std.file : dirEntries; import std.process : thisProcessID; import std.range.primitives : walkLength; diff --git a/libphobos/src/std/format.d b/libphobos/src/std/format.d index 64b1bd3..17e5906 100644 --- a/libphobos/src/std/format.d +++ b/libphobos/src/std/format.d @@ -5199,7 +5199,7 @@ body } debug (unformatRange) printf("\t"); debug (unformatRange) if (!input.empty) printf("input.front = %c, ", input.front); - debug (unformatRange) printf("cont = %.*s\n", cont); + debug (unformatRange) printf("cont = %.*s\n", cast(int) cont.length, cont.ptr); bool checkEnd() { @@ -5246,7 +5246,7 @@ body auto sep = spec.sep !is null ? spec.sep : fmt.trailing; debug (unformatRange) { - if (!sep.empty && !input.empty) printf("-> %c, sep = %.*s\n", input.front, sep); + if (!sep.empty && !input.empty) printf("-> %c, sep = %.*s\n", input.front, cast(int) sep.length, sep.ptr); else printf("\n"); } diff --git a/libphobos/src/std/internal/math/biguintcore.d b/libphobos/src/std/internal/math/biguintcore.d index f5cd769..6fc2d16 100644 --- a/libphobos/src/std/internal/math/biguintcore.d +++ b/libphobos/src/std/internal/math/biguintcore.d @@ -2503,13 +2503,13 @@ pure nothrow void printBiguint(const uint [] data) { char [] buff = biguintToHex(new char[data.length*9], data, '_'); - printf("%.*s\n", buff.length, buff.ptr); + printf("%.*s\n", cast(int) buff.length, buff.ptr); } void printDecimalBigUint(BigUint data) { auto str = data.toDecimalString(0); - printf("%.*s\n", str.length, str.ptr); + printf("%.*s\n", cast(int) str.length, str.ptr); } uint [] a, b; diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d index ff368b7..336c11a 100644 --- a/libphobos/src/std/math.d +++ b/libphobos/src/std/math.d @@ -263,8 +263,8 @@ version (unittest) alias real_t = double; else alias real_t = real; - ix = sprintf(bufx.ptr, "%.*Lg", ndigits, cast(real_t) x); - iy = sprintf(bufy.ptr, "%.*Lg", ndigits, cast(real_t) y); + ix = sprintf(bufx.ptr, is(real_t == real) ? "%.*Lg" : "%.*g", ndigits, cast(real_t) x); + iy = sprintf(bufy.ptr, is(real_t == real) ? "%.*Lg" : "%.*g", ndigits, cast(real_t) y); assert(ix < bufx.length && ix > 0); assert(ix < bufy.length && ix > 0); diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d index 43a1ba5..61d5cea 100644 --- a/libphobos/src/std/parallelism.d +++ b/libphobos/src/std/parallelism.d @@ -4000,7 +4000,7 @@ version (unittest) import std.array : split; import std.conv : text; import std.exception : assertThrown; - import std.math : approxEqual, sqrt, log; + import std.math : approxEqual, sqrt, log, abs; import std.range : indexed, iota, join; import std.typecons : Tuple, tuple; @@ -4329,7 +4329,7 @@ version (unittest) assert(equal(iota(1_000_000), bufTrickTest)); - auto myTask = task!(std.math.abs)(-1); + auto myTask = task!(abs)(-1); taskPool.put(myTask); assert(myTask.spinForce == 1); diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d index 13601cb..deedb68 100644 --- a/libphobos/src/std/range/package.d +++ b/libphobos/src/std/range/package.d @@ -11379,7 +11379,6 @@ if (isInputRange!R && isIntegral!(ElementType!R)) bw.popFront(); assert(bw[2 * bitsNum - 3] == true); - import core.exception : Error; import std.exception : assertThrown; // Check out of bounds error diff --git a/libphobos/src/std/regex/internal/tests.d b/libphobos/src/std/regex/internal/tests.d index 1c4f295..fe75ce0 100644 --- a/libphobos/src/std/regex/internal/tests.d +++ b/libphobos/src/std/regex/internal/tests.d @@ -8,7 +8,7 @@ package(std.regex): import std.conv, std.exception, std.meta, std.range, std.typecons, std.regex; -import std.regex.internal.parser : Escapables; // characters that need escaping +import std.regex.internal.ir : Escapables; // characters that need escaping alias Sequence(int B, int E) = staticIota!(B, E); @@ -467,654 +467,3 @@ alias Sequence(int B, int E) = staticIota!(B, E); run_tests!match(); //thompson VM } -@safe unittest -{ - auto cr = ctRegex!("abc"); - assert(bmatch("abc",cr).hit == "abc"); - auto cr2 = ctRegex!("ab*c"); - assert(bmatch("abbbbc",cr2).hit == "abbbbc"); -} -@safe unittest -{ - auto cr3 = ctRegex!("^abc$"); - assert(bmatch("abc",cr3).hit == "abc"); - auto cr4 = ctRegex!(`\b(a\B[a-z]b)\b`); - assert(array(match("azb",cr4).captures) == ["azb", "azb"]); -} - -@safe unittest -{ - auto cr5 = ctRegex!("(?:a{2,4}b{1,3}){1,2}"); - assert(bmatch("aaabaaaabbb", cr5).hit == "aaabaaaabbb"); - auto cr6 = ctRegex!("(?:a{2,4}b{1,3}){1,2}?"w); - assert(bmatch("aaabaaaabbb"w, cr6).hit == "aaab"w); -} - -@safe unittest -{ - auto cr7 = ctRegex!(`\r.*?$`,"sm"); - assert(bmatch("abc\r\nxy", cr7).hit == "\r\nxy"); - auto greed = ctRegex!(""); - assert(bmatch("texttext", greed).hit - == "text"); -} - -@safe unittest -{ - import std.algorithm.comparison : equal; - auto cr8 = ctRegex!("^(a)(b)?(c*)"); - auto m8 = bmatch("abcc",cr8); - assert(m8); - assert(m8.captures[1] == "a"); - assert(m8.captures[2] == "b"); - assert(m8.captures[3] == "cc"); - auto cr9 = ctRegex!("q(a|b)*q"); - auto m9 = match("xxqababqyy",cr9); - assert(m9); - assert(equal(bmatch("xxqababqyy",cr9).captures, ["qababq", "b"])); -} - -@safe unittest -{ - import std.algorithm.comparison : equal; - auto rtr = regex("a|b|c"); - enum ctr = regex("a|b|c"); - assert(equal(rtr.ir,ctr.ir)); - //CTFE parser BUG is triggered by group - //in the middle of alternation (at least not first and not last) - enum testCT = regex(`abc|(edf)|xyz`); - auto testRT = regex(`abc|(edf)|xyz`); - assert(equal(testCT.ir,testRT.ir)); -} - -@safe unittest -{ - import std.algorithm.comparison : equal; - import std.algorithm.iteration : map; - enum cx = ctRegex!"(A|B|C)"; - auto mx = match("B",cx); - assert(mx); - assert(equal(mx.captures, [ "B", "B"])); - enum cx2 = ctRegex!"(A|B)*"; - assert(match("BAAA",cx2)); - - enum cx3 = ctRegex!("a{3,4}","i"); - auto mx3 = match("AaA",cx3); - assert(mx3); - assert(mx3.captures[0] == "AaA"); - enum cx4 = ctRegex!(`^a{3,4}?[a-zA-Z0-9~]{1,2}`,"i"); - auto mx4 = match("aaaabc", cx4); - assert(mx4); - assert(mx4.captures[0] == "aaaab"); - auto cr8 = ctRegex!("(a)(b)?(c*)"); - auto m8 = bmatch("abcc",cr8); - assert(m8); - assert(m8.captures[1] == "a"); - assert(m8.captures[2] == "b"); - assert(m8.captures[3] == "cc"); - auto cr9 = ctRegex!(".*$", "gm"); - auto m9 = match("First\rSecond", cr9); - assert(m9); - assert(equal(map!"a.hit"(m9), ["First", "", "Second"])); -} - -@safe unittest -{ - import std.algorithm.comparison : equal; - import std.algorithm.iteration : map; -//global matching - void test_body(alias matchFn)() - { - string s = "a quick brown fox jumps over a lazy dog"; - auto r1 = regex("\\b[a-z]+\\b","g"); - string[] test; - foreach (m; matchFn(s, r1)) - test ~= m.hit; - assert(equal(test, [ "a", "quick", "brown", "fox", "jumps", "over", "a", "lazy", "dog"])); - auto free_reg = regex(` - - abc - \s+ - " - ( - [^"]+ - | \\ " - )+ - " - z - `, "x"); - auto m = match(`abc "quoted string with \" inside"z`,free_reg); - assert(m); - string mails = " hey@you.com no@spam.net "; - auto rm = regex(`@(?<=\S+@)\S+`,"g"); - assert(equal(map!"a[0]"(matchFn(mails, rm)), ["@you.com", "@spam.net"])); - auto m2 = matchFn("First line\nSecond line",regex(".*$","gm")); - assert(equal(map!"a[0]"(m2), ["First line", "", "Second line"])); - auto m2a = matchFn("First line\nSecond line",regex(".+$","gm")); - assert(equal(map!"a[0]"(m2a), ["First line", "Second line"])); - auto m2b = matchFn("First line\nSecond line",regex(".+?$","gm")); - assert(equal(map!"a[0]"(m2b), ["First line", "Second line"])); - debug(std_regex_test) writeln("!!! FReD FLAGS test done "~matchFn.stringof~" !!!"); - } - test_body!bmatch(); - test_body!match(); -} - -//tests for accumulated std.regex issues and other regressions -@safe unittest -{ - import std.algorithm.comparison : equal; - import std.algorithm.iteration : map; - void test_body(alias matchFn)() - { - //issue 5857 - //matching goes out of control if ... in (...){x} has .*/.+ - auto c = matchFn("axxxzayyyyyzd",regex("(a.*z){2}d")).captures; - assert(c[0] == "axxxzayyyyyzd"); - assert(c[1] == "ayyyyyz"); - auto c2 = matchFn("axxxayyyyyd",regex("(a.*){2}d")).captures; - assert(c2[0] == "axxxayyyyyd"); - assert(c2[1] == "ayyyyy"); - //issue 2108 - //greedy vs non-greedy - auto nogreed = regex(""); - assert(matchFn("texttext", nogreed).hit - == "text"); - auto greed = regex(""); - assert(matchFn("texttext", greed).hit - == "texttext"); - //issue 4574 - //empty successful match still advances the input - string[] pres, posts, hits; - foreach (m; matchFn("abcabc", regex("","g"))) - { - pres ~= m.pre; - posts ~= m.post; - assert(m.hit.empty); - - } - auto heads = [ - "abcabc", - "abcab", - "abca", - "abc", - "ab", - "a", - "" - ]; - auto tails = [ - "abcabc", - "bcabc", - "cabc", - "abc", - "bc", - "c", - "" - ]; - assert(pres == array(retro(heads))); - assert(posts == tails); - //issue 6076 - //regression on .* - auto re = regex("c.*|d"); - auto m = matchFn("mm", re); - assert(!m); - debug(std_regex_test) writeln("!!! FReD REGRESSION test done "~matchFn.stringof~" !!!"); - auto rprealloc = regex(`((.){5}.{1,10}){5}`); - auto arr = array(repeat('0',100)); - auto m2 = matchFn(arr, rprealloc); - assert(m2); - assert(collectException( - regex(r"^(import|file|binary|config)\s+([^\(]+)\(?([^\)]*)\)?\s*$") - ) is null); - foreach (ch; [Escapables]) - { - assert(match(to!string(ch),regex(`[\`~ch~`]`))); - assert(!match(to!string(ch),regex(`[^\`~ch~`]`))); - assert(match(to!string(ch),regex(`[\`~ch~`-\`~ch~`]`))); - } - //bugzilla 7718 - string strcmd = "./myApp.rb -os OSX -path \"/GIT/Ruby Apps/sec\" -conf 'notimer'"; - auto reStrCmd = regex (`(".*")|('.*')`, "g"); - assert(equal(map!"a[0]"(matchFn(strcmd, reStrCmd)), - [`"/GIT/Ruby Apps/sec"`, `'notimer'`])); - } - test_body!bmatch(); - test_body!match(); -} - -// tests for replace -@safe unittest -{ - void test(alias matchFn)() - { - import std.uni : toUpper; - - foreach (i, v; AliasSeq!(string, wstring, dstring)) - { - auto baz(Cap)(Cap m) - if (is(Cap == Captures!(Cap.String))) - { - return toUpper(m.hit); - } - alias String = v; - assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r")), to!String("c")) - == to!String("ack rapacity")); - assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r"), "g"), to!String("c")) - == to!String("ack capacity")); - assert(std.regex.replace!(matchFn)(to!String("noon"), regex(to!String("^n")), to!String("[$&]")) - == to!String("[n]oon")); - assert(std.regex.replace!(matchFn)( - to!String("test1 test2"), regex(to!String(`\w+`),"g"), to!String("$`:$'") - ) == to!String(": test2 test1 :")); - auto s = std.regex.replace!(baz!(Captures!(String)))(to!String("Strap a rocket engine on a chicken."), - regex(to!String("[ar]"), "g")); - assert(s == "StRAp A Rocket engine on A chicken."); - } - debug(std_regex_test) writeln("!!! Replace test done "~matchFn.stringof~" !!!"); - } - test!(bmatch)(); - test!(match)(); -} - -// tests for splitter -@safe unittest -{ - import std.algorithm.comparison : equal; - auto s1 = ", abc, de, fg, hi, "; - auto sp1 = splitter(s1, regex(", *")); - auto w1 = ["", "abc", "de", "fg", "hi", ""]; - assert(equal(sp1, w1)); - - auto s2 = ", abc, de, fg, hi"; - auto sp2 = splitter(s2, regex(", *")); - auto w2 = ["", "abc", "de", "fg", "hi"]; - - uint cnt; - foreach (e; sp2) - { - assert(w2[cnt++] == e); - } - assert(equal(sp2, w2)); -} - -@safe unittest -{ - char[] s1 = ", abc, de, fg, hi, ".dup; - auto sp2 = splitter(s1, regex(", *")); -} - -@safe unittest -{ - import std.algorithm.comparison : equal; - auto s1 = ", abc, de, fg, hi, "; - auto w1 = ["", "abc", "de", "fg", "hi", ""]; - assert(equal(split(s1, regex(", *")), w1[])); -} - -@safe unittest -{ // bugzilla 7141 - string pattern = `[a\--b]`; - assert(match("-", pattern)); - assert(match("b", pattern)); - string pattern2 = `[&-z]`; - assert(match("b", pattern2)); -} -@safe unittest -{//bugzilla 7111 - assert(match("", regex("^"))); -} -@safe unittest -{//bugzilla 7300 - assert(!match("a"d, "aa"d)); -} - -// bugzilla 7551 -@safe unittest -{ - auto r = regex("[]abc]*"); - assert("]ab".matchFirst(r).hit == "]ab"); - assertThrown(regex("[]")); - auto r2 = regex("[]abc--ab]*"); - assert("]ac".matchFirst(r2).hit == "]"); -} - -@safe unittest -{//bugzilla 7674 - assert("1234".replace(regex("^"), "$$") == "$1234"); - assert("hello?".replace(regex(r"\?", "g"), r"\?") == r"hello\?"); - assert("hello?".replace(regex(r"\?", "g"), r"\\?") != r"hello\?"); -} -@safe unittest -{// bugzilla 7679 - import std.algorithm.comparison : equal; - foreach (S; AliasSeq!(string, wstring, dstring)) - (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396 - enum re = ctRegex!(to!S(r"\.")); - auto str = to!S("a.b"); - assert(equal(std.regex.splitter(str, re), [to!S("a"), to!S("b")])); - assert(split(str, re) == [to!S("a"), to!S("b")]); - }(); -} -@safe unittest -{//bugzilla 8203 - string data = " - NAME = XPAW01_STA:STATION - NAME = XPAW01_STA - "; - auto uniFileOld = data; - auto r = regex( - r"^NAME = (?P[a-zA-Z0-9_]+):*(?P[a-zA-Z0-9_]*)","gm"); - auto uniCapturesNew = match(uniFileOld, r); - for (int i = 0; i < 20; i++) - foreach (matchNew; uniCapturesNew) {} - //a second issue with same symptoms - auto r2 = regex(`([а-яА-Я\-_]+\s*)+(?<=[\s\.,\^])`); - match("аллея Театральная", r2); -} -@safe unittest -{// bugzilla 8637 purity of enforce - auto m = match("hello world", regex("world")); - enforce(m); -} - -// bugzilla 8725 -@safe unittest -{ - static italic = regex( r"\* - (?!\s+) - (.*?) - (?!\s+) - \*", "gx" ); - string input = "this * is* interesting, *very* interesting"; - assert(replace(input, italic, "$1") == - "this * is* interesting, very interesting"); -} - -// bugzilla 8349 -@safe unittest -{ - enum peakRegexStr = r"\>(wgEncode.*Tfbs.*\.(?:narrow)|(?:broad)Peak.gz)"; - enum peakRegex = ctRegex!(peakRegexStr); - //note that the regex pattern itself is probably bogus - assert(match(r"\>wgEncode-blah-Tfbs.narrow", peakRegex)); -} - -// bugzilla 9211 -@safe unittest -{ - import std.algorithm.comparison : equal; - auto rx_1 = regex(r"^(\w)*(\d)"); - auto m = match("1234", rx_1); - assert(equal(m.front, ["1234", "3", "4"])); - auto rx_2 = regex(r"^([0-9])*(\d)"); - auto m2 = match("1234", rx_2); - assert(equal(m2.front, ["1234", "3", "4"])); -} - -// bugzilla 9280 -@safe unittest -{ - string tomatch = "a!b@c"; - static r = regex(r"^(?P.*?)!(?P.*?)@(?P.*?)$"); - auto nm = match(tomatch, r); - assert(nm); - auto c = nm.captures; - assert(c[1] == "a"); - assert(c["nick"] == "a"); -} - - -// bugzilla 9579 -@safe unittest -{ - char[] input = ['a', 'b', 'c']; - string format = "($1)"; - // used to give a compile error: - auto re = regex(`(a)`, "g"); - auto r = replace(input, re, format); - assert(r == "(a)bc"); -} - -// bugzilla 9634 -@safe unittest -{ - auto re = ctRegex!"(?:a+)"; - assert(match("aaaa", re).hit == "aaaa"); -} - -//bugzilla 10798 -@safe unittest -{ - auto cr = ctRegex!("[abcd--c]*"); - auto m = "abc".match(cr); - assert(m); - assert(m.hit == "ab"); -} - -// bugzilla 10913 -@system unittest -{ - @system static string foo(const(char)[] s) - { - return s.dup; - } - @safe static string bar(const(char)[] s) - { - return s.dup; - } - () @system { - replace!((a) => foo(a.hit))("blah", regex(`a`)); - }(); - () @safe { - replace!((a) => bar(a.hit))("blah", regex(`a`)); - }(); -} - -// bugzilla 11262 -@safe unittest -{ - enum reg = ctRegex!(r",", "g"); - auto str = "This,List"; - str = str.replace(reg, "-"); - assert(str == "This-List"); -} - -// bugzilla 11775 -@safe unittest -{ - assert(collectException(regex("a{1,0}"))); -} - -// bugzilla 11839 -@safe unittest -{ - import std.algorithm.comparison : equal; - assert(regex(`(?P\w+)`).namedCaptures.equal(["var1"])); - assert(collectException(regex(`(?P<1>\w+)`))); - assert(regex(`(?P\w+)`).namedCaptures.equal(["v1"])); - assert(regex(`(?P<__>\w+)`).namedCaptures.equal(["__"])); - assert(regex(`(?P<я>\w+)`).namedCaptures.equal(["я"])); -} - -// bugzilla 12076 -@safe unittest -{ - auto RE = ctRegex!(r"(?abc)`); - assert(collectException("abc".matchFirst(r)["b"])); -} - -// bugzilla 12691 -@safe unittest -{ - assert(bmatch("e@", "^([a-z]|)*$").empty); - assert(bmatch("e@", ctRegex!`^([a-z]|)*$`).empty); -} - -//bugzilla 12713 -@safe unittest -{ - assertThrown(regex("[[a-z]([a-z]|(([[a-z])))")); -} - -//bugzilla 12747 -@safe unittest -{ - assertThrown(regex(`^x(\1)`)); - assertThrown(regex(`^(x(\1))`)); - assertThrown(regex(`^((x)(?=\1))`)); -} - -// bugzilla 14504 -@safe unittest -{ - auto p = ctRegex!("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?" ~ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); -} - -// bugzilla 14529 -@safe unittest -{ - auto ctPat2 = regex(r"^[CDF]$", "i"); - foreach (v; ["C", "c", "D", "d", "F", "f"]) - assert(matchAll(v, ctPat2).front.hit == v); -} - -// bugzilla 14615 -@safe unittest -{ - import std.array : appender; - import std.regex : replaceFirst, replaceFirstInto, regex; - import std.stdio : writeln; - - auto example = "Hello, world!"; - auto pattern = regex("^Hello, (bug)"); // won't find this one - auto result = replaceFirst(example, pattern, "$1 Sponge Bob"); - assert(result == "Hello, world!"); // Ok. - - auto sink = appender!string; - replaceFirstInto(sink, example, pattern, "$1 Sponge Bob"); - assert(sink.data == "Hello, world!"); - replaceAllInto(sink, example, pattern, "$1 Sponge Bob"); - assert(sink.data == "Hello, world!Hello, world!"); -} - -// bugzilla 15573 -@safe unittest -{ - auto rx = regex("[c d]", "x"); - assert("a b".matchFirst(rx)); -} - -// bugzilla 15864 -@safe unittest -{ - regex(`((.+)`; - static titleRegex = ctRegex!titlePattern; - string input = "" ~ "<".repeat(100_000).join; - assert(input.matchFirst(titleRegex).empty); -} - -// bugzilla 17212 -@safe unittest -{ - auto r = regex(" [a] ", "x"); - assert("a".matchFirst(r)); -} - -// bugzilla 17157 -@safe unittest -{ - import std.algorithm.comparison : equal; - auto ctr = ctRegex!"(a)|(b)|(c)|(d)"; - auto r = regex("(a)|(b)|(c)|(d)", "g"); - auto s = "--a--b--c--d--"; - auto outcomes = [ - ["a", "a", "", "", ""], - ["b", "", "b", "", ""], - ["c", "", "", "c", ""], - ["d", "", "", "", "d"] - ]; - assert(equal!equal(s.matchAll(ctr), outcomes)); - assert(equal!equal(s.bmatch(r), outcomes)); -} - -// bugzilla 17667 -@safe unittest -{ - import std.algorithm.searching : canFind; - void willThrow(T, size_t line = __LINE__)(T arg, string msg) - { - auto e = collectException(regex(arg)); - assert(e.msg.canFind(msg), to!string(line) ~ ": " ~ e.msg); - } - willThrow([r".", r"[\(\{[\]\}\)]"], "no matching ']' found while parsing character class"); - willThrow([r"[\", r"123"], "no matching ']' found while parsing character class"); - willThrow([r"[a-", r"123"], "no matching ']' found while parsing character class"); - willThrow([r"[a-\", r"123"], "invalid escape sequence"); - willThrow([r"\", r"123"], "invalid escape sequence"); -} - -// bugzilla 17668 -@safe unittest -{ - import std.algorithm.searching; - auto e = collectException!RegexException(regex(q"<[^]>")); - assert(e.msg.canFind("no operand for '^'")); -} - -// bugzilla 17673 -@safe unittest -{ - string str = `<">`; - string[] regexps = ["abc", "\"|x"]; - auto regexp = regex(regexps); - auto c = matchFirst(str, regexp); - assert(c); - assert(c.whichPattern == 2); -} - diff --git a/libphobos/src/std/regex/internal/tests2.d b/libphobos/src/std/regex/internal/tests2.d new file mode 100644 index 0000000..420f8d3 --- /dev/null +++ b/libphobos/src/std/regex/internal/tests2.d @@ -0,0 +1,662 @@ +// Split-up due to DMD's enormous memory consumption + +module std.regex.internal.tests2; + +package(std.regex): + +import std.conv, std.exception, std.meta, std.range, + std.typecons, std.regex; + +import std.regex.internal.ir : Escapables; // characters that need escaping + +@safe unittest +{ + auto cr = ctRegex!("abc"); + assert(bmatch("abc",cr).hit == "abc"); + auto cr2 = ctRegex!("ab*c"); + assert(bmatch("abbbbc",cr2).hit == "abbbbc"); +} +@safe unittest +{ + auto cr3 = ctRegex!("^abc$"); + assert(bmatch("abc",cr3).hit == "abc"); + auto cr4 = ctRegex!(`\b(a\B[a-z]b)\b`); + assert(array(match("azb",cr4).captures) == ["azb", "azb"]); +} + +@safe unittest +{ + auto cr5 = ctRegex!("(?:a{2,4}b{1,3}){1,2}"); + assert(bmatch("aaabaaaabbb", cr5).hit == "aaabaaaabbb"); + auto cr6 = ctRegex!("(?:a{2,4}b{1,3}){1,2}?"w); + assert(bmatch("aaabaaaabbb"w, cr6).hit == "aaab"w); +} + +@safe unittest +{ + auto cr7 = ctRegex!(`\r.*?$`,"sm"); + assert(bmatch("abc\r\nxy", cr7).hit == "\r\nxy"); + auto greed = ctRegex!("<packet.*?/packet>"); + assert(bmatch("<packet>text</packet><packet>text</packet>", greed).hit + == "<packet>text</packet>"); +} + +@safe unittest +{ + import std.algorithm.comparison : equal; + auto cr8 = ctRegex!("^(a)(b)?(c*)"); + auto m8 = bmatch("abcc",cr8); + assert(m8); + assert(m8.captures[1] == "a"); + assert(m8.captures[2] == "b"); + assert(m8.captures[3] == "cc"); + auto cr9 = ctRegex!("q(a|b)*q"); + auto m9 = match("xxqababqyy",cr9); + assert(m9); + assert(equal(bmatch("xxqababqyy",cr9).captures, ["qababq", "b"])); +} + +@safe unittest +{ + import std.algorithm.comparison : equal; + auto rtr = regex("a|b|c"); + enum ctr = regex("a|b|c"); + assert(equal(rtr.ir,ctr.ir)); + //CTFE parser BUG is triggered by group + //in the middle of alternation (at least not first and not last) + enum testCT = regex(`abc|(edf)|xyz`); + auto testRT = regex(`abc|(edf)|xyz`); + assert(equal(testCT.ir,testRT.ir)); +} + +@safe unittest +{ + import std.algorithm.comparison : equal; + import std.algorithm.iteration : map; + enum cx = ctRegex!"(A|B|C)"; + auto mx = match("B",cx); + assert(mx); + assert(equal(mx.captures, [ "B", "B"])); + enum cx2 = ctRegex!"(A|B)*"; + assert(match("BAAA",cx2)); + + enum cx3 = ctRegex!("a{3,4}","i"); + auto mx3 = match("AaA",cx3); + assert(mx3); + assert(mx3.captures[0] == "AaA"); + enum cx4 = ctRegex!(`^a{3,4}?[a-zA-Z0-9~]{1,2}`,"i"); + auto mx4 = match("aaaabc", cx4); + assert(mx4); + assert(mx4.captures[0] == "aaaab"); + auto cr8 = ctRegex!("(a)(b)?(c*)"); + auto m8 = bmatch("abcc",cr8); + assert(m8); + assert(m8.captures[1] == "a"); + assert(m8.captures[2] == "b"); + assert(m8.captures[3] == "cc"); + auto cr9 = ctRegex!(".*$", "gm"); + auto m9 = match("First\rSecond", cr9); + assert(m9); + assert(equal(map!"a.hit"(m9), ["First", "", "Second"])); +} + +@safe unittest +{ + import std.algorithm.comparison : equal; + import std.algorithm.iteration : map; +//global matching + void test_body(alias matchFn)() + { + string s = "a quick brown fox jumps over a lazy dog"; + auto r1 = regex("\\b[a-z]+\\b","g"); + string[] test; + foreach (m; matchFn(s, r1)) + test ~= m.hit; + assert(equal(test, [ "a", "quick", "brown", "fox", "jumps", "over", "a", "lazy", "dog"])); + auto free_reg = regex(` + + abc + \s+ + " + ( + [^"]+ + | \\ " + )+ + " + z + `, "x"); + auto m = match(`abc "quoted string with \" inside"z`,free_reg); + assert(m); + string mails = " hey@you.com no@spam.net "; + auto rm = regex(`@(?<=\S+@)\S+`,"g"); + assert(equal(map!"a[0]"(matchFn(mails, rm)), ["@you.com", "@spam.net"])); + auto m2 = matchFn("First line\nSecond line",regex(".*$","gm")); + assert(equal(map!"a[0]"(m2), ["First line", "", "Second line"])); + auto m2a = matchFn("First line\nSecond line",regex(".+$","gm")); + assert(equal(map!"a[0]"(m2a), ["First line", "Second line"])); + auto m2b = matchFn("First line\nSecond line",regex(".+?$","gm")); + assert(equal(map!"a[0]"(m2b), ["First line", "Second line"])); + debug(std_regex_test) writeln("!!! FReD FLAGS test done "~matchFn.stringof~" !!!"); + } + test_body!bmatch(); + test_body!match(); +} + +//tests for accumulated std.regex issues and other regressions +@safe unittest +{ + import std.algorithm.comparison : equal; + import std.algorithm.iteration : map; + void test_body(alias matchFn)() + { + //issue 5857 + //matching goes out of control if ... in (...){x} has .*/.+ + auto c = matchFn("axxxzayyyyyzd",regex("(a.*z){2}d")).captures; + assert(c[0] == "axxxzayyyyyzd"); + assert(c[1] == "ayyyyyz"); + auto c2 = matchFn("axxxayyyyyd",regex("(a.*){2}d")).captures; + assert(c2[0] == "axxxayyyyyd"); + assert(c2[1] == "ayyyyy"); + //issue 2108 + //greedy vs non-greedy + auto nogreed = regex("<packet.*?/packet>"); + assert(matchFn("<packet>text</packet><packet>text</packet>", nogreed).hit + == "<packet>text</packet>"); + auto greed = regex("<packet.*/packet>"); + assert(matchFn("<packet>text</packet><packet>text</packet>", greed).hit + == "<packet>text</packet><packet>text</packet>"); + //issue 4574 + //empty successful match still advances the input + string[] pres, posts, hits; + foreach (m; matchFn("abcabc", regex("","g"))) + { + pres ~= m.pre; + posts ~= m.post; + assert(m.hit.empty); + + } + auto heads = [ + "abcabc", + "abcab", + "abca", + "abc", + "ab", + "a", + "" + ]; + auto tails = [ + "abcabc", + "bcabc", + "cabc", + "abc", + "bc", + "c", + "" + ]; + assert(pres == array(retro(heads))); + assert(posts == tails); + //issue 6076 + //regression on .* + auto re = regex("c.*|d"); + auto m = matchFn("mm", re); + assert(!m); + debug(std_regex_test) writeln("!!! FReD REGRESSION test done "~matchFn.stringof~" !!!"); + auto rprealloc = regex(`((.){5}.{1,10}){5}`); + auto arr = array(repeat('0',100)); + auto m2 = matchFn(arr, rprealloc); + assert(m2); + assert(collectException( + regex(r"^(import|file|binary|config)\s+([^\(]+)\(?([^\)]*)\)?\s*$") + ) is null); + foreach (ch; [Escapables]) + { + assert(match(to!string(ch),regex(`[\`~ch~`]`))); + assert(!match(to!string(ch),regex(`[^\`~ch~`]`))); + assert(match(to!string(ch),regex(`[\`~ch~`-\`~ch~`]`))); + } + //bugzilla 7718 + string strcmd = "./myApp.rb -os OSX -path \"/GIT/Ruby Apps/sec\" -conf 'notimer'"; + auto reStrCmd = regex (`(".*")|('.*')`, "g"); + assert(equal(map!"a[0]"(matchFn(strcmd, reStrCmd)), + [`"/GIT/Ruby Apps/sec"`, `'notimer'`])); + } + test_body!bmatch(); + test_body!match(); +} + +// tests for replace +@safe unittest +{ + void test(alias matchFn)() + { + import std.uni : toUpper; + + foreach (i, v; AliasSeq!(string, wstring, dstring)) + { + auto baz(Cap)(Cap m) + if (is(Cap == Captures!(Cap.String))) + { + return toUpper(m.hit); + } + alias String = v; + assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r")), to!String("c")) + == to!String("ack rapacity")); + assert(std.regex.replace!(matchFn)(to!String("ark rapacity"), regex(to!String("r"), "g"), to!String("c")) + == to!String("ack capacity")); + assert(std.regex.replace!(matchFn)(to!String("noon"), regex(to!String("^n")), to!String("[$&]")) + == to!String("[n]oon")); + assert(std.regex.replace!(matchFn)( + to!String("test1 test2"), regex(to!String(`\w+`),"g"), to!String("$`:$'") + ) == to!String(": test2 test1 :")); + auto s = std.regex.replace!(baz!(Captures!(String)))(to!String("Strap a rocket engine on a chicken."), + regex(to!String("[ar]"), "g")); + assert(s == "StRAp A Rocket engine on A chicken."); + } + debug(std_regex_test) writeln("!!! Replace test done "~matchFn.stringof~" !!!"); + } + test!(bmatch)(); + test!(match)(); +} + +// tests for splitter +@safe unittest +{ + import std.algorithm.comparison : equal; + auto s1 = ", abc, de, fg, hi, "; + auto sp1 = splitter(s1, regex(", *")); + auto w1 = ["", "abc", "de", "fg", "hi", ""]; + assert(equal(sp1, w1)); + + auto s2 = ", abc, de, fg, hi"; + auto sp2 = splitter(s2, regex(", *")); + auto w2 = ["", "abc", "de", "fg", "hi"]; + + uint cnt; + foreach (e; sp2) + { + assert(w2[cnt++] == e); + } + assert(equal(sp2, w2)); +} + +@safe unittest +{ + char[] s1 = ", abc, de, fg, hi, ".dup; + auto sp2 = splitter(s1, regex(", *")); +} + +@safe unittest +{ + import std.algorithm.comparison : equal; + auto s1 = ", abc, de, fg, hi, "; + auto w1 = ["", "abc", "de", "fg", "hi", ""]; + assert(equal(split(s1, regex(", *")), w1[])); +} + +@safe unittest +{ // bugzilla 7141 + string pattern = `[a\--b]`; + assert(match("-", pattern)); + assert(match("b", pattern)); + string pattern2 = `[&-z]`; + assert(match("b", pattern2)); +} +@safe unittest +{//bugzilla 7111 + assert(match("", regex("^"))); +} +@safe unittest +{//bugzilla 7300 + assert(!match("a"d, "aa"d)); +} + +// bugzilla 7551 +@safe unittest +{ + auto r = regex("[]abc]*"); + assert("]ab".matchFirst(r).hit == "]ab"); + assertThrown(regex("[]")); + auto r2 = regex("[]abc--ab]*"); + assert("]ac".matchFirst(r2).hit == "]"); +} + +@safe unittest +{//bugzilla 7674 + assert("1234".replace(regex("^"), "$$") == "$1234"); + assert("hello?".replace(regex(r"\?", "g"), r"\?") == r"hello\?"); + assert("hello?".replace(regex(r"\?", "g"), r"\\?") != r"hello\?"); +} +@safe unittest +{// bugzilla 7679 + import std.algorithm.comparison : equal; + foreach (S; AliasSeq!(string, wstring, dstring)) + (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396 + enum re = ctRegex!(to!S(r"\.")); + auto str = to!S("a.b"); + assert(equal(std.regex.splitter(str, re), [to!S("a"), to!S("b")])); + assert(split(str, re) == [to!S("a"), to!S("b")]); + }(); +} +@safe unittest +{//bugzilla 8203 + string data = " + NAME = XPAW01_STA:STATION + NAME = XPAW01_STA + "; + auto uniFileOld = data; + auto r = regex( + r"^NAME = (?P<comp>[a-zA-Z0-9_]+):*(?P<blk>[a-zA-Z0-9_]*)","gm"); + auto uniCapturesNew = match(uniFileOld, r); + for (int i = 0; i < 20; i++) + foreach (matchNew; uniCapturesNew) {} + //a second issue with same symptoms + auto r2 = regex(`([а-яА-Я\-_]+\s*)+(?<=[\s\.,\^])`); + match("аллея Театральная", r2); +} +@safe unittest +{// bugzilla 8637 purity of enforce + auto m = match("hello world", regex("world")); + enforce(m); +} + +// bugzilla 8725 +@safe unittest +{ + static italic = regex( r"\* + (?!\s+) + (.*?) + (?!\s+) + \*", "gx" ); + string input = "this * is* interesting, *very* interesting"; + assert(replace(input, italic, "<i>$1</i>") == + "this * is* interesting, <i>very</i> interesting"); +} + +// bugzilla 8349 +@safe unittest +{ + enum peakRegexStr = r"\>(wgEncode.*Tfbs.*\.(?:narrow)|(?:broad)Peak.gz)</a>"; + enum peakRegex = ctRegex!(peakRegexStr); + //note that the regex pattern itself is probably bogus + assert(match(r"\>wgEncode-blah-Tfbs.narrow</a>", peakRegex)); +} + +// bugzilla 9211 +@safe unittest +{ + import std.algorithm.comparison : equal; + auto rx_1 = regex(r"^(\w)*(\d)"); + auto m = match("1234", rx_1); + assert(equal(m.front, ["1234", "3", "4"])); + auto rx_2 = regex(r"^([0-9])*(\d)"); + auto m2 = match("1234", rx_2); + assert(equal(m2.front, ["1234", "3", "4"])); +} + +// bugzilla 9280 +@safe unittest +{ + string tomatch = "a!b@c"; + static r = regex(r"^(?P<nick>.*?)!(?P<ident>.*?)@(?P<host>.*?)$"); + auto nm = match(tomatch, r); + assert(nm); + auto c = nm.captures; + assert(c[1] == "a"); + assert(c["nick"] == "a"); +} + + +// bugzilla 9579 +@safe unittest +{ + char[] input = ['a', 'b', 'c']; + string format = "($1)"; + // used to give a compile error: + auto re = regex(`(a)`, "g"); + auto r = replace(input, re, format); + assert(r == "(a)bc"); +} + +// bugzilla 9634 +@safe unittest +{ + auto re = ctRegex!"(?:a+)"; + assert(match("aaaa", re).hit == "aaaa"); +} + +//bugzilla 10798 +@safe unittest +{ + auto cr = ctRegex!("[abcd--c]*"); + auto m = "abc".match(cr); + assert(m); + assert(m.hit == "ab"); +} + +// bugzilla 10913 +@system unittest +{ + @system static string foo(const(char)[] s) + { + return s.dup; + } + @safe static string bar(const(char)[] s) + { + return s.dup; + } + () @system { + replace!((a) => foo(a.hit))("blah", regex(`a`)); + }(); + () @safe { + replace!((a) => bar(a.hit))("blah", regex(`a`)); + }(); +} + +// bugzilla 11262 +@safe unittest +{ + enum reg = ctRegex!(r",", "g"); + auto str = "This,List"; + str = str.replace(reg, "-"); + assert(str == "This-List"); +} + +// bugzilla 11775 +@safe unittest +{ + assert(collectException(regex("a{1,0}"))); +} + +// bugzilla 11839 +@safe unittest +{ + import std.algorithm.comparison : equal; + assert(regex(`(?P<var1>\w+)`).namedCaptures.equal(["var1"])); + assert(collectException(regex(`(?P<1>\w+)`))); + assert(regex(`(?P<v1>\w+)`).namedCaptures.equal(["v1"])); + assert(regex(`(?P<__>\w+)`).namedCaptures.equal(["__"])); + assert(regex(`(?P<я>\w+)`).namedCaptures.equal(["я"])); +} + +// bugzilla 12076 +@safe unittest +{ + auto RE = ctRegex!(r"(?<!x[a-z]+)\s([a-z]+)"); + string s = "one two"; + auto m = match(s, RE); +} + +// bugzilla 12105 +@safe unittest +{ + auto r = ctRegex!`.*?(?!a)`; + assert("aaab".matchFirst(r).hit == "aaa"); + auto r2 = ctRegex!`.*(?!a)`; + assert("aaab".matchFirst(r2).hit == "aaab"); +} + +//bugzilla 11784 +@safe unittest +{ + assert("abcdefghijklmnopqrstuvwxyz" + .matchFirst("[a-z&&[^aeiuo]]").hit == "b"); +} + +//bugzilla 12366 +@safe unittest +{ + auto re = ctRegex!(`^((?=(xx+?)\2+$)((?=\2+$)(?=(x+)(\4+$))\5){2})*x?$`); + assert("xxxxxxxx".match(re).empty); + assert(!"xxxx".match(re).empty); +} + +// bugzilla 12582 +@safe unittest +{ + auto r = regex(`(?P<a>abc)`); + assert(collectException("abc".matchFirst(r)["b"])); +} + +// bugzilla 12691 +@safe unittest +{ + assert(bmatch("e@", "^([a-z]|)*$").empty); + assert(bmatch("e@", ctRegex!`^([a-z]|)*$`).empty); +} + +//bugzilla 12713 +@safe unittest +{ + assertThrown(regex("[[a-z]([a-z]|(([[a-z])))")); +} + +//bugzilla 12747 +@safe unittest +{ + assertThrown(regex(`^x(\1)`)); + assertThrown(regex(`^(x(\1))`)); + assertThrown(regex(`^((x)(?=\1))`)); +} + +// bugzilla 14504 +@safe unittest +{ + auto p = ctRegex!("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?" ~ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); +} + +// bugzilla 14529 +@safe unittest +{ + auto ctPat2 = regex(r"^[CDF]$", "i"); + foreach (v; ["C", "c", "D", "d", "F", "f"]) + assert(matchAll(v, ctPat2).front.hit == v); +} + +// bugzilla 14615 +@safe unittest +{ + import std.array : appender; + import std.regex : replaceFirst, replaceFirstInto, regex; + import std.stdio : writeln; + + auto example = "Hello, world!"; + auto pattern = regex("^Hello, (bug)"); // won't find this one + auto result = replaceFirst(example, pattern, "$1 Sponge Bob"); + assert(result == "Hello, world!"); // Ok. + + auto sink = appender!string; + replaceFirstInto(sink, example, pattern, "$1 Sponge Bob"); + assert(sink.data == "Hello, world!"); + replaceAllInto(sink, example, pattern, "$1 Sponge Bob"); + assert(sink.data == "Hello, world!Hello, world!"); +} + +// bugzilla 15573 +@safe unittest +{ + auto rx = regex("[c d]", "x"); + assert("a b".matchFirst(rx)); +} + +// bugzilla 15864 +@safe unittest +{ + regex(`(<a (?:(?:\w+=\"[^"]*\")?\s*)*href="\.\.?)"`); +} + +@safe unittest +{ + auto r = regex("(?# comment)abc(?# comment2)"); + assert("abc".matchFirst(r)); + assertThrown(regex("(?#...")); +} + +// bugzilla 17075 +@safe unittest +{ + enum titlePattern = `<title>(.+)`; + static titleRegex = ctRegex!titlePattern; + string input = "" ~ "<".repeat(100_000).join; + assert(input.matchFirst(titleRegex).empty); +} + +// bugzilla 17212 +@safe unittest +{ + auto r = regex(" [a] ", "x"); + assert("a".matchFirst(r)); +} + +// bugzilla 17157 +@safe unittest +{ + import std.algorithm.comparison : equal; + auto ctr = ctRegex!"(a)|(b)|(c)|(d)"; + auto r = regex("(a)|(b)|(c)|(d)", "g"); + auto s = "--a--b--c--d--"; + auto outcomes = [ + ["a", "a", "", "", ""], + ["b", "", "b", "", ""], + ["c", "", "", "c", ""], + ["d", "", "", "", "d"] + ]; + assert(equal!equal(s.matchAll(ctr), outcomes)); + assert(equal!equal(s.bmatch(r), outcomes)); +} + +// bugzilla 17667 +@safe unittest +{ + import std.algorithm.searching : canFind; + void willThrow(T, size_t line = __LINE__)(T arg, string msg) + { + auto e = collectException(regex(arg)); + assert(e.msg.canFind(msg), to!string(line) ~ ": " ~ e.msg); + } + willThrow([r".", r"[\(\{[\]\}\)]"], "no matching ']' found while parsing character class"); + willThrow([r"[\", r"123"], "no matching ']' found while parsing character class"); + willThrow([r"[a-", r"123"], "no matching ']' found while parsing character class"); + willThrow([r"[a-\", r"123"], "invalid escape sequence"); + willThrow([r"\", r"123"], "invalid escape sequence"); +} + +// bugzilla 17668 +@safe unittest +{ + import std.algorithm.searching; + auto e = collectException!RegexException(regex(q"<[^]>")); + assert(e.msg.canFind("no operand for '^'")); +} + +// bugzilla 17673 +@safe unittest +{ + string str = `<">`; + string[] regexps = ["abc", "\"|x"]; + auto regexp = regex(regexps); + auto c = matchFirst(str, regexp); + assert(c); + assert(c.whichPattern == 2); +} + diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d index ecb2c8b..d7de153 100644 --- a/libphobos/src/std/socket.d +++ b/libphobos/src/std/socket.d @@ -85,10 +85,10 @@ else version (Posix) } } + public import core.sys.posix.netinet.in_; import core.sys.posix.arpa.inet; import core.sys.posix.fcntl; import core.sys.posix.netdb; - import core.sys.posix.netinet.in_; import core.sys.posix.netinet.tcp; import core.sys.posix.sys.select; import core.sys.posix.sys.socket; diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index a63227c..55119fc 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -4204,10 +4204,11 @@ package template OverloadSet(string nam, T...) /* Used by MemberFunctionGenerator. */ -package template FuncInfo(alias func, /+[BUG 4217 ?]+/ T = typeof(&func)) +package template FuncInfo(alias func) +if (is(typeof(&func))) { - alias RT = ReturnType!T; - alias PT = Parameters!T; + alias RT = ReturnType!(typeof(&func)); + alias PT = Parameters!(typeof(&func)); } package template FuncInfo(Func) { @@ -4248,6 +4249,7 @@ private static: // Internal stuffs //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::// import std.format; + alias format = std.format.format; enum CONSTRUCTOR_NAME = "__ctor"; @@ -5024,7 +5026,7 @@ package template GetOverloadedMethods(T) enum isMethod = false; } alias follows = AliasSeq!( - std.meta.Filter!(isMethod, __traits(getOverloads, T, name)), + Filter!(isMethod, __traits(getOverloads, T, name)), follows!(i + 1)); } } diff --git a/libphobos/src/std/zip.d b/libphobos/src/std/zip.d index 8b130ea..9e55d19 100644 --- a/libphobos/src/std/zip.d +++ b/libphobos/src/std/zip.d @@ -263,8 +263,8 @@ final class ArchiveMember { void print() { - printf("name = '%.*s'\n", name.length, name.ptr); - printf("\tcomment = '%.*s'\n", comment.length, comment.ptr); + printf("name = '%.*s'\n", cast(int) name.length, name.ptr); + printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr); printf("\tmadeVersion = x%04x\n", _madeVersion); printf("\textractVersion = x%04x\n", extractVersion); printf("\tflags = x%04x\n", flags); @@ -348,7 +348,7 @@ final class ZipArchive printf("\tdiskStartDir = %u\n", diskStartDir); printf("\tnumEntries = %u\n", numEntries); printf("\ttotalEntries = %u\n", totalEntries); - printf("\tcomment = '%.*s'\n", comment.length, comment.ptr); + printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr); } } diff --git a/libphobos/testsuite/libphobos.exceptions/chain.d b/libphobos/testsuite/libphobos.exceptions/chain.d index 462ba24..0305707 100644 --- a/libphobos/testsuite/libphobos.exceptions/chain.d +++ b/libphobos/testsuite/libphobos.exceptions/chain.d @@ -65,14 +65,14 @@ void main() string prefix = ""; for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i) { - printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); + printf("%.*s%.*s\n", cast(int)prefix.length, prefix.ptr, cast(int)ex.msg.length, ex.msg.ptr); prefix = prefix~" "; } printf("Bypassed chain was:\n"); prefix = ""; for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i) { - printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); + printf("%.*s%.*s\n", cast(int)prefix.length, prefix.ptr, cast(int)ex.msg.length, ex.msg.ptr); prefix = prefix~" "; } } diff --git a/libphobos/testsuite/libphobos.exceptions/line_trace.d b/libphobos/testsuite/libphobos.exceptions/line_trace.d index 7b75d3a..70762ff 100644 --- a/libphobos/testsuite/libphobos.exceptions/line_trace.d +++ b/libphobos/testsuite/libphobos.exceptions/line_trace.d @@ -9,7 +9,7 @@ void main() { import core.stdc.stdio; auto str = e.toString(); - printf("%.*s\n", str.length, str.ptr); + printf("%.*s\n", cast(int)str.length, str.ptr); } } -- cgit v1.1 From c0756c4eb36b6bf4bf1ea0cf3633f08ae0e1c13d Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Sun, 4 Apr 2021 00:16:26 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index e58bd3c..1b1ba37 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,17 @@ +2021-04-03 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/MERGE: Merge upstream druntime 483bc129. + * libdruntime/Makefile.am (DRUNTIME_DSOURCES_DARWIN): Add + core/sys/darwin/fcntl.d. + (DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/unistd.d. + (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/stdc/malloc.d. + * libdruntime/Makefile.in: Regenerate. + * src/MERGE: Merge upstream phobos f89dc217a. + * src/Makefile.am (PHOBOS_DSOURCES): Add std/regex/internal/tests2.d. + * src/Makefile.in: Regenerate. + * testsuite/libphobos.exceptions/chain.d: Fix format arguments. + * testsuite/libphobos.exceptions/line_trace.d: Likewise. + 2021-03-26 Iain Buclaw <ibuclaw@gdcproject.org> * Makefile.in: Regenerate. -- cgit v1.1 From dddf3bb0c37e8ff7f2c0488a46edfa18716d8a00 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon, 5 Apr 2021 14:05:28 +0200 Subject: d: Merge upstream dmd 5cc71ff83, druntime 1134b710 D front-end changes: - Fix ICEs that occurred when using opaque enums. - Update `pragma(printf)' checking code to work on 16-bit targets. Phobos change: - Don't compile in argTypes code on AArch64 Reviewed-on: https://github.com/dlang/dmd/pull/12378 https://github.com/dlang/druntime/pull/3431 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 5cc71ff83. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 1134b710. --- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/object.d | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libphobos') diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index b797682..d839a08 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -483bc12977af3c1288fd52e7b4fa14b716896c5a +1134b71039881464e9bf021836d82796b3a1fcfc The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index c05643b..e96d1c4 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -42,7 +42,7 @@ else version (X86_64) else version (Windows) { /* no need for Win64 ABI */ } else version = WithArgTypes; } -version (AArch64) +else version (AArch64) { // Apple uses a trivial varargs implementation version (OSX) {} -- cgit v1.1 From 8cac6af6f8ba5cce69161459e572e59c2be60e75 Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed, 7 Apr 2021 00:16:39 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 1b1ba37..b8af486 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,7 @@ +2021-04-06 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/MERGE: Merge upstream druntime 1134b710. + 2021-04-03 Iain Buclaw <ibuclaw@gdcproject.org> * libdruntime/MERGE: Merge upstream druntime 483bc129. -- cgit v1.1 From 8e84a142913a1f3084d415462024964f97356bee Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Tue, 14 Apr 2020 09:29:10 +0200 Subject: d: Update language attribute support, and implement gcc.attributes D attribute support has been updated to have a baseline parity with the LLVM D compiler's own `ldc.attributes'. The handler that extracts GCC attributes from a list of UDAs has been improved to take care of some mistakes that could have been warnings. UDAs attached to field variables are also now processed for any GCC attributes attached to them. The following new attributes have been added to the D front-end: - @attribute("alloc_size") - @attribute("used") - @attribute("optimize") - @attribute("restrict") - @attribute("cold") - @attribute("noplt") - @attribute("target_clones") - @attribute("no_icf") - @attribute("noipa") - @attribute("symver") With convenience aliases in a new `gcc.attributes' module to match the same naming convention as `ldc.attributes': - @allocSize() - @assumeUsed - @fastmath - @naked - @restrict - @cold - @noplt - @optStrategy() - @polly - @section() - @target() - @weak The old gcc.attribute module has been deprecated, along with the removal of the following attribute handlers: - @attribute("alias"): Has been superseded by `pragma(mangle)'. - @attribute("forceinline"): Renamed to always_inline. gcc/d/ChangeLog: * d-attribs.cc: Include fold-const.h and opts.h. (attr_noreturn_exclusions): Add alloc_size. (attr_const_pure_exclusions): Likewise. (attr_inline_exclusions): Add target_clones. (attr_noinline_exclusions): Rename forceinline to always_inline. (attr_target_exclusions): New array. (attr_target_clones_exclusions): New array. (attr_alloc_exclusions): New array. (attr_cold_hot_exclusions): New array. (d_langhook_common_attribute_table): Add new D attribute handlers. (build_attributes): Update to look for gcc.attributes. Issue warning if not given a struct literal. Handle void initialized arguments. (handle_always_inline_attribute): Remove function. (d_handle_noinline_attribute): Don't extract TYPE_LANG_FRONTEND. (d_handle_forceinline_attribute): Rename to... (d_handle_always_inline_attribute): ...this. Remove special handling. (d_handle_flatten_attribute): Don't extract TYPE_LANG_FRONTEND. (d_handle_target_attribute): Likewise. Warn about empty arguments. (d_handle_target_clones_attribute): New function. (optimize_args): New static variable. (parse_optimize_options): New function. (d_handle_optimize_attribute): New function. (d_handle_noclone_attribute): Don't extract TYPE_LANG_FRONTEND. (d_handle_alias_attribute): Remove function. (d_handle_noicf_attribute): New function. (d_handle_noipa_attribute): New function. (d_handle_section_attribute): Call the handle_generic_attribute target hook after performing target independent processing. (d_handle_symver_attribute): New function. (d_handle_noplt_attribute): New function. (positional_argument): New function. (d_handle_alloc_size_attribute): New function. (d_handle_cold_attribute): New function. (d_handle_restrict_attribute): New function. (d_handle_used_attribute): New function. * decl.cc (gcc_attribute_p): Update to look for gcc.attributes. (get_symbol_decl): Update decl source location of old prototypes to the new declaration being merged. * types.cc (layout_aggregate_members): Apply user defined attributes on fields. libphobos/ChangeLog: * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add gcc/attributes.d. * libdruntime/Makefile.in: Regenerate. * libdruntime/gcc/attribute.d: Deprecate module, publicly import gcc.attributes. * libdruntime/gcc/deh.d: Update imports. * libdruntime/gcc/attributes.d: New file. gcc/testsuite/ChangeLog: * gdc.dg/gdc108.d: Update test. * gdc.dg/gdc142.d: Likewise. * gdc.dg/pr90136a.d: Likewise. * gdc.dg/pr90136b.d: Likewise. * gdc.dg/pr90136c.d: Likewise. * gdc.dg/pr95173.d: Likewise. * gdc.dg/attr_allocsize1.d: New test. * gdc.dg/attr_allocsize2.d: New test. * gdc.dg/attr_alwaysinline1.d: New test. * gdc.dg/attr_cold1.d: New test. * gdc.dg/attr_exclusions1.d: New test. * gdc.dg/attr_exclusions2.d: New test. * gdc.dg/attr_flatten1.d: New test. * gdc.dg/attr_module.d: New test. * gdc.dg/attr_noclone1.d: New test. * gdc.dg/attr_noicf1.d: New test. * gdc.dg/attr_noinline1.d: New test. * gdc.dg/attr_noipa1.d: New test. * gdc.dg/attr_noplt1.d: New test. * gdc.dg/attr_optimize1.d: New test. * gdc.dg/attr_optimize2.d: New test. * gdc.dg/attr_optimize3.d: New test. * gdc.dg/attr_optimize4.d: New test. * gdc.dg/attr_restrict1.d: New test. * gdc.dg/attr_section1.d: New test. * gdc.dg/attr_symver1.d: New test. * gdc.dg/attr_target1.d: New test. * gdc.dg/attr_targetclones1.d: New test. * gdc.dg/attr_used1.d: New test. * gdc.dg/attr_used2.d: New test. * gdc.dg/attr_weak1.d: New test. * gdc.dg/imports/attributes.d: New test. --- libphobos/libdruntime/Makefile.am | 4 +- libphobos/libdruntime/Makefile.in | 16 +- libphobos/libdruntime/gcc/attribute.d | 11 +- libphobos/libdruntime/gcc/attributes.d | 605 +++++++++++++++++++++++++++++++++ libphobos/libdruntime/gcc/deh.d | 2 +- 5 files changed, 619 insertions(+), 19 deletions(-) create mode 100644 libphobos/libdruntime/gcc/attributes.d (limited to 'libphobos') diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 2a5c793..5137f85 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -184,8 +184,8 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ core/thread/threadbase.d core/thread/threadgroup.d core/thread/types.d \ core/time.d core/vararg.d core/volatile.d gc/bits.d gc/config.d \ gc/gcinterface.d gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.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 \ + 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/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index b00fe02..4a93b49 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -209,11 +209,12 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ core/thread/types.lo core/time.lo core/vararg.lo \ core/volatile.lo gc/bits.lo gc/config.lo gc/gcinterface.lo \ gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \ - gc/pooltable.lo gc/proxy.lo gcc/attribute.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/win64.lo gcc/unwind/arm.lo \ + gc/pooltable.lo gc/proxy.lo gcc/attribute.lo gcc/attributes.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/win64.lo gcc/unwind/arm.lo \ gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \ gcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \ object.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \ @@ -816,8 +817,8 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ core/thread/threadbase.d core/thread/threadgroup.d core/thread/types.d \ core/time.d core/vararg.d core/volatile.d gc/bits.d gc/config.d \ gc/gcinterface.d gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.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 \ + 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/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \ @@ -1209,6 +1210,7 @@ gcc/$(am__dirstamp): @$(MKDIR_P) gcc @: > gcc/$(am__dirstamp) gcc/attribute.lo: gcc/$(am__dirstamp) +gcc/attributes.lo: gcc/$(am__dirstamp) gcc/backtrace.lo: gcc/$(am__dirstamp) gcc/builtins.lo: gcc/$(am__dirstamp) gcc/deh.lo: gcc/$(am__dirstamp) diff --git a/libphobos/libdruntime/gcc/attribute.d b/libphobos/libdruntime/gcc/attribute.d index fc90d2a..d1ff5c7 100644 --- a/libphobos/libdruntime/gcc/attribute.d +++ b/libphobos/libdruntime/gcc/attribute.d @@ -20,14 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +deprecated("Import gcc.attributes instead") module gcc.attribute; -private struct Attribute(A...) -{ - A args; -} - -auto attribute(A...)(A args) if (A.length > 0 && is(A[0] == string)) -{ - return Attribute!A(args); -} +public import gcc.attributes; diff --git a/libphobos/libdruntime/gcc/attributes.d b/libphobos/libdruntime/gcc/attributes.d new file mode 100644 index 0000000..58a4023 --- /dev/null +++ b/libphobos/libdruntime/gcc/attributes.d @@ -0,0 +1,605 @@ +// GNU D Compiler attribute support declarations. +// 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.attributes; + +// Private helper templates. +private struct Attribute(A...) +{ + A arguments; +} + +private enum bool isStringValue(alias T) = is(typeof(T) == string); + +private enum bool isStringOrIntValue(alias T) + = is(typeof(T) == string) || is(typeof(T) == int); + +private template allSatisfy(alias F, T...) +{ + static if (T.length == 0) + enum allSatisfy = true; + else static if (T.length == 1) + enum allSatisfy = F!(T[0]); + else + { + enum allSatisfy = allSatisfy!(F, T[ 0 .. $/2]) + && allSatisfy!(F, T[$/2 .. $ ]); + } +} + +/** + * Generic entrypoint for applying GCC attributes to a function or type. + * There is no type checking done, as well as no deprecation path for + * attributes removed from the compiler. So the recommendation is to use any + , of the other UDAs available unless it is a target-specific attribute. + * + * Function attributes introduced by the @attribute UDA are used in the + * declaration of a function, followed by an attribute name string and + * any arguments separated by commas enclosed in parentheses. + * + * Example: + * --- + * import gcc.attributes; + * + * @attribute("regparm", 1) int func(int size); + * --- + */ +@system +auto attribute(A...)(A arguments) + if (A.length > 0 && is(A[0] == string)) +{ + return Attribute!A(arguments); +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// Supported common attributes exposed by GDC. +// +/////////////////////////////////////////////////////////////////////////////// + +/** + * The `@alloc_size` attribute may be applied to a function that returns a + * pointer and takes at least one argument of an integer or enumerated type. + * It indicates that the returned pointer points to memory whose size is given + * by the function argument at `sizeArgIdx`, or by the product of the arguments + * at `sizeArgIdx` and `numArgIdx`. Meaningful sizes are positive values less + * than `ptrdiff_t.max`. Unless `zeroBasedNumbering` is true, argument + * numbering starts at one for ordinary functions, and at two for non-static + * member functions. + * + * If `numArgIdx` is less than `0`, it is taken to mean there is no argument + * specifying the element count. + * + * Example: + * --- + * import gcc.attributes; + * + * @alloc_size(1) extern(C) void* malloc(size_t size); + * @alloc_size(3,2) extern(C) void* reallocarray(void *ptr, size_t nmemb, + * size_t size); + * @alloc_size(1,2) void* my_calloc(size_t element_size, size_t count, + * bool irrelevant); + * --- + */ +auto alloc_size(int sizeArgIdx) +{ + return attribute("alloc_size", sizeArgIdx); +} + +/// ditto +auto alloc_size(int sizeArgIdx, int numArgIdx) +{ + return attribute("alloc_size", sizeArgIdx, numArgIdx); +} + +/// ditto +auto alloc_size(int sizeArgIdx, int numArgIdx, bool zeroBasedNumbering) +{ + return attribute("alloc_size", sizeArgIdx, numArgIdx, zeroBasedNumbering); +} + +auto alloc_size(A...)(A arguments) +{ + assert(false, "alloc_size attribute argument value is not an integer constant"); +} + +/** + * The `@always_inline` attribute inlines the function independent of any + * restrictions that otherwise apply to inlining. Failure to inline such a + * function is diagnosed as an error. + * + * Example: + * --- + * import gcc.attributes; + * + * @always_inline int func(); + * --- + */ +enum always_inline = attribute("always_inline"); + +/** + * The `@cold` attribute on functions is used to inform the compiler that the + * function is unlikely to be executed. The function is optimized for size + * rather than speed and on many targets it is placed into a special subsection + * of the text section so all cold functions appear close together, improving + * code locality of non-cold parts of program. The paths leading to calls of + * cold functions within code are considered to be cold too. + * + * Example: + * --- + * import gcc.attributes; + * + * @cold int func(); + * --- + */ +enum cold = attribute("cold"); + +/** + * The `@flatten` attribute is used to inform the compiler that every call + * inside this function should be inlined, if possible. Functions declared with + * attribute `@noinline` and similar are not inlined. + * + * Example: + * --- + * import gcc.attributes; + * + * @flatten int func(); + * --- + */ +enum flatten = attribute("flatten"); + +/** + * The `@no_icf` attribute prevents a functions from being merged with another + * semantically equivalent function. + * + * Example: + * --- + * import gcc.attributes; + * + * @no_icf int func(); + * --- + */ +enum no_icf = attribute("no_icf"); + +/** + * The `@noclone` attribute prevents a function from being considered for + * cloning - a mechanism that produces specialized copies of functions and + * which is (currently) performed by interprocedural constant propagation. + * + * Example: + * --- + * import gcc.attributes; + * + * @noclone int func(); + * --- + */ +enum noclone = attribute("noclone"); + +/** + * The `@noinline` attribute prevents a function from being considered for + * inlining. If the function does not have side effects, there are + * optimizations other than inlining that cause function calls to be optimized + * away, although the function call is live. To keep such calls from being + * optimized away, put `asm { ""; }` in the called function, to serve as a + * special side effect. + * + * Example: + * --- + * import gcc.attributes; + * + * @noinline int func(); + * --- + */ +enum noinline = attribute("noinline"); + +/** + * The `@noipa` attribute disables interprocedural optimizations between the + * function with this attribute and its callers, as if the body of the function + * is not available when optimizing callers and the callers are unavailable when + * optimizing the body. This attribute implies `@noinline`, `@noclone`, and + * `@no_icf` attributes. However, this attribute is not equivalent to a + * combination of other attributes, because its purpose is to suppress existing + * and future optimizations employing interprocedural analysis, including those + * that do not have an attribute suitable for disabling them individually. + * + * This attribute is supported mainly for the purpose of testing the compiler. + * + * Example: + * --- + * import gcc.attributes; + * + * @noipa int func(); + * --- + */ +enum noipa = attribute("noipa"); + +/** + * The `@optimize` attribute is used to specify that a function is to be + * compiled with different optimization options than specified on the command + * line. Valid `arguments` are constant non-negative integers and strings. + * Multiple arguments can be provided, separated by commas to specify multiple + * options. Each numeric argument specifies an optimization level. Each string + * argument that begins with the letter O refers to an optimization option such + * as `-O0` or `-Os`. Other options are taken as suffixes to the `-f` prefix + * jointly forming the name of an optimization option. + * + * Not every optimization option that starts with the `-f` prefix specified by + * the attribute necessarily has an effect on the function. The `@optimize` + * attribute should be used for debugging purposes only. It is not suitable in + * production code. + * + * Example: + * --- + * import gcc.attributes; + * + * @optimize(2) double fn0(double x); + * @optimize("2") double fn1(double x); + * @optimize("s") double fn2(double x); + * @optimize("Ofast") double fn3(double x); + * @optimize("-O2") double fn4(double x); + * @optimize("tree-vectorize") double fn5(double x); + * @optimize("-ftree-vectorize") double fn6(double x); + * @optimize("no-finite-math-only", 3) double fn7(double x); + * --- + */ +auto optimize(A...)(A arguments) + if (allSatisfy!(isStringOrIntValue, arguments)) +{ + return attribute("optimize", arguments); +} + +auto optimize(A...)(A arguments) + if (!allSatisfy!(isStringOrIntValue, arguments)) +{ + assert(false, "optimize attribute argument not a string or integer constant"); +} + +/** + * The `@restrict` attribute specifies that a function parameter is to be + * restrict-qualified in the C99 sense of the term. The parameter needs to + * boil down to either a pointer or reference type, such as a D pointer, + * class reference, or a `ref` parameter. + * + * Example: + * --- + * import gcc.attributes; + * + * void func(@restrict ref const float[16] array); + * --- + */ +enum restrict = attribute("restrict"); + +/** + * The `@section` attribute specifies that a function lives in a particular + * section. For when you need certain particular functions to appear in + * special sections. + * + * Some file formats do not support arbitrary sections so the section attribute + * is not available on all platforms. If you need to map the entire contents + * of a module to a particular section, consider using the facilities of the + * linker instead. + * + * Example: + * --- + * import gcc.attributes; + * + * @section("bar") extern void func(); + * --- + */ +auto section(string sectionName) +{ + return attribute("section", sectionName); +} + +auto section(A...)(A arguments) +{ + assert(false, "section attribute argument not a string constant"); +} + +/** + * The `@symver` attribute creates a symbol version on ELF targets. The syntax + * of the string parameter is `name@nodename`. The `name` part of the parameter + * is the actual name of the symbol by which it will be externally referenced. + * The `nodename` portion should be the name of a node specified in the version + * script supplied to the linker when building a shared library. Versioned + * symbol must be defined and must be exported with default visibility. + * + * Finally if the parameter is `name@@nodename` then in addition to creating a + * symbol version (as if `name@nodename` was used) the version will be also used + * to resolve `name` by the linker. + * + * Example: + * --- + * import gcc.attributes; + * + * @symver("foo@VERS_1") int foo_v1(); + * --- + */ +auto symver(A...)(A arguments) + if (allSatisfy!(isStringValue, arguments)) +{ + return attribute("symver", arguments); +} + +auto symver(A...)(A arguments) + if (!allSatisfy!(isStringValue, arguments)) +{ + assert(false, "symver attribute argument not a string constant"); +} + +/** + * The `@target` attribute is used to specify that a function is to be + * compiled with different target options than specified on the command line. + * One or more strings can be provided as arguments, separated by commas to + * specify multiple options. Each string consists of one or more + * comma-separated suffixes to the `-m` prefix jointly forming the name of a + * machine-dependent option. + * + * The target attribute can be used for instance to have a function compiled + * with a different ISA (instruction set architecture) than the default. + * + * The options supported are specific to each target. + * + * Example: + * --- + * import gcc.attributes; + * + * @target("arch=core2") void core2_func(); + * @target("sse3") void sse3_func(); + * --- + */ +auto target(A...)(A arguments) + if (allSatisfy!(isStringValue, arguments)) +{ + return attribute("target", arguments); +} + +auto target(A...)(A arguments) + if (!allSatisfy!(isStringValue, arguments)) +{ + assert(false, "target attribute argument not a string constant"); +} + +/** + * The `@target_clones` attribute is used to specify that a function be cloned + * into multiple versions compiled with different target `options` than + * specified on the command line. The supported options and restrictions are + * the same as for `@target` attribute. + * + * It also creates a resolver function that dynamically selects a clone suitable + * for current architecture. The resolver is created only if there is a usage + * of a function with `@target_clones` attribute. + * + * Example: + * --- + * import gcc.attributes; + * + * @target_clones("sse4.1,avx,default") double func(double x); + * --- + */ +auto target_clones(A...)(A arguments) + if (allSatisfy!(isStringValue, arguments)) +{ + return attribute("target_clones", arguments); +} + +auto target_clones(A...)(A arguments) + if (!allSatisfy!(isStringValue, arguments)) +{ + assert(false, "target attribute argument not a string constant"); +} + +/** + * The `@used` attribute, annotated to a function, means that code must be + * emitted for the function even if it appears that the function is not + * referenced. This is useful, for example, when the function is referenced + * only in inline assembly. + * + * Example: + * --- + * import gcc.attributes; + * + * @used __gshared int var = 0x1000; + * --- + */ +enum used = attribute("used"); + +/** + * The `@weak` attribute causes a declaration of an external symbol to be + * emitted as a weak symbol rather than a global. This is primarily useful in + * defining library functions that can be overridden in user code, though it can + * also be used with non-function declarations. The overriding symbol must have + * the same type as the weak symbol. In addition, if it designates a variable + * it must also have the same size and alignment as the weak symbol. + * + * Weak symbols are supported for ELF targets, and also for a.out targets when + * using the GNU assembler and linker. + * + * Example: + * --- + * import gcc.attributes; + * + * @weak int func() { return 1; } + * --- + */ +enum weak = attribute("weak"); + +/** + * The `@noplt` attribute is the counterpart to option `-fno-plt`. Calls to + * functions marked with this attribute in position-independent code do not use + * the PLT in position-independent code. + * + * In position-dependant code, a few targets also convert call to functions + * that are marked to not use the PLT to use the GOT instead. + * + * Example: + * --- + * import gcc.attributes; + * + * @noplt int func(); + * + * --- + */ +enum noplt = attribute("noplt"); + +/////////////////////////////////////////////////////////////////////////////// +// +// Attributes defined for compatibility with LDC. +// +/////////////////////////////////////////////////////////////////////////////// + +/** + * Specifies that the function returns `null` or a pointer to at least a + * certain number of allocated bytes. `sizeArgIdx` and `numArgIdx` specify + * the 0-based index of the function arguments that should be used to calculate + * the number of bytes returned. + * + * Example: + * --- + * import gcc.attributes; + * + * @allocSize(0) extern(C) void* malloc(size_t size); + * @allocSize(2,1) extern(C) void* reallocarray(void *ptr, size_t nmemb, + * size_t size); + * @allocSize(0,1) void* my_calloc(size_t element_size, size_t count, + * bool irrelevant); + * --- + */ +auto allocSize(int sizeArgIdx, int numArgIdx = int.min) +{ + return alloc_size(sizeArgIdx, numArgIdx, true); +} + +auto allocSize(A...)(A arguments) +{ + assert(false, "allocSize attribute argument value is not an integer constant"); +} + +/** + * When applied to a global symbol, the compiler, assembler, and linker are + * required to treat the symbol as if there is a reference to the symbol that + * it cannot see (which is why they have to be named). For example, it + * prevents the deletion by the linker of an unreferenced symbol. + * + * Example: + * --- + * import gcc.attributes; + * + * @assumeUsed __gshared int var = 0x1000; + * --- + */ +alias assumeUsed = used; + +/// This attribute has no effect. +enum dynamicCompile = false; + +/// ditto +enum dynamicCompileConst = false; + +/// ditto +enum dynamicCompileEmit = false; + +/** + * Explicitly sets "fast-math" for a function, enabling aggressive math + * optimizations. These optimizations may dramatically change the outcome of + * floating point calculations (e.g. because of reassociation). + * + * Example: + * --- + * import gcc.attributes; + * + * @fastmath + * double dot(double[] a, double[] b) { + * double s = 0; + * foreach(size_t i; 0..a.length) + * { + * // will result in vectorized fused-multiply-add instructions + * s += a * b; + * } + * return s; + * } + * --- + */ +enum fastmath = optimize("Ofast"); + +/** + * Adds GCC's "naked" attribute to a function, disabling function prologue / + * epilogue emission. + * Intended to be used in combination with basic `asm` statement. While using + * extended `asm` or a mixture of basic `asm` and D code may appear to work, + * they cannot be depended upon to work reliably and are not supported. + * + * Example: + * --- + * import gcc.attributes; + * + * @naked void abort() { + * asm { "ud2"; } + * } + * --- + */ +enum naked = attribute("naked"); + +/** + * Sets the optimization strategy for a function. + * Valid strategies are "none", "optsize", "minsize". The strategies are + * mutually exclusive. + * + * Example: + * --- + * import gcc.attributes; + * + * @optStrategy("none") + * int func() { + * return call(); + * } + * --- + */ +auto optStrategy(string strategy) +{ + if (strategy == "none") + return optimize("O0"); + else if (strategy == "optsize" || strategy == "minsize") + return optimize("Os"); + else + { + assert(false, "unrecognized parameter `" ~ strategy + ~ "` for `gcc.attribute.optStrategy`"); + } +} + +auto optStrategy(A...)(A arguments) +{ + assert(false, "optStrategy attribute argument value is not a string constant"); +} + +/** + * When applied to a function, specifies that the function should be optimzed + * by Graphite, GCC's polyhedral optimizer. Useful for optimizing loops for + * data locality, vectorization and parallelism. + * + * Experimental! + * + * Only effective when GDC was built with ISL included. + */ +enum polly = optimize("loop-parallelize-all", "loop-nest-optimize"); diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index c747b51..2e67932 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -28,7 +28,7 @@ import gcc.unwind; import gcc.unwind.pe; import gcc.builtins; import gcc.config; -import gcc.attribute; +import gcc.attributes; extern(C) { -- cgit v1.1 From 019a922063f26784d5a070d9198a1f937b8a8343 Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Fri, 9 Apr 2021 00:16:56 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index b8af486..807664c 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,13 @@ +2021-04-08 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add + gcc/attributes.d. + * libdruntime/Makefile.in: Regenerate. + * libdruntime/gcc/attribute.d: Deprecate module, publicly import + gcc.attributes. + * libdruntime/gcc/deh.d: Update imports. + * libdruntime/gcc/attributes.d: New file. + 2021-04-06 Iain Buclaw <ibuclaw@gdcproject.org> * libdruntime/MERGE: Merge upstream druntime 1134b710. -- cgit v1.1 From 38258326dc9e5581e2cd6318ae1b5e675dd00d4a Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Sat, 10 Apr 2021 12:01:04 +0200 Subject: libphobos: Re-add -fno-moduleinfo flag to dg-runtest [PR99812] libphobos/ChangeLog: PR d/99812 * testsuite/libphobos.druntime_shared/druntime_shared.exp: Re-add -fno-moduleinfo flag to dg-runtest. * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise. --- libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp | 2 +- libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libphobos') diff --git a/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp b/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp index 2b25613..51f9c2c 100644 --- a/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp +++ b/libphobos/testsuite/libphobos.druntime_shared/druntime_shared.exp @@ -35,7 +35,7 @@ dg-init foreach test $tests { set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../libdruntime $test]" dg-runtest $test "-shared-libphobos" \ - "-fmain -fbuilding-libphobos-tests $version_flags" + "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags" set libphobos_test_name "" } diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp index 3a847e7..8498522 100644 --- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp +++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp @@ -46,7 +46,7 @@ dg-init foreach test $tests { set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]" dg-runtest $test "-shared-libphobos" \ - "-fmain -fbuilding-libphobos-tests $version_flags" + "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags" set libphobos_test_name "" } -- cgit v1.1 From 2b778748319ffe8434f68d147c168423a1af388d Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Sat, 10 Apr 2021 12:18:57 +0200 Subject: libphobos: Remove is-effective-target static from druntime and phobos tests This test isn't compiling with `-static', it's there to verify that the libphobos is functional when linked in statically. libphobos/ChangeLog: * testsuite/libphobos.druntime/druntime.exp: Remove is-effective-target static. * testsuite/libphobos.phobos/phobos.exp: Likewise. --- libphobos/testsuite/libphobos.druntime/druntime.exp | 2 +- libphobos/testsuite/libphobos.phobos/phobos.exp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libphobos') diff --git a/libphobos/testsuite/libphobos.druntime/druntime.exp b/libphobos/testsuite/libphobos.druntime/druntime.exp index 2f3a36f..df01fcc 100644 --- a/libphobos/testsuite/libphobos.druntime/druntime.exp +++ b/libphobos/testsuite/libphobos.druntime/druntime.exp @@ -15,7 +15,7 @@ # <http://www.gnu.org/licenses/>. # Immediately exit if we can't run target executables. -if { ![isnative] || ![is-effective-target static] } { +if { ![isnative] } { return } diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp index 0975ab1..770e576 100644 --- a/libphobos/testsuite/libphobos.phobos/phobos.exp +++ b/libphobos/testsuite/libphobos.phobos/phobos.exp @@ -15,7 +15,7 @@ # <http://www.gnu.org/licenses/>. # Immediately exit if we can't run target executables. -if { ![isnative] || ![is-effective-target static] } { +if { ![isnative] } { return } -- cgit v1.1 From 385ee099eeae53bff5dd5adf673ad4f4b8d22981 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Sat, 10 Apr 2021 12:24:40 +0200 Subject: libphobos: Explicitly use -static-libphobos in druntime and phobos tests Linking to libphobos statically is the default in the driver, however this may change in future. Be explicit that the static libphobos is what's being tested. libphobos/ChangeLog: * testsuite/libphobos.druntime/druntime.exp: Compile all tests with -static-libphobos. * testsuite/libphobos.phobos/phobos.exp: Likewise. --- libphobos/testsuite/libphobos.druntime/druntime.exp | 3 ++- libphobos/testsuite/libphobos.phobos/phobos.exp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'libphobos') diff --git a/libphobos/testsuite/libphobos.druntime/druntime.exp b/libphobos/testsuite/libphobos.druntime/druntime.exp index df01fcc..daedfd7 100644 --- a/libphobos/testsuite/libphobos.druntime/druntime.exp +++ b/libphobos/testsuite/libphobos.druntime/druntime.exp @@ -34,7 +34,8 @@ dg-init # Main loop. foreach test $tests { set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../libdruntime $test]" - dg-runtest $test "" "-fmain -fbuilding-libphobos-tests $version_flags" + dg-runtest $test "-static-libphobos" \ + "-fmain -fbuilding-libphobos-tests $version_flags" set libphobos_test_name "" } diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp index 770e576..937849e 100644 --- a/libphobos/testsuite/libphobos.phobos/phobos.exp +++ b/libphobos/testsuite/libphobos.phobos/phobos.exp @@ -45,7 +45,8 @@ dg-init # Main loop. foreach test $tests { set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]" - dg-runtest $test "" "-fmain -fbuilding-libphobos-tests $version_flags" + dg-runtest $test "-static-libphobos" \ + "-fmain -fbuilding-libphobos-tests $version_flags" set libphobos_test_name "" } -- cgit v1.1 From 32703b80f66f7ca504eb79bee7e745f22cf096a8 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Thu, 8 Apr 2021 16:11:16 +0200 Subject: libphobos: Add section support code for MACHO and PE/COFF This replaces the original and untested support for Windows and OSX, and is the 90% of the work needed to support libphobos on those targets. The core.thread interface has been updated to accomodate for the same function might be implemented by any of the platform-dependent modules. libphobos/ChangeLog: * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Removed gcc/sections/android.d, elf_shared.d, osx.d, win32.d, and win64.d. Added gcc/sections/common.d, elf.d macho.d, and pecoff.d. * libdruntime/Makefile.in: Regenerate. * libdruntime/core/thread/osthread.d: Update externDFunc FQDN names to use platform independant section function names. * libdruntime/gcc/sections/elf_shared.d: Renamed to... * libdruntime/gcc/sections/elf.d: ...this. Mangle functions for core.thread interface as if they come from the gcc.sections module. * libdruntime/gcc/sections/package.d: Update public imports, declare functions for core.thread interface. * libdruntime/gcc/sections/android.d: Removed. * libdruntime/gcc/sections/osx.d: Removed. * libdruntime/gcc/sections/win32.d: Removed. * libdruntime/gcc/sections/win64.d: Removed. * libdruntime/gcc/sections/common.d: New file. * libdruntime/gcc/sections/macho.d: New file. * libdruntime/gcc/sections/pecoff.d: New file. --- libphobos/libdruntime/Makefile.am | 23 +- libphobos/libdruntime/Makefile.in | 39 +- libphobos/libdruntime/core/thread/osthread.d | 10 +- libphobos/libdruntime/gcc/sections/android.d | 184 ---- libphobos/libdruntime/gcc/sections/common.d | 39 + libphobos/libdruntime/gcc/sections/elf.d | 1073 ++++++++++++++++++++++ libphobos/libdruntime/gcc/sections/elf_shared.d | 1122 ----------------------- libphobos/libdruntime/gcc/sections/macho.d | 738 +++++++++++++++ libphobos/libdruntime/gcc/sections/osx.d | 284 ------ libphobos/libdruntime/gcc/sections/package.d | 47 +- libphobos/libdruntime/gcc/sections/pecoff.d | 826 +++++++++++++++++ libphobos/libdruntime/gcc/sections/win32.d | 183 ---- libphobos/libdruntime/gcc/sections/win64.d | 321 ------- 13 files changed, 2735 insertions(+), 2154 deletions(-) delete mode 100644 libphobos/libdruntime/gcc/sections/android.d create mode 100644 libphobos/libdruntime/gcc/sections/common.d create mode 100644 libphobos/libdruntime/gcc/sections/elf.d delete mode 100644 libphobos/libdruntime/gcc/sections/elf_shared.d create mode 100644 libphobos/libdruntime/gcc/sections/macho.d delete mode 100644 libphobos/libdruntime/gcc/sections/osx.d create mode 100644 libphobos/libdruntime/gcc/sections/pecoff.d delete mode 100644 libphobos/libdruntime/gcc/sections/win32.d delete mode 100644 libphobos/libdruntime/gcc/sections/win64.d (limited to 'libphobos') diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 5137f85..74a0f00 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -186,18 +186,17 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ gc/gcinterface.d gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.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/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \ - gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \ - rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \ - rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \ - rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \ - rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \ - rt/switch_.d rt/tlsgc.d rt/util/array.d rt/util/container/array.d \ - rt/util/container/common.d rt/util/container/hashtab.d \ - rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \ - rt/util/utf.d + gcc/sections/common.d gcc/sections/elf.d gcc/sections/macho.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 rt/arraycast.d rt/arraycat.d \ + rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \ + rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \ + rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \ + rt/util/array.d rt/util/container/array.d rt/util/container/common.d \ + rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \ + rt/util/typeinfo.d rt/util/utf.d DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \ core/stdcpp/typeinfo.d diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 4a93b49..63b2133 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -211,10 +211,9 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \ gc/pooltable.lo gc/proxy.lo gcc/attribute.lo gcc/attributes.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/win64.lo gcc/unwind/arm.lo \ + gcc/gthread.lo gcc/sections/common.lo gcc/sections/elf.lo \ + gcc/sections/macho.lo gcc/sections/package.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 \ @@ -819,18 +818,17 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ gc/gcinterface.d gc/impl/conservative/gc.d gc/impl/manual/gc.d gc/os.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/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \ - gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \ - rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arrayassign.d \ - rt/arraycast.d rt/arraycat.d rt/cast_.d rt/config.d rt/critical_.d \ - rt/deh.d rt/dmain2.d rt/invariant.d rt/lifetime.d rt/memory.d \ - rt/minfo.d rt/monitor_.d rt/obj.d rt/qsort.d rt/sections.d \ - rt/switch_.d rt/tlsgc.d rt/util/array.d rt/util/container/array.d \ - rt/util/container/common.d rt/util/container/hashtab.d \ - rt/util/container/treap.d rt/util/random.d rt/util/typeinfo.d \ - rt/util/utf.d + gcc/sections/common.d gcc/sections/elf.d gcc/sections/macho.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 rt/arraycast.d rt/arraycat.d \ + rt/cast_.d rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d \ + rt/invariant.d rt/lifetime.d rt/memory.d rt/minfo.d rt/monitor_.d \ + rt/obj.d rt/qsort.d rt/sections.d rt/switch_.d rt/tlsgc.d \ + rt/util/array.d rt/util/container/array.d rt/util/container/common.d \ + rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \ + rt/util/typeinfo.d rt/util/utf.d DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \ core/stdcpp/typeinfo.d @@ -1219,12 +1217,11 @@ gcc/gthread.lo: gcc/$(am__dirstamp) gcc/sections/$(am__dirstamp): @$(MKDIR_P) gcc/sections @: > gcc/sections/$(am__dirstamp) -gcc/sections/android.lo: gcc/sections/$(am__dirstamp) -gcc/sections/elf_shared.lo: gcc/sections/$(am__dirstamp) -gcc/sections/osx.lo: gcc/sections/$(am__dirstamp) +gcc/sections/common.lo: gcc/sections/$(am__dirstamp) +gcc/sections/elf.lo: gcc/sections/$(am__dirstamp) +gcc/sections/macho.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) diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index defdc95..880836e 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -510,7 +510,7 @@ class Thread : ThreadBase { version (GNU) { - auto libs = externDFunc!("gcc.sections.elf_shared.pinLoadedLibraries", + auto libs = externDFunc!("gcc.sections.pinLoadedLibraries", void* function() @nogc nothrow)(); } else @@ -527,7 +527,7 @@ class Thread : ThreadBase { version (GNU) { - externDFunc!("gcc.sections.elf_shared.unpinLoadedLibraries", + externDFunc!("gcc.sections.unpinLoadedLibraries", void function(void*) @nogc nothrow)(libs); } else @@ -2196,7 +2196,7 @@ else version (Posix) // before initilizing GC for TLS (rt_tlsgc_init) version (GNUShared) { - externDFunc!("gcc.sections.elf_shared.inheritLoadedLibraries", + externDFunc!("gcc.sections.inheritLoadedLibraries", void function(void*) @nogc nothrow)(loadedLibraries); } else version (Shared) @@ -2287,7 +2287,7 @@ else version (Posix) rt_moduleTlsDtor(); version (GNUShared) { - externDFunc!("gcc.sections.elf_shared.cleanupLoadedLibraries", + externDFunc!("gcc.sections.cleanupLoadedLibraries", void function() @nogc nothrow)(); } else version (Shared) @@ -2786,7 +2786,7 @@ private size_t adjustStackSize(size_t sz) nothrow @nogc // On glibc, TLS uses the top of the stack, so add its size to the requested size version (GNU) { - sz += externDFunc!("gcc.sections.elf_shared.sizeOfTLS", + sz += externDFunc!("gcc.sections.elf.sizeOfTLS", size_t function() @nogc nothrow)(); } else diff --git a/libphobos/libdruntime/gcc/sections/android.d b/libphobos/libdruntime/gcc/sections/android.d deleted file mode 100644 index 4af26b4..0000000 --- a/libphobos/libdruntime/gcc/sections/android.d +++ /dev/null @@ -1,184 +0,0 @@ -// Bionic-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.android; - -version (CRuntime_Bionic): - -// debug = PRINTF; -debug(PRINTF) import core.stdc.stdio; -import core.stdc.stdlib : malloc, free; -import rt.deh, rt.minfo; -import core.sys.posix.pthread; -import core.stdc.stdlib : calloc; -import core.stdc.string : memcpy; - -struct SectionGroup -{ - static int opApply(scope int delegate(ref SectionGroup) dg) - { - return dg(_sections); - } - - static int opApplyReverse(scope int delegate(ref SectionGroup) dg) - { - return dg(_sections); - } - - @property immutable(ModuleInfo*)[] modules() const nothrow @nogc - { - return _moduleGroup.modules; - } - - @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc - { - return _moduleGroup; - } - - @property immutable(FuncTable)[] ehTables() const nothrow @nogc - { - auto pbeg = cast(immutable(FuncTable)*)&__start_deh; - auto pend = cast(immutable(FuncTable)*)&__stop_deh; - return pbeg[0 .. pend - pbeg]; - } - - @property inout(void[])[] gcRanges() inout nothrow @nogc - { - return _gcRanges[]; - } - -private: - ModuleGroup _moduleGroup; - void[][1] _gcRanges; -} - -void initSections() nothrow @nogc -{ - pthread_key_create(&_tlsKey, null); - - auto mbeg = cast(immutable ModuleInfo**)&__start_minfo; - auto mend = cast(immutable ModuleInfo**)&__stop_minfo; - _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]); - - auto pbeg = cast(void*)&_tlsend; - auto pend = cast(void*)&__bss_end__; - // _tlsend is a 32-bit int and may not be 64-bit void*-aligned, so align pbeg. - version (D_LP64) pbeg = cast(void*)(cast(size_t)(pbeg + 7) & ~cast(size_t)7); - _sections._gcRanges[0] = pbeg[0 .. pend - pbeg]; -} - -void finiSections() nothrow @nogc -{ - pthread_key_delete(_tlsKey); -} - -void[]* initTLSRanges() nothrow @nogc -{ - return &getTLSBlock(); -} - -void finiTLSRanges(void[]* rng) nothrow @nogc -{ - .free(rng.ptr); - .free(rng); -} - -void scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow -{ - dg(rng.ptr, rng.ptr + rng.length); -} - -/* NOTE: The Bionic C library ignores thread-local data stored in the normal - * .tbss/.tdata ELF sections, which are marked with the SHF_TLS/STT_TLS - * flags. So instead we roll our own by keeping TLS data in the - * .tdata/.tbss sections but removing the SHF_TLS/STT_TLS flags, and - * access the TLS data using this function and the _tlsstart/_tlsend - * symbols as delimiters. - * - * This function is called by the code emitted by the compiler. It - * is expected to translate an address in the TLS static data to - * the corresponding address in the TLS dynamic per-thread data. - */ - -extern(C) void* __tls_get_addr( void* p ) nothrow @nogc -{ - debug(PRINTF) printf(" __tls_get_addr input - %p\n", p); - immutable offset = cast(size_t)(p - cast(void*)&_tlsstart); - auto tls = getTLSBlockAlloc(); - assert(offset < tls.length); - return tls.ptr + offset; -} - -private: - -__gshared pthread_key_t _tlsKey; - -ref void[] getTLSBlock() nothrow @nogc -{ - auto pary = cast(void[]*)pthread_getspecific(_tlsKey); - if (pary is null) - { - pary = cast(void[]*).calloc(1, (void[]).sizeof); - if (pthread_setspecific(_tlsKey, pary) != 0) - { - import core.stdc.stdio; - perror("pthread_setspecific failed with"); - assert(0); - } - } - return *pary; -} - -ref void[] getTLSBlockAlloc() nothrow @nogc -{ - auto pary = &getTLSBlock(); - if (!pary.length) - { - auto pbeg = cast(void*)&_tlsstart; - auto pend = cast(void*)&_tlsend; - auto p = .malloc(pend - pbeg); - memcpy(p, pbeg, pend - pbeg); - *pary = p[0 .. pend - pbeg]; - } - return *pary; -} - -__gshared SectionGroup _sections; - -extern(C) -{ - /* Symbols created by the compiler/linker and inserted into the - * object file that 'bracket' sections. - */ - extern __gshared - { - void* __start_deh; - void* __stop_deh; - void* __start_minfo; - void* __stop_minfo; - - size_t __bss_end__; - - int _tlsstart; - int _tlsend; - } -} diff --git a/libphobos/libdruntime/gcc/sections/common.d b/libphobos/libdruntime/gcc/sections/common.d new file mode 100644 index 0000000..85fdc0e --- /dev/null +++ b/libphobos/libdruntime/gcc/sections/common.d @@ -0,0 +1,39 @@ +// Contains various utility functions used by the runtime implementation. +// 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.common; + +/** + * Asserts that the given condition is `true`. + * + * The assertion is independent from -release, by abort()ing. Regular assertions + * throw an AssertError and thus require an initialized GC, which might not be + * the case (yet or anymore) for the startup/shutdown code in this package + * (called by CRT ctors/dtors etc.). + */ +package(gcc) void safeAssert( + bool condition, scope string msg, scope string file = __FILE__, size_t line = __LINE__ +) nothrow @nogc @safe +{ + import core.internal.abort; + condition || abort(msg, file, line); +} diff --git a/libphobos/libdruntime/gcc/sections/elf.d b/libphobos/libdruntime/gcc/sections/elf.d new file mode 100644 index 0000000..8450aec --- /dev/null +++ b/libphobos/libdruntime/gcc/sections/elf.d @@ -0,0 +1,1073 @@ +// ELF-specific support for sections with shared libraries. +// 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.elf; + +version (MIPS32) version = MIPS_Any; +version (MIPS64) version = MIPS_Any; +version (RISCV32) version = RISCV_Any; +version (RISCV64) version = RISCV_Any; +version (S390) version = IBMZ_Any; +version (SystemZ) version = IBMZ_Any; + +version (CRuntime_Glibc) enum SharedELF = true; +else version (CRuntime_Musl) enum SharedELF = true; +else version (FreeBSD) enum SharedELF = true; +else version (NetBSD) enum SharedELF = true; +else version (DragonFlyBSD) enum SharedELF = true; +else version (CRuntime_UClibc) enum SharedELF = true; +else version (Solaris) enum SharedELF = true; +else enum SharedELF = false; +static if (SharedELF): + +import core.memory; +import core.stdc.config; +import core.stdc.stdio; +import core.stdc.stdlib : calloc, exit, free, malloc, EXIT_FAILURE; +import core.stdc.string : strlen; +version (linux) +{ + import core.sys.linux.dlfcn; + import core.sys.linux.elf; + import core.sys.linux.link; +} +else version (FreeBSD) +{ + import core.sys.freebsd.dlfcn; + import core.sys.freebsd.sys.elf; + import core.sys.freebsd.sys.link_elf; +} +else version (NetBSD) +{ + import core.sys.netbsd.dlfcn; + import core.sys.netbsd.sys.elf; + import core.sys.netbsd.sys.link_elf; +} +else version (DragonFlyBSD) +{ + import core.sys.dragonflybsd.dlfcn; + import core.sys.dragonflybsd.sys.elf; + import core.sys.dragonflybsd.sys.link_elf; +} +else version (Solaris) +{ + import core.sys.solaris.dlfcn; + import core.sys.solaris.link; + import core.sys.solaris.sys.elf; + import core.sys.solaris.sys.link; +} +else +{ + static assert(0, "unimplemented"); +} +import core.sys.posix.pthread; +import rt.deh; +import rt.dmain2; +import rt.minfo; +import rt.util.container.array; +import rt.util.container.hashtab; +import gcc.builtins; +import gcc.config; +import gcc.sections.common; + +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."); + safeAssert(_tlsMod || !_tlsSize, "Inconsistent TLS fields for DSO."); + } + + ModuleGroup _moduleGroup; + Array!(void[]) _gcRanges; + size_t _tlsMod; + size_t _tlsSize; + + version (Shared) + { + Array!(void[]) _codeSegments; // array of code segments + Array!(DSO*) _deps; // D libraries needed by this DSO + void* _handle; // corresponding handle + } + + // get the TLS range for the executing thread + void[] tlsRange() const nothrow @nogc + { + return getTLSRange(_tlsMod, _tlsSize); + } +} + +/**** + * 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) +{ + import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries, + inheritLoadedLibraries, cleanupLoadedLibraries; + + /*** + * 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) + { + import gcc.emutls; + _d_emutls_scan(dg); + } + else + { + foreach (ref tdso; *tdsos) + dg(tdso._tlsRange.ptr, tdso._tlsRange.ptr + tdso._tlsRange.length); + } + } + + size_t sizeOfTLS() nothrow @nogc + { + auto tdsos = initTLSRanges(); + size_t sum; + foreach (ref tdso; *tdsos) + sum += tdso._tlsRange.length; + return sum; + } + + // interface for core.thread to inherit loaded libraries + pragma(mangle, gcc.sections.pinLoadedLibraries.mangleof) + 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 dlopen ref for explicitly loaded libraries to pin them. + const success = .dlopen(linkMapForHandle(tdso._pdso._handle).l_name, RTLD_LAZY) !is null; + safeAssert(success, "Failed to increment dlopen ref."); + (*res)[i]._addCnt = 1; // new array takes over the additional ref count + } + } + return res; + } + + pragma(mangle, gcc.sections.unpinLoadedLibraries.mangleof) + 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."); + .dlclose(handle); + } + } + pary.reset(); + .free(pary); + } + + // Called before TLS ctors are ran, copy over the loaded libraries + // of the parent thread. + pragma(mangle, gcc.sections.inheritLoadedLibraries.mangleof) + 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); + foreach (ref dso; _loadedDSOs) + { + // the copied _tlsRange corresponds to parent thread + dso.updateTLSRange(); + } + } + + // Called after all TLS dtors ran, decrements all remaining dlopen refs. + pragma(mangle, gcc.sections.cleanupLoadedLibraries.mangleof) + 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) + .dlclose(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 + { + auto rngs = &_tlsRanges(); + if (rngs.empty) + { + foreach (ref pdso; _loadedDSOs) + rngs.insertBack(pdso.tlsRange()); + } + return rngs; + } + + void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc + { + rngs.reset(); + } + + void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow + { + version (GNU_EMUTLS) + { + import gcc.emutls; + _d_emutls_scan(dg); + } + else + { + foreach (rng; *rngs) + dg(rng.ptr, rng.ptr + rng.length); + } + } + + size_t sizeOfTLS() nothrow @nogc + { + auto rngs = initTLSRanges(); + size_t sum; + foreach (rng; *rngs) + sum += rng.length; + return sum; + } +} + +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"); + void[] _tlsRange; + alias _pdso this; + // update the _tlsRange for the executing thread + void updateTLSRange() nothrow @nogc + { + _tlsRange = _pdso.tlsRange(); + } + } + @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 link_map* to corresponding DSO*. + * The hash table is protected by a Mutex. + */ + __gshared pthread_mutex_t _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; } + + /* + * Thread local array that contains TLS memory ranges for each + * library initialized in this thread. + */ + @property ref Array!(void[]) _tlsRanges() @nogc nothrow { static Array!(void[]) 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); + *data._slot = pdso; // store backlink in library record + + pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end)); + + dl_phdr_info info = void; + const headerFound = findDSOInfoForAddr(data._slot, &info); + safeAssert(headerFound, "Failed to find image header."); + + scanSegments(info, pdso); + + version (Shared) + { + auto handle = handleForAddr(data._slot); + + getDependencies(info, 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, pdso.tlsRange())); + } + } + else + { + foreach (p; _loadedDSOs) + safeAssert(p !is pdso, "DSO already registered."); + _loadedDSOs.insertBack(pdso); + _tlsRanges.insertBack(pdso.tlsRange()); + } + + // don't initialize modules before rt_init was called (see Bugzilla 11378) + 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 (Shared) + { + safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs."); + _handleToDSO.reset(); + } + finiLocks(); + version (GNU_EMUTLS) + { + import gcc.emutls; + _d_emutls_destroy(); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// 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.tlsRange())); + 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); + } + + extern(C) void* rt_loadLibrary(const char* name) + { + immutable save = _rtLoading; + _rtLoading = true; + scope (exit) _rtLoading = save; + + auto handle = .dlopen(name, RTLD_LAZY); + if (handle is null) return null; + + // if it's a D library + if (auto pdso = dsoForHandle(handle)) + incThreadRef(pdso, true); + return handle; + } + + extern(C) int rt_unloadLibrary(void* handle) + { + if (handle is null) return false; + + immutable save = _rtLoading; + _rtLoading = true; + scope (exit) _rtLoading = save; + + // if it's a D library + if (auto pdso = dsoForHandle(handle)) + decThreadRef(pdso, true); + return .dlclose(handle) == 0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Helper functions +/////////////////////////////////////////////////////////////////////////////// + +void initLocks() nothrow @nogc +{ + version (Shared) + !pthread_mutex_init(&_handleToDSOMutex, null) || assert(0); +} + +void finiLocks() nothrow @nogc +{ + version (Shared) + !pthread_mutex_destroy(&_handleToDSOMutex) || assert(0); +} + +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: + link_map* linkMapForHandle(void* handle) + { + link_map* map; + const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0; + safeAssert(success, "Failed to get DSO info."); + return map; + } + + link_map* exeLinkMap(link_map* map) + { + safeAssert(map !is null, "Invalid link_map."); + while (map.l_prev !is null) + map = map.l_prev; + return map; + } + + DSO* dsoForHandle(void* handle) + { + DSO* pdso; + !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); + if (auto ppdso = handle in _handleToDSO) + pdso = *ppdso; + !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); + return pdso; + } + + void setDSOForHandle(DSO* pdso, void* handle) + { + !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); + safeAssert(handle !in _handleToDSO, "DSO already registered."); + _handleToDSO[handle] = pdso; + !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); + } + + void unsetDSOForHandle(DSO* pdso, void* handle) + { + !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); + safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO."); + _handleToDSO.remove(handle); + !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); + } + + void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps) + { + // get the entries of the .dynamic section + ElfW!"Dyn"[] dyns; + foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum]) + { + if (phdr.p_type == PT_DYNAMIC) + { + auto p = cast(ElfW!"Dyn"*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1))); + dyns = p[0 .. phdr.p_memsz / ElfW!"Dyn".sizeof]; + break; + } + } + // find the string table which contains the sonames + const(char)* strtab; + foreach (dyn; dyns) + { + if (dyn.d_tag == DT_STRTAB) + { + version (CRuntime_Musl) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (linux) + { + // This might change in future glibc releases (after 2.29) as dynamic sections + // are not required to be read-only on RISC-V. This was copy & pasted from MIPS + // while upstreaming RISC-V support. Otherwise MIPS is the only arch which sets + // in glibc: #define DL_RO_DYN_SECTION 1 + version (RISCV_Any) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (MIPS_Any) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else + strtab = cast(const(char)*)dyn.d_un.d_ptr; + } + else version (FreeBSD) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (NetBSD) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (DragonFlyBSD) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (Solaris) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else + static assert(0, "unimplemented"); + break; + } + } + foreach (dyn; dyns) + { + immutable tag = dyn.d_tag; + if (!(tag == DT_NEEDED || tag == DT_AUXILIARY || tag == DT_FILTER)) + continue; + + // soname of the dependency + auto name = strtab + dyn.d_un.d_val; + // get handle without loading the library + auto handle = 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) + { + auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY); + version (Solaris) { } + else if (handle !is null) .dlclose(handle); // drop reference count + return handle; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Elf program header iteration +/////////////////////////////////////////////////////////////////////////////// + +/************ + * Scan segments in Linux dl_phdr_info struct and store + * the TLS and writeable data segments in *pdso. + */ +void scanSegments(in ref dl_phdr_info info, DSO* pdso) nothrow @nogc +{ + foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum]) + { + switch (phdr.p_type) + { + case PT_LOAD: + if (phdr.p_flags & PF_W) // writeable data segment + { + auto beg = cast(void*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1))); + pdso._gcRanges.insertBack(beg[0 .. phdr.p_memsz]); + } + version (Shared) if (phdr.p_flags & PF_X) // code segment + { + auto beg = cast(void*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1))); + pdso._codeSegments.insertBack(beg[0 .. phdr.p_memsz]); + } + break; + + case PT_TLS: // TLS segment + version (GNU_EMUTLS) + { + } + else + { + safeAssert(!pdso._tlsSize, "Multiple TLS segments in image header."); + static if (OS_Have_Dlpi_Tls_Modid) + { + pdso._tlsMod = info.dlpi_tls_modid; + pdso._tlsSize = phdr.p_memsz; + } + else version (Solaris) + { + struct Rt_map + { + Link_map rt_public; + const char* rt_pathname; + c_ulong rt_padstart; + c_ulong rt_padimlen; + c_ulong rt_msize; + uint rt_flags; + uint rt_flags1; + c_ulong rt_tlsmodid; + } + + Rt_map* map; + version (Shared) + dlinfo(handleForName(info.dlpi_name), RTLD_DI_LINKMAP, &map); + else + dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); + // Until Solaris 11.4, tlsmodid for the executable is 0. + // Let it start at 1 as the rest of the code expects. + pdso._tlsMod = map.rt_tlsmodid + 1; + pdso._tlsSize = phdr.p_memsz; + } + else + { + pdso._tlsMod = 0; + pdso._tlsSize = 0; + } + } + break; + + default: + break; + } + } +} + +/************************** + * Input: + * result where the output is to be written; dl_phdr_info is an OS struct + * Returns: + * true if found, and *result is filled in + * References: + * http://linux.die.net/man/3/dl_iterate_phdr + */ +bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc +{ + version (linux) enum IterateManually = true; + else version (NetBSD) enum IterateManually = true; + else version (Solaris) enum IterateManually = true; + else enum IterateManually = false; + + static if (IterateManually) + { + static struct DG { const(void)* addr; dl_phdr_info* result; } + + extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc + { + auto p = cast(DG*)arg; + if (findSegmentForAddr(*info, p.addr)) + { + if (p.result !is null) *p.result = *info; + return 1; // break; + } + return 0; // continue iteration + } + + auto dg = DG(addr, result); + + /* OS function that walks through the list of an application's shared objects and + * calls 'callback' once for each object, until either all shared objects + * have been processed or 'callback' returns a nonzero value. + */ + return dl_iterate_phdr(&callback, &dg) != 0; + } + else version (FreeBSD) + { + return !!_rtld_addr_phdr(addr, result); + } + else version (DragonFlyBSD) + { + return !!_rtld_addr_phdr(addr, result); + } + else + static assert(0, "unimplemented"); +} + +/********************************* + * Determine if 'addr' lies within shared object 'info'. + * If so, return true and fill in 'result' with the corresponding ELF program header. + */ +bool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!"Phdr"* result=null) nothrow @nogc +{ + if (addr < cast(void*)info.dlpi_addr) // less than base address of object means quick reject + return false; + + foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum]) + { + auto beg = cast(void*)(info.dlpi_addr + phdr.p_vaddr); + if (cast(size_t)(addr - beg) < phdr.p_memsz) + { + if (result !is null) *result = phdr; + return true; + } + } + return false; +} + +/************************** + * Input: + * addr an internal address of a DSO + * Returns: + * the dlopen handle for that DSO or null if addr is not within a loaded DSO + */ +version (Shared) void* handleForAddr(void* addr) nothrow @nogc +{ + Dl_info info = void; + if (dladdr(addr, &info) != 0) + return handleForName(info.dli_fname); + return null; +} + +/////////////////////////////////////////////////////////////////////////////// +// TLS module helper +/////////////////////////////////////////////////////////////////////////////// + + +/* + * Returns: the TLS memory range for a given module and the calling + * thread or null if that module has no TLS. + * + * Note: This will cause the TLS memory to be eagerly allocated. + */ +struct tls_index +{ + version (CRuntime_Glibc) + { + // For x86_64, fields are of type uint64_t, this is important for x32 + // where tls_index would otherwise have the wrong size. + // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/dl-tls.h + version (X86_64) + { + ulong ti_module; + ulong ti_offset; + } + else + { + c_ulong ti_module; + c_ulong ti_offset; + } + } + else + { + size_t ti_module; + size_t ti_offset; + } +} + +extern(C) void* __tls_get_addr(tls_index* ti) nothrow @nogc; +extern(C) void* __ibmz_get_tls_offset(tls_index *ti) nothrow @nogc; + +/* The dynamic thread vector (DTV) pointers may point 0x8000 past the start of + * each TLS block. This is at least true for PowerPC and Mips platforms. + * See: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/dl-tls.h;h=f7cf6f96ebfb505abfd2f02be0ad0e833107c0cd;hb=HEAD#l34 + * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/dl-tls.h;h=93a6dc050cb144b9f68b96fb3199c60f5b1fcd18;hb=HEAD#l32 + * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/dl-tls.h;h=ab2d860314de94c18812bc894ff6b3f55368f20f;hb=HEAD#l32 + */ +version (X86) + enum TLS_DTV_OFFSET = 0x0; +else version (X86_64) + enum TLS_DTV_OFFSET = 0x0; +else version (ARM) + enum TLS_DTV_OFFSET = 0x0; +else version (AArch64) + enum TLS_DTV_OFFSET = 0x0; +else version (RISCV32) + enum TLS_DTV_OFFSET = 0x800; +else version (RISCV64) + enum TLS_DTV_OFFSET = 0x800; +else version (HPPA) + enum TLS_DTV_OFFSET = 0x0; +else version (SPARC) + enum TLS_DTV_OFFSET = 0x0; +else version (SPARC64) + enum TLS_DTV_OFFSET = 0x0; +else version (PPC) + enum TLS_DTV_OFFSET = 0x8000; +else version (PPC64) + enum TLS_DTV_OFFSET = 0x8000; +else version (MIPS32) + enum TLS_DTV_OFFSET = 0x8000; +else version (MIPS64) + enum TLS_DTV_OFFSET = 0x8000; +else version (IBMZ_Any) + enum TLS_DTV_OFFSET = 0x0; +else + static assert( false, "Platform not supported." ); + +void[] getTLSRange(size_t mod, size_t sz) nothrow @nogc +{ + if (mod == 0) + return null; + + version (GNU_EMUTLS) + return null; // Handled in scanTLSRanges(). + else + { + version (Solaris) + { + static if (!OS_Have_Dlpi_Tls_Modid) + mod -= 1; + } + + // base offset + auto ti = tls_index(mod, 0); + version (CRuntime_Musl) + return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; + else version (IBMZ_Any) + { + // IBM Z only provides __tls_get_offset instead of __tls_get_addr + // which returns an offset relative to the thread pointer. + auto addr = __ibmz_get_tls_offset(&ti); + addr = addr + cast(c_ulong)__builtin_thread_pointer(); + return addr[0 .. sz]; + } + else + return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; + } +} diff --git a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d deleted file mode 100644 index 5b0fad9..0000000 --- a/libphobos/libdruntime/gcc/sections/elf_shared.d +++ /dev/null @@ -1,1122 +0,0 @@ -// ELF-specific support for sections with shared libraries. -// 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.elf_shared; - -version (MIPS32) version = MIPS_Any; -version (MIPS64) version = MIPS_Any; -version (RISCV32) version = RISCV_Any; -version (RISCV64) version = RISCV_Any; -version (S390) version = IBMZ_Any; -version (SystemZ) version = IBMZ_Any; - -version (CRuntime_Glibc) enum SharedELF = true; -else version (CRuntime_Musl) enum SharedELF = true; -else version (FreeBSD) enum SharedELF = true; -else version (NetBSD) enum SharedELF = true; -else version (DragonFlyBSD) enum SharedELF = true; -else version (CRuntime_UClibc) enum SharedELF = true; -else version (Solaris) enum SharedELF = true; -else enum SharedELF = false; -static if (SharedELF): - -// debug = PRINTF; -import core.memory; -import core.stdc.config; -import core.stdc.stdio; -import core.stdc.stdlib : calloc, exit, free, malloc, EXIT_FAILURE; -import core.stdc.string : strlen; -version (linux) -{ - import core.sys.linux.dlfcn; - import core.sys.linux.elf; - import core.sys.linux.link; -} -else version (FreeBSD) -{ - import core.sys.freebsd.dlfcn; - import core.sys.freebsd.sys.elf; - import core.sys.freebsd.sys.link_elf; -} -else version (NetBSD) -{ - import core.sys.netbsd.dlfcn; - import core.sys.netbsd.sys.elf; - import core.sys.netbsd.sys.link_elf; -} -else version (DragonFlyBSD) -{ - import core.sys.dragonflybsd.dlfcn; - import core.sys.dragonflybsd.sys.elf; - import core.sys.dragonflybsd.sys.link_elf; -} -else version (Solaris) -{ - import core.sys.solaris.dlfcn; - import core.sys.solaris.link; - import core.sys.solaris.sys.elf; - import core.sys.solaris.sys.link; -} -else -{ - static assert(0, "unimplemented"); -} -import core.sys.posix.pthread; -import gcc.builtins; -import gcc.config; -import rt.deh; -import rt.dmain2; -import rt.minfo; -import rt.util.container.array; -import rt.util.container.hashtab; - -/**** - * Asserts the specified condition, independent from -release, by abort()ing. - * Regular assertions throw an AssertError and thus require an initialized - * GC, which isn't the case (yet or anymore) for the startup/shutdown code in - * this module (called by CRT ctors/dtors etc.). - */ -private void safeAssert(bool condition, scope string msg, size_t line = __LINE__) @nogc nothrow @safe -{ - import core.internal.abort; - condition || abort(msg, __FILE__, line); -} - -alias DSO SectionGroup; -struct DSO -{ - 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 immutable(FuncTable)[] ehTables() const nothrow @nogc - { - return null; - } - - @property inout(void[])[] gcRanges() inout nothrow @nogc - { - return _gcRanges[]; - } - -private: - - invariant() - { - safeAssert(_moduleGroup.modules.length > 0, "No modules for DSO."); - safeAssert(_tlsMod || !_tlsSize, "Inconsistent TLS fields for DSO."); - } - - ModuleGroup _moduleGroup; - Array!(void[]) _gcRanges; - size_t _tlsMod; - size_t _tlsSize; - - version (Shared) - { - Array!(void[]) _codeSegments; // array of code segments - Array!(DSO*) _deps; // D libraries needed by this DSO - void* _handle; // corresponding handle - } - - // get the TLS range for the executing thread - void[] tlsRange() const nothrow @nogc - { - return getTLSRange(_tlsMod, _tlsSize); - } -} - -/**** - * Boolean flag set to true while the runtime is initialized. - */ -__gshared bool _isRuntimeInitialized; - - -version (FreeBSD) private __gshared void* dummy_ref; -version (DragonFlyBSD) private __gshared void* dummy_ref; -version (NetBSD) private __gshared void* dummy_ref; -version (Solaris) private __gshared void* dummy_ref; - -/**** - * Gets called on program startup just before GC is initialized. - */ -void initSections() nothrow @nogc -{ - _isRuntimeInitialized = true; - // reference symbol to support weak linkage - version (FreeBSD) dummy_ref = &_d_dso_registry; - version (DragonFlyBSD) dummy_ref = &_d_dso_registry; - version (NetBSD) dummy_ref = &_d_dso_registry; - version (Solaris) dummy_ref = &_d_dso_registry; -} - - -/*** - * 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) - { - import gcc.emutls; - _d_emutls_scan(dg); - } - else - { - foreach (ref tdso; *tdsos) - dg(tdso._tlsRange.ptr, tdso._tlsRange.ptr + tdso._tlsRange.length); - } - } - - size_t sizeOfTLS() nothrow @nogc - { - auto tdsos = initTLSRanges(); - size_t sum; - foreach (ref tdso; *tdsos) - sum += tdso._tlsRange.length; - return sum; - } - - // 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 dlopen ref for explicitly loaded libraries to pin them. - const success = .dlopen(linkMapForHandle(tdso._pdso._handle).l_name, RTLD_LAZY) !is null; - safeAssert(success, "Failed to increment dlopen ref."); - (*res)[i]._addCnt = 1; // new array takes over the additional ref count - } - } - 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."); - .dlclose(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); - foreach (ref dso; _loadedDSOs) - { - // the copied _tlsRange corresponds to parent thread - dso.updateTLSRange(); - } - } - - // Called after all TLS dtors ran, decrements all remaining dlopen 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) - .dlclose(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 - { - auto rngs = &_tlsRanges(); - if (rngs.empty) - { - foreach (ref pdso; _loadedDSOs) - rngs.insertBack(pdso.tlsRange()); - } - return rngs; - } - - void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc - { - rngs.reset(); - } - - void scanTLSRanges(Array!(void[])* rngs, scope ScanDG dg) nothrow - { - version (GNU_EMUTLS) - { - import gcc.emutls; - _d_emutls_scan(dg); - } - else - { - foreach (rng; *rngs) - dg(rng.ptr, rng.ptr + rng.length); - } - } - - size_t sizeOfTLS() nothrow @nogc - { - auto rngs = initTLSRanges(); - size_t sum; - foreach (rng; *rngs) - sum += rng.length; - return sum; - } -} - -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"); - void[] _tlsRange; - alias _pdso this; - // update the _tlsRange for the executing thread - void updateTLSRange() nothrow @nogc - { - _tlsRange = _pdso.tlsRange(); - } - } - @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 link_map* to corresponding DSO*. - * The hash table is protected by a Mutex. - */ - __gshared pthread_mutex_t _handleToDSOMutex; - @property ref HashTab!(void*, DSO*) _handleToDSO() @nogc nothrow { __gshared HashTab!(void*, DSO*) x; return x; } - - /* - * Section in executable that contains copy relocations. - * Might be null when druntime is dynamically loaded by a C host. - */ - __gshared const(void)[] _copyRelocSection; -} -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; } - - /* - * Thread local array that contains TLS memory ranges for each - * library initialized in this thread. - */ - @property ref Array!(void[]) _tlsRanges() @nogc nothrow { static Array!(void[]) 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); - *data._slot = pdso; // store backlink in library record - - pdso._moduleGroup = ModuleGroup(toRange(data._minfo_beg, data._minfo_end)); - - dl_phdr_info info = void; - const headerFound = findDSOInfoForAddr(data._slot, &info); - safeAssert(headerFound, "Failed to find image header."); - - scanSegments(info, pdso); - - version (Shared) - { - auto handle = handleForAddr(data._slot); - - getDependencies(info, 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, pdso.tlsRange())); - } - } - else - { - foreach (p; _loadedDSOs) - safeAssert(p !is pdso, "DSO already registered."); - _loadedDSOs.insertBack(pdso); - _tlsRanges.insertBack(pdso.tlsRange()); - } - - // don't initialize modules before rt_init was called (see Bugzilla 11378) - 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 (Shared) - { - safeAssert(_handleToDSO.empty, "_handleToDSO not in sync with _loadedDSOs."); - _handleToDSO.reset(); - } - finiLocks(); - version (GNU_EMUTLS) - { - import gcc.emutls; - _d_emutls_destroy(); - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// 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.tlsRange())); - 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); - } - - extern(C) void* rt_loadLibrary(const char* name) - { - immutable save = _rtLoading; - _rtLoading = true; - scope (exit) _rtLoading = save; - - auto handle = .dlopen(name, RTLD_LAZY); - if (handle is null) return null; - - // if it's a D library - if (auto pdso = dsoForHandle(handle)) - incThreadRef(pdso, true); - return handle; - } - - extern(C) int rt_unloadLibrary(void* handle) - { - if (handle is null) return false; - - immutable save = _rtLoading; - _rtLoading = true; - scope (exit) _rtLoading = save; - - // if it's a D library - if (auto pdso = dsoForHandle(handle)) - decThreadRef(pdso, true); - return .dlclose(handle) == 0; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Helper functions -/////////////////////////////////////////////////////////////////////////////// - -void initLocks() nothrow @nogc -{ - version (Shared) - !pthread_mutex_init(&_handleToDSOMutex, null) || assert(0); -} - -void finiLocks() nothrow @nogc -{ - version (Shared) - !pthread_mutex_destroy(&_handleToDSOMutex) || assert(0); -} - -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: - link_map* linkMapForHandle(void* handle) - { - link_map* map; - const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0; - safeAssert(success, "Failed to get DSO info."); - return map; - } - - link_map* exeLinkMap(link_map* map) - { - safeAssert(map !is null, "Invalid link_map."); - while (map.l_prev !is null) - map = map.l_prev; - return map; - } - - DSO* dsoForHandle(void* handle) - { - DSO* pdso; - !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); - if (auto ppdso = handle in _handleToDSO) - pdso = *ppdso; - !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); - return pdso; - } - - void setDSOForHandle(DSO* pdso, void* handle) - { - !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); - safeAssert(handle !in _handleToDSO, "DSO already registered."); - _handleToDSO[handle] = pdso; - !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); - } - - void unsetDSOForHandle(DSO* pdso, void* handle) - { - !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); - safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO."); - _handleToDSO.remove(handle); - !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); - } - - void getDependencies(in ref dl_phdr_info info, ref Array!(DSO*) deps) - { - // get the entries of the .dynamic section - ElfW!"Dyn"[] dyns; - foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum]) - { - if (phdr.p_type == PT_DYNAMIC) - { - auto p = cast(ElfW!"Dyn"*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1))); - dyns = p[0 .. phdr.p_memsz / ElfW!"Dyn".sizeof]; - break; - } - } - // find the string table which contains the sonames - const(char)* strtab; - foreach (dyn; dyns) - { - if (dyn.d_tag == DT_STRTAB) - { - version (CRuntime_Musl) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else version (linux) - { - // This might change in future glibc releases (after 2.29) as dynamic sections - // are not required to be read-only on RISC-V. This was copy & pasted from MIPS - // while upstreaming RISC-V support. Otherwise MIPS is the only arch which sets - // in glibc: #define DL_RO_DYN_SECTION 1 - version (RISCV_Any) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else version (MIPS_Any) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else - strtab = cast(const(char)*)dyn.d_un.d_ptr; - } - else version (FreeBSD) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else version (NetBSD) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else version (DragonFlyBSD) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else version (Solaris) - strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate - else - static assert(0, "unimplemented"); - break; - } - } - foreach (dyn; dyns) - { - immutable tag = dyn.d_tag; - if (!(tag == DT_NEEDED || tag == DT_AUXILIARY || tag == DT_FILTER)) - continue; - - // soname of the dependency - auto name = strtab + dyn.d_un.d_val; - // get handle without loading the library - auto handle = 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) - { - auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY); - version (Solaris) { } - else if (handle !is null) .dlclose(handle); // drop reference count - return handle; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Elf program header iteration -/////////////////////////////////////////////////////////////////////////////// - -/************ - * Scan segments in Linux dl_phdr_info struct and store - * the TLS and writeable data segments in *pdso. - */ -void scanSegments(in ref dl_phdr_info info, DSO* pdso) nothrow @nogc -{ - foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum]) - { - switch (phdr.p_type) - { - case PT_LOAD: - if (phdr.p_flags & PF_W) // writeable data segment - { - auto beg = cast(void*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1))); - pdso._gcRanges.insertBack(beg[0 .. phdr.p_memsz]); - } - version (Shared) if (phdr.p_flags & PF_X) // code segment - { - auto beg = cast(void*)(info.dlpi_addr + (phdr.p_vaddr & ~(size_t.sizeof - 1))); - pdso._codeSegments.insertBack(beg[0 .. phdr.p_memsz]); - } - break; - - case PT_TLS: // TLS segment - version (GNU_EMUTLS) - { - } - else - { - safeAssert(!pdso._tlsSize, "Multiple TLS segments in image header."); - static if (OS_Have_Dlpi_Tls_Modid) - { - pdso._tlsMod = info.dlpi_tls_modid; - pdso._tlsSize = phdr.p_memsz; - } - else version (Solaris) - { - struct Rt_map - { - Link_map rt_public; - const char* rt_pathname; - c_ulong rt_padstart; - c_ulong rt_padimlen; - c_ulong rt_msize; - uint rt_flags; - uint rt_flags1; - c_ulong rt_tlsmodid; - } - - Rt_map* map; - version (Shared) - dlinfo(handleForName(info.dlpi_name), RTLD_DI_LINKMAP, &map); - else - dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); - // Until Solaris 11.4, tlsmodid for the executable is 0. - // Let it start at 1 as the rest of the code expects. - pdso._tlsMod = map.rt_tlsmodid + 1; - pdso._tlsSize = phdr.p_memsz; - } - else - { - pdso._tlsMod = 0; - pdso._tlsSize = 0; - } - } - break; - - default: - break; - } - } -} - -/************************** - * Input: - * result where the output is to be written; dl_phdr_info is an OS struct - * Returns: - * true if found, and *result is filled in - * References: - * http://linux.die.net/man/3/dl_iterate_phdr - */ -bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc -{ - version (linux) enum IterateManually = true; - else version (NetBSD) enum IterateManually = true; - else version (Solaris) enum IterateManually = true; - else enum IterateManually = false; - - static if (IterateManually) - { - static struct DG { const(void)* addr; dl_phdr_info* result; } - - extern(C) int callback(dl_phdr_info* info, size_t sz, void* arg) nothrow @nogc - { - auto p = cast(DG*)arg; - if (findSegmentForAddr(*info, p.addr)) - { - if (p.result !is null) *p.result = *info; - return 1; // break; - } - return 0; // continue iteration - } - - auto dg = DG(addr, result); - - /* OS function that walks through the list of an application's shared objects and - * calls 'callback' once for each object, until either all shared objects - * have been processed or 'callback' returns a nonzero value. - */ - return dl_iterate_phdr(&callback, &dg) != 0; - } - else version (FreeBSD) - { - return !!_rtld_addr_phdr(addr, result); - } - else version (DragonFlyBSD) - { - return !!_rtld_addr_phdr(addr, result); - } - else - static assert(0, "unimplemented"); -} - -/********************************* - * Determine if 'addr' lies within shared object 'info'. - * If so, return true and fill in 'result' with the corresponding ELF program header. - */ -bool findSegmentForAddr(in ref dl_phdr_info info, in void* addr, ElfW!"Phdr"* result=null) nothrow @nogc -{ - if (addr < cast(void*)info.dlpi_addr) // less than base address of object means quick reject - return false; - - foreach (ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum]) - { - auto beg = cast(void*)(info.dlpi_addr + phdr.p_vaddr); - if (cast(size_t)(addr - beg) < phdr.p_memsz) - { - if (result !is null) *result = phdr; - return true; - } - } - return false; -} - -version (linux) import core.sys.linux.errno : program_invocation_name; -// should be in core.sys.freebsd.stdlib -version (FreeBSD) extern(C) const(char)* getprogname() nothrow @nogc; -version (DragonFlyBSD) extern(C) const(char)* getprogname() nothrow @nogc; -version (NetBSD) extern(C) const(char)* getprogname() nothrow @nogc; -version (Solaris) extern(C) const(char)* getprogname() nothrow @nogc; - -@property const(char)* progname() nothrow @nogc -{ - version (linux) return program_invocation_name; - version (FreeBSD) return getprogname(); - version (DragonFlyBSD) return getprogname(); - version (NetBSD) return getprogname(); - version (Solaris) return getprogname(); -} - -const(char)[] dsoName(const char* dlpi_name) nothrow @nogc -{ - // the main executable doesn't have a name in its dlpi_name field - const char* p = dlpi_name[0] != 0 ? dlpi_name : progname; - return p[0 .. strlen(p)]; -} - -/************************** - * Input: - * addr an internal address of a DSO - * Returns: - * the dlopen handle for that DSO or null if addr is not within a loaded DSO - */ -version (Shared) void* handleForAddr(void* addr) nothrow @nogc -{ - Dl_info info = void; - if (dladdr(addr, &info) != 0) - return handleForName(info.dli_fname); - return null; -} - -/////////////////////////////////////////////////////////////////////////////// -// TLS module helper -/////////////////////////////////////////////////////////////////////////////// - - -/* - * Returns: the TLS memory range for a given module and the calling - * thread or null if that module has no TLS. - * - * Note: This will cause the TLS memory to be eagerly allocated. - */ -struct tls_index -{ - version (CRuntime_Glibc) - { - // For x86_64, fields are of type uint64_t, this is important for x32 - // where tls_index would otherwise have the wrong size. - // See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/dl-tls.h - version (X86_64) - { - ulong ti_module; - ulong ti_offset; - } - else - { - c_ulong ti_module; - c_ulong ti_offset; - } - } - else - { - size_t ti_module; - size_t ti_offset; - } -} - -extern(C) void* __tls_get_addr(tls_index* ti) nothrow @nogc; -extern(C) void* __ibmz_get_tls_offset(tls_index *ti) nothrow @nogc; - -/* The dynamic thread vector (DTV) pointers may point 0x8000 past the start of - * each TLS block. This is at least true for PowerPC and Mips platforms. - * See: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/dl-tls.h;h=f7cf6f96ebfb505abfd2f02be0ad0e833107c0cd;hb=HEAD#l34 - * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/dl-tls.h;h=93a6dc050cb144b9f68b96fb3199c60f5b1fcd18;hb=HEAD#l32 - * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/dl-tls.h;h=ab2d860314de94c18812bc894ff6b3f55368f20f;hb=HEAD#l32 - */ -version (X86) - enum TLS_DTV_OFFSET = 0x0; -else version (X86_64) - enum TLS_DTV_OFFSET = 0x0; -else version (ARM) - enum TLS_DTV_OFFSET = 0x0; -else version (AArch64) - enum TLS_DTV_OFFSET = 0x0; -else version (RISCV32) - enum TLS_DTV_OFFSET = 0x800; -else version (RISCV64) - enum TLS_DTV_OFFSET = 0x800; -else version (HPPA) - enum TLS_DTV_OFFSET = 0x0; -else version (SPARC) - enum TLS_DTV_OFFSET = 0x0; -else version (SPARC64) - enum TLS_DTV_OFFSET = 0x0; -else version (PPC) - enum TLS_DTV_OFFSET = 0x8000; -else version (PPC64) - enum TLS_DTV_OFFSET = 0x8000; -else version (MIPS32) - enum TLS_DTV_OFFSET = 0x8000; -else version (MIPS64) - enum TLS_DTV_OFFSET = 0x8000; -else version (IBMZ_Any) - enum TLS_DTV_OFFSET = 0x0; -else - static assert( false, "Platform not supported." ); - -void[] getTLSRange(size_t mod, size_t sz) nothrow @nogc -{ - if (mod == 0) - return null; - - version (GNU_EMUTLS) - return null; // Handled in scanTLSRanges(). - else - { - version (Solaris) - { - static if (!OS_Have_Dlpi_Tls_Modid) - mod -= 1; - } - - // base offset - auto ti = tls_index(mod, 0); - version (CRuntime_Musl) - return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; - else version (IBMZ_Any) - { - // IBM Z only provides __tls_get_offset instead of __tls_get_addr - // which returns an offset relative to the thread pointer. - auto addr = __ibmz_get_tls_offset(&ti); - addr = addr + cast(c_ulong)__builtin_thread_pointer(); - return addr[0 .. sz]; - } - else - return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; - } -} diff --git a/libphobos/libdruntime/gcc/sections/macho.d b/libphobos/libdruntime/gcc/sections/macho.d new file mode 100644 index 0000000..3ce58a5 --- /dev/null +++ b/libphobos/libdruntime/gcc/sections/macho.d @@ -0,0 +1,738 @@ +// MACHO-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.macho; + +version (OSX): + +import core.memory; +import core.stdc.stdlib; +import core.sys.darwin.dlfcn; +import core.sys.darwin.mach.dyld; +import core.sys.darwin.mach.getsect; +import core.sys.posix.pthread; +import rt.minfo; +import rt.util.container.array; +import rt.util.container.hashtab; +import gcc.sections.common; + +version (GNU_EMUTLS) + import gcc.emutls; + +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) +{ + import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries, + inheritLoadedLibraries, cleanupLoadedLibraries; + + /*** + * 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 + pragma(mangle, gcc.sections.pinLoadedLibraries.mangleof) + 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 dlopen ref for explicitly loaded libraries to pin them. + const success = .dlopen(nameForDSO(tdso._pdso), RTLD_LAZY) !is null; + safeAssert(success, "Failed to increment dlopen ref."); + (*res)[i]._addCnt = 1; // new array takes over the additional ref count + } + } + return res; + } + + pragma(mangle, gcc.sections.unpinLoadedLibraries.mangleof) + 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."); + .dlclose(handle); + } + } + pary.reset(); + .free(pary); + } + + // Called before TLS ctors are ran, copy over the loaded libraries + // of the parent thread. + pragma(mangle, gcc.sections.inheritLoadedLibraries.mangleof) + 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 dlopen refs. + pragma(mangle, gcc.sections.cleanupLoadedLibraries.mangleof) + 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) + .dlclose(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 pthread_mutex_t _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. +/////////////////////////////////////////////////////////////////////////////// + +struct MachHeader +{ + const(mach_header)* header; // the mach header of the image + intptr_t slide; // virtural memory address slide amount +} + +/**** + * 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)); + + MachHeader header = void; + const headerFound = findImageHeaderForAddr(data._slot, header); + safeAssert(headerFound, "Failed to find image header."); + + scanSegments(header, pdso); + + version (Shared) + { + auto handle = handleForAddr(data._slot); + + getDependencies(header, 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); + } + + extern(C) void* rt_loadLibrary(const char* name) + { + immutable save = _rtLoading; + _rtLoading = true; + scope (exit) _rtLoading = save; + + auto handle = .dlopen(name, RTLD_LAZY); + if (handle is null) return null; + + // if it's a D library + if (auto pdso = dsoForHandle(handle)) + incThreadRef(pdso, true); + return handle; + } + + extern(C) int rt_unloadLibrary(void* handle) + { + if (handle is null) return false; + + immutable save = _rtLoading; + _rtLoading = true; + scope (exit) _rtLoading = save; + + // if it's a D library + if (auto pdso = dsoForHandle(handle)) + decThreadRef(pdso, true); + return .dlclose(handle) == 0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// helper functions +/////////////////////////////////////////////////////////////////////////////// + +void initLocks() nothrow @nogc +{ + version (Shared) + !pthread_mutex_init(&_handleToDSOMutex, null) || assert(0); +} + +void finiLocks() nothrow @nogc +{ + version (Shared) + !pthread_mutex_destroy(&_handleToDSOMutex) || assert(0); +} + +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(in DSO* pdso) + { + Dl_info info = void; + const success = dladdr(pdso._slot, &info) != 0; + safeAssert(success, "Failed to get DSO info."); + return info.dli_fname; + } + + DSO* dsoForHandle(void* handle) + { + DSO* pdso; + !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); + if (auto ppdso = handle in _handleToDSO) + pdso = *ppdso; + !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); + return pdso; + } + + void setDSOForHandle(DSO* pdso, void* handle) + { + !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); + safeAssert(handle !in _handleToDSO, "DSO already registered."); + _handleToDSO[handle] = pdso; + !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); + } + + void unsetDSOForHandle(DSO* pdso, void* handle) + { + !pthread_mutex_lock(&_handleToDSOMutex) || assert(0); + safeAssert(_handleToDSO[handle] == pdso, "Handle doesn't match registered DSO."); + _handleToDSO.remove(handle); + !pthread_mutex_unlock(&_handleToDSOMutex) || assert(0); + } + + void getDependencies(in MachHeader info, ref Array!(DSO*) deps) + { + // FIXME: Not implemented yet. + } + + void* handleForName(const char* name) + { + auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY); + if (handle !is null) .dlclose(handle); // drop reference count + return handle; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Mach-O program header iteration +/////////////////////////////////////////////////////////////////////////////// + +/************ + * Scan segments in the image header and store + * the writeable data segments in *pdso. + */ + +void scanSegments(in MachHeader info, DSO* pdso) +{ + foreach (e; dataSegs) + { + auto sect = getSection(info.header, info.slide, e.seg.ptr, e.sect.ptr); + if (sect != null) + pdso._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]); + } + + version (Shared) + { + void[] text = getSection(info.header, info.slide, "__TEXT", "__text"); + if (!text) + assert(0, "Failed to get text section."); + pdso._codeSegments.insertBack(text); + } +} + +/************************** + * Input: + * result where the output is to be written + * Returns: + * true if found, and *result is filled in + */ + +bool findImageHeaderForAddr(in void* addr, out MachHeader result) +{ + Dl_info info; + if (dladdr(addr, &info) == 0) + return false; + + foreach (i; 0 .. _dyld_image_count()) + { + if (info.dli_fbase == _dyld_get_image_header(i)) + { + result.header = cast(const(mach_header)*)info.dli_fbase; + result.slide = _dyld_get_image_vmaddr_slide(i); + return true; + } + } + return false; +} + +/************************** + * Input: + * addr an internal address of a DSO + * Returns: + * the dlopen handle for that DSO or null if addr is not within a loaded DSO + */ +version (Shared) void* handleForAddr(void* addr) nothrow @nogc +{ + Dl_info info = void; + if (dladdr(addr, &info) != 0) + return handleForName(info.dli_fname); + return null; +} + +struct SegRef +{ + string seg; + string sect; +} + +static immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA}, + {SEG_DATA, SECT_BSS}, + {SEG_DATA, SECT_COMMON}]; + +/** + * Returns the section for the named section in the named segment + * for the mach_header pointer passed, or null if not found. + */ +ubyte[] getSection(in mach_header* header, intptr_t slide, + in char* segmentName, in char* sectionName) +{ + version (D_LP64) + { + assert(header.magic == MH_MAGIC_64); + auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header, + segmentName, + sectionName); + } + else + { + assert(header.magic == MH_MAGIC); + auto sect = getsectbynamefromheader(header, + segmentName, + sectionName); + } + + if (sect !is null && sect.size > 0) + return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size]; + return null; +} diff --git a/libphobos/libdruntime/gcc/sections/osx.d b/libphobos/libdruntime/gcc/sections/osx.d deleted file mode 100644 index 3e3db70..0000000 --- a/libphobos/libdruntime/gcc/sections/osx.d +++ /dev/null @@ -1,284 +0,0 @@ -// OSX-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.osx; - -version (OSX): - -// debug = PRINTF; -import core.stdc.stdio; -import core.stdc.string, core.stdc.stdlib; -import core.sys.posix.pthread; -import core.sys.darwin.mach.dyld; -import core.sys.darwin.mach.getsect; -import rt.deh, rt.minfo; -import rt.util.container.array; - -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[]; - } - - @property immutable(FuncTable)[] ehTables() const nothrow @nogc - { - return _ehTables[]; - } - -private: - immutable(FuncTable)[] _ehTables; - ModuleGroup _moduleGroup; - Array!(void[]) _gcRanges; - immutable(void)[][2] _tlsImage; -} - -/**** - * 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 -{ - pthread_key_create(&_tlsKey, null); - _dyld_register_func_for_add_image(§ions_osx_onAddImage); - _isRuntimeInitialized = true; -} - -/*** - * Gets called on program shutdown just after GC is terminated. - */ -void finiSections() nothrow @nogc -{ - _sections._gcRanges.reset(); - pthread_key_delete(_tlsKey); - _isRuntimeInitialized = false; -} - -void[]* initTLSRanges() nothrow @nogc -{ - return &getTLSBlock(); -} - -void finiTLSRanges(void[]* rng) nothrow @nogc -{ - .free(rng.ptr); - .free(rng); -} - -void scanTLSRanges(void[]* rng, scope void delegate(void* pbeg, void* pend) nothrow dg) nothrow -{ - dg(rng.ptr, rng.ptr + rng.length); -} - -// NOTE: The Mach-O object file format does not allow for thread local -// storage declarations. So instead we roll our own by putting tls -// into the __tls_data and the __tlscoal_nt sections. -// -// This function is called by the code emitted by the compiler. It -// is expected to translate an address into the TLS static data to -// the corresponding address in the TLS dynamic per-thread data. - -// NB: the compiler mangles this function as '___tls_get_addr' even though it is extern(D) -extern(D) void* ___tls_get_addr( void* p ) -{ - immutable off = tlsOffset(p); - auto tls = getTLSBlockAlloc(); - assert(off < tls.length); - return tls.ptr + off; -} - -private: - -__gshared pthread_key_t _tlsKey; - -size_t tlsOffset(void* p) -in -{ - assert(_sections._tlsImage[0].ptr !is null || - _sections._tlsImage[1].ptr !is null); -} -body -{ - // NOTE: p is an address in the TLS static data emitted by the - // compiler. If it isn't, something is disastrously wrong. - immutable off0 = cast(size_t)(p - _sections._tlsImage[0].ptr); - if (off0 < _sections._tlsImage[0].length) - { - return off0; - } - immutable off1 = cast(size_t)(p - _sections._tlsImage[1].ptr); - if (off1 < _sections._tlsImage[1].length) - { - size_t sz = (_sections._tlsImage[0].length + 15) & ~cast(size_t)15; - return sz + off1; - } - assert(0); -} - -ref void[] getTLSBlock() nothrow @nogc -{ - auto pary = cast(void[]*)pthread_getspecific(_tlsKey); - if (pary is null) - { - pary = cast(void[]*).calloc(1, (void[]).sizeof); - if (pthread_setspecific(_tlsKey, pary) != 0) - { - import core.stdc.stdio; - perror("pthread_setspecific failed with"); - assert(0); - } - } - return *pary; -} - -ref void[] getTLSBlockAlloc() -{ - auto pary = &getTLSBlock(); - if (!pary.length) - { - auto imgs = _sections._tlsImage; - immutable sz0 = (imgs[0].length + 15) & ~cast(size_t)15; - immutable sz2 = sz0 + imgs[1].length; - auto p = .malloc(sz2); - memcpy(p, imgs[0].ptr, imgs[0].length); - memcpy(p + sz0, imgs[1].ptr, imgs[1].length); - *pary = p[0 .. sz2]; - } - return *pary; -} - -__gshared SectionGroup _sections; - -extern (C) void sections_osx_onAddImage(in mach_header* h, intptr_t slide) -{ - foreach (e; dataSegs) - { - auto sect = getSection(h, slide, e.seg.ptr, e.sect.ptr); - if (sect != null) - _sections._gcRanges.insertBack((cast(void*)sect.ptr)[0 .. sect.length]); - } - - auto minfosect = getSection(h, slide, "__DATA", "__minfodata"); - if (minfosect != null) - { - // no support for multiple images yet - // take the sections from the last static image which is the executable - if (_isRuntimeInitialized) - { - fprintf(stderr, "Loading shared libraries isn't yet supported on OSX.\n"); - return; - } - else if (_sections.modules.ptr !is null) - { - fprintf(stderr, "Shared libraries are not yet supported on OSX.\n"); - } - - debug(PRINTF) printf(" minfodata\n"); - auto p = cast(immutable(ModuleInfo*)*)minfosect.ptr; - immutable len = minfosect.length / (*p).sizeof; - - _sections._moduleGroup = ModuleGroup(p[0 .. len]); - } - - auto ehsect = getSection(h, slide, "__DATA", "__deh_eh"); - if (ehsect != null) - { - debug(PRINTF) printf(" deh_eh\n"); - auto p = cast(immutable(FuncTable)*)ehsect.ptr; - immutable len = ehsect.length / (*p).sizeof; - - _sections._ehTables = p[0 .. len]; - } - - auto tlssect = getSection(h, slide, "__DATA", "__tls_data"); - if (tlssect != null) - { - debug(PRINTF) printf(" tls_data %p %p\n", tlssect.ptr, tlssect.ptr + tlssect.length); - _sections._tlsImage[0] = (cast(immutable(void)*)tlssect.ptr)[0 .. tlssect.length]; - } - - auto tlssect2 = getSection(h, slide, "__DATA", "__tlscoal_nt"); - if (tlssect2 != null) - { - debug(PRINTF) printf(" tlscoal_nt %p %p\n", tlssect2.ptr, tlssect2.ptr + tlssect2.length); - _sections._tlsImage[1] = (cast(immutable(void)*)tlssect2.ptr)[0 .. tlssect2.length]; - } -} - -struct SegRef -{ - string seg; - string sect; -} - -static immutable SegRef[] dataSegs = [{SEG_DATA, SECT_DATA}, - {SEG_DATA, SECT_BSS}, - {SEG_DATA, SECT_COMMON}]; - -ubyte[] getSection(in mach_header* header, intptr_t slide, - in char* segmentName, in char* sectionName) -{ - version (X86) - { - assert(header.magic == MH_MAGIC); - auto sect = getsectbynamefromheader(header, - segmentName, - sectionName); - } - else version (X86_64) - { - assert(header.magic == MH_MAGIC_64); - auto sect = getsectbynamefromheader_64(cast(mach_header_64*)header, - segmentName, - sectionName); - } - else - static assert(0, "unimplemented"); - - if (sect !is null && sect.size > 0) - return (cast(ubyte*)sect.addr + slide)[0 .. cast(size_t)sect.size]; - return null; -} diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d index fdaf039..4c2b542 100644 --- a/libphobos/libdruntime/gcc/sections/package.d +++ b/libphobos/libdruntime/gcc/sections/package.d @@ -22,27 +22,30 @@ module gcc.sections; -version (CRuntime_Glibc) - public import gcc.sections.elf_shared; -else version (CRuntime_Musl) - public import gcc.sections.elf_shared; -else version (CRuntime_UClibc) - public import gcc.sections.elf_shared; -else version (FreeBSD) - public import gcc.sections.elf_shared; -else version (NetBSD) - public import gcc.sections.elf_shared; -else version (DragonFlyBSD) - public import gcc.sections.elf_shared; -else version (Solaris) - public import gcc.sections.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 (CRuntime_Bionic) - public import gcc.sections.android; +version (CRuntime_Glibc) version = SectionsElf; +version (CRuntime_Musl) version = SectionsElf; +version (CRuntime_UClibc) version = SectionsElf; +version (FreeBSD) version = SectionsElf; +version (NetBSD) version = SectionsElf; +version (DragonFlyBSD) version = SectionsElf; +version (Solaris) version = SectionsElf; +version (OSX) version = SectionsMacho; +version (Windows) version = SectionsPeCoff; + +version (SectionsElf) + public import gcc.sections.elf; +else version (SectionsMacho) + public import gcc.sections.macho; +else version (SectionsPeCoff) + public import gcc.sections.pecoff; else static assert(0, "unimplemented"); + +version (Shared) +{ + // interface for core.thread to inherit loaded libraries + void* pinLoadedLibraries() nothrow @nogc; + void unpinLoadedLibraries(void* p) nothrow @nogc; + void inheritLoadedLibraries(void* p) nothrow @nogc; + void cleanupLoadedLibraries() nothrow @nogc; +} diff --git a/libphobos/libdruntime/gcc/sections/pecoff.d b/libphobos/libdruntime/gcc/sections/pecoff.d new file mode 100644 index 0000000..ed0340e --- /dev/null +++ b/libphobos/libdruntime/gcc/sections/pecoff.d @@ -0,0 +1,826 @@ +// 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; +import gcc.sections.common; + +version (GNU_EMUTLS) + import gcc.emutls; + +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) +{ + import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries, + inheritLoadedLibraries, cleanupLoadedLibraries; + + /*** + * 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 + pragma(mangle, gcc.sections.pinLoadedLibraries.mangleof) + 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; + } + + pragma(mangle, gcc.sections.unpinLoadedLibraries.mangleof) + 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. + pragma(mangle, gcc.sections.inheritLoadedLibraries.mangleof) + 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. + pragma(mangle, gcc.sections.cleanupLoadedLibraries.mangleof) + 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 b355dfc..0000000 --- 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 deleted file mode 100644 index 357940b..0000000 --- a/libphobos/libdruntime/gcc/sections/win64.d +++ /dev/null @@ -1,321 +0,0 @@ -// Win64-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.win64; - -version (CRuntime_Microsoft): - -// debug = PRINTF; -debug(PRINTF) import core.stdc.stdio; -import core.stdc.stdlib : malloc, free; -import rt.deh, rt.minfo; - -struct SectionGroup -{ - static int opApply(scope int delegate(ref SectionGroup) dg) - { - return dg(_sections); - } - - static int opApplyReverse(scope int delegate(ref SectionGroup) dg) - { - return dg(_sections); - } - - @property immutable(ModuleInfo*)[] modules() const nothrow @nogc - { - return _moduleGroup.modules; - } - - @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc - { - return _moduleGroup; - } - - 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[]; - } - -private: - ModuleGroup _moduleGroup; - void[][] _gcRanges; -} - -shared(bool) conservative; - -void initSections() nothrow @nogc -{ - _sections._moduleGroup = ModuleGroup(getModuleInfos()); - - // the ".data" image section includes both object file sections ".data" and ".bss" - void[] dataSection = findImageSection(".data"); - debug(PRINTF) printf("found .data section: [%p,+%llx]\n", dataSection.ptr, - cast(ulong)dataSection.length); - - import rt.sections; - conservative = !scanDataSegPrecisely(); - - if (conservative) - { - _sections._gcRanges = (cast(void[]*) malloc((void[]).sizeof))[0..1]; - _sections._gcRanges[0] = dataSection; - } - else - { - size_t count = &_DP_end - &_DP_beg; - auto ranges = cast(void[]*) malloc(count * (void[]).sizeof); - size_t r = 0; - void* prev = null; - for (size_t i = 0; i < count; i++) - { - auto off = (&_DP_beg)[i]; - if (off == 0) // skip zero entries added by incremental linking - continue; // assumes there is no D-pointer at the very beginning of .data - void* addr = dataSection.ptr + off; - debug(PRINTF) printf(" scan %p\n", addr); - // combine consecutive pointers into single range - 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(cast(void*)_sections.modules.ptr); - .free(_sections._gcRanges.ptr); -} - -void[] initTLSRanges() nothrow @nogc -{ - void* pbeg; - void* pend; - // with VS2017 15.3.1, the linker no longer puts TLS segments into a - // separate image section. That way _tls_start and _tls_end no - // longer generate offsets into .tls, but DATA. - // Use the TEB entry to find the start of TLS instead and read the - // length from the TLS directory - version (D_InlineAsm_X86) - { - asm @nogc nothrow - { - mov EAX, _tls_index; - mov ECX, FS:[0x2C]; // _tls_array - mov EAX, [ECX+4*EAX]; - mov pbeg, EAX; - add EAX, [_tls_used+4]; // end - sub EAX, [_tls_used+0]; // start - mov pend, EAX; - } - } - else version (D_InlineAsm_X86_64) - { - asm @nogc nothrow - { - xor RAX, RAX; - mov EAX, _tls_index; - mov RCX, 0x58; - mov RCX, GS:[RCX]; // _tls_array (immediate value causes fixup) - mov RAX, [RCX+8*RAX]; - mov pbeg, RAX; - add RAX, [_tls_used+8]; // end - sub RAX, [_tls_used+0]; // start - mov pend, RAX; - } - } - else - static assert(false, "Architecture not supported."); - - 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 = &_TP_beg; p < &_TP_end; ) - { - uint beg = *p++; - uint end = beg + cast(uint)((void*).sizeof); - while (p < &_TP_end && *p == end) - { - end += (void*).sizeof; - p++; - } - dg(rng.ptr + beg, rng.ptr + end); - } - } -} - -private: -__gshared SectionGroup _sections; - -extern(C) -{ - extern __gshared void* _minfo_beg; - extern __gshared void* _minfo_end; -} - -immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc -out (result) -{ - foreach (m; result) - assert(m !is null); -} -body -{ - auto m = (cast(immutable(ModuleInfo*)*)&_minfo_beg)[1 .. &_minfo_end - &_minfo_beg]; - /* Because of alignment inserted by the linker, various null pointers - * are there. We need to filter them out. - */ - auto p = m.ptr; - auto pend = m.ptr + m.length; - - // count non-null pointers - size_t cnt; - for (; p < pend; ++p) - { - if (*p !is null) ++cnt; - } - - auto result = (cast(immutable(ModuleInfo)**).malloc(cnt * size_t.sizeof))[0 .. cnt]; - - p = m.ptr; - cnt = 0; - for (; p < pend; ++p) - if (*p !is null) result[cnt++] = *p; - - return cast(immutable)result; -} - -extern(C) -{ - /* Symbols created by the compiler/linker and inserted into the - * object file that 'bracket' sections. - */ - extern __gshared - { - void* __ImageBase; - - void* _deh_beg; - void* _deh_end; - - uint _DP_beg; - uint _DP_end; - uint _TP_beg; - uint _TP_end; - - void*[2] _tls_used; // start, end - int _tls_index; - } -} - -///////////////////////////////////////////////////////////////////// - -enum IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ - -struct IMAGE_DOS_HEADER // DOS .EXE header -{ - ushort e_magic; // Magic number - ushort[29] e_res2; // Reserved ushorts - int e_lfanew; // File address of new exe header -} - -struct IMAGE_FILE_HEADER -{ - ushort Machine; - ushort NumberOfSections; - uint TimeDateStamp; - uint PointerToSymbolTable; - uint NumberOfSymbols; - ushort SizeOfOptionalHeader; - ushort Characteristics; -} - -struct IMAGE_NT_HEADERS -{ - uint Signature; - IMAGE_FILE_HEADER FileHeader; - // optional header follows -} - -struct IMAGE_SECTION_HEADER -{ - char[8] Name = 0; - union { - uint PhysicalAddress; - uint VirtualSize; - } - uint VirtualAddress; - uint SizeOfRawData; - uint PointerToRawData; - uint PointerToRelocations; - uint PointerToLinenumbers; - ushort NumberOfRelocations; - ushort NumberOfLinenumbers; - uint Characteristics; -} - -bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc -{ - if (name[] != section.Name[0 .. name.length]) - return false; - return name.length == 8 || section.Name[name.length] == 0; -} - -void[] findImageSection(string name) nothrow @nogc -{ - if (name.length > 8) // section name from string table not supported - return null; - IMAGE_DOS_HEADER* doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase; - if (doshdr.e_magic != IMAGE_DOS_SIGNATURE) - return null; - - auto nthdr = cast(IMAGE_NT_HEADERS*)(cast(void*)doshdr + doshdr.e_lfanew); - auto sections = cast(IMAGE_SECTION_HEADER*)(cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader); - for (ushort i = 0; i < nthdr.FileHeader.NumberOfSections; i++) - if (compareSectionName (sections[i], name)) - return (cast(void*)&__ImageBase + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize]; - - return null; -} -- cgit v1.1 From d118ec221dd5fc829d2170c257e10b8159dce274 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Thu, 8 Apr 2021 18:31:04 +0200 Subject: libphobos: Build runtime library with -ffunction-sections -fdata-sections Tests for `-ffunction-sections -fdata-sections' and sets SECTION_FLAGS accordingly. If there is no warning when using it, take advantage of the smaller executables that can be had with `--gc-sections'. libphobos/ChangeLog: * Makefile.in: Regenerate. * configure: Regenerate. * configure.ac: Call DRUNTIME_SECTION_FLAGS. * libdruntime/Makefile.am: Add SECTION_FLAGS to AM_DFLAGS. * libdruntime/Makefile.in: Regenerate. * m4/druntime.m4 (DRUNTIME_SECTION_FLAGS): New macro. * src/Makefile.am: Add SECTION_FLAGS to AM_DFLAGS. * src/Makefile.in: Regenerate. * testsuite/Makefile.in: Regenerate. --- libphobos/Makefile.in | 1 + libphobos/configure | 47 +++++++++++++++++++++++++++++++++++++-- libphobos/configure.ac | 1 + libphobos/libdruntime/Makefile.am | 2 +- libphobos/libdruntime/Makefile.in | 3 ++- libphobos/m4/druntime.m4 | 19 ++++++++++++++++ libphobos/src/Makefile.am | 2 +- libphobos/src/Makefile.in | 3 ++- libphobos/testsuite/Makefile.in | 1 + 9 files changed, 73 insertions(+), 6 deletions(-) (limited to 'libphobos') diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in index eab1268..a8f7e16 100644 --- a/libphobos/Makefile.in +++ b/libphobos/Makefile.in @@ -271,6 +271,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SECTION_FLAGS = @SECTION_FLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/libphobos/configure b/libphobos/configure index 59ca64a..fe7cd9c 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -700,6 +700,7 @@ DRUNTIME_CPU_ARM_FALSE DRUNTIME_CPU_ARM_TRUE DRUNTIME_CPU_AARCH64_FALSE DRUNTIME_CPU_AARCH64_TRUE +SECTION_FLAGS libphobos_srcdir libphobos_builddir get_gcc_base_ver @@ -11749,7 +11750,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11752 "configure" +#line 11753 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11855,7 +11856,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11858 "configure" +#line 11859 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14085,6 +14086,48 @@ fi fi + + + gdc_save_DFLAGS=$GDCFLAGS + GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS" + + ac_ext=d +ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5' +ac_link='$GDC -o conftest$ac_exeext $GDCFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=yes + + GDCFLAGS="$GDCFLAGS -g -Werror -ffunction-sections -fdata-sections" + cat > conftest.$ac_ext <<_ACEOF +module mod; +int foo; void bar() { } + +extern(C) int main() { + return 0; +} +_ACEOF +if ac_fn_d_try_compile "$LINENO"; then : + ac_fdsections=yes +else + ac_fdsections=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test "x$ac_fdsections" = "xyes"; then + SECTION_FLAGS='-ffunction-sections -fdata-sections' + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_fdsections" >&5 +$as_echo "$ac_fdsections" >&6; } + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + GDCFLAGS=$gdc_save_DFLAGS + + + + druntime_target_cpu_parsed="" case "$target_cpu" in aarch64*) diff --git a/libphobos/configure.ac b/libphobos/configure.ac index 248d0eb..3b5a830 100644 --- a/libphobos/configure.ac +++ b/libphobos/configure.ac @@ -137,6 +137,7 @@ GCC_BASE_VER DRUNTIME_CONFIGURE DRUNTIME_MULTILIB DRUNTIME_WERROR +DRUNTIME_SECTION_FLAGS DRUNTIME_CPU_SOURCES DRUNTIME_OS_SOURCES DRUNTIME_OS_THREAD_MODEL diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 74a0f00..02a68b1 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -24,7 +24,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) -I . # D flags for compilation AM_DFLAGS= \ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \ - $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS) + $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS) # Flags for other kinds of sources AM_CFLAGS=$(CET_FLAGS) diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 63b2133..853a7fc 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -635,6 +635,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SECTION_FLAGS = @SECTION_FLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -727,7 +728,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) -I . # D flags for compilation AM_DFLAGS = \ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \ - $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS) + $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS) # Flags for other kinds of sources diff --git a/libphobos/m4/druntime.m4 b/libphobos/m4/druntime.m4 index 7221712..2a7a689 100644 --- a/libphobos/m4/druntime.m4 +++ b/libphobos/m4/druntime.m4 @@ -116,3 +116,22 @@ AC_DEFUN([DRUNTIME_INSTALL_DIRECTORIES], gdc_include_dir='$(libdir)/gcc/${target_alias}/${gcc_version}/include/d' AC_SUBST(gdc_include_dir) ]) + +# DRUNTIME_SECTION_FLAGS +# ---------------------- +# Check for -ffunction-sections nad -fdata-sections. +AC_DEFUN([DRUNTIME_SECTION_FLAGS], +[ + WITH_LOCAL_DRUNTIME([ + AC_LANG_PUSH([D]) + GDCFLAGS="$GDCFLAGS -g -Werror -ffunction-sections -fdata-sections" + AC_TRY_COMPILE([int foo; void bar() { }],[return 0;], + [ac_fdsections=yes], [ac_fdsections=no]) + if test "x$ac_fdsections" = "xyes"; then + SECTION_FLAGS='-ffunction-sections -fdata-sections' + fi + AC_MSG_RESULT($ac_fdsections) + AC_LANG_POP([D]) + ], [-nophoboslib]) + AC_SUBST(SECTION_FLAGS) +]) diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am index 2dedc74..f97ddcc 100644 --- a/libphobos/src/Makefile.am +++ b/libphobos/src/Makefile.am @@ -25,7 +25,7 @@ D_EXTRA_DFLAGS=-nostdinc -I $(srcdir) \ # D flags for compilation AM_DFLAGS= \ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \ - $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS) + $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS) # Flags for other kinds of sources AM_CFLAGS=$(CET_FLAGS) diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in index 9e410e5..4f76e10 100644 --- a/libphobos/src/Makefile.in +++ b/libphobos/src/Makefile.in @@ -388,6 +388,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SECTION_FLAGS = @SECTION_FLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -482,7 +483,7 @@ D_EXTRA_DFLAGS = -nostdinc -I $(srcdir) \ # D flags for compilation AM_DFLAGS = \ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \ - $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(CET_DFLAGS) + $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_DFLAGS) # Flags for other kinds of sources diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in index 51eb4ef..8855480 100644 --- a/libphobos/testsuite/Makefile.in +++ b/libphobos/testsuite/Makefile.in @@ -215,6 +215,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SECTION_FLAGS = @SECTION_FLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ -- cgit v1.1 From 1d54b13841774aa40f5d0a5ab87b19e7e1276d42 Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Sun, 11 Apr 2021 00:16:24 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 807664c..b4431a4 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,55 @@ +2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org> + + * Makefile.in: Regenerate. + * configure: Regenerate. + * configure.ac: Call DRUNTIME_SECTION_FLAGS. + * libdruntime/Makefile.am: Add SECTION_FLAGS to AM_DFLAGS. + * libdruntime/Makefile.in: Regenerate. + * m4/druntime.m4 (DRUNTIME_SECTION_FLAGS): New macro. + * src/Makefile.am: Add SECTION_FLAGS to AM_DFLAGS. + * src/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Removed + gcc/sections/android.d, elf_shared.d, osx.d, win32.d, and win64.d. + Added gcc/sections/common.d, elf.d macho.d, and pecoff.d. + * libdruntime/Makefile.in: Regenerate. + * libdruntime/core/thread/osthread.d: Update externDFunc FQDN names to + use platform independant section function names. + * libdruntime/gcc/sections/elf_shared.d: Renamed to... + * libdruntime/gcc/sections/elf.d: ...this. Mangle functions for + core.thread interface as if they come from the gcc.sections module. + * libdruntime/gcc/sections/package.d: Update public imports, declare + functions for core.thread interface. + * libdruntime/gcc/sections/android.d: Removed. + * libdruntime/gcc/sections/osx.d: Removed. + * libdruntime/gcc/sections/win32.d: Removed. + * libdruntime/gcc/sections/win64.d: Removed. + * libdruntime/gcc/sections/common.d: New file. + * libdruntime/gcc/sections/macho.d: New file. + * libdruntime/gcc/sections/pecoff.d: New file. + +2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org> + + * testsuite/libphobos.druntime/druntime.exp: Compile all tests with + -static-libphobos. + * testsuite/libphobos.phobos/phobos.exp: Likewise. + +2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org> + + * testsuite/libphobos.druntime/druntime.exp: Remove + is-effective-target static. + * testsuite/libphobos.phobos/phobos.exp: Likewise. + +2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/99812 + * testsuite/libphobos.druntime_shared/druntime_shared.exp: Re-add + -fno-moduleinfo flag to dg-runtest. + * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise. + 2021-04-08 Iain Buclaw <ibuclaw@gdcproject.org> * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add -- cgit v1.1 From d86e60855f05a0e493f8362c12bfd40d5432d337 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon, 19 Apr 2021 14:23:00 +0200 Subject: libphobos: Add section support code for OpenBSD (PR99691) libphobos/ChangeLog: PR d/99691 * configure: Regenerate. * libdruntime/config/common/threadasm.S: Add __OpenBSD__. * libdruntime/gcc/backtrace.d: Import core.sys.openbsd.dlfcn on OpenBSD platforms. * libdruntime/gcc/sections/elf.d (SharedElf): Define on OpenBSD. (linkMapForHandle): Implement for OpenBSD. (exeLinkMap): Remove. (getDependencies): Adjust dlpi_addr on OpenBSD. (handleForName): Implement for OpenBSD. (IterateManually): Define on OpenBSD. * libdruntime/gcc/sections/package.d (SectionsElf): Define on OpenBSD. * m4/druntime/libraries.m4 (DRUNTIME_LIBRARIES_ATOMIC): Test for enable_libatomic. (DRUNTIME_LIBRARIES_BACKTRACE): Test for enable_libbacktrace. --- libphobos/configure | 4 +- libphobos/libdruntime/config/common/threadasm.S | 2 +- libphobos/libdruntime/gcc/backtrace.d | 4 +- libphobos/libdruntime/gcc/sections/elf.d | 54 ++++++++++++++++++------- libphobos/libdruntime/gcc/sections/package.d | 1 + libphobos/m4/druntime/libraries.m4 | 4 +- 6 files changed, 48 insertions(+), 21 deletions(-) (limited to 'libphobos') diff --git a/libphobos/configure b/libphobos/configure index fe7cd9c..2c0f57c 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -14917,7 +14917,7 @@ fi DCFG_HAVE_LIBATOMIC=false LIBATOMIC= - if test "x$with_libatomic" != "xno"; then : + if test "x$enable_libatomic" != "xno" && test "x$with_libatomic" != "xno"; then : DCFG_HAVE_LIBATOMIC=true LIBATOMIC=../../libatomic/libatomic_convenience.la @@ -14953,7 +14953,7 @@ if test "${with_libbacktrace+set}" = set; then : fi - if test "x$with_libbacktrace" != "xno"; then : + if test "x$enable_libbacktrace" != "xno" && test "x$with_libbacktrace" != "xno"; then : LIBBACKTRACE=../../libbacktrace/libbacktrace.la diff --git a/libphobos/libdruntime/config/common/threadasm.S b/libphobos/libdruntime/config/common/threadasm.S index 1e9bc76..3546217 100644 --- a/libphobos/libdruntime/config/common/threadasm.S +++ b/libphobos/libdruntime/config/common/threadasm.S @@ -22,7 +22,7 @@ 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/>. */ -#if (__linux__ || __FreeBSD__ || __NetBSD__ || __DragonFly__) && __ELF__ +#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__) && __ELF__ /* * Mark the resulting object file as not requiring execution permissions on * stack memory. The absence of this section would mark the whole resulting diff --git a/libphobos/libdruntime/gcc/backtrace.d b/libphobos/libdruntime/gcc/backtrace.d index 45dd011..8f5582d 100644 --- a/libphobos/libdruntime/gcc/backtrace.d +++ b/libphobos/libdruntime/gcc/backtrace.d @@ -424,8 +424,10 @@ private: import core.sys.freebsd.dlfcn; else version (NetBSD) import core.sys.netbsd.dlfcn; + else version (OpenBSD) + import core.sys.openbsd.dlfcn; else version (Solaris) - import core.sys.netbsd.dlfcn; + import core.sys.solaris.dlfcn; else version (Posix) import core.sys.posix.dlfcn; diff --git a/libphobos/libdruntime/gcc/sections/elf.d b/libphobos/libdruntime/gcc/sections/elf.d index 8450aec..3480fb9 100644 --- a/libphobos/libdruntime/gcc/sections/elf.d +++ b/libphobos/libdruntime/gcc/sections/elf.d @@ -33,6 +33,7 @@ version (CRuntime_Glibc) enum SharedELF = true; else version (CRuntime_Musl) enum SharedELF = true; else version (FreeBSD) enum SharedELF = true; else version (NetBSD) enum SharedELF = true; +else version (OpenBSD) enum SharedELF = true; else version (DragonFlyBSD) enum SharedELF = true; else version (CRuntime_UClibc) enum SharedELF = true; else version (Solaris) enum SharedELF = true; @@ -62,6 +63,12 @@ else version (NetBSD) import core.sys.netbsd.sys.elf; import core.sys.netbsd.sys.link_elf; } +else version (OpenBSD) +{ + import core.sys.openbsd.dlfcn; + import core.sys.openbsd.sys.elf; + import core.sys.openbsd.sys.link_elf; +} else version (DragonFlyBSD) { import core.sys.dragonflybsd.dlfcn; @@ -688,20 +695,22 @@ version (Shared) @nogc nothrow: link_map* linkMapForHandle(void* handle) { - link_map* map; - const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0; - safeAssert(success, "Failed to get DSO info."); - return map; + static if (__traits(compiles, RTLD_DI_LINKMAP)) + { + link_map* map; + const success = dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0; + safeAssert(success, "Failed to get DSO info."); + return map; + } + else version (OpenBSD) + { + safeAssert(handle !is null, "Failed to get DSO info."); + return cast(link_map*)handle; + } + else + static assert(0, "unimplemented"); } - link_map* exeLinkMap(link_map* map) - { - safeAssert(map !is null, "Invalid link_map."); - while (map.l_prev !is null) - map = map.l_prev; - return map; - } - DSO* dsoForHandle(void* handle) { DSO* pdso; @@ -766,6 +775,8 @@ version (Shared) strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate else version (NetBSD) strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate + else version (OpenBSD) + strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate else version (DragonFlyBSD) strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate else version (Solaris) @@ -795,9 +806,21 @@ version (Shared) void* handleForName(const char* name) { - auto handle = .dlopen(name, RTLD_NOLOAD | RTLD_LAZY); - version (Solaris) { } - else if (handle !is null) .dlclose(handle); // drop reference count + version (Solaris) enum refCounted = false; + else version (OpenBSD) enum refCounted = false; + else enum refCounted = true; + + static if (__traits(compiles, RTLD_NOLOAD)) + enum flags = (RTLD_NOLOAD | RTLD_LAZY); + else + enum flags = RTLD_LAZY; + + auto handle = .dlopen(name, flags); + static if (refCounted) + { + if (handle !is null) + .dlclose(handle); // drop reference count + } return handle; } } @@ -891,6 +914,7 @@ bool findDSOInfoForAddr(in void* addr, dl_phdr_info* result=null) nothrow @nogc { version (linux) enum IterateManually = true; else version (NetBSD) enum IterateManually = true; + else version (OpenBSD) enum IterateManually = true; else version (Solaris) enum IterateManually = true; else enum IterateManually = false; diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d index 4c2b542..1e887cd 100644 --- a/libphobos/libdruntime/gcc/sections/package.d +++ b/libphobos/libdruntime/gcc/sections/package.d @@ -27,6 +27,7 @@ version (CRuntime_Musl) version = SectionsElf; version (CRuntime_UClibc) version = SectionsElf; version (FreeBSD) version = SectionsElf; version (NetBSD) version = SectionsElf; +version (OpenBSD) version = SectionsElf; version (DragonFlyBSD) version = SectionsElf; version (Solaris) version = SectionsElf; version (OSX) version = SectionsMacho; diff --git a/libphobos/m4/druntime/libraries.m4 b/libphobos/m4/druntime/libraries.m4 index 743d3e3..45a56f6 100644 --- a/libphobos/m4/druntime/libraries.m4 +++ b/libphobos/m4/druntime/libraries.m4 @@ -116,7 +116,7 @@ AC_DEFUN([DRUNTIME_LIBRARIES_ATOMIC], DCFG_HAVE_LIBATOMIC=false LIBATOMIC= - AS_IF([test "x$with_libatomic" != "xno"], [ + AS_IF([test "x$enable_libatomic" != "xno" && test "x$with_libatomic" != "xno"], [ DCFG_HAVE_LIBATOMIC=true LIBATOMIC=../../libatomic/libatomic_convenience.la ], [ @@ -145,7 +145,7 @@ AC_DEFUN([DRUNTIME_LIBRARIES_BACKTRACE], AS_HELP_STRING([--without-libbacktrace], [Do not use libbacktrace in core.runtime (default: auto)])) - AS_IF([test "x$with_libbacktrace" != "xno"], [ + AS_IF([test "x$enable_libbacktrace" != "xno" && test "x$with_libbacktrace" != "xno"], [ LIBBACKTRACE=../../libbacktrace/libbacktrace.la gdc_save_CPPFLAGS=$CPPFLAGS -- cgit v1.1 From b66e72b43e1e8f402dc958ce3cca35f7c273340d Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon, 19 Apr 2021 14:36:14 +0200 Subject: 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 (limited to 'libphobos') diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 02a68b1..fdac627 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 853a7fc..1ff2ac6 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 0000000..da40718 --- /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 +<http://www.gnu.org/licenses/>. */ + +#ifdef __MINGW32__ +#include <_mingw.h> +#endif +#include <stdio.h> + +/* 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 6592ff6..0cb8b01 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 2e67932..5ce4869 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 ef35a3c27..5003637 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 5315739..592b3af 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 3d5ba29..e6acbd5 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(). */ -- cgit v1.1 From 6eae7549b8a350b92435be904efed195bd190bae Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon, 19 Apr 2021 14:48:32 +0200 Subject: libphobos: Add Thread/Fiber support code for Darwin (PR98058) libphobos/ChangeLog: PR d/98058 * configure: Regenerate. * libdruntime/Makefile.am (DRUNTIME_DSOURCES_DARWIN): Add core/sys/darwin/config.d * libdruntime/Makefile.in: Regenerate. * libdruntime/config/powerpc/switchcontext.S: Implement fiber_switchContext for __MACH__. * libdruntime/config/x86/switchcontext.S: Likewise. * libdruntime/core/sys/darwin/config.d: New file. * libdruntime/core/thread/fiber.d (Fiber.getThis): Mark noinline. (UnsafeFiberMigration): Define for OSX/X86 and OSX/X86_64. * libdruntime/core/thread/osthread.d (callWithStackShell): Add inline assembler implementation for X86, X86_64, PPC, and PPC64. * libdruntime/core/thread/threadbase.d (ThreadBase.getThis): Mark noinline. * libdruntime/gcc/deh.d (FuncTable): Remove definition. * m4/druntime/os.m4 (DRUNTIME_OS_MINFO_BRACKETING): Check for right bracket symbol on darwin* targets. * testsuite/libphobos.thread/fiber_guard_page.d: Update test to support ucontext-based Fibers. --- libphobos/configure | 22 +- libphobos/libdruntime/Makefile.am | 26 +- libphobos/libdruntime/Makefile.in | 37 +-- .../libdruntime/config/powerpc/switchcontext.S | 278 ++++++++++++++++++++- libphobos/libdruntime/config/x86/switchcontext.S | 159 +++++++++++- libphobos/libdruntime/core/sys/darwin/config.d | 53 ++++ libphobos/libdruntime/core/thread/fiber.d | 6 + libphobos/libdruntime/core/thread/osthread.d | 94 ++++++- libphobos/libdruntime/core/thread/threadbase.d | 1 + libphobos/libdruntime/gcc/deh.d | 5 - libphobos/m4/druntime/os.m4 | 22 +- .../testsuite/libphobos.thread/fiber_guard_page.d | 6 +- 12 files changed, 656 insertions(+), 53 deletions(-) create mode 100644 libphobos/libdruntime/core/sys/darwin/config.d (limited to 'libphobos') diff --git a/libphobos/configure b/libphobos/configure index 2c0f57c..b1c8ecb 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -14422,6 +14422,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -14430,17 +14432,29 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for minfo section bracketing" >&5 $as_echo_n "checking for minfo section bracketing... " >&6; } + case "$druntime_cv_target_os" in + darwin*) + section="__DATA,__minfodata" + start="section\$start\$__DATA\$__minfodata" + stop="section\$end\$__DATA\$__minfodata" + ;; + *) + section="minfo" + start="__start_minfo" + stop="__stop_minfo" + ;; + esac cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - void* module_info_ptr __attribute__((section ("minfo"))); - extern void* __start_minfo __attribute__((visibility ("hidden"))); - extern void* __stop_minfo __attribute__((visibility ("hidden"))); + void* module_info_ptr __attribute__((section ("$section"))); + extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden"))); + extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden"))); int main() { // Never run, just to prevent compiler from optimizing access - return &__start_minfo == &__stop_minfo; + return (int)(&stop_minfo - &start_minfo); } _ACEOF diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index fdac627..a2e2bff 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -206,19 +206,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \ core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \ core/sys/bionic/string.d core/sys/bionic/unistd.d -DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \ - core/sys/darwin/dlfcn.d core/sys/darwin/err.d \ - core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \ - core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \ - core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \ - core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \ - core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \ - core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \ - core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \ - core/sys/darwin/stdlib.d core/sys/darwin/string.d \ - core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \ - core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \ - core/sys/darwin/sys/sysctl.d +DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \ + core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \ + core/sys/darwin/err.d core/sys/darwin/execinfo.d \ + core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \ + core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \ + core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \ + core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \ + core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \ + core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \ + core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \ + core/sys/darwin/string.d core/sys/darwin/sys/attr.d \ + core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \ + core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \ core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 1ff2ac6..cb2e372 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -256,11 +256,11 @@ am__objects_3 = core/sys/posix/aio.lo core/sys/posix/arpa/inet.lo \ core/sys/posix/time.lo core/sys/posix/ucontext.lo \ core/sys/posix/unistd.lo core/sys/posix/utime.lo @DRUNTIME_OS_POSIX_TRUE@am__objects_4 = $(am__objects_3) -am__objects_5 = core/sys/darwin/crt_externs.lo \ - core/sys/darwin/dlfcn.lo core/sys/darwin/err.lo \ - core/sys/darwin/execinfo.lo core/sys/darwin/fcntl.lo \ - core/sys/darwin/ifaddrs.lo core/sys/darwin/mach/dyld.lo \ - core/sys/darwin/mach/getsect.lo \ +am__objects_5 = core/sys/darwin/config.lo \ + core/sys/darwin/crt_externs.lo core/sys/darwin/dlfcn.lo \ + core/sys/darwin/err.lo core/sys/darwin/execinfo.lo \ + core/sys/darwin/fcntl.lo core/sys/darwin/ifaddrs.lo \ + core/sys/darwin/mach/dyld.lo core/sys/darwin/mach/getsect.lo \ core/sys/darwin/mach/kern_return.lo \ core/sys/darwin/mach/loader.lo core/sys/darwin/mach/nlist.lo \ core/sys/darwin/mach/port.lo core/sys/darwin/mach/semaphore.lo \ @@ -843,19 +843,19 @@ DRUNTIME_DSOURCES_BIONIC = core/sys/bionic/err.d \ core/sys/bionic/fcntl.d core/sys/bionic/stdlib.d \ core/sys/bionic/string.d core/sys/bionic/unistd.d -DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/crt_externs.d \ - core/sys/darwin/dlfcn.d core/sys/darwin/err.d \ - core/sys/darwin/execinfo.d core/sys/darwin/fcntl.d \ - core/sys/darwin/ifaddrs.d core/sys/darwin/mach/dyld.d \ - core/sys/darwin/mach/getsect.d core/sys/darwin/mach/kern_return.d \ - core/sys/darwin/mach/loader.d core/sys/darwin/mach/nlist.d \ - core/sys/darwin/mach/port.d core/sys/darwin/mach/semaphore.d \ - core/sys/darwin/mach/stab.d core/sys/darwin/mach/thread_act.d \ - core/sys/darwin/netinet/in_.d core/sys/darwin/pthread.d \ - core/sys/darwin/stdlib.d core/sys/darwin/string.d \ - core/sys/darwin/sys/attr.d core/sys/darwin/sys/cdefs.d \ - core/sys/darwin/sys/event.d core/sys/darwin/sys/mman.d \ - core/sys/darwin/sys/sysctl.d +DRUNTIME_DSOURCES_DARWIN = core/sys/darwin/config.d \ + core/sys/darwin/crt_externs.d core/sys/darwin/dlfcn.d \ + core/sys/darwin/err.d core/sys/darwin/execinfo.d \ + core/sys/darwin/fcntl.d core/sys/darwin/ifaddrs.d \ + core/sys/darwin/mach/dyld.d core/sys/darwin/mach/getsect.d \ + core/sys/darwin/mach/kern_return.d core/sys/darwin/mach/loader.d \ + core/sys/darwin/mach/nlist.d core/sys/darwin/mach/port.d \ + core/sys/darwin/mach/semaphore.d core/sys/darwin/mach/stab.d \ + core/sys/darwin/mach/thread_act.d core/sys/darwin/netinet/in_.d \ + core/sys/darwin/pthread.d core/sys/darwin/stdlib.d \ + core/sys/darwin/string.d core/sys/darwin/sys/attr.d \ + core/sys/darwin/sys/cdefs.d core/sys/darwin/sys/event.d \ + core/sys/darwin/sys/mman.d core/sys/darwin/sys/sysctl.d DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \ core/sys/dragonflybsd/err.d core/sys/dragonflybsd/execinfo.d \ @@ -1352,6 +1352,7 @@ core/sys/posix/utime.lo: core/sys/posix/$(am__dirstamp) core/sys/darwin/$(am__dirstamp): @$(MKDIR_P) core/sys/darwin @: > core/sys/darwin/$(am__dirstamp) +core/sys/darwin/config.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/crt_externs.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/dlfcn.lo: core/sys/darwin/$(am__dirstamp) core/sys/darwin/err.lo: core/sys/darwin/$(am__dirstamp) diff --git a/libphobos/libdruntime/config/powerpc/switchcontext.S b/libphobos/libdruntime/config/powerpc/switchcontext.S index d4ea577..74395b0 100644 --- a/libphobos/libdruntime/config/powerpc/switchcontext.S +++ b/libphobos/libdruntime/config/powerpc/switchcontext.S @@ -24,7 +24,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "../common/threadasm.S" -#if !defined(__PPC64__) +#if !defined(__PPC64__) && !defined(__MACH__) /** * Performs a context switch. @@ -151,4 +151,278 @@ CSYM(fiber_switchContext): .cfi_endproc .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) -#endif /* !defined(__PPC64__) */ +#elif defined(__MACH__) + +/* Implementation for Darwin/macOS preserving callee-saved regs. + + FIXME : There is no unwind frame. + FIXME : not sure if we should save the vsave reg (perhaps using the slot we have + r11 in at present). */ + +/* Darwin has a red zone (220 bytes for PPC 288 for PPC64) which we can write + to before the stack is updated without worrying about it being clobbered by + signals or hardware interrupts. + + The stack will be 16byte aligned on entry with: + PPC PPC64 + SP-> +---------------------------------------+ + | back chain to caller | 0 0 + +---------------------------------------+ + | slot to save CR | 4 8 + +---------------------------------------+ + | slot to save LR | 8 16 + +---------------------------------------+ + | etc.. etc.. as per C calling conv. | */ + +# if __PPC64__ +# define LD ld +# define ST std +# define STU stdu +# define SZ 8 +# define MACHINE ppc64 +# define RED_ZONE 288 +# else +# define LD lwz +# define ST stw +# define STU stwu +# define SZ 4 +# define MACHINE ppc7400 +# define RED_ZONE 220 +# endif + +# define SAVE_VECTORS 0 +/** + * Performs a context switch. + * + * r3 - old context pointer + * r4 - new context pointer + * + */ + .machine MACHINE + .text + .globl CSYM(fiber_switchContext) + .align 2 +CSYM(fiber_switchContext): +LFB0: + /* Get the link reg. */ + mflr r0 + /* Get the callee-saved crs (well all of them, actually). */ + mfcr r12 + + /* Save GPRs, we save the static chain here too although it is not clear if we need to. */ + ST r31, ( -1 * SZ)(r1) + ST r30, ( -2 * SZ)(r1) + ST r29, ( -3 * SZ)(r1) + ST r28, ( -4 * SZ)(r1) + ST r27, ( -5 * SZ)(r1) + ST r26, ( -6 * SZ)(r1) + ST r25, ( -7 * SZ)(r1) + ST r24, ( -8 * SZ)(r1) + ST r23, ( -9 * SZ)(r1) + ST r22, (-10 * SZ)(r1) + ST r21, (-11 * SZ)(r1) + ST r20, (-12 * SZ)(r1) + ST r19, (-13 * SZ)(r1) + ST r18, (-14 * SZ)(r1) + ST r17, (-15 * SZ)(r1) + ST r16, (-16 * SZ)(r1) + ST r15, (-17 * SZ)(r1) + ST r14, (-18 * SZ)(r1) + ST r13, (-19 * SZ)(r1) + + /* Save the lr and cr into the normal function linkage area. */ + ST r0, 2*SZ(r1) + ST r12, SZ(r1) + + /* We update the stack pointer here, since we do not want the GC to + scan the floating point registers. We are still 16-byte aligned. */ + STU r11, (-20 * SZ)(r1) + + /* Update the stack pointer in the old context as per comment above. */ + ST r1, 0(r3) + + /* Save FPRs - same for PPC and PPC64 */ + stfd f14, (-18 * 8)(r1) + stfd f15, (-17 * 8)(r1) + stfd f16, (-16 * 8)(r1) + stfd f17, (-15 * 8)(r1) + stfd f18, (-14 * 8)(r1) + stfd f19, (-13 * 8)(r1) + stfd f20, (-12 * 8)(r1) + stfd f21, (-11 * 8)(r1) + stfd f22, (-10 * 8)(r1) + stfd f23, ( -9 * 8)(r1) + stfd f24, ( -8 * 8)(r1) + stfd f25, ( -7 * 8)(r1) + stfd f26, ( -6 * 8)(r1) + stfd f27, ( -5 * 8)(r1) + stfd f28, ( -4 * 8)(r1) + stfd f29, ( -3 * 8)(r1) + stfd f30, ( -2 * 8)(r1) + stfd f31, ( -1 * 8)(r1) + +#if SAVE_VECTORS + /* We are still 16byte aligned - so we are ok for vector saves. + but the combined size of the vectors (12 x 16) + the FPRs (144) exceeds the + red zone size so we need to adjust the stack again - note this means careful + ordering is needed on the restore. */ + + addi r1, r1, -(12*16+18*8) + li r11, 0 + stvx v20,r11,r1 + addi r11, r11, 16 + stvx v21,r11,r1 + addi r11, r11, 16 + stvx v22,r11,r1 + addi r11, r11, 16 + stvx v23,r11,r1 + addi r11, r11, 16 + stvx v24,r11,r1 + addi r11, r11, 16 + stvx v25,r11,r1 + addi r11, r11, 16 + stvx v26,r11,r1 + addi r11, r11, 16 + stvx v27,r11,r1 + addi r11, r11, 16 + stvx v28,r11,r1 + addi r11, r11, 16 + stvx v29,r11,r1 + addi r11, r11, 16 + stvx v30,r11,r1 + addi r11, r11, 16 + stvx v31,r11,r1 + + /* Now do the same thing in reverse - starting with r4 pointing to + the block of GPRs - stage 1 point to the saved vectors and fprs. */ + + addi r1, r4, -(12*16+18*8) + li r11, 0 + lvx v20,r11,r1 + addi r11, r11, 16 + lvx v21,r11,r1 + addi r11, r11, 16 + lvx v22,r11,r1 + addi r11, r11, 16 + lvx v23,r11,r1 + addi r11, r11, 16 + lvx v24,r11,r1 + addi r11, r11, 16 + lvx v25,r11,r1 + addi r11, r11, 16 + lvx v26,r11,r1 + addi r11, r11, 16 + lvx v27,r11,r1 + addi r11, r11, 16 + lvx v28,r11,r1 + addi r11, r11, 16 + lvx v29,r11,r1 + addi r11, r11, 16 + lvx v30,r11,r1 + addi r11, r11, 16 + lvx v31,r11,r1 +#endif + + /* Now it is safe to update the stack pointer since the combined + size of the GPRs and FPRs will not exceed the red zone. */ + + addi r1, r4, 20 * SZ + + /* Restore FPRs */ + lfd f14, (-18 * 8)(r4) + lfd f15, (-17 * 8)(r4) + lfd f16, (-16 * 8)(r4) + lfd f17, (-15 * 8)(r4) + lfd f18, (-14 * 8)(r4) + lfd f19, (-13 * 8)(r4) + lfd f20, (-12 * 8)(r4) + lfd f21, (-11 * 8)(r4) + lfd f22, (-10 * 8)(r4) + lfd f23, ( -9 * 8)(r4) + lfd f24, ( -8 * 8)(r4) + lfd f25, ( -7 * 8)(r4) + lfd f26, ( -6 * 8)(r4) + lfd f27, ( -5 * 8)(r4) + lfd f28, ( -4 * 8)(r4) + lfd f29, ( -3 * 8)(r4) + lfd f30, ( -2 * 8)(r4) + lfd f31, ( -1 * 8)(r4) + + /* Pick up lr and cr */ + LD r0, 2*SZ(r1) + LD r12, SZ(r1) + + /* Restore GPRs */ + LD r11, (-20 * SZ)(r1) + LD r13, (-19 * SZ)(r1) + LD r14, (-18 * SZ)(r1) + LD r15, (-17 * SZ)(r1) + LD r16, (-16 * SZ)(r1) + LD r17, (-15 * SZ)(r1) + LD r18, (-14 * SZ)(r1) + LD r19, (-13 * SZ)(r1) + LD r20, (-12 * SZ)(r1) + LD r21, (-11 * SZ)(r1) + LD r22, (-10 * SZ)(r1) + LD r23, ( -9 * SZ)(r1) + LD r24, ( -8 * SZ)(r1) + LD r25, ( -7 * SZ)(r1) + LD r26, ( -6 * SZ)(r1) + LD r27, ( -5 * SZ)(r1) + LD r28, ( -4 * SZ)(r1) + LD r29, ( -3 * SZ)(r1) + LD r30, ( -2 * SZ)(r1) + LD r31, ( -1 * SZ)(r1) + + /* Set cr and lr */ + mtcr r12 + mtlr r0 + + /* Return and switch context */ + blr +LFE0: + +/* Minimal CFI / FDE which does not describe the stacking of the GPRs - but only that + the routine has been entered/exited. */ + +# if __PPC64__ +# define DATA_ALIGN 0x78 +# define ALIGN_SIZE 3 +# define ADDRD .quad +# else +# define DATA_ALIGN 0x7c +# define ALIGN_SIZE 3 +# define ADDRD .long +# endif + + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0 ; CIE Identifier Tag + .byte 0x3 ; CIE Version + .ascii "zR\0" ; CIE Augmentation + .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor + .byte DATA_ALIGN ; sleb128 -4/-8; CIE Data Alignment Factor + .byte 0x41 ; uleb128 0x41; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0 ; uleb128 0 + .p2align ALIGN_SIZE,0 +LECIE1: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + ADDRD LFB0-. ; FDE initial location + .set L$set$2,LFE0-LFB0 + ADDRD L$set$2 ; FDE address range + .byte 0 ; uleb128 0; Augmentation size + .p2align ALIGN_SIZE,0 +LEFDE1: + +#endif /* defined(__MACH__) */ diff --git a/libphobos/libdruntime/config/x86/switchcontext.S b/libphobos/libdruntime/config/x86/switchcontext.S index 82420c6..9f4befd 100644 --- a/libphobos/libdruntime/config/x86/switchcontext.S +++ b/libphobos/libdruntime/config/x86/switchcontext.S @@ -29,7 +29,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # include <cet.h> #endif -#if defined(__i386__) && !defined(__CET__) +#if !defined(__CET__) + +# if defined(__ELF__) + +# if defined(__i386__) .text .globl CSYM(fiber_switchContext) @@ -63,7 +67,9 @@ CSYM(fiber_switchContext): .cfi_endproc .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) -#elif defined(__x86_64__) && !defined(__ILP32__) && !defined(__CET__) +# endif /* defined(__ELF__) && defined(__i386__) */ + +# if defined(__x86_64__) && !defined(__ILP32__) .text .globl CSYM(fiber_switchContext) @@ -98,4 +104,151 @@ CSYM(fiber_switchContext): .cfi_endproc .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) -#endif +# endif /* defined(__ELF__) && defined(__x86_64__) && !defined(__ILP32__) */ + +# endif /* defined(__ELF__) */ + +# if defined(__MACH__) + +# if defined(__i386__) + + .text + .globl CSYM(fiber_switchContext) + .p2align 4 +CSYM(fiber_switchContext): +LFB0: + // save current stack state + push %ebp + mov %esp, %ebp + push %edi + push %esi + push %ebx + push %eax + + // store oldp again with more accurate address + mov 8(%ebp), %eax + mov %esp, (%eax) + // load newp to begin context switch + mov 12(%ebp), %esp + + // load saved state from new stack + pop %eax + pop %ebx + pop %esi + pop %edi + pop %ebp + + // 'return' to complete switch + ret +LFE0: + +/* CFI */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 # Length of Common Information Entry +LSCIE1: + .long 0 # CIE Identifier Tag + .byte 0x1 # CIE Version + .ascii "zR\0" # CIE Augmentation + .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor + .byte 0x7c # sleb128 -4; CIE Data Alignment Factor + .byte 0x8 # CIE RA Column + .byte 0x1 # uleb128 0x1; Augmentation size + .byte 0x10 # FDE Encoding (pcrel) + .byte 0xc # DW_CFA_def_cfa + .byte 0x5 # uleb128 0x5 + .byte 0x4 # uleb128 0x4 + .byte 0x88 # DW_CFA_offset, column 0x8 + .byte 0x1 # uleb128 0x1 + .p2align 2,0 +LECIE1: + +/* minimal FDE - does not record the stack frame changes. */ +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 # FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 # FDE CIE offset + .long LFB0-. # FDE initial location + .set L$set$2,LFE0-LFB0 + .long L$set$2 # FDE address range + .byte 0 # uleb128 0; Augmentation size + .p2align 2,0 +LEFDE1: + +# endif /* defined(__MACH__) && defined(__i386__) */ + +# if defined(__x86_64__) && !defined(__ILP32__) + + .text + .globl CSYM(fiber_switchContext) + .p2align 4 +CSYM(fiber_switchContext): +LFB0: + // Save current stack state.save current stack state + push %rbp + mov %rsp, %rbp + push %r15 + push %r14 + push %r13 + push %r12 + push %rbx + + // store oldp again with more accurate address + mov %rsp, (%rdi) + // load newp to begin context switch + mov %rsi, %rsp + + // load saved state from new stack + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + + // 'return' to complete switch + ret +LFE0: + +/* CFI */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 # Length of Common Information Entry +LSCIE1: + .long 0 # CIE Identifier Tag + .byte 0x1 # CIE Version + .ascii "zR\0" # CIE Augmentation + .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor + .byte 0x78 # sleb128 -8; CIE Data Alignment Factor + .byte 0x10 # CIE RA Column + .byte 0x1 # uleb128 0x1; Augmentation size + .byte 0x10 # FDE Encoding (pcrel) + .byte 0xc # DW_CFA_def_cfa + .byte 0x7 # uleb128 0x7 + .byte 0x8 # uleb128 0x8 + .byte 0x90 # DW_CFA_offset, column 0x10 + .byte 0x1 # uleb128 0x1 + .p2align 3,0 +LECIE1: + +/* minimal FDE - does not record the stack frame changes. */ +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 # FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 # FDE CIE offset + .quad LFB0-. # FDE initial location + .set L$set$2,LFE0-LFB0 + .quad L$set$2 # FDE address range + .byte 0 # uleb128 0; Augmentation size + .p2align 3,0 +LEFDE1: + +# endif /* defined(__MACH__) && defined(__x86_64__) && !defined(__ILP32__) */ + +# endif /* defined (__MACH__) */ + +#endif /* !defined(__CET__) */ diff --git a/libphobos/libdruntime/core/sys/darwin/config.d b/libphobos/libdruntime/core/sys/darwin/config.d new file mode 100644 index 0000000..87f3fd4 --- /dev/null +++ b/libphobos/libdruntime/core/sys/darwin/config.d @@ -0,0 +1,53 @@ +/** + * D header file for Darwin. + * + * Copyright: Copyright (c) 2021 D Language Foundation + * Authors: Iain Buclaw + */ +module core.sys.darwin.config; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (Darwin): + +public import core.sys.posix.config; + +enum __MAC_10_0 = 100000; +enum __MAC_10_1 = 100100; +enum __MAC_10_2 = 100200; +enum __MAC_10_3 = 100300; +enum __MAC_10_4 = 100400; +enum __MAC_10_5 = 100500; +enum __MAC_10_6 = 100600; +enum __MAC_10_7 = 100700; +enum __MAC_10_8 = 100800; +enum __MAC_10_9 = 100900; +enum __MAC_10_10 = 101000; +enum __MAC_10_10_2 = 101002; +enum __MAC_10_10_3 = 101003; +enum __MAC_10_11 = 101100; +enum __MAC_10_11_2 = 101102; +enum __MAC_10_11_3 = 101103; +enum __MAC_10_11_4 = 101104; +enum __MAC_10_12 = 101200; +enum __MAC_10_12_1 = 101201; +enum __MAC_10_12_2 = 101202; +enum __MAC_10_12_4 = 101204; +enum __MAC_10_13 = 101300; +enum __MAC_10_13_1 = 101301; +enum __MAC_10_13_2 = 101302; +enum __MAC_10_13_4 = 101304; +enum __MAC_10_14 = 101400; +enum __MAC_10_14_1 = 101401; +enum __MAC_10_14_4 = 101404; +enum __MAC_10_15 = 101500; +enum __MAC_10_15_1 = 101501; +enum __MAC_10_16 = 101501; +enum __MAC_11_0 = 110000; diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d index 3270f2e..67d9937 100644 --- a/libphobos/libdruntime/core/thread/fiber.d +++ b/libphobos/libdruntime/core/thread/fiber.d @@ -883,6 +883,7 @@ class Fiber */ static Fiber getThis() @safe nothrow @nogc { + version (GNU) pragma(inline, false); return sm_this; } @@ -1731,6 +1732,11 @@ unittest // Multiple threads running shared fibers version (PPC) version = UnsafeFiberMigration; version (PPC64) version = UnsafeFiberMigration; +version (OSX) +{ + version (X86) version = UnsafeFiberMigration; + version (X86_64) version = UnsafeFiberMigration; +} version (UnsafeFiberMigration) { diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 880836e..0fffc7e 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -1396,8 +1396,98 @@ in (fn) void *sp = void; version (GNU) { - __builtin_unwind_init(); - sp = &sp; + // The generic solution below using a call to __builtin_unwind_init () + // followed by an assignment to sp has two issues: + // 1) On some archs it stores a huge amount of FP and Vector state which + // is not the subject of the scan - and, indeed might produce false + // hits. + // 2) Even on archs like X86, where there are no callee-saved FPRs/VRs there + // tend to be 'holes' in the frame allocations (to deal with alignment) which + // also will contain random data which could produce false positives. + // This solution stores only the integer callee-saved registers. + version (X86) + { + void*[3] regs = void; + asm pure nothrow @nogc + { + "movl %%ebx, %0" : "=m" (regs[0]); + "movl %%esi, %0" : "=m" (regs[1]); + "movl %%edi, %0" : "=m" (regs[2]); + } + sp = cast(void*)®s[0]; + } + else version (X86_64) + { + void*[5] regs = void; + asm pure nothrow @nogc + { + "movq %%rbx, %0" : "=m" (regs[0]); + "movq %%r12, %0" : "=m" (regs[1]); + "movq %%r13, %0" : "=m" (regs[2]); + "movq %%r14, %0" : "=m" (regs[3]); + "movq %%r15, %0" : "=m" (regs[4]); + } + sp = cast(void*)®s[0]; + } + else version (PPC) + { + void*[19] regs = void; + asm pure nothrow @nogc + { + "stw r13, %0" : "=m" (regs[ 0]); + "stw r14, %0" : "=m" (regs[ 1]); + "stw r15, %0" : "=m" (regs[ 2]); + "stw r16, %0" : "=m" (regs[ 3]); + "stw r17, %0" : "=m" (regs[ 4]); + "stw r18, %0" : "=m" (regs[ 5]); + "stw r19, %0" : "=m" (regs[ 6]); + "stw r20, %0" : "=m" (regs[ 7]); + "stw r21, %0" : "=m" (regs[ 9]); + "stw r22, %0" : "=m" (regs[ 9]); + "stw r23, %0" : "=m" (regs[10]); + "stw r24, %0" : "=m" (regs[11]); + "stw r25, %0" : "=m" (regs[12]); + "stw r26, %0" : "=m" (regs[13]); + "stw r27, %0" : "=m" (regs[14]); + "stw r28, %0" : "=m" (regs[15]); + "stw r29, %0" : "=m" (regs[16]); + "stw r30, %0" : "=m" (regs[17]); + "stw r31, %0" : "=m" (regs[18]); + } + sp = cast(void*)®s[0]; + } + else version (PPC64) + { + void*[19] regs = void; + asm pure nothrow @nogc + { + "std r13, %0" : "=m" (regs[ 0]); + "std r14, %0" : "=m" (regs[ 1]); + "std r15, %0" : "=m" (regs[ 2]); + "std r16, %0" : "=m" (regs[ 3]); + "std r17, %0" : "=m" (regs[ 4]); + "std r18, %0" : "=m" (regs[ 5]); + "std r19, %0" : "=m" (regs[ 6]); + "std r20, %0" : "=m" (regs[ 7]); + "std r21, %0" : "=m" (regs[ 8]); + "std r22, %0" : "=m" (regs[ 9]); + "std r23, %0" : "=m" (regs[10]); + "std r24, %0" : "=m" (regs[11]); + "std r25, %0" : "=m" (regs[12]); + "std r26, %0" : "=m" (regs[13]); + "std r27, %0" : "=m" (regs[14]); + "std r28, %0" : "=m" (regs[15]); + "std r29, %0" : "=m" (regs[16]); + "std r30, %0" : "=m" (regs[17]); + "std r31, %0" : "=m" (regs[18]); + } + sp = cast(void*)®s[0]; + } + else + { + __builtin_unwind_init(); + sp = &sp; + } } else version (AsmX86_Posix) { diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d index c2c2333..50795e4 100644 --- a/libphobos/libdruntime/core/thread/threadbase.d +++ b/libphobos/libdruntime/core/thread/threadbase.d @@ -313,6 +313,7 @@ class ThreadBase // NOTE: This function may not be called until thread_init has // completed. See thread_suspendAll for more information // on why this might occur. + version (GNU) pragma(inline, false); return sm_this; } diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index 5ce4869..712f5d7 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -34,11 +34,6 @@ extern(C) { int _d_isbaseof(ClassInfo, ClassInfo); void _d_createTrace(Object, void*); - - // Not used in GDC but declaration required by rt/sections.d - struct FuncTable - { - } } /** diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4 index ed93e30..351558d 100644 --- a/libphobos/m4/druntime/os.m4 +++ b/libphobos/m4/druntime/os.m4 @@ -149,17 +149,31 @@ AC_DEFUN([DRUNTIME_OS_ARM_EABI_UNWINDER], # substitute DCFG_MINFO_BRACKETING. AC_DEFUN([DRUNTIME_OS_MINFO_BRACKETING], [ + AC_REQUIRE([DRUNTIME_OS_DETECT]) + AC_LANG_PUSH([C]) AC_MSG_CHECKING([for minfo section bracketing]) + case "$druntime_cv_target_os" in + darwin*) + section="__DATA,__minfodata" + start="section\$start\$__DATA\$__minfodata" + stop="section\$end\$__DATA\$__minfodata" + ;; + *) + section="minfo" + start="__start_minfo" + stop="__stop_minfo" + ;; + esac AC_LINK_IFELSE([AC_LANG_SOURCE([ - void* module_info_ptr __attribute__((section ("minfo"))); - extern void* __start_minfo __attribute__((visibility ("hidden"))); - extern void* __stop_minfo __attribute__((visibility ("hidden"))); + void* module_info_ptr __attribute__((section ("$section"))); + extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden"))); + extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden"))); int main() { // Never run, just to prevent compiler from optimizing access - return &__start_minfo == &__stop_minfo; + return (int)(&stop_minfo - &start_minfo); } ])], [AC_MSG_RESULT([yes]) diff --git a/libphobos/testsuite/libphobos.thread/fiber_guard_page.d b/libphobos/testsuite/libphobos.thread/fiber_guard_page.d index 9f754e1..ca54a19 100644 --- a/libphobos/testsuite/libphobos.thread/fiber_guard_page.d +++ b/libphobos/testsuite/libphobos.thread/fiber_guard_page.d @@ -1,13 +1,15 @@ // { dg-options "-O0" } // { dg-shouldfail "segv or bus error" } import core.thread; +import core.sys.posix.signal; import core.sys.posix.sys.mman; // this should be true for most architectures // (taken from core.thread) -version = StackGrowsDown; +version (GNU_StackGrowsDown) + version = StackGrowsDown; -enum stackSize = 4096; +enum stackSize = MINSIGSTKSZ; // Simple method that causes a stack overflow void stackMethod() -- cgit v1.1 From e19c6389966216af5925d2917a206cedc40540e8 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon, 19 Apr 2021 13:51:02 +0200 Subject: libphobos: Merge upstream druntime 89f870b7, phobos e6907ff3e Phobos changes: - Synchronize C bindings with the latest port fixes in upstream druntime. - Add Config.stderrPassThrough to std.process (PR98494). Reviewed-on: https://github.com/dlang/druntime/pull/3448 https://github.com/dlang/phobos/pull/7984 libphobos/ChangeLog: PR d/98494 * libdruntime/MERGE: Merge upstream druntime 89f870b7. * src/MERGE: Merge upstream phobos e6907ff3e. --- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/stdc/config.d | 39 ++- libphobos/libdruntime/core/stdc/math.d | 295 +++++++++++---------- libphobos/libdruntime/core/stdc/stdio.d | 82 +++++- libphobos/libdruntime/core/stdc/stdlib.d | 27 +- libphobos/libdruntime/core/stdc/tgmath.d | 7 + .../libdruntime/core/sys/darwin/mach/thread_act.d | 66 +++++ .../libdruntime/core/sys/openbsd/sys/link_elf.d | 5 + libphobos/libdruntime/core/sys/posix/stdio.d | 50 ++++ libphobos/libdruntime/core/sys/windows/com.d | 4 +- libphobos/libdruntime/core/sys/windows/dbghelp.d | 2 +- libphobos/libdruntime/core/sys/windows/dll.d | 4 +- libphobos/libdruntime/core/sys/windows/threadaux.d | 4 +- libphobos/libdruntime/core/thread/fiber.d | 42 ++- libphobos/libdruntime/core/thread/osthread.d | 44 ++- libphobos/libdruntime/core/thread/threadbase.d | 3 + libphobos/src/MERGE | 2 +- libphobos/src/std/process.d | 51 +++- 18 files changed, 520 insertions(+), 209 deletions(-) (limited to 'libphobos') diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index d839a08..25cbb95 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -1134b71039881464e9bf021836d82796b3a1fcfc +89f870b76710a4cfa96f711bb5b14a7439c5c2a7 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d index 802f5b6..44bb707 100644 --- a/libphobos/libdruntime/core/stdc/config.d +++ b/libphobos/libdruntime/core/stdc/config.d @@ -186,7 +186,18 @@ else version (Posix) } } -version (CRuntime_Microsoft) +version (GNU) + alias c_long_double = real; +else version (LDC) + alias c_long_double = real; // 64-bit real for MSVC targets +else version (SDC) +{ + version (X86) + alias c_long_double = real; + else version (X86_64) + alias c_long_double = real; +} +else version (CRuntime_Microsoft) { /* long double is 64 bits, not 80 bits, but is mangled differently * than double. To distinguish double from long double, create a wrapper to represent @@ -222,17 +233,6 @@ else version (DigitalMars) alias real c_long_double; } } -else version (GNU) - alias real c_long_double; -else version (LDC) - alias real c_long_double; -else version (SDC) -{ - version (X86) - alias real c_long_double; - else version (X86_64) - alias real c_long_double; -} static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture."); @@ -257,18 +257,9 @@ private struct _Complex(T) T im; } -version (Posix) -{ - align(float.alignof) enum __c_complex_float : _Complex!float; - align(double.alignof) enum __c_complex_double : _Complex!double; - align(real.alignof) enum __c_complex_real : _Complex!real; -} -else -{ - align(float.sizeof * 2) enum __c_complex_float : _Complex!float; - align(double.sizeof * 2) enum __c_complex_double : _Complex!double; - align(real.alignof) enum __c_complex_real : _Complex!real; -} +enum __c_complex_float : _Complex!float; +enum __c_complex_double : _Complex!double; +enum __c_complex_real : _Complex!c_long_double; alias c_complex_float = __c_complex_float; alias c_complex_double = __c_complex_double; diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d index fba78ee..2de6e57 100644 --- a/libphobos/libdruntime/core/stdc/math.d +++ b/libphobos/libdruntime/core/stdc/math.d @@ -424,92 +424,177 @@ else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) o pure int _fpclass(double x); } + version (MinGW) + { enum { /// - FP_SUBNORMAL = -2, + FP_NAN = 0x0100, /// - FP_NORMAL = -1, + FP_NORMAL = 0x0400, /// - FP_ZERO = 0, + FP_INFINITE = FP_NAN | FP_NORMAL, /// - FP_INFINITE = 1, + FP_ZERO = 0x0400, /// - FP_NAN = 2, + FP_SUBNORMAL = FP_NORMAL | FP_ZERO } - extern(D) - { - //int fpclassify(real-floating x); - /// - extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x); - /// - extern(C) pragma(mangle, "_dclass") pure int fpclassify(double x); - /// - pure int fpclassify()(real x) - { - static if (real.sizeof == double.sizeof) - return fpclassify(cast(double) x); - else - static assert(false, "fpclassify(real) not supported by MS C runtime"); - } + pure int __fpclassifyf(float x); + pure int __fpclassify(double x); + pure int __fpclassifyl(real x); - //int isfinite(real-floating x); - /// - pure int isfinite()(float x) { return fpclassify(x) <= 0; } - /// - pure int isfinite()(double x) { return fpclassify(x) <= 0; } - /// - pure int isfinite()(real x) { return fpclassify(x) <= 0; } + pure int __isnanf(float x); + pure int __isnan(double x); + pure int __isnanl(real x); - //int isinf(real-floating x); - /// - pure int isinf()(float x) { return fpclassify(x) == FP_INFINITE; } - /// - pure int isinf()(double x) { return fpclassify(x) == FP_INFINITE; } - /// - pure int isinf()(real x) { return fpclassify(x) == FP_INFINITE; } + pure int __signbitf(float x); + pure int __signbit(double x); + pure int __signbitl(real x); - //int isnan(real-floating x); - version (none) // requires MSVCRT 12+ (VS 2013) + extern (D) { + //int fpclassify(real-floating x); + /// + extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); + /// + extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x); + /// + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl") + pure int fpclassify(real x); + + //int isfinite(real-floating x); + /// + pure int isfinite(float x) { return (fpclassify(x) & FP_NORMAL) == 0; } /// - pure int isnan(float x) { return fpclassify(x) == FP_NAN; } + pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; } /// - pure int isnan(double x) { return fpclassify(x) == FP_NAN; } + pure int isfinite(real x) { return (fpclassify(x) & FP_NORMAL) == 0; } + + //int isinf(real-floating x); + /// + pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; } + /// + pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; } + /// + pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; } + + //int isnan(real-floating x); /// - pure int isnan(real x) { return fpclassify(x) == FP_NAN; } + extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); + /// + extern(C) pragma(mangle, "__isnan") pure int isnan(double x); + /// + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") + pure int isnan(real x); + + //int isnormal(real-floating x); + /// + int isnormal(float x) { return fpclassify(x) == FP_NORMAL; } + /// + int isnormal(double x) { return fpclassify(x) == FP_NORMAL; } + /// + int isnormal(real x) { return fpclassify(x) == FP_NORMAL; } + + //int signbit(real-floating x); + /// + extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); + /// + extern(C) pragma(mangle, "__signbit") pure int signbit(double x); + /// + extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl") + int signbit(real x); } - else // for backward compatibility with older runtimes + } + else + { + enum { /// - pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); } + FP_SUBNORMAL = -2, + /// + FP_NORMAL = -1, /// - extern(C) pragma(mangle, "_isnan") pure int isnan(double x); + FP_ZERO = 0, /// - pure int isnan(real x) { return _isnan(cast(double) x); } + FP_INFINITE = 1, + /// + FP_NAN = 2, } - //int isnormal(real-floating x); - /// - pure int isnormal()(float x) { return fpclassify(x) == FP_NORMAL; } - /// - pure int isnormal()(double x) { return fpclassify(x) == FP_NORMAL; } - /// - pure int isnormal()(real x) { return fpclassify(x) == FP_NORMAL; } - - //int signbit(real-floating x); - /// - extern(C) pragma(mangle, "_fdsign") pure int signbit(float x); - /// - extern(C) pragma(mangle, "_dsign") pure int signbit(double x); - /// - pure int signbit()(real x) + extern(D) { - static if (real.sizeof == double.sizeof) - return signbit(cast(double) x); - else - return (cast(short*)&(x))[4] & 0x8000; + //int fpclassify(real-floating x); + /// + extern(C) pragma(mangle, "_fdclass") pure int fpclassify(float x); + /// + extern(C) pragma(mangle, "_dclass") pure int fpclassify(double x); + /// + pure int fpclassify()(real x) + { + static if (real.sizeof == double.sizeof) + return fpclassify(cast(double) x); + else + static assert(false, "fpclassify(real) not supported by MS C runtime"); + } + + //int isfinite(real-floating x); + /// + pure int isfinite()(float x) { return fpclassify(x) <= 0; } + /// + pure int isfinite()(double x) { return fpclassify(x) <= 0; } + /// + pure int isfinite()(real x) { return fpclassify(x) <= 0; } + + //int isinf(real-floating x); + /// + pure int isinf()(float x) { return fpclassify(x) == FP_INFINITE; } + /// + pure int isinf()(double x) { return fpclassify(x) == FP_INFINITE; } + /// + pure int isinf()(real x) { return fpclassify(x) == FP_INFINITE; } + + //int isnan(real-floating x); + version (none) // requires MSVCRT 12+ (VS 2013) + { + /// + pure int isnan(float x) { return fpclassify(x) == FP_NAN; } + /// + pure int isnan(double x) { return fpclassify(x) == FP_NAN; } + /// + pure int isnan(real x) { return fpclassify(x) == FP_NAN; } + } + else // for backward compatibility with older runtimes + { + /// + pure int isnan(float x) { version (Win64) return _isnanf(x); else return _isnan(cast(double) x); } + /// + extern(C) pragma(mangle, "_isnan") pure int isnan(double x); + /// + pure int isnan(real x) { return _isnan(cast(double) x); } + } + + //int isnormal(real-floating x); + /// + pure int isnormal()(float x) { return fpclassify(x) == FP_NORMAL; } + /// + pure int isnormal()(double x) { return fpclassify(x) == FP_NORMAL; } + /// + pure int isnormal()(real x) { return fpclassify(x) == FP_NORMAL; } + + //int signbit(real-floating x); + /// + extern(C) pragma(mangle, "_fdsign") pure int signbit(float x); + /// + extern(C) pragma(mangle, "_dsign") pure int signbit(double x); + /// + pure int signbit()(real x) + { + static if (real.sizeof == double.sizeof) + return signbit(cast(double) x); + else + return (cast(short*)&(x))[4] & 0x8000; + } } } } @@ -835,88 +920,6 @@ else version (CRuntime_UClibc) int signbit(real x); } } -else version (MinGW) -{ - enum - { - /// - FP_NAN = 0x0100, - /// - FP_NORMAL = 0x0400, - /// - FP_INFINITE = FP_NAN | FP_NORMAL, - /// - FP_ZERO = 0x0400, - /// - FP_SUBNORMAL = FP_NORMAL | FP_ZERO - } - - pure int __fpclassifyf(float x); - pure int __fpclassify(double x); - pure int __fpclassifyl(real x); - - pure int __isnanf(float x); - pure int __isnan(double x); - pure int __isnanl(real x); - - pure int __signbitf(float x); - pure int __signbit(double x); - pure int __signbitl(real x); - - extern (D) - { - //int fpclassify(real-floating x); - /// - extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); - /// - extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x); - /// - extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify" : "__fpclassifyl") - pure int fpclassify(real x); - - //int isfinite(real-floating x); - /// - pure int isfinite(float x) { return (fpclassify(x) & FP_NORMAL) == 0; } - /// - pure int isfinite(double x) { return (fpclassify(x) & FP_NORMAL) == 0; } - /// - pure int isfinite(real x) { return (fpclassify(x) & FP_NORMAL) == 0; } - - //int isinf(real-floating x); - /// - pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; } - /// - pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; } - /// - pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; } - - //int isnan(real-floating x); - /// - extern(C) pragma(mangle, "__isnanf") pure int isnan(float x); - /// - extern(C) pragma(mangle, "__isnan") pure int isnan(double x); - /// - extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") - pure int isnan(real x); - - //int isnormal(real-floating x); - /// - int isnormal(float x) { return fpclassify(x) == FP_NORMAL; } - /// - int isnormal(double x) { return fpclassify(x) == FP_NORMAL; } - /// - int isnormal(real x) { return fpclassify(x) == FP_NORMAL; } - - //int signbit(real-floating x); - /// - extern(C) pragma(mangle, "__signbitf") pure int signbit(float x); - /// - extern(C) pragma(mangle, "__signbit") pure int signbit(double x); - /// - extern(C) pragma(mangle, real.sizeof == double.sizeof ? "__signbit" : "__signbitl") - int signbit(real x); - } -} else version (Darwin) { enum @@ -1166,7 +1169,7 @@ else version (OpenBSD) FP_FAST_FMAL = 1, } - pure int __fpclassifyd(double); + pure int __fpclassify(double); pure int __fpclassifyf(float); pure int __fpclassifyl(real); pure int __isfinitef(float); @@ -1188,7 +1191,7 @@ else version (OpenBSD) /// extern(C) pragma(mangle, "__fpclassifyf") pure int fpclassify(float x); /// - extern(C) pragma(mangle, "__fpclassifyd") pure int fpclassify(double x); + extern(C) pragma(mangle, "__fpclassify") pure int fpclassify(double x); /// extern(C) pragma(mangle, "__fpclassifyl") pure int fpclassify(real x); diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index 532a080..c76b922 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -1347,7 +1347,7 @@ version (CRuntime_DigitalMars) /// pure int fileno()(FILE* stream) { return stream._file; } } - /// + /// pragma(printf) int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// @@ -1358,6 +1358,26 @@ version (CRuntime_DigitalMars) int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// alias _vsnprintf vsnprintf; + + // + // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the + // unshared version of FILE*, usable when the FILE is locked. + // + + /// + int _fputc_nlock(int c, _iobuf* fp); + /// + int _fputwc_nlock(int c, _iobuf* fp); + /// + int _fgetc_nlock(_iobuf* fp); + /// + int _fgetwc_nlock(_iobuf* fp); + /// + int __fp_lock(FILE* fp); + /// + void __fp_unlock(FILE* fp); + /// + int setmode(int fd, int mode); } else version (CRuntime_Microsoft) { @@ -1410,16 +1430,31 @@ else version (CRuntime_Microsoft) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } + // + // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared + // version of FILE*, usable when the FILE is locked. + // + import core.stdc.stddef : wchar_t; + import core.stdc.wchar_ : wint_t; + /// - int _fputc_nolock(int c, FILE *fp); + int _fputc_nolock(int c, _iobuf* fp); /// - int _fgetc_nolock(FILE *fp); - + int _fgetc_nolock(_iobuf* fp); /// - int _lock_file(FILE *fp); + wint_t _fputwc_nolock(wchar_t c, _iobuf* fp); /// - int _unlock_file(FILE *fp); - + wint_t _fgetwc_nolock(_iobuf* fp); + /// + void _lock_file(FILE* fp); + /// + void _unlock_file(FILE* fp); + /// + int _setmode(int fd, int mode); + /// + int _fseeki64(FILE* stream, long offset, int origin); + /// + long _ftelli64(FILE* stream); /// intptr_t _get_osfhandle(int fd); /// @@ -1448,6 +1483,23 @@ else version (CRuntime_Glibc) /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); + + // + // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared + // version of FILE*, usable when the FILE is locked. + // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html + // + import core.stdc.wchar_ : wint_t; + import core.stdc.stddef : wchar_t; + + /// + int fputc_unlocked(int c, _iobuf* stream); + /// + int fgetc_unlocked(_iobuf* stream); + /// + wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream); + /// + wint_t fgetwc_unlocked(_iobuf* stream); } else version (Darwin) { @@ -1907,6 +1959,22 @@ version (Windows) O_TEXT = _O_TEXT, /// _O_BINARY = 0x8000, /// O_BINARY = _O_BINARY, /// + _O_WTEXT = 0x10000, /// + _O_U16TEXT = 0x20000, /// + _O_U8TEXT = 0x40000, /// + _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), /// + O_ACCMODE = _O_ACCMODE, /// + _O_RAW = _O_BINARY, /// + O_RAW = _O_BINARY, /// + _O_NOINHERIT = 0x0080, /// + O_NOINHERIT = _O_NOINHERIT, /// + _O_TEMPORARY = 0x0040, /// + O_TEMPORARY = _O_TEMPORARY, /// + _O_SHORT_LIVED = 0x1000, /// + _O_SEQUENTIAL = 0x0020, /// + O_SEQUENTIAL = _O_SEQUENTIAL, /// + _O_RANDOM = 0x0010, /// + O_RANDOM = _O_RANDOM, /// } enum diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 5d69b88..35e81a2 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 2ff1522..2d1a198 100644 --- a/libphobos/libdruntime/core/stdc/tgmath.d +++ b/libphobos/libdruntime/core/stdc/tgmath.d @@ -1285,6 +1285,13 @@ 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 { diff --git a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d index b61673f..d455d1b 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/thread_act.d @@ -38,6 +38,10 @@ version (AArch64) version = AnyARM; version (ARM) version = AnyARM; +version (PPC) + version = AnyPPC; +version (PPC64) + version = AnyPPC; version (i386) { @@ -235,3 +239,65 @@ else version (AnyARM) kern_return_t thread_resume(thread_act_t); kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*); } +else version (AnyPPC) +{ + alias thread_act_t = mach_port_t; + alias thread_state_t = void; + alias thread_state_flavor_t = int; + alias mach_msg_type_number_t = natural_t; + + enum + { + PPC_THREAD_STATE = 1, + PPC_FLOAT_STATE = 2, + PPC_EXCEPTION_STATE = 3, + PPC_VECTOR_STATE = 4, + PPC_THREAD_STATE64 = 5, + PPC_EXCEPTION_STATE64 = 6, + THREAD_STATE_NONE = 7 + } + + struct ppc_thread_state_t + { + uint srr0; /// Instruction address register (PC) + uint srr1; /// Machine state register (supervisor) + uint[32] r; /// General purpose register r0-r31 + uint cr; /// Condition register + uint xer; /// User's integer exception register + uint lr; /// Link register + uint ctr; /// Count register + uint mq; /// MQ register (601 only) + uint vrsave; /// Vector save register + } + + alias ppc_thread_state32_t = ppc_thread_state_t; + + struct ppc_thread_state64_t + { + ulong srr0; /// Instruction address register (PC) + ulong srr1; /// Machine state register (supervisor) + ulong[32] r; /// General purpose register r0-r31 + uint cr; /// Condition register + uint pad0; + ulong xer; /// User's integer exception register + ulong lr; /// Link register + ulong ctr; /// Count register + uint vrsave; /// Vector save register + uint pad1; + } + + enum : mach_msg_type_number_t + { + PPC_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state_t.sizeof / uint.sizeof), + PPC_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state32_t.sizeof / uint.sizeof), + PPC_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state64_t.sizeof / uint.sizeof), + } + + alias MACHINE_THREAD_STATE = PPC_THREAD_STATE; + alias MACHINE_THREAD_STATE_COUNT = PPC_THREAD_STATE_COUNT; + + mach_port_t mach_thread_self(); + kern_return_t thread_suspend(thread_act_t); + kern_return_t thread_resume(thread_act_t); + kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*); +} diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d index f88671a..55fc792 100644 --- a/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d +++ b/libphobos/libdruntime/core/sys/openbsd/sys/link_elf.d @@ -63,3 +63,8 @@ private alias int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_ int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data); int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc; + +int _rtld_addr_phdr(const void*, dl_phdr_info*) @nogc +{ + return 0; +} diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d index 031bcb7..41b52da 100644 --- a/libphobos/libdruntime/core/sys/posix/stdio.d +++ b/libphobos/libdruntime/core/sys/posix/stdio.d @@ -516,6 +516,46 @@ version (CRuntime_Glibc) int putc_unlocked(int, FILE*); int putchar_unlocked(int); } +else version (CRuntime_Musl) +{ + void flockfile(FILE*); + int ftrylockfile(FILE*); + void funlockfile(FILE*); + int getc_unlocked(FILE*); + int getchar_unlocked(); + int putc_unlocked(int, FILE*); + int putchar_unlocked(int); +} +else version (Darwin) +{ + void flockfile(FILE*); + int ftrylockfile(FILE*); + void funlockfile(FILE*); + int getc_unlocked(FILE*); + int getchar_unlocked(); + int putc_unlocked(int, FILE*); + int putchar_unlocked(int); +} +else version (FreeBSD) +{ + void flockfile(FILE*); + int ftrylockfile(FILE*); + void funlockfile(FILE*); + int getc_unlocked(FILE*); + int getchar_unlocked(); + int putc_unlocked(int, FILE*); + int putchar_unlocked(int); +} +else version (NetBSD) +{ + void flockfile(FILE*); + int ftrylockfile(FILE*); + void funlockfile(FILE*); + int getc_unlocked(FILE*); + int getchar_unlocked(); + int putc_unlocked(int, FILE*); + int putchar_unlocked(int); +} else version (OpenBSD) { void flockfile(FILE*); @@ -526,6 +566,16 @@ else version (OpenBSD) int putc_unlocked(int, FILE*); int putchar_unlocked(int); } +else version (DragonFlyBSD) +{ + void flockfile(FILE*); + int ftrylockfile(FILE*); + void funlockfile(FILE*); + int getc_unlocked(FILE*); + int getchar_unlocked(); + int putc_unlocked(int, FILE*); + int putchar_unlocked(int); +} else version (Solaris) { void flockfile(FILE*); diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d index 88007ad..6935dd9 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 8c98270..9848fb9 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 3df0d7f..cc2422b 100644 --- a/libphobos/libdruntime/core/sys/windows/dll.d +++ b/libphobos/libdruntime/core/sys/windows/dll.d @@ -414,7 +414,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc { version (GNU_InlineAsm) { - asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" peb; } + asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); } } else { @@ -431,7 +431,7 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc { version (GNU_InlineAsm) { - asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" peb; } + asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); } } else { diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d index fb4d1ee..34fda65 100644 --- a/libphobos/libdruntime/core/sys/windows/threadaux.d +++ b/libphobos/libdruntime/core/sys/windows/threadaux.d @@ -172,7 +172,7 @@ struct thread_aux version (GNU_InlineAsm) { void** teb; - asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" teb; } + asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); } return teb; } else @@ -190,7 +190,7 @@ struct thread_aux version (GNU_InlineAsm) { void** teb; - asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" teb; } + asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" (teb); } return teb; } else diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d index 67d9937..f4c04ce 100644 --- a/libphobos/libdruntime/core/thread/fiber.d +++ b/libphobos/libdruntime/core/thread/fiber.d @@ -82,6 +82,8 @@ private version (MinGW) version = GNU_AsmX86_Windows; + else version (OSX) + version = AsmX86_Posix; else version (Posix) version = AsmX86_Posix; } @@ -105,13 +107,21 @@ private version (MinGW) version = GNU_AsmX86_64_Windows; + else version (OSX) + version = AsmX86_64_Posix; else version (Posix) version = AsmX86_64_Posix; } } else version (PPC) { - version (Posix) + version (OSX) + { + version = AsmPPC_Darwin; + version = AsmExternal; + version = AlignFiberStackTo16Byte; + } + else version (Posix) { version = AsmPPC_Posix; version = AsmExternal; @@ -119,7 +129,13 @@ private } else version (PPC64) { - version (Posix) + version (OSX) + { + version = AsmPPC_Darwin; + version = AsmExternal; + version = AlignFiberStackTo16Byte; + } + else version (Posix) { version = AlignFiberStackTo16Byte; } @@ -1347,6 +1363,28 @@ private: assert( (cast(size_t) pstack & 0x0f) == 0 ); } + else version (AsmPPC_Darwin) + { + version (StackGrowsDown) {} + else static assert(false, "PowerPC Darwin only supports decrementing stacks"); + + uint wsize = size_t.sizeof; + + // linkage + regs + FPRs + VRs + uint space = 8 * wsize + 20 * wsize + 18 * 8 + 12 * 16; + (cast(ubyte*)pstack - space)[0 .. space] = 0; + + pstack -= wsize * 6; + *cast(size_t*)pstack = cast(size_t) &fiber_entryPoint; // LR + pstack -= wsize * 22; + + // On Darwin PPC64 pthread self is in R13 (which is reserved). + // At present, it is not safe to migrate fibers between threads, but if that + // changes, then updating the value of R13 will also need to be handled. + version (PPC64) + *cast(size_t*)(pstack + wsize) = cast(size_t) Thread.getThis().m_addr; + assert( (cast(size_t) pstack & 0x0f) == 0 ); + } else version (AsmMIPS_O32_Posix) { version (StackGrowsDown) {} diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 0fffc7e..31764e6 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -349,7 +349,8 @@ class Thread : ThreadBase } else version (Posix) { - pthread_detach( m_addr ); + if (m_addr != m_addr.init) + pthread_detach( m_addr ); m_addr = m_addr.init; } version (Darwin) @@ -420,6 +421,17 @@ class Thread : ThreadBase { uint[16] m_reg; // r0-r15 } + else version (PPC) + { + // Make the assumption that we only care about non-fp and non-vr regs. + // ??? : it seems plausible that a valid address can be copied into a VR. + uint[32] m_reg; // r0-31 + } + else version (PPC64) + { + // As above. + ulong[32] m_reg; // r0-31 + } else { static assert(false, "Architecture not supported." ); @@ -578,7 +590,7 @@ class Thread : ThreadBase { version (Windows) { - if ( WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 ) + if ( m_addr != m_addr.init && WaitForSingleObject( m_hndl, INFINITE ) != WAIT_OBJECT_0 ) throw new ThreadException( "Unable to join thread" ); // NOTE: m_addr must be cleared before m_hndl is closed to avoid // a race condition with isRunning. The operation is done @@ -589,7 +601,7 @@ class Thread : ThreadBase } else version (Posix) { - if ( pthread_join( m_addr, null ) != 0 ) + if ( m_addr != m_addr.init && pthread_join( m_addr, null ) != 0 ) throw new ThreadException( "Unable to join thread" ); // NOTE: pthread_join acts as a substitute for pthread_detach, // which is normally called by the dtor. Setting m_addr @@ -1629,9 +1641,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."); @@ -1880,6 +1892,28 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc t.m_reg[14] = state.lr; t.m_reg[15] = state.pc; } + else version (PPC) + { + ppc_thread_state_t state = void; + mach_msg_type_number_t count = PPC_THREAD_STATE_COUNT; + + if (thread_get_state(t.m_tmach, PPC_THREAD_STATE, &state, &count) != KERN_SUCCESS) + onThreadError("Unable to load thread state"); + if (!t.m_lock) + t.m_curr.tstack = cast(void*) state.r[1]; + t.m_reg[] = state.r[]; + } + else version (PPC64) + { + ppc_thread_state64_t state = void; + mach_msg_type_number_t count = PPC_THREAD_STATE64_COUNT; + + if (thread_get_state(t.m_tmach, PPC_THREAD_STATE64, &state, &count) != KERN_SUCCESS) + onThreadError("Unable to load thread state"); + if (!t.m_lock) + t.m_curr.tstack = cast(void*) state.r[1]; + t.m_reg[] = state.r[]; + } else { static assert(false, "Architecture not supported." ); diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d index 50795e4..0a8de10 100644 --- a/libphobos/libdruntime/core/thread/threadbase.d +++ b/libphobos/libdruntime/core/thread/threadbase.d @@ -10,6 +10,9 @@ * Source: $(DRUNTIMESRC core/thread/osthread.d) */ +/* NOTE: This file has been patched from the original DMD distribution to + * work with the GDC compiler. + */ module core.thread.threadbase; import core.thread.context; diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 4f6a168..6f97404 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -f89dc217a680fa1a83f2999fea04b7c562f705ee +e6907ff3e28d3c43469c46df4a0426726ecb8631 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index b0310a8..9cbeca8e 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -1358,7 +1358,8 @@ version (Windows) /** -Flags that control the behaviour of $(LREF spawnProcess) and +Flags that control the behaviour of process creation functions in this +module. Most flags only apply to $(LREF spawnProcess) and $(LREF spawnShell). Use bitwise OR to combine flags. @@ -1433,6 +1434,21 @@ enum Config Calling $(LREF wait) or $(LREF kill) with the resulting $(D Pid) is invalid. */ detached = 64, + + /** + By default, the $(LREF execute) and $(LREF executeShell) functions + will capture child processes' both stdout and stderr. This can be + undesirable if the standard output is to be processed or otherwise + used by the invoking program, as `execute`'s result would then + contain a mix of output and warning/error messages. + + Specify this flag when calling `execute` or `executeShell` to + cause invoked processes' stderr stream to be sent to $(REF stderr, + std,stdio), and only capture and return standard output. + + This flag has no effect on $(LREF spawnProcess) or $(LREF spawnShell). + */ + stderrPassThrough = 128, } @@ -2487,7 +2503,11 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)( import std.array : appender; import std.typecons : Tuple; - auto p = pipeFunc(commandLine, Redirect.stdout | Redirect.stderrToStdout, + auto redirect = (config & Config.stderrPassThrough) + ? Redirect.stdout + : Redirect.stdout | Redirect.stderrToStdout; + + auto p = pipeFunc(commandLine, redirect, env, config, workDir, extraArgs); auto a = appender!(ubyte[])(); @@ -2551,6 +2571,30 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)( assert(r3.output.empty); } +@system unittest +{ + // Temporarily disable output to stderr so as to not spam the build log. + import std.stdio : stderr; + import std.typecons : Tuple; + import std.file : readText; + import std.traits : ReturnType; + + ReturnType!executeShell r; + auto tmpname = uniqueTempPath; + auto t = stderr; + // Open a new scope to minimize code ran with stderr redirected. + { + stderr.open(tmpname, "w"); + scope(exit) stderr = t; + r = executeShell("echo D rox>&2", null, Config.stderrPassThrough); + } + assert(r.status == 0); + assert(r.output.empty); + auto witness = readText(tmpname); + import std.ascii : newline; + assert(witness == "D rox" ~ newline, "'" ~ witness ~ "'"); +} + @safe unittest { import std.typecons : Tuple; @@ -2750,8 +2794,7 @@ private struct TestScript string path; } -version (unittest) -private string uniqueTempPath() @safe +package(std) string uniqueTempPath() @safe { import std.file : tempDir; import std.path : buildPath; -- cgit v1.1 From 6e81e015d91568fc3df3939623ae999e0681a0fc Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Tue, 20 Apr 2021 00:16:27 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index b4431a4..56f7de5 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,69 @@ +2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/98494 + * libdruntime/MERGE: Merge upstream druntime 89f870b7. + * src/MERGE: Merge upstream phobos e6907ff3e. + +2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/98058 + * configure: Regenerate. + * libdruntime/Makefile.am (DRUNTIME_DSOURCES_DARWIN): Add + core/sys/darwin/config.d + * libdruntime/Makefile.in: Regenerate. + * libdruntime/config/powerpc/switchcontext.S: Implement + fiber_switchContext for __MACH__. + * libdruntime/config/x86/switchcontext.S: Likewise. + * libdruntime/core/sys/darwin/config.d: New file. + * libdruntime/core/thread/fiber.d (Fiber.getThis): Mark noinline. + (UnsafeFiberMigration): Define for OSX/X86 and OSX/X86_64. + * libdruntime/core/thread/osthread.d (callWithStackShell): Add inline + assembler implementation for X86, X86_64, PPC, and PPC64. + * libdruntime/core/thread/threadbase.d (ThreadBase.getThis): Mark + noinline. + * libdruntime/gcc/deh.d (FuncTable): Remove definition. + * m4/druntime/os.m4 (DRUNTIME_OS_MINFO_BRACKETING): Check for right + bracket symbol on darwin* targets. + * testsuite/libphobos.thread/fiber_guard_page.d: Update test to + support ucontext-based Fibers. + +2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org> + + 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. + +2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/99691 + * configure: Regenerate. + * libdruntime/config/common/threadasm.S: Add __OpenBSD__. + * libdruntime/gcc/backtrace.d: Import core.sys.openbsd.dlfcn on + OpenBSD platforms. + * libdruntime/gcc/sections/elf.d (SharedElf): Define on OpenBSD. + (linkMapForHandle): Implement for OpenBSD. + (exeLinkMap): Remove. + (getDependencies): Adjust dlpi_addr on OpenBSD. + (handleForName): Implement for OpenBSD. + (IterateManually): Define on OpenBSD. + * libdruntime/gcc/sections/package.d (SectionsElf): Define on OpenBSD. + * m4/druntime/libraries.m4 (DRUNTIME_LIBRARIES_ATOMIC): Test for + enable_libatomic. + (DRUNTIME_LIBRARIES_BACKTRACE): Test for enable_libbacktrace. + 2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org> * Makefile.in: Regenerate. -- cgit v1.1 From 30b11d8d1be9c683f1517472c47a3cb69df02c4f Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Tue, 20 Apr 2021 02:09:51 +0200 Subject: libphobos: Fix SIGBUS in read_encoded_value_with_base on sparc-sun-solaris (PR98584) Instead of unsafe pointer dereferencing, use memcpy() to read encoded values from memory. The function `read_encoded_value' has been updated to accept a ref parameter, this simplifies handling of the pointer to memory needing to be read. libphobos/ChangeLog: PR d/98584 * libdruntime/gcc/deh.d (scanLSDA): Update calls to read_uleb128 and read_encoded_value. (actionTableLookup): Update calls to read_sleb128 and read_encoded_value_with_base. * libdruntime/gcc/unwind/pe.d (read_uleb128): Update signature. (read_sleb128): Update signature. (read_unaligned): New function. (read_encoded_value_with_base): Update signature. Call read_unaligned instead of unsafe pointer dereferencing. (read_encoded_value): Update signature. --- libphobos/libdruntime/gcc/deh.d | 24 +++++------ libphobos/libdruntime/gcc/unwind/pe.d | 81 +++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 48 deletions(-) (limited to 'libphobos') diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index 712f5d7..eb83751c 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -547,7 +547,7 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti _Unwind_Ptr LPStart = 0; if (LPStartEncoding != DW_EH_PE_omit) - LPStart = read_encoded_value(context, LPStartEncoding, &p); + LPStart = read_encoded_value(context, LPStartEncoding, p); else LPStart = Start; @@ -563,14 +563,14 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti // hardcoded OS-specific format. TTypeEncoding = _TTYPE_ENCODING; } - auto TTbase = read_uleb128(&p); + auto TTbase = read_uleb128(p); TType = p + TTbase; } // The encoding and length of the call-site table; the action table // immediately follows. ubyte CSEncoding = *p++; - auto CSTableSize = read_uleb128(&p); + auto CSTableSize = read_uleb128(p); const(ubyte)* actionTable = p + CSTableSize; auto TTypeBase = base_of_encoded_value(TTypeEncoding, context); @@ -608,8 +608,8 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti _uleb128_t CSLandingPad, CSAction; do { - CSLandingPad = read_uleb128(&p); - CSAction = read_uleb128(&p); + CSLandingPad = read_uleb128(p); + CSAction = read_uleb128(p); } while (--ip); @@ -626,10 +626,10 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti while (p < actionTable) { // Note that all call-site encodings are "absolute" displacements. - auto CSStart = read_encoded_value(null, CSEncoding, &p); - auto CSLen = read_encoded_value(null, CSEncoding, &p); - auto CSLandingPad = read_encoded_value(null, CSEncoding, &p); - auto CSAction = read_uleb128(&p); + auto CSStart = read_encoded_value(null, CSEncoding, p); + auto CSLen = read_encoded_value(null, CSEncoding, p); + auto CSLandingPad = read_encoded_value(null, CSEncoding, p); + auto CSAction = read_uleb128(p); // The table is sorted, so if we've passed the ip, stop. if (ip < Start + CSStart) @@ -703,9 +703,9 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, while (1) { auto ap = actionRecord; - auto ARFilter = read_sleb128(&ap); + auto ARFilter = read_sleb128(ap); auto apn = ap; - auto ARDisp = read_sleb128(&ap); + auto ARDisp = read_sleb128(ap); if (ARFilter == 0) { @@ -725,7 +725,7 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, // the ClassInfo is stored. const(ubyte)* tp = TType - ARFilter * encodedSize; - auto entry = read_encoded_value_with_base(TTypeEncoding, TTypeBase, &tp); + auto entry = read_encoded_value_with_base(TTypeEncoding, TTypeBase, tp); ClassInfo ci = cast(ClassInfo)cast(void*)(entry); // D does not have catch-all handlers, and so the following diff --git a/libphobos/libdruntime/gcc/unwind/pe.d b/libphobos/libdruntime/gcc/unwind/pe.d index 361ec12..b9b05cb 100644 --- a/libphobos/libdruntime/gcc/unwind/pe.d +++ b/libphobos/libdruntime/gcc/unwind/pe.d @@ -103,40 +103,37 @@ _Unwind_Ptr base_of_encoded_value(ubyte encoding, _Unwind_Context* context) assert(0); } -// Read an unsigned leb128 value from P, *P is incremented past the value. +// Read an unsigned leb128 value from P, P is incremented past the value. // We assume that a word is large enough to hold any value so encoded; // if it is smaller than a pointer on some target, pointers should not be // leb128 encoded on that target. -_uleb128_t read_uleb128(const(ubyte)** p) +_uleb128_t read_uleb128(ref const(ubyte)* p) { - auto q = *p; _uleb128_t result = 0; uint shift = 0; while (1) { - ubyte b = *q++; + ubyte b = *p++; result |= cast(_uleb128_t)(b & 0x7F) << shift; if ((b & 0x80) == 0) break; shift += 7; } - *p = q; return result; } // Similar, but read a signed leb128 value. -_sleb128_t read_sleb128(const(ubyte)** p) +_sleb128_t read_sleb128(ref const(ubyte)* p) { - auto q = *p; _sleb128_t result = 0; uint shift = 0; ubyte b = void; while (1) { - b = *q++; + b = *p++; result |= cast(_sleb128_t)(b & 0x7F) << shift; shift += 7; if ((b & 0x80) == 0) @@ -147,69 +144,82 @@ _sleb128_t read_sleb128(const(ubyte)** p) if (shift < result.sizeof * 8 && (b & 0x40)) result |= -(cast(_sleb128_t)1 << shift); - *p = q; return result; } -// Load an encoded value from memory at P. The value is returned in VAL; -// The function returns P incremented past the value. BASE is as given +// Similar, but read an unaligned value of type T. +pragma(inline, true) +private T read_unaligned(T)(ref const(ubyte)* p) +{ + version (X86) enum hasUnalignedLoads = true; + else version (X86_64) enum hasUnalignedLoads = true; + else enum hasUnalignedLoads = false; + + static if (hasUnalignedLoads) + { + T result = *cast(T*)p; + } + else + { + import core.stdc.string : memcpy; + T result = void; + memcpy(&result, p, T.sizeof); + } + p += T.sizeof; + return result; +} + +// Load an encoded value from memory at P. The function returns the +// encoded value. P is incremented past the value. BASE is as given // by base_of_encoded_value for this encoding in the appropriate context. _Unwind_Ptr read_encoded_value_with_base(ubyte encoding, _Unwind_Ptr base, - const(ubyte)** p) + ref const(ubyte)* p) { - auto q = *p; + auto psave = p; _Unwind_Internal_Ptr result; if (encoding == DW_EH_PE_aligned) { - _Unwind_Internal_Ptr a = cast(_Unwind_Internal_Ptr)q; + _Unwind_Internal_Ptr a = cast(_Unwind_Internal_Ptr)p; a = cast(_Unwind_Internal_Ptr)((a + (void*).sizeof - 1) & - (void*).sizeof); result = *cast(_Unwind_Internal_Ptr*)a; - q = cast(ubyte*) cast(_Unwind_Internal_Ptr)(a + (void*).sizeof); + p = cast(ubyte*) cast(_Unwind_Internal_Ptr)(a + (void*).sizeof); } else { switch (encoding & 0x0f) { case DW_EH_PE_uleb128: - result = cast(_Unwind_Internal_Ptr)read_uleb128(&q); + result = cast(_Unwind_Internal_Ptr)read_uleb128(p); break; case DW_EH_PE_sleb128: - result = cast(_Unwind_Internal_Ptr)read_sleb128(&q); + result = cast(_Unwind_Internal_Ptr)read_sleb128(p); break; case DW_EH_PE_udata2: - result = cast(_Unwind_Internal_Ptr) *cast(ushort*)q; - q += 2; + result = cast(_Unwind_Internal_Ptr)read_unaligned!ushort(p); break; case DW_EH_PE_udata4: - result = cast(_Unwind_Internal_Ptr) *cast(uint*)q; - q += 4; + result = cast(_Unwind_Internal_Ptr)read_unaligned!uint(p); break; case DW_EH_PE_udata8: - result = cast(_Unwind_Internal_Ptr) *cast(ulong*)q; - q += 8; + result = cast(_Unwind_Internal_Ptr)read_unaligned!ulong(p); break; case DW_EH_PE_sdata2: - result = cast(_Unwind_Internal_Ptr) *cast(short*)q; - q += 2; + result = cast(_Unwind_Internal_Ptr)read_unaligned!short(p); break; case DW_EH_PE_sdata4: - result = cast(_Unwind_Internal_Ptr) *cast(int*)q; - q += 4; + result = cast(_Unwind_Internal_Ptr)read_unaligned!int(p); break; case DW_EH_PE_sdata8: - result = cast(_Unwind_Internal_Ptr) *cast(long*)q; - q += 8; + result = cast(_Unwind_Internal_Ptr)read_unaligned!long(p); break; case DW_EH_PE_absptr: - if (size_t.sizeof == 8) - goto case DW_EH_PE_udata8; - else - goto case DW_EH_PE_udata4; + result = cast(_Unwind_Internal_Ptr)read_unaligned!(size_t)(p); + break; default: __builtin_abort(); @@ -218,20 +228,19 @@ _Unwind_Ptr read_encoded_value_with_base(ubyte encoding, _Unwind_Ptr base, if (result != 0) { result += ((encoding & 0x70) == DW_EH_PE_pcrel - ? cast(_Unwind_Internal_Ptr)*p : base); + ? cast(_Unwind_Internal_Ptr)psave : base); if (encoding & DW_EH_PE_indirect) result = *cast(_Unwind_Internal_Ptr*)result; } } - *p = q; return result; } // Like read_encoded_value_with_base, but get the base from the context // rather than providing it directly. _Unwind_Ptr read_encoded_value(_Unwind_Context* context, ubyte encoding, - const(ubyte)** p) + ref const(ubyte)* p) { auto base = base_of_encoded_value(encoding, context); return read_encoded_value_with_base(encoding, base, p); -- cgit v1.1 From be8aad8d73f47e2581c873ba1069489e071c2a86 Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed, 21 Apr 2021 00:16:23 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 56f7de5..ddb1830 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,17 @@ +2021-04-20 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/98584 + * libdruntime/gcc/deh.d (scanLSDA): Update calls to read_uleb128 and + read_encoded_value. + (actionTableLookup): Update calls to read_sleb128 and + read_encoded_value_with_base. + * libdruntime/gcc/unwind/pe.d (read_uleb128): Update signature. + (read_sleb128): Update signature. + (read_unaligned): New function. + (read_encoded_value_with_base): Update signature. Call read_unaligned + instead of unsafe pointer dereferencing. + (read_encoded_value): Update signature. + 2021-04-19 Iain Buclaw <ibuclaw@gdcproject.org> PR d/98494 -- cgit v1.1 From ea7b1cf534a7a653e1221bcd9004c2d0f5418e88 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Wed, 21 Apr 2021 01:15:33 +0200 Subject: libphobos: Fix build fails for powerpc-linux As register names are required for darwin, but not accepted by gas unless you use `-mregnames', they have been conditionally removed on non-darwin targets. To avoid duplicating large blocks of almost identical code, the inline assembly is now statically generated. libphobos/ChangeLog: * libdruntime/core/thread/osthread.d (callWithStackShell): Statically generate PPC and PPC64 asm implementations, and conditionally remove PPC register names on non-Darwin targets. --- libphobos/libdruntime/core/thread/osthread.d | 68 ++++++++++------------------ 1 file changed, 24 insertions(+), 44 deletions(-) (limited to 'libphobos') diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 31764e6..9fcd30e 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -1444,55 +1444,35 @@ in (fn) else version (PPC) { void*[19] regs = void; - asm pure nothrow @nogc - { - "stw r13, %0" : "=m" (regs[ 0]); - "stw r14, %0" : "=m" (regs[ 1]); - "stw r15, %0" : "=m" (regs[ 2]); - "stw r16, %0" : "=m" (regs[ 3]); - "stw r17, %0" : "=m" (regs[ 4]); - "stw r18, %0" : "=m" (regs[ 5]); - "stw r19, %0" : "=m" (regs[ 6]); - "stw r20, %0" : "=m" (regs[ 7]); - "stw r21, %0" : "=m" (regs[ 9]); - "stw r22, %0" : "=m" (regs[ 9]); - "stw r23, %0" : "=m" (regs[10]); - "stw r24, %0" : "=m" (regs[11]); - "stw r25, %0" : "=m" (regs[12]); - "stw r26, %0" : "=m" (regs[13]); - "stw r27, %0" : "=m" (regs[14]); - "stw r28, %0" : "=m" (regs[15]); - "stw r29, %0" : "=m" (regs[16]); - "stw r30, %0" : "=m" (regs[17]); - "stw r31, %0" : "=m" (regs[18]); - } + version (Darwin) + enum regname = "r"; + else + enum regname = ""; + static foreach (i; 0 .. regs.length) + {{ + enum int j = 13 + i; // source register + asm pure nothrow @nogc + { + "stw "~regname~j.stringof~", %0" : "=m" (regs[i]); + } + }} sp = cast(void*)®s[0]; } else version (PPC64) { void*[19] regs = void; - asm pure nothrow @nogc - { - "std r13, %0" : "=m" (regs[ 0]); - "std r14, %0" : "=m" (regs[ 1]); - "std r15, %0" : "=m" (regs[ 2]); - "std r16, %0" : "=m" (regs[ 3]); - "std r17, %0" : "=m" (regs[ 4]); - "std r18, %0" : "=m" (regs[ 5]); - "std r19, %0" : "=m" (regs[ 6]); - "std r20, %0" : "=m" (regs[ 7]); - "std r21, %0" : "=m" (regs[ 8]); - "std r22, %0" : "=m" (regs[ 9]); - "std r23, %0" : "=m" (regs[10]); - "std r24, %0" : "=m" (regs[11]); - "std r25, %0" : "=m" (regs[12]); - "std r26, %0" : "=m" (regs[13]); - "std r27, %0" : "=m" (regs[14]); - "std r28, %0" : "=m" (regs[15]); - "std r29, %0" : "=m" (regs[16]); - "std r30, %0" : "=m" (regs[17]); - "std r31, %0" : "=m" (regs[18]); - } + version (Darwin) + enum regname = "r"; + else + enum regname = ""; + static foreach (i; 0 .. regs.length) + {{ + enum int j = 13 + i; // source register + asm pure nothrow @nogc + { + "std "~regname~j.stringof~", %0" : "=m" (regs[i]); + } + }} sp = cast(void*)®s[0]; } else -- cgit v1.1 From c1ef0c9234c29c33397b7687ba54c1221fcbcb6b Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Thu, 22 Apr 2021 00:16:32 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index ddb1830..a588ad2 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,9 @@ +2021-04-21 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/core/thread/osthread.d (callWithStackShell): Statically + generate PPC and PPC64 asm implementations, and conditionally remove + PPC register names on non-Darwin targets. + 2021-04-20 Iain Buclaw <ibuclaw@gdcproject.org> PR d/98584 -- cgit v1.1 From 1f58114db8cd90284367928cc79bb71d95db248d Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Wed, 5 May 2021 00:28:44 +0200 Subject: libphobos: Fix visibility of std.process.searchPathFor This symbol is used by std.file.thisExePath on OpenBSD. Reviewed-on: https://github.com/dlang/phobos/pull/8041 libphobos/ChangeLog: * src/MERGE: Merge upstream phobos 32cfe9b61. --- libphobos/src/MERGE | 2 +- libphobos/src/std/process.d | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libphobos') diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 6f97404..49622c5 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -e6907ff3e28d3c43469c46df4a0426726ecb8631 +32cfe9b61570d52d9885b0208fd20de0d351b51e The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 9cbeca8e..63ec493 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -887,7 +887,7 @@ version (Windows) @system unittest // Searches the PATH variable for the given executable file, // (checking that it is in fact executable). version (Posix) -private string searchPathFor(in char[] executable) +package(std) string searchPathFor(in char[] executable) @trusted //TODO: @safe nothrow { import std.algorithm.iteration : splitter; -- cgit v1.1 From aa891c56f25baac94db004e309d1b6e40b770a95 Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Tue, 11 May 2021 00:16:36 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index a588ad2..62118c0 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,7 @@ +2021-05-10 Iain Buclaw <ibuclaw@gdcproject.org> + + * src/MERGE: Merge upstream phobos 32cfe9b61. + 2021-04-21 Iain Buclaw <ibuclaw@gdcproject.org> * libdruntime/core/thread/osthread.d (callWithStackShell): Statically -- cgit v1.1 From b7b413152ecb9e6a734a45688f3a9df77a686206 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Thu, 13 May 2021 19:09:48 +0200 Subject: libphobos: Fix static asserts on NetBSD, FreeBSD, DragonFlyBSD The function declarations were updated to use `const scope', but the static asserts were not. Reviewed-on: https://github.com/dlang/druntime/pull/3470 libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 98c6ff0c. --- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d | 15 ++++++--------- libphobos/libdruntime/core/sys/freebsd/dlfcn.d | 4 ++-- libphobos/libdruntime/core/sys/netbsd/dlfcn.d | 15 ++++++--------- libphobos/libdruntime/core/sys/posix/dlfcn.d | 4 ++-- 5 files changed, 17 insertions(+), 23 deletions(-) (limited to 'libphobos') diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 25cbb95..0d554e0 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -89f870b76710a4cfa96f711bb5b14a7439c5c2a7 +98c6ff0cf1241a0cfac196bf8a0523b1d4ecd3ac The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d b/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d index 1d3812f..2c5d8d7 100644 --- a/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d +++ b/libphobos/libdruntime/core/sys/dragonflybsd/dlfcn.d @@ -82,16 +82,13 @@ struct __dlfunc_arg { alias dlfunc_t = void function(__dlfunc_arg); -private template __externC(RT, P...) -{ - alias __externC = extern(C) RT function(P) nothrow @nogc @system; -} - /* XSI functions first. */ -static assert(is(typeof(&dlclose) == __externC!(int, void*))); -static assert(is(typeof(&dlerror) == __externC!(char*))); -static assert(is(typeof(&dlopen) == __externC!(void*, const char*, int))); -static assert(is(typeof(&dlsym) == __externC!(void*, void*, const char*))); +extern(C) { + static assert(is(typeof(&dlclose) == int function(void*))); + static assert(is(typeof(&dlerror) == char* function())); + static assert(is(typeof(&dlopen) == void* function(const scope char*, int))); + static assert(is(typeof(&dlsym) == void* function(void*, const scope char*))); +} void* fdlopen(int, int); int dladdr(const(void)*, Dl_info*); diff --git a/libphobos/libdruntime/core/sys/freebsd/dlfcn.d b/libphobos/libdruntime/core/sys/freebsd/dlfcn.d index fad9141..7baacfe 100644 --- a/libphobos/libdruntime/core/sys/freebsd/dlfcn.d +++ b/libphobos/libdruntime/core/sys/freebsd/dlfcn.d @@ -90,8 +90,8 @@ static if (__BSD_VISIBLE) extern(C) { static assert(is(typeof(&dlclose) == int function(void*))); static assert(is(typeof(&dlerror) == char* function())); - static assert(is(typeof(&dlopen) == void* function(in char*, int))); - static assert(is(typeof(&dlsym) == void* function(void*, in char*))); + static assert(is(typeof(&dlopen) == void* function(const scope char*, int))); + static assert(is(typeof(&dlsym) == void* function(void*, const scope char*))); } static if (__BSD_VISIBLE) diff --git a/libphobos/libdruntime/core/sys/netbsd/dlfcn.d b/libphobos/libdruntime/core/sys/netbsd/dlfcn.d index dbbcc76..468ffbf 100644 --- a/libphobos/libdruntime/core/sys/netbsd/dlfcn.d +++ b/libphobos/libdruntime/core/sys/netbsd/dlfcn.d @@ -87,16 +87,13 @@ static if (__BSD_VISIBLE) } } -private template __externC(RT, P...) -{ - alias __externC = extern(C) RT function(P) nothrow @nogc; -} - /* XSI functions first. */ -static assert(is(typeof(&dlclose) == __externC!(int, void*))); -static assert(is(typeof(&dlerror) == __externC!(char*))); -static assert(is(typeof(&dlopen) == __externC!(void*, const char*, int))); -static assert(is(typeof(&dlsym) == __externC!(void*, void*, const char*))); +extern(C) { + static assert(is(typeof(&dlclose) == int function(void*))); + static assert(is(typeof(&dlerror) == char* function())); + static assert(is(typeof(&dlopen) == void* function(const scope char*, int))); + static assert(is(typeof(&dlsym) == void* function(void*, const scope char*))); +} static if (__BSD_VISIBLE) { diff --git a/libphobos/libdruntime/core/sys/posix/dlfcn.d b/libphobos/libdruntime/core/sys/posix/dlfcn.d index 2477e26..f6476ec 100644 --- a/libphobos/libdruntime/core/sys/posix/dlfcn.d +++ b/libphobos/libdruntime/core/sys/posix/dlfcn.d @@ -158,8 +158,8 @@ else version (FreeBSD) int dlclose(void*); char* dlerror(); - void* dlopen(in char*, int); - void* dlsym(void*, in char*); + void* dlopen(const scope char*, int); + void* dlsym(void*, const scope char*); int dladdr(const(void)* addr, Dl_info* info); struct Dl_info -- cgit v1.1 From f9af11c7f156bede9aa28410073acbab7b0fa0fe Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Fri, 14 May 2021 00:16:30 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 62118c0..7574416 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,7 @@ +2021-05-13 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/MERGE: Merge upstream druntime 98c6ff0c. + 2021-05-10 Iain Buclaw <ibuclaw@gdcproject.org> * src/MERGE: Merge upstream phobos 32cfe9b61. -- cgit v1.1 From cb787efa45782adab764575a2efc356e082828b6 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger <bernd.edlinger@hotmail.de> Date: Fri, 14 May 2021 07:10:59 +0200 Subject: Cleanup temp files in libphobos unittest at src/std/process.d 2021-05-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * src/std/process.d (unittest): Remove tmpname on exit. * src/MERGE: Merge upstream phobos 63f4caa90. --- libphobos/src/MERGE | 2 +- libphobos/src/std/process.d | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'libphobos') diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 49622c5..ac709f9 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -32cfe9b61570d52d9885b0208fd20de0d351b51e +63f4caa900e17c541042617b2fa187059b86bf88 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 63ec493..1e977aa 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -2581,6 +2581,7 @@ private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)( ReturnType!executeShell r; auto tmpname = uniqueTempPath; + scope(exit) if (exists(tmpname)) remove(tmpname); auto t = stderr; // Open a new scope to minimize code ran with stderr redirected. { -- cgit v1.1 From 87a7d10c2e9ec34a276e6acb5d2282a35b9cfafb Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Sat, 15 May 2021 00:16:27 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 7574416..7b57d92 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,8 @@ +2021-05-14 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * src/std/process.d (unittest): Remove tmpname on exit. + * src/MERGE: Merge upstream phobos 63f4caa90. + 2021-05-13 Iain Buclaw <ibuclaw@gdcproject.org> * libdruntime/MERGE: Merge upstream druntime 98c6ff0c. -- cgit v1.1 From 68f46862d33707450bdf70cfddd91ae2a12527a8 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Fri, 11 Jun 2021 19:33:07 +0200 Subject: d: foreach over a tuple doesn't work on 16-bit targets (PR100999) Improves semantic passes in the front-end around the `foreach' and `static foreach' statements to be more resilient to compiling in a minimal D runtime environment. Checking of the index type has been improved as well so now there won't be needless compiler errors when using 8 or 16-bit integers as index types when the size fits the expected loop range. gcc/d/ChangeLog: PR d/100999 * dmd/MERGE: Merge upstream dmd 7a3808254. libphobos/ChangeLog: PR d/100999 * src/MERGE: Merge upstream phobos 55bb17543. --- libphobos/src/MERGE | 2 +- libphobos/src/std/typecons.d | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'libphobos') diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index ac709f9..01cf594 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -63f4caa900e17c541042617b2fa187059b86bf88 +55bb17543138a87c376a84745f2a30ec00bdecd9 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index 55119fc..84e876f 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -5935,13 +5935,7 @@ mixin template Proxy(alias a) // built-in type field, manifest constant, and static non-mutable field enum opDispatch = mixin("a."~name); } - else static if (is(typeof(mixin("a."~name))) || __traits(getOverloads, a, name).length != 0) - { - // field or property function - @property auto ref opDispatch(this X)() { return mixin("a."~name); } - @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); } - } - else + else static if (__traits(isTemplate, mixin("a."~name))) { // member template template opDispatch(T...) @@ -5950,6 +5944,13 @@ mixin template Proxy(alias a) auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); } } } + else + { + // field or property function + @property auto ref opDispatch(this X)() { return mixin("a."~name); } + @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); } + } + } import std.traits : isArray; -- cgit v1.1 From f16f65f8364b5bf23c72a8fdbba4974ecadc5cb6 Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Sat, 12 Jun 2021 00:16:27 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 7b57d92..60a67a9 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,8 @@ +2021-06-11 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/100999 + * src/MERGE: Merge upstream phobos 55bb17543. + 2021-05-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * src/std/process.d (unittest): Remove tmpname on exit. -- cgit v1.1 From 02dbf5d1273eda7db1ef6164b56879e8dc0530f8 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon, 30 Aug 2021 12:12:25 +0200 Subject: libphobos: Compile configure tests with -fno-druntime libphobos/ChangeLog: * configure: Regenerate. * m4/autoconf.m4 (AC_LANG_PROGRAM): Declare module name 'object'. * m4/gcc_support.m4 (WITH_LOCAL_DRUNTIME): Compile tests with -fno-druntime. --- libphobos/configure | 28 ++++++++++++++-------------- libphobos/m4/autoconf.m4 | 2 +- libphobos/m4/gcc_support.m4 | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'libphobos') diff --git a/libphobos/configure b/libphobos/configure index b1c8ecb..14298a0 100755 --- a/libphobos/configure +++ b/libphobos/configure @@ -5382,7 +5382,7 @@ fi gdc_save_DFLAGS=$GDCFLAGS - GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS" + GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS" ac_ext=d ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5' @@ -5392,7 +5392,7 @@ ac_compiler_gnu=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking If $GDC can compile D sources" >&5 $as_echo_n "checking If $GDC can compile D sources... " >&6; } cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; extern(C) int main() { @@ -12097,7 +12097,7 @@ CC="$lt_save_CC" gdc_save_DFLAGS=$GDCFLAGS - GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS" + GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $GDCFLAGS" # Source file extension for D test sources. @@ -14089,7 +14089,7 @@ fi gdc_save_DFLAGS=$GDCFLAGS - GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS" + GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS" ac_ext=d ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5' @@ -14098,7 +14098,7 @@ ac_compiler_gnu=yes GDCFLAGS="$GDCFLAGS -g -Werror -ffunction-sections -fdata-sections" cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; int foo; void bar() { } extern(C) int main() { @@ -14562,7 +14562,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu gdc_save_DFLAGS=$GDCFLAGS - GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS" + GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime -nophoboslib $GDCFLAGS" ac_ext=d ac_compile='$GDC -c $GDCFLAGS conftest.$ac_ext >&5' @@ -14576,7 +14576,7 @@ if ${ac_cv_search_malloc+:} false; then : else ac_func_search_save_LIBS=$LIBS cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; extern(C) int malloc(); extern(C) int main() { @@ -14622,7 +14622,7 @@ if ${ac_cv_search_pthread_create+:} false; then : else ac_func_search_save_LIBS=$LIBS cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; extern(C) int pthread_create(); extern(C) int main() { @@ -14668,7 +14668,7 @@ if ${ac_cv_search_cosf+:} false; then : else ac_func_search_save_LIBS=$LIBS cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; extern(C) int cosf(); extern(C) int main() { @@ -14714,7 +14714,7 @@ if ${ac_cv_search_clock_gettime+:} false; then : else ac_func_search_save_LIBS=$LIBS cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; extern(C) int clock_gettime(); extern(C) int main() { @@ -14765,7 +14765,7 @@ $as_echo_n "checking for atomic builtins for byte... " >&6; } else cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; import gcc.builtins; extern(C) int main() { @@ -14799,7 +14799,7 @@ $as_echo_n "checking for atomic builtins for short... " >&6; } else cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; import gcc.builtins; extern(C) int main() { @@ -14833,7 +14833,7 @@ $as_echo_n "checking for atomic builtins for int... " >&6; } else cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; import gcc.builtins; extern(C) int main() { @@ -14867,7 +14867,7 @@ $as_echo_n "checking for atomic builtins for long... " >&6; } else cat > conftest.$ac_ext <<_ACEOF -module mod; +module object; import gcc.builtins; extern(C) int main() { diff --git a/libphobos/m4/autoconf.m4 b/libphobos/m4/autoconf.m4 index f46a780..f0ca947 100644 --- a/libphobos/m4/autoconf.m4 +++ b/libphobos/m4/autoconf.m4 @@ -27,7 +27,7 @@ AU_DEFUN([AC_LANG_D], [AC_LANG(D)]) # AC_LANG_PROGRAM(D)([PROLOGUE], [BODY]) # --------------------------------------- m4_define([AC_LANG_PROGRAM(D)], -[module mod; +[module object; $1 extern(C) int main() { diff --git a/libphobos/m4/gcc_support.m4 b/libphobos/m4/gcc_support.m4 index 0903ed4..cc1acb4 100644 --- a/libphobos/m4/gcc_support.m4 +++ b/libphobos/m4/gcc_support.m4 @@ -27,7 +27,7 @@ AC_DEFUN([PHOBOS_ABS_SRCDIR], [ AC_DEFUN([WITH_LOCAL_DRUNTIME], [ AC_REQUIRE([PHOBOS_ABS_SRCDIR]) gdc_save_DFLAGS=$GDCFLAGS - GDCFLAGS="-fno-moduleinfo -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $2 $GDCFLAGS" + GDCFLAGS="-fno-druntime -nostdinc -I $phobos_cv_abs_srcdir/libdruntime $2 $GDCFLAGS" $1 GDCFLAGS=$gdc_save_DFLAGS ]) -- cgit v1.1 From 1e2f030b80cb650708b02086dbd5431cd231495f Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Tue, 31 Aug 2021 00:16:50 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 60a67a9..d9efdad 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,10 @@ +2021-08-30 Iain Buclaw <ibuclaw@gdcproject.org> + + * configure: Regenerate. + * m4/autoconf.m4 (AC_LANG_PROGRAM): Declare module name 'object'. + * m4/gcc_support.m4 (WITH_LOCAL_DRUNTIME): Compile tests with + -fno-druntime. + 2021-06-11 Iain Buclaw <ibuclaw@gdcproject.org> PR d/100999 -- cgit v1.1 From 53cfed5cc920e3aba98958415b42d49e9a80a6e3 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Wed, 1 Sep 2021 14:11:05 +0200 Subject: libphobos: Don't add zlib when ENABLE_LIBDRUNTIME_ONLY The D run-time library does not depend on zlib, so only include it in the library when Phobos is being built as well. libphobos/ChangeLog: * src/Makefile.am: Don't add zlib when ENABLE_LIBDRUNTIME_ONLY. * src/Makefile.in: Regenerate. --- libphobos/src/Makefile.am | 4 ++++ libphobos/src/Makefile.in | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'libphobos') diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am index f97ddcc..9f62510 100644 --- a/libphobos/src/Makefile.am +++ b/libphobos/src/Makefile.am @@ -45,8 +45,12 @@ libgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) libgphobos_la_LIBTOOLFLAGS = libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \ -version-info $(libtool_VERSION) +if ENABLE_LIBDRUNTIME_ONLY +libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la +else libgphobos_la_LIBADD = \ ../libdruntime/libgdruntime_convenience.la $(LIBZ) +endif libgphobos_la_DEPENDENCIES = \ ../libdruntime/libgdruntime_convenience.la libgphobos.spec diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in index 4f76e10..f8b7648 100644 --- a/libphobos/src/Makefile.in +++ b/libphobos/src/Makefile.in @@ -504,9 +504,10 @@ libgphobos_la_LIBTOOLFLAGS = libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \ -version-info $(libtool_VERSION) -libgphobos_la_LIBADD = \ - ../libdruntime/libgdruntime_convenience.la $(LIBZ) +@ENABLE_LIBDRUNTIME_ONLY_FALSE@libgphobos_la_LIBADD = \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ ../libdruntime/libgdruntime_convenience.la $(LIBZ) +@ENABLE_LIBDRUNTIME_ONLY_TRUE@libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la libgphobos_la_DEPENDENCIES = \ ../libdruntime/libgdruntime_convenience.la libgphobos.spec -- cgit v1.1 From fcc0c84cf5d29de431172347a28366ee0b428a86 Mon Sep 17 00:00:00 2001 From: Iain Buclaw <ibuclaw@gdcproject.org> Date: Wed, 1 Sep 2021 14:18:16 +0200 Subject: libphobos: Update comment for DRUNTIME_OS_SOURCES libphobos/ChangeLog: * m4/druntime/os.m4: Update comment for DRUNTIME_OS_SOURCES. --- libphobos/m4/druntime/os.m4 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'libphobos') diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4 index 351558d..15cde3b 100644 --- a/libphobos/m4/druntime/os.m4 +++ b/libphobos/m4/druntime/os.m4 @@ -54,9 +54,10 @@ AC_DEFUN([DRUNTIME_OS_DETECT], # DRUNTIME_OS_SOURCES # ------------------- -# Detect target OS and add DRUNTIME_OS_AIX DRUNTIME_OS_DARWIN -# DRUNTIME_OS_FREEBSD DRUNTIME_OS_LINUX DRUNTIME_OS_MINGW -# DRUNTIME_OS_SOLARIS DRUNTIME_OS_OPENBSD conditionals. +# Detect target OS and add DRUNTIME_OS_AIX DRUNTIME_OS_ANDROID +# DRUNTIME_OS_DARWIN DRUNTIME_OS_DRAGONFLYBSD DRUNTIME_OS_FREEBSD +# DRUNTIME_OS_LINUX DRUNTIME_OS_MINGW DRUNTIME_OS_NETBSD +# DRUNTIME_OS_OPENBSD DRUNTIME_OS_SOLARIS conditionals. # If the system is posix, add DRUNTIME_OS_POSIX conditional. AC_DEFUN([DRUNTIME_OS_SOURCES], [ -- cgit v1.1 From e11c6046f9c8bc891a67f37f0260ef4ece482f5d Mon Sep 17 00:00:00 2001 From: GCC Administrator <gccadmin@gcc.gnu.org> Date: Thu, 2 Sep 2021 00:16:59 +0000 Subject: Daily bump. --- libphobos/ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'libphobos') diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index d9efdad..fa1aef7 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,12 @@ +2021-09-01 Iain Buclaw <ibuclaw@gdcproject.org> + + * m4/druntime/os.m4: Update comment for DRUNTIME_OS_SOURCES. + +2021-09-01 Iain Buclaw <ibuclaw@gdcproject.org> + + * src/Makefile.am: Don't add zlib when ENABLE_LIBDRUNTIME_ONLY. + * src/Makefile.in: Regenerate. + 2021-08-30 Iain Buclaw <ibuclaw@gdcproject.org> * configure: Regenerate. -- cgit v1.1