This is _really_ nice.

On Thu, 4 Jun 2020, at 08:33, Martin Storsjö wrote:
> This adds libucrtapp.a, which is the same as libucrt.a, but excluding
> libapi-ms-win-crt-private-l1-1-0.a, and with a few statically
> linked functions added that otherwise normally are linked from
> libapi-ms-win-crt-private-l1-1-0.a.
> 
> Linking against the private dll (and ucrtbase.dll) is prohibited when
> targeting UWP. An app built and packaged with MSVC would link against
> these functions from vcruntime140_app.dll, which ends up bundled with
> the app itself. However, the goal of this patch is to make it possible
> to build a UWP app with mingw tools and redistribute it without bundling
> vcruntime140_app.dll or similar ones from MSVC.
> 
> By using a separate copy of libucrt*.a, without the forbidden bits, it
> gives a clear linker error if an app requires linking against other
> functions that aren't implemented yet, instead of silently ending up
> depending on the forbidden api-ms-win-crt-private-l1-1-0.dll.
> 
> The functions from this DLL, that end up linked in a mingw build,
> are primarily one of the these three areas:
> - __C_specific_handler
>   The implementation so far is a dummy; wine should have a suitable
>   proper implementation for reference. This shouldn't matter much, except
>   potentially for turning unhandled exceptions into signals (but that
>   might also be handled via a different mechanism).
> - setjmp/longjmp
>   The implementation should be ok, but doesn't do a SEH unwind (yet) but
>   just a plain longjmp. A full implementation should be doable, but is
>   not really needed for mingw code.
> - string functions like memcpy, memmove, strchr, strstr, wcschr, wcsstr
>   These are copied from musl. These can be performance sensitive. Musl
>   does have some basic assembly implementations for some architectures that
>   could be imported later. (I haven't measured to see how musl's
>   implementations perform compared to msvcrt.dll/ucrtbase.dll's
>   implementations, or other ones like the one in glibc.)
> 
> By naming the library libucrtapp.a, clang users can choose to link
> against this by passing -lucrtapp (which makes clang omit the default
> -lmsvcrt, which would be equal to libucrt.a in such a case).
> 
> Signed-off-by: Martin Storsjö <[email protected]>
> ---
>  mingw-w64-crt/Makefile.am                |  53 ++++++-
>  mingw-w64-crt/crt/__C_specific_handler.c |  52 +++++++
>  mingw-w64-crt/lib-common/ucrtapp.mri     |  19 +++
>  mingw-w64-crt/misc/longjmp.S             |  96 ++++++++++++
>  mingw-w64-crt/misc/setjmp.S              | 115 +++++++++++++++
>  mingw-w64-crt/string/memchr.c            |  50 +++++++
>  mingw-w64-crt/string/memcmp.c            |  31 ++++
>  mingw-w64-crt/string/memcpy.c            | 146 +++++++++++++++++++
>  mingw-w64-crt/string/memmove.c           |  65 +++++++++
>  mingw-w64-crt/string/memrchr.c           |  34 +++++
>  mingw-w64-crt/string/strchr.c            |  32 ++++
>  mingw-w64-crt/string/strchrnul.c         |  51 +++++++
>  mingw-w64-crt/string/strrchr.c           |  31 ++++
>  mingw-w64-crt/string/strstr.c            | 177 +++++++++++++++++++++++
>  mingw-w64-crt/string/wcschr.c            |  31 ++++
>  mingw-w64-crt/string/wcsrchr.c           |  31 ++++
>  mingw-w64-crt/string/wcsstr.c            | 128 ++++++++++++++++
>  17 files changed, 1134 insertions(+), 8 deletions(-)
>  create mode 100644 mingw-w64-crt/crt/__C_specific_handler.c
>  create mode 100644 mingw-w64-crt/lib-common/ucrtapp.mri
>  create mode 100644 mingw-w64-crt/misc/longjmp.S
>  create mode 100644 mingw-w64-crt/misc/setjmp.S
>  create mode 100644 mingw-w64-crt/string/memchr.c
>  create mode 100644 mingw-w64-crt/string/memcmp.c
>  create mode 100644 mingw-w64-crt/string/memcpy.c
>  create mode 100644 mingw-w64-crt/string/memmove.c
>  create mode 100644 mingw-w64-crt/string/memrchr.c
>  create mode 100644 mingw-w64-crt/string/strchr.c
>  create mode 100644 mingw-w64-crt/string/strchrnul.c
>  create mode 100644 mingw-w64-crt/string/strrchr.c
>  create mode 100644 mingw-w64-crt/string/strstr.c
>  create mode 100644 mingw-w64-crt/string/wcschr.c
>  create mode 100644 mingw-w64-crt/string/wcsrchr.c
>  create mode 100644 mingw-w64-crt/string/wcsstr.c
> 
> diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
> index 9a9384bf1..7cc3c92e8 100644
> --- a/mingw-w64-crt/Makefile.am
> +++ b/mingw-w64-crt/Makefile.am
> @@ -241,6 +241,23 @@ src_ucrtbase=\
>    stdio/ucrt_vsnprintf.c \
>    stdio/ucrt_vsprintf.c
>  
> +src_ucrtapp=\
> +  crt/__C_specific_handler.c \
> +  misc/longjmp.S \
> +  misc/setjmp.S \
> +  string/memchr.c \
> +  string/memcmp.c \
> +  string/memcpy.c \
> +  string/memmove.c \
> +  string/memrchr.c \
> +  string/strchr.c \
> +  string/strchrnul.c \
> +  string/strrchr.c \
> +  string/strstr.c \
> +  string/wcschr.c \
> +  string/wcsrchr.c \
> +  string/wcsstr.c
> +
>  src_msvcrt32=\
>    $(src_msvcrt) \
>    math/x86/_copysignf.c \
> @@ -862,10 +879,12 @@ lib32_libucrtbase_a_AR = $(DTDEF32) 
> lib32/ucrtbase.def && $(AR) $(ARFLAGS)
>  lib32_libucrtbase_a_CPPFLAGS=$(CPPFLAGS32) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  EXTRA_lib32_libucrtbase_a_DEPENDENCIES=lib32/ucrtbase.def
>  
> -lib32_DATA += lib32/libucrt.a
> -noinst_LIBRARIES += lib32/libucrt_extra.a
> +lib32_DATA += lib32/libucrt.a lib32/libucrtapp.a
> +noinst_LIBRARIES += lib32/libucrt_extra.a lib32/libucrtapp_extra.a
>  lib32_libucrt_extra_a_SOURCES = $(src_ucrtbase)
>  lib32_libucrt_extra_a_CPPFLAGS=$(CPPFLAGS32) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
> +lib32_libucrtapp_extra_a_SOURCES = $(src_ucrtapp)
> +lib32_libucrtapp_extra_a_CPPFLAGS=$(CPPFLAGS32) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  
>  lib32_DATA += lib32/libvcruntime140_app.a
>  endif
> @@ -1189,10 +1208,12 @@ lib64_libucrtbase_a_AR = $(DTDEF64) 
> lib64/ucrtbase.def && $(AR) $(ARFLAGS)
>  lib64_libucrtbase_a_CPPFLAGS=$(CPPFLAGS64) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  EXTRA_lib64_libucrtbase_a_DEPENDENCIES=lib64/ucrtbase.def
>  
> -lib64_DATA += lib64/libucrt.a
> -noinst_LIBRARIES += lib64/libucrt_extra.a
> +lib64_DATA += lib64/libucrt.a lib64/libucrtapp.a
> +noinst_LIBRARIES += lib64/libucrt_extra.a lib64/libucrtapp_extra.a
>  lib64_libucrt_extra_a_SOURCES = $(src_ucrtbase)
>  lib64_libucrt_extra_a_CPPFLAGS=$(CPPFLAGS64) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
> +lib64_libucrtapp_extra_a_SOURCES = $(src_ucrtapp)
> +lib64_libucrtapp_extra_a_CPPFLAGS=$(CPPFLAGS64) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  
>  lib64_DATA += lib64/libvcruntime140_app.a
>  endif
> @@ -1476,10 +1497,12 @@ libarm32_libucrtbase_a_AR = $(DTDEFARM32) 
> libarm32/ucrtbase.def && $(AR) $(ARFLA
>  libarm32_libucrtbase_a_CPPFLAGS=$(CPPFLAGSARM32) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  EXTRA_libarm32_libucrtbase_a_DEPENDENCIES=libarm32/ucrtbase.def
>  
> -libarm32_DATA += libarm32/libucrt.a
> -noinst_LIBRARIES += libarm32/libucrt_extra.a
> +libarm32_DATA += libarm32/libucrt.a libarm32/libucrtapp.a
> +noinst_LIBRARIES += libarm32/libucrt_extra.a 
> libarm32/libucrtapp_extra.a
>  libarm32_libucrt_extra_a_SOURCES = $(src_ucrtbase)
>  libarm32_libucrt_extra_a_CPPFLAGS=$(CPPFLAGSARM32) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
> +libarm32_libucrtapp_extra_a_SOURCES = $(src_ucrtapp)
> +libarm32_libucrtapp_extra_a_CPPFLAGS=$(CPPFLAGSARM32) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  
>  libarm32_DATA += libarm32/libvcruntime140_app.a
>  endif
> @@ -1732,10 +1755,12 @@ libarm64_libucrtbase_a_AR = $(DTDEFARM64) 
> libarm64/ucrtbase.def && $(AR) $(ARFLA
>  libarm64_libucrtbase_a_CPPFLAGS=$(CPPFLAGSARM64) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  EXTRA_libarm64_libucrtbase_a_DEPENDENCIES=libarm64/ucrtbase.def
>  
> -libarm64_DATA += libarm64/libucrt.a
> -noinst_LIBRARIES += libarm64/libucrt_extra.a
> +libarm64_DATA += libarm64/libucrt.a libarm64/libucrtapp.a
> +noinst_LIBRARIES += libarm64/libucrt_extra.a 
> libarm64/libucrtapp_extra.a
>  libarm64_libucrt_extra_a_SOURCES = $(src_ucrtbase)
>  libarm64_libucrt_extra_a_CPPFLAGS=$(CPPFLAGSARM64) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
> +libarm64_libucrtapp_extra_a_SOURCES = $(src_ucrtapp)
> +libarm64_libucrtapp_extra_a_CPPFLAGS=$(CPPFLAGSARM64) -D__LIBMSVCRT__ 
> $(extra_include) $(sysincludes)
>  
>  libarm64_DATA += libarm64/libvcruntime140_app.a
>  endif
> @@ -2068,6 +2093,18 @@ endif
>       cd $(dir $@) && $(AR) -M < $(abspath $<)
>       $(RANLIB) $@
>  
> +# The same as libucrt.a above, but without the -private lib and with 
> some more
> +# statically linked functions.
> +%/libucrtapp.a: lib-common/ucrtapp.mri %/libucrt_extra.a 
> %/libucrtapp_extra.a \
> +             %/libapi-ms-win-crt-conio-l1-1-0.a 
> %/libapi-ms-win-crt-convert-l1-1-0.a 
> %/libapi-ms-win-crt-environment-l1-1-0.a \
> +             %/libapi-ms-win-crt-filesystem-l1-1-0.a 
> %/libapi-ms-win-crt-heap-l1-1-0.a %/libapi-ms-win-crt-locale-l1-1-0.a \
> +             %/libapi-ms-win-crt-math-l1-1-0.a 
> %/libapi-ms-win-crt-multibyte-l1-1-0.a \
> +             %/libapi-ms-win-crt-process-l1-1-0.a 
> %/libapi-ms-win-crt-runtime-l1-1-0.a %/libapi-ms-win-crt-stdio-l1-1-0.a 
> \
> +             %/libapi-ms-win-crt-string-l1-1-0.a 
> %/libapi-ms-win-crt-time-l1-1-0.a %/libapi-ms-win-crt-utility-l1-1-0.a
> +     rm -f $@
> +     cd $(dir $@) && $(AR) -M < $(abspath $<)
> +     $(RANLIB) $@
> +
>  %.def: %.def.in
>       $(MKDIR_P) $(@D) && $(CPP) -x c $< -Wp,-w -undef -P 
> -I$(top_srcdir)/def-include > $@
>  
> diff --git a/mingw-w64-crt/crt/__C_specific_handler.c 
> b/mingw-w64-crt/crt/__C_specific_handler.c
> new file mode 100644
> index 000000000..fa15d07ca
> --- /dev/null
> +++ b/mingw-w64-crt/crt/__C_specific_handler.c
> @@ -0,0 +1,52 @@
> +/*
> +    Copyright (c) 2020 mingw-w64 project
> +
> +    Contributing authors: Martin Storsjo
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining a
> +    copy of this software and associated documentation files (the 
> "Software"),
> +    to deal in the Software without restriction, including without 
> limitation
> +    the rights to use, copy, modify, merge, publish, distribute, 
> sublicense,
> +    and/or sell copies of the Software, and to permit persons to whom 
> the
> +    Software is furnished to do so, subject to the following 
> conditions:
> +
> +    The above copyright notice and this permission notice shall be 
> included in
> +    all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
> EXPRESS OR
> +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
> MERCHANTABILITY,
> +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
> SHALL THE
> +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
> OTHER
> +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
> ARISING
> +    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> +    DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <excpt.h>
> +
> +#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
> +EXCEPTION_DISPOSITION __cdecl
> +__C_specific_handler(struct _EXCEPTION_RECORD *_ExceptionRecord,
> +                     void *_EstablisherFrame,
> +                     struct _CONTEXT *_ContextRecord,
> +                     struct _DISPATCHER_CONTEXT *_DispatcherContext)
> +{
> +  (void)_ExceptionRecord;
> +  (void)_EstablisherFrame;
> +  (void)_ContextRecord;
> +  (void)_DispatcherContext;
> +  // TODO A more comprehensive implementation. Normally this is only 
> used
> +  // by the toplevel SEH handler for uncaught exceptions, for calling
> +  // signal handlers. If signal handling isn't used, this no-op 
> implementation
> +  // should be ok. Wine does contain a supposedly correct 
> implementation of
> +  // this for x86_64 at least.
> +  return ExceptionContinueSearch;
> +}
> +
> +EXCEPTION_DISPOSITION
> +(__cdecl *__MINGW_IMP_SYMBOL(__C_specific_handler))(
> +    struct _EXCEPTION_RECORD *_ExceptionRecord,
> +    void *_EstablisherFrame,
> +    struct _CONTEXT *_ContextRecord,
> +    struct _DISPATCHER_CONTEXT *_DispatcherContext) = 
> __C_specific_handler;
> +#endif
> diff --git a/mingw-w64-crt/lib-common/ucrtapp.mri 
> b/mingw-w64-crt/lib-common/ucrtapp.mri
> new file mode 100644
> index 000000000..c9c0fb039
> --- /dev/null
> +++ b/mingw-w64-crt/lib-common/ucrtapp.mri
> @@ -0,0 +1,19 @@
> +CREATE libucrtapp.a
> +ADDLIB libapi-ms-win-crt-conio-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-convert-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-environment-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-filesystem-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-heap-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-locale-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-math-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-multibyte-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-process-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-runtime-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-stdio-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-string-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-time-l1-1-0.a
> +ADDLIB libapi-ms-win-crt-utility-l1-1-0.a
> +ADDLIB libucrt_extra.a
> +ADDLIB libucrtapp_extra.a
> +SAVE
> +END
> diff --git a/mingw-w64-crt/misc/longjmp.S b/mingw-w64-crt/misc/longjmp.S
> new file mode 100644
> index 000000000..3d22954ee
> --- /dev/null
> +++ b/mingw-w64-crt/misc/longjmp.S
> @@ -0,0 +1,96 @@
> +/**
> + * This file has no copyright assigned and is placed in the Public 
> Domain.
> + * This file is part of the mingw-w64 runtime package.
> + * No warranty is given; refer to the file DISCLAIMER.PD within this 
> package.
> + */
> +#include <_mingw_mac.h>
> +
> +        .globl  __MINGW_USYMBOL(longjmp)
> +        .def    __MINGW_USYMBOL(longjmp); .scl 2; .type 32; .endef
> +
> +__MINGW_USYMBOL(longjmp):
> +#if defined(__i386__)
> +        movl    4(%esp),%ecx         /* jmp_buf */
> +        movl    8(%esp),%eax         /* retval */
> +        movl    0(%ecx),%ebp         /* jmp_buf.Ebp */
> +        movl    4(%ecx),%ebx         /* jmp_buf.Ebx */
> +        movl    8(%ecx),%edi         /* jmp_buf.Edi */
> +        movl    12(%ecx),%esi        /* jmp_buf.Esi */
> +        movl    16(%ecx),%esp        /* jmp_buf.Esp */
> +        addl    $4,%esp              /* get rid of return address */
> +        jmp     *20(%ecx)            /* jmp_buf.Eip */
> +#elif defined(__x86_64__)
> +        movq    %rdx,%rax            /* retval */
> +        movq    0x8(%rcx),%rbx       /* jmp_buf->Rbx */
> +        movq    0x18(%rcx),%rbp      /* jmp_buf->Rbp */
> +        movq    0x20(%rcx),%rsi      /* jmp_buf->Rsi */
> +        movq    0x28(%rcx),%rdi      /* jmp_buf->Rdi */
> +        movq    0x30(%rcx),%r12      /* jmp_buf->R12 */
> +        movq    0x38(%rcx),%r13      /* jmp_buf->R13 */
> +        movq    0x40(%rcx),%r14      /* jmp_buf->R14 */
> +        movq    0x48(%rcx),%r15      /* jmp_buf->R15 */
> +        movdqa  0x60(%rcx),%xmm6     /* jmp_buf->Xmm6 */
> +        movdqa  0x70(%rcx),%xmm7     /* jmp_buf->Xmm7 */
> +        movdqa  0x80(%rcx),%xmm8     /* jmp_buf->Xmm8 */
> +        movdqa  0x90(%rcx),%xmm9     /* jmp_buf->Xmm9 */
> +        movdqa  0xa0(%rcx),%xmm10    /* jmp_buf->Xmm10 */
> +        movdqa  0xb0(%rcx),%xmm11    /* jmp_buf->Xmm11 */
> +        movdqa  0xc0(%rcx),%xmm12    /* jmp_buf->Xmm12 */
> +        movdqa  0xd0(%rcx),%xmm13    /* jmp_buf->Xmm13 */
> +        movdqa  0xe0(%rcx),%xmm14    /* jmp_buf->Xmm14 */
> +        movdqa  0xf0(%rcx),%xmm15    /* jmp_buf->Xmm15 */
> +        movq    0x50(%rcx),%rdx      /* jmp_buf->Rip */
> +        movq    0x10(%rcx),%rsp      /* jmp_buf->Rsp */
> +        jmp     *%rdx
> +#elif defined(__arm__)
> +        ldr     r4,  [r0, #0x4]      /* jmp_buf->R4 */
> +        ldr     r5,  [r0, #0x8]      /* jmp_buf->R5 */
> +        ldr     r6,  [r0, #0xc]      /* jmp_buf->R6 */
> +        ldr     r7,  [r0, #0x10]     /* jmp_buf->R7 */
> +        ldr     r8,  [r0, #0x14]     /* jmp_buf->R8 */
> +        ldr     r9,  [r0, #0x18]     /* jmp_buf->R9 */
> +        ldr     r10, [r0, #0x1c]     /* jmp_buf->R10 */
> +        ldr     r11, [r0, #0x20]     /* jmp_buf->R11 */
> +        ldr     sp,  [r0, #0x24]     /* jmp_buf->Sp */
> +        ldr     r2,  [r0, #0x28]     /* jmp_buf->Pc */
> +        ldr     r3,  [r0, #0x2c]     /* jmp_buf->Fpscr */
> +        vmsr    fpscr, r3
> +        vldr    d8,  [r0, #0x30]     /* jmp_buf->D[0] */
> +        vldr    d9,  [r0, #0x38]     /* jmp_buf->D[1] */
> +        vldr    d10, [r0, #0x40]     /* jmp_buf->D[2] */
> +        vldr    d11, [r0, #0x48]     /* jmp_buf->D[3] */
> +        vldr    d12, [r0, #0x50]     /* jmp_buf->D[4] */
> +        vldr    d13, [r0, #0x58]     /* jmp_buf->D[5] */
> +        vldr    d14, [r0, #0x60]     /* jmp_buf->D[6] */
> +        vldr    d15, [r0, #0x68]     /* jmp_buf->D[7] */
> +        mov     r0,  r1              /* retval */
> +        bx      r2
> +#elif defined(__aarch64__)
> +        ldp     x19, x20, [x0, #0x10] /* jmp_buf->X19, X20 */
> +        ldp     x21, x22, [x0, #0x20] /* jmp_buf->X21, X22 */
> +        ldp     x23, x24, [x0, #0x30] /* jmp_buf->X23, X24 */
> +        ldp     x25, x26, [x0, #0x40] /* jmp_buf->X25, X26 */
> +        ldp     x27, x28, [x0, #0x50] /* jmp_buf->X27, X28 */
> +        ldp     x29, x30, [x0, #0x60] /* jmp_buf->Fp,  Lr  */
> +        ldr     x2,       [x0, #0x70] /* jmp_buf->Sp */
> +        mov     sp,  x2
> +        ldr     w2,       [x0, #0x78] /* jmp_buf->Fpcr */
> +        msr     fpcr, x2
> +        ldr     w2,       [x0, #0x7c] /* jmp_buf->Fpsr */
> +        msr     fpsr, x2
> +        ldp     d8,  d9,  [x0, #0x80] /* jmp_buf->D[0-1] */
> +        ldp     d10, d11, [x0, #0x90] /* jmp_buf->D[2-3] */
> +        ldp     d12, d13, [x0, #0xa0] /* jmp_buf->D[4-5] */
> +        ldp     d14, d15, [x0, #0xb0] /* jmp_buf->D[6-7] */
> +        mov     x0,  x1               /* retval */
> +        ret
> +#endif
> +
> +        .data
> +        .globl  __MINGW_IMP_LSYMBOL(longjmp)
> +__MINGW_IMP_LSYMBOL(longjmp):
> +#ifdef _WIN64
> +        .quad   __MINGW_USYMBOL(longjmp)
> +#else
> +        .long   __MINGW_USYMBOL(longjmp)
> +#endif
> diff --git a/mingw-w64-crt/misc/setjmp.S b/mingw-w64-crt/misc/setjmp.S
> new file mode 100644
> index 000000000..b2058e9e2
> --- /dev/null
> +++ b/mingw-w64-crt/misc/setjmp.S
> @@ -0,0 +1,115 @@
> +/**
> + * This file has no copyright assigned and is placed in the Public 
> Domain.
> + * This file is part of the mingw-w64 runtime package.
> + * No warranty is given; refer to the file DISCLAIMER.PD within this 
> package.
> + */
> +
> +#include <_mingw_mac.h>
> +
> +        .globl  __MINGW_USYMBOL(__intrinsic_setjmp)
> +        .def    __MINGW_USYMBOL(__intrinsic_setjmp); .scl 2; .type 32; 
> .endef
> +
> +#if defined(_WIN64)
> +        .globl  __MINGW_USYMBOL(__intrinsic_setjmpex)
> +        .def    __MINGW_USYMBOL(__intrinsic_setjmpex); .scl 2; .type 
> 32; .endef
> +#endif
> +
> +#if defined(__i386__)
> +        .globl  __MINGW_USYMBOL(_setjmp3)
> +        .def    __MINGW_USYMBOL(_setjmp3); .scl 2; .type 32; .endef
> +__MINGW_USYMBOL(_setjmp3):
> +__MINGW_USYMBOL(__intrinsic_setjmp):
> +        movl    4(%esp),%ecx         /* jmp_buf */
> +        movl    %ebp,0(%ecx)         /* jmp_buf.Ebp */
> +        movl    %ebx,4(%ecx)         /* jmp_buf.Ebx */
> +        movl    %edi,8(%ecx)         /* jmp_buf.Edi */
> +        movl    %esi,12(%ecx)        /* jmp_buf.Esi */
> +        movl    %esp,16(%ecx)        /* jmp_buf.Esp */
> +        movl    0(%esp),%eax
> +        movl    %eax,20(%ecx)        /* jmp_buf.Eip */
> +        xorl    %eax, %eax
> +        retl
> +
> +#elif defined(__x86_64__)
> +        .globl  __MINGW_USYMBOL(setjmp)
> +        .def    __MINGW_USYMBOL(setjmp); .scl 2; .type 32; .endef
> +__MINGW_USYMBOL(setjmp):
> +__MINGW_USYMBOL(__intrinsic_setjmp):
> +        xorq    %rdx,%rdx
> +__MINGW_USYMBOL(__intrinsic_setjmpex):
> +        movq    %rdx,(%rcx)          /* jmp_buf->Frame */
> +        movq    %rbx,0x8(%rcx)       /* jmp_buf->Rbx */
> +        leaq    0x8(%rsp),%rax
> +        movq    %rax,0x10(%rcx)      /* jmp_buf->Rsp */
> +        movq    %rbp,0x18(%rcx)      /* jmp_buf->Rbp */
> +        movq    %rsi,0x20(%rcx)      /* jmp_buf->Rsi */
> +        movq    %rdi,0x28(%rcx)      /* jmp_buf->Rdi */
> +        movq    %r12,0x30(%rcx)      /* jmp_buf->R12 */
> +        movq    %r13,0x38(%rcx)      /* jmp_buf->R13 */
> +        movq    %r14,0x40(%rcx)      /* jmp_buf->R14 */
> +        movq    %r15,0x48(%rcx)      /* jmp_buf->R15 */
> +        movq    (%rsp),%rax
> +        movq    %rax,0x50(%rcx)      /* jmp_buf->Rip */
> +        movdqa  %xmm6,0x60(%rcx)     /* jmp_buf->Xmm6 */
> +        movdqa  %xmm7,0x70(%rcx)     /* jmp_buf->Xmm7 */
> +        movdqa  %xmm8,0x80(%rcx)     /* jmp_buf->Xmm8 */
> +        movdqa  %xmm9,0x90(%rcx)     /* jmp_buf->Xmm9 */
> +        movdqa  %xmm10,0xa0(%rcx)    /* jmp_buf->Xmm10 */
> +        movdqa  %xmm11,0xb0(%rcx)    /* jmp_buf->Xmm11 */
> +        movdqa  %xmm12,0xc0(%rcx)    /* jmp_buf->Xmm12 */
> +        movdqa  %xmm13,0xd0(%rcx)    /* jmp_buf->Xmm13 */
> +        movdqa  %xmm14,0xe0(%rcx)    /* jmp_buf->Xmm14 */
> +        movdqa  %xmm15,0xf0(%rcx)    /* jmp_buf->Xmm15 */
> +        xorq    %rax,%rax
> +        retq
> +
> +#elif defined(__arm__)
> +__MINGW_USYMBOL(__intrinsic_setjmp):
> +        mov     r1,  #0
> +        str     r1,  [r0]            /* jmp_buf->Frame */
> +        str     r4,  [r0, #0x4]      /* jmp_buf->R4 */
> +        str     r5,  [r0, #0x8]      /* jmp_buf->R5 */
> +        str     r6,  [r0, #0xc]      /* jmp_buf->R6 */
> +        str     r7,  [r0, #0x10]     /* jmp_buf->R7 */
> +        str     r8,  [r0, #0x14]     /* jmp_buf->R8 */
> +        str     r9,  [r0, #0x18]     /* jmp_buf->R9 */
> +        str     r10, [r0, #0x1c]     /* jmp_buf->R10 */
> +        str     r11, [r0, #0x20]     /* jmp_buf->R11 */
> +        str     sp,  [r0, #0x24]     /* jmp_buf->Sp */
> +        str     lr,  [r0, #0x28]     /* jmp_buf->Pc */
> +        vmrs    r2,  fpscr
> +        str     r2,  [r0, #0x2c]     /* jmp_buf->Fpscr */
> +        vstr    d8,  [r0, #0x30]     /* jmp_buf->D[0] */
> +        vstr    d9,  [r0, #0x38]     /* jmp_buf->D[1] */
> +        vstr    d10, [r0, #0x40]     /* jmp_buf->D[2] */
> +        vstr    d11, [r0, #0x48]     /* jmp_buf->D[3] */
> +        vstr    d12, [r0, #0x50]     /* jmp_buf->D[4] */
> +        vstr    d13, [r0, #0x58]     /* jmp_buf->D[5] */
> +        vstr    d14, [r0, #0x60]     /* jmp_buf->D[6] */
> +        vstr    d15, [r0, #0x68]     /* jmp_buf->D[7] */
> +        mov     r0,  #0
> +        bx      lr
> +#elif defined(__aarch64__)
> +__MINGW_USYMBOL(__intrinsic_setjmp):
> +        mov     x1,  #0
> +__MINGW_USYMBOL(__intrinsic_setjmpex):
> +        str     x1,  [x0]             /* jmp_buf->Frame */
> +        stp     x19, x20, [x0, #0x10] /* jmp_buf->X19, X20 */
> +        stp     x21, x22, [x0, #0x20] /* jmp_buf->X21, X22 */
> +        stp     x23, x24, [x0, #0x30] /* jmp_buf->X23, X24 */
> +        stp     x25, x26, [x0, #0x40] /* jmp_buf->X25, X26 */
> +        stp     x27, x28, [x0, #0x50] /* jmp_buf->X27, X28 */
> +        stp     x29, x30, [x0, #0x60] /* jmp_buf->Fp,  Lr  */
> +        mov     x2,  sp
> +        str     x2,       [x0, #0x70] /* jmp_buf->Sp */
> +        mrs     x2,  fpcr
> +        str     w2,       [x0, #0x78] /* jmp_buf->Fpcr */
> +        mrs     x2,  fpsr
> +        str     w2,       [x0, #0x7c] /* jmp_buf->Fpsr */
> +        stp     d8,  d9,  [x0, #0x80] /* jmp_buf->D[0-1] */
> +        stp     d10, d11, [x0, #0x90] /* jmp_buf->D[2-3] */
> +        stp     d12, d13, [x0, #0xa0] /* jmp_buf->D[4-5] */
> +        stp     d14, d15, [x0, #0xb0] /* jmp_buf->D[6-7] */
> +        mov     x0,  #0
> +        ret
> +#endif
> diff --git a/mingw-w64-crt/string/memchr.c 
> b/mingw-w64-crt/string/memchr.c
> new file mode 100644
> index 000000000..e115afc80
> --- /dev/null
> +++ b/mingw-w64-crt/string/memchr.c
> @@ -0,0 +1,50 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +#include <stdint.h>
> +#include <limits.h>
> +
> +#define SS (sizeof(size_t))
> +#define ALIGN (sizeof(size_t)-1)
> +#define ONES ((size_t)-1/UCHAR_MAX)
> +#define HIGHS (ONES * (UCHAR_MAX/2+1))
> +#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
> +
> +void *memchr(const void *src, int c, size_t n)
> +{
> +     const unsigned char *s = src;
> +     c = (unsigned char)c;
> +#ifdef __GNUC__
> +     for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
> +     if (n && *s != c) {
> +             typedef size_t __attribute__((__may_alias__)) word;
> +             const word *w;
> +             size_t k = ONES * c;
> +             for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
> +             s = (const void *)w;
> +     }
> +#endif
> +     for (; n && *s != c; s++, n--);
> +     return n ? (void *)s : 0;
> +}
> diff --git a/mingw-w64-crt/string/memcmp.c 
> b/mingw-w64-crt/string/memcmp.c
> new file mode 100644
> index 000000000..95afa9078
> --- /dev/null
> +++ b/mingw-w64-crt/string/memcmp.c
> @@ -0,0 +1,31 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +
> +int memcmp(const void *vl, const void *vr, size_t n)
> +{
> +     const unsigned char *l=vl, *r=vr;
> +     for (; n && *l == *r; n--, l++, r++);
> +     return n ? *l-*r : 0;
> +}
> diff --git a/mingw-w64-crt/string/memcpy.c 
> b/mingw-w64-crt/string/memcpy.c
> new file mode 100644
> index 000000000..dd3e50d60
> --- /dev/null
> +++ b/mingw-w64-crt/string/memcpy.c
> @@ -0,0 +1,146 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +#include <stdint.h>
> +
> +void *memcpy(void *restrict dest, const void *restrict src, size_t n)
> +{
> +     unsigned char *d = dest;
> +     const unsigned char *s = src;
> +
> +#ifdef __GNUC__
> +
> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> +#define LS >>
> +#define RS <<
> +#else
> +#define LS <<
> +#define RS >>
> +#endif
> +
> +     typedef uint32_t __attribute__((__may_alias__)) u32;
> +     uint32_t w, x;
> +
> +     for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
> +
> +     if ((uintptr_t)d % 4 == 0) {
> +             for (; n>=16; s+=16, d+=16, n-=16) {
> +                     *(u32 *)(d+0) = *(u32 *)(s+0);
> +                     *(u32 *)(d+4) = *(u32 *)(s+4);
> +                     *(u32 *)(d+8) = *(u32 *)(s+8);
> +                     *(u32 *)(d+12) = *(u32 *)(s+12);
> +             }
> +             if (n&8) {
> +                     *(u32 *)(d+0) = *(u32 *)(s+0);
> +                     *(u32 *)(d+4) = *(u32 *)(s+4);
> +                     d += 8; s += 8;
> +             }
> +             if (n&4) {
> +                     *(u32 *)(d+0) = *(u32 *)(s+0);
> +                     d += 4; s += 4;
> +             }
> +             if (n&2) {
> +                     *d++ = *s++; *d++ = *s++;
> +             }
> +             if (n&1) {
> +                     *d = *s;
> +             }
> +             return dest;
> +     }
> +
> +     if (n >= 32) switch ((uintptr_t)d % 4) {
> +     case 1:
> +             w = *(u32 *)s;
> +             *d++ = *s++;
> +             *d++ = *s++;
> +             *d++ = *s++;
> +             n -= 3;
> +             for (; n>=17; s+=16, d+=16, n-=16) {
> +                     x = *(u32 *)(s+1);
> +                     *(u32 *)(d+0) = (w LS 24) | (x RS 8);
> +                     w = *(u32 *)(s+5);
> +                     *(u32 *)(d+4) = (x LS 24) | (w RS 8);
> +                     x = *(u32 *)(s+9);
> +                     *(u32 *)(d+8) = (w LS 24) | (x RS 8);
> +                     w = *(u32 *)(s+13);
> +                     *(u32 *)(d+12) = (x LS 24) | (w RS 8);
> +             }
> +             break;
> +     case 2:
> +             w = *(u32 *)s;
> +             *d++ = *s++;
> +             *d++ = *s++;
> +             n -= 2;
> +             for (; n>=18; s+=16, d+=16, n-=16) {
> +                     x = *(u32 *)(s+2);
> +                     *(u32 *)(d+0) = (w LS 16) | (x RS 16);
> +                     w = *(u32 *)(s+6);
> +                     *(u32 *)(d+4) = (x LS 16) | (w RS 16);
> +                     x = *(u32 *)(s+10);
> +                     *(u32 *)(d+8) = (w LS 16) | (x RS 16);
> +                     w = *(u32 *)(s+14);
> +                     *(u32 *)(d+12) = (x LS 16) | (w RS 16);
> +             }
> +             break;
> +     case 3:
> +             w = *(u32 *)s;
> +             *d++ = *s++;
> +             n -= 1;
> +             for (; n>=19; s+=16, d+=16, n-=16) {
> +                     x = *(u32 *)(s+3);
> +                     *(u32 *)(d+0) = (w LS 8) | (x RS 24);
> +                     w = *(u32 *)(s+7);
> +                     *(u32 *)(d+4) = (x LS 8) | (w RS 24);
> +                     x = *(u32 *)(s+11);
> +                     *(u32 *)(d+8) = (w LS 8) | (x RS 24);
> +                     w = *(u32 *)(s+15);
> +                     *(u32 *)(d+12) = (x LS 8) | (w RS 24);
> +             }
> +             break;
> +     }
> +     if (n&16) {
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +     }
> +     if (n&8) {
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +     }
> +     if (n&4) {
> +             *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
> +     }
> +     if (n&2) {
> +             *d++ = *s++; *d++ = *s++;
> +     }
> +     if (n&1) {
> +             *d = *s;
> +     }
> +     return dest;
> +#endif
> +
> +     for (; n; n--) *d++ = *s++;
> +     return dest;
> +}
> diff --git a/mingw-w64-crt/string/memmove.c 
> b/mingw-w64-crt/string/memmove.c
> new file mode 100644
> index 000000000..4dcf67e14
> --- /dev/null
> +++ b/mingw-w64-crt/string/memmove.c
> @@ -0,0 +1,65 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +#include <stdint.h>
> +
> +#ifdef __GNUC__
> +typedef __attribute__((__may_alias__)) size_t WT;
> +#define WS (sizeof(WT))
> +#endif
> +
> +void *memmove(void *dest, const void *src, size_t n)
> +{
> +     char *d = dest;
> +     const char *s = src;
> +
> +     if (d==s) return d;
> +     if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);
> +
> +     if (d<s) {
> +#ifdef __GNUC__
> +             if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
> +                     while ((uintptr_t)d % WS) {
> +                             if (!n--) return dest;
> +                             *d++ = *s++;
> +                     }
> +                     for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
> +             }
> +#endif
> +             for (; n; n--) *d++ = *s++;
> +     } else {
> +#ifdef __GNUC__
> +             if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
> +                     while ((uintptr_t)(d+n) % WS) {
> +                             if (!n--) return dest;
> +                             d[n] = s[n];
> +                     }
> +                     while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
> +             }
> +#endif
> +             while (n) n--, d[n] = s[n];
> +     }
> +
> +     return dest;
> +}
> diff --git a/mingw-w64-crt/string/memrchr.c 
> b/mingw-w64-crt/string/memrchr.c
> new file mode 100644
> index 000000000..83b7b8b39
> --- /dev/null
> +++ b/mingw-w64-crt/string/memrchr.c
> @@ -0,0 +1,34 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +
> +void *__memrchr(const void *m, int c, size_t n);
> +
> +void *__memrchr(const void *m, int c, size_t n)
> +{
> +     const unsigned char *s = m;
> +     c = (unsigned char)c;
> +     while (n--) if (s[n]==c) return (void *)(s+n);
> +     return 0;
> +}
> diff --git a/mingw-w64-crt/string/strchr.c 
> b/mingw-w64-crt/string/strchr.c
> new file mode 100644
> index 000000000..8eecdf561
> --- /dev/null
> +++ b/mingw-w64-crt/string/strchr.c
> @@ -0,0 +1,32 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +
> +char *__strchrnul(const char *s, int c);
> +
> +char *strchr(const char *s, int c)
> +{
> +     char *r = __strchrnul(s, c);
> +     return *(unsigned char *)r == (unsigned char)c ? r : 0;
> +}
> diff --git a/mingw-w64-crt/string/strchrnul.c 
> b/mingw-w64-crt/string/strchrnul.c
> new file mode 100644
> index 000000000..889446ac5
> --- /dev/null
> +++ b/mingw-w64-crt/string/strchrnul.c
> @@ -0,0 +1,51 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +#include <stdint.h>
> +#include <limits.h>
> +
> +#define ALIGN (sizeof(size_t))
> +#define ONES ((size_t)-1/UCHAR_MAX)
> +#define HIGHS (ONES * (UCHAR_MAX/2+1))
> +#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
> +
> +char *__strchrnul(const char *s, int c);
> +
> +char *__strchrnul(const char *s, int c)
> +{
> +     c = (unsigned char)c;
> +     if (!c) return (char *)s + strlen(s);
> +
> +#ifdef __GNUC__
> +     typedef size_t __attribute__((__may_alias__)) word;
> +     const word *w;
> +     for (; (uintptr_t)s % ALIGN; s++)
> +             if (!*s || *(unsigned char *)s == c) return (char *)s;
> +     size_t k = ONES * c;
> +     for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
> +     s = (void *)w;
> +#endif
> +     for (; *s && *(unsigned char *)s != c; s++);
> +     return (char *)s;
> +}
> diff --git a/mingw-w64-crt/string/strrchr.c 
> b/mingw-w64-crt/string/strrchr.c
> new file mode 100644
> index 000000000..9015af1df
> --- /dev/null
> +++ b/mingw-w64-crt/string/strrchr.c
> @@ -0,0 +1,31 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +
> +void *__memrchr(const void *m, int c, size_t n);
> +
> +char *strrchr(const char *s, int c)
> +{
> +     return __memrchr(s, c, strlen(s) + 1);
> +}
> diff --git a/mingw-w64-crt/string/strstr.c 
> b/mingw-w64-crt/string/strstr.c
> new file mode 100644
> index 000000000..dbd1997d3
> --- /dev/null
> +++ b/mingw-w64-crt/string/strstr.c
> @@ -0,0 +1,177 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <string.h>
> +#include <stdint.h>
> +
> +static char *twobyte_strstr(const unsigned char *h, const unsigned 
> char *n)
> +{
> +     uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
> +     for (h++; *h && hw != nw; hw = hw<<8 | *++h);
> +     return *h ? (char *)h-1 : 0;
> +}
> +
> +static char *threebyte_strstr(const unsigned char *h, const unsigned 
> char *n)
> +{
> +     uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8;
> +     uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8;
> +     for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
> +     return *h ? (char *)h-2 : 0;
> +}
> +
> +static char *fourbyte_strstr(const unsigned char *h, const unsigned 
> char *n)
> +{
> +     uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
> +     uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
> +     for (h+=3; *h && hw != nw; hw = hw<<8 | *++h);
> +     return *h ? (char *)h-3 : 0;
> +}
> +
> +#define MAX(a,b) ((a)>(b)?(a):(b))
> +#define MIN(a,b) ((a)<(b)?(a):(b))
> +
> +#define BITOP(a,b,op) \
> + ((a)[(size_t)(b)/(8*sizeof *(a))] op 
> (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
> +
> +static char *twoway_strstr(const unsigned char *h, const unsigned char 
> *n)
> +{
> +     const unsigned char *z;
> +     size_t l, ip, jp, k, p, ms, p0, mem, mem0;
> +     size_t byteset[32 / sizeof(size_t)] = { 0 };
> +     size_t shift[256];
> +
> +     /* Computing length of needle and fill shift table */
> +     for (l=0; n[l] && h[l]; l++)
> +             BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
> +     if (n[l]) return 0; /* hit the end of h */
> +
> +     /* Compute maximal suffix */
> +     ip = -1; jp = 0; k = p = 1;
> +     while (jp+k<l) {
> +             if (n[ip+k] == n[jp+k]) {
> +                     if (k == p) {
> +                             jp += p;
> +                             k = 1;
> +                     } else k++;
> +             } else if (n[ip+k] > n[jp+k]) {
> +                     jp += k;
> +                     k = 1;
> +                     p = jp - ip;
> +             } else {
> +                     ip = jp++;
> +                     k = p = 1;
> +             }
> +     }
> +     ms = ip;
> +     p0 = p;
> +
> +     /* And with the opposite comparison */
> +     ip = -1; jp = 0; k = p = 1;
> +     while (jp+k<l) {
> +             if (n[ip+k] == n[jp+k]) {
> +                     if (k == p) {
> +                             jp += p;
> +                             k = 1;
> +                     } else k++;
> +             } else if (n[ip+k] < n[jp+k]) {
> +                     jp += k;
> +                     k = 1;
> +                     p = jp - ip;
> +             } else {
> +                     ip = jp++;
> +                     k = p = 1;
> +             }
> +     }
> +     if (ip+1 > ms+1) ms = ip;
> +     else p = p0;
> +
> +     /* Periodic needle? */
> +     if (memcmp(n, n+p, ms+1)) {
> +             mem0 = 0;
> +             p = MAX(ms, l-ms-1) + 1;
> +     } else mem0 = l-p;
> +     mem = 0;
> +
> +     /* Initialize incremental end-of-haystack pointer */
> +     z = h;
> +
> +     /* Search loop */
> +     for (;;) {
> +             /* Update incremental end-of-haystack pointer */
> +             if ((size_t)(z-h) < l) {
> +                     /* Fast estimate for MIN(l,63) */
> +                     size_t grow = l | 63;
> +                     const unsigned char *z2 = memchr(z, 0, grow);
> +                     if (z2) {
> +                             z = z2;
> +                             if ((size_t)(z-h) < l) return 0;
> +                     } else z += grow;
> +             }
> +
> +             /* Check last byte first; advance by shift on mismatch */
> +             if (BITOP(byteset, h[l-1], &)) {
> +                     k = l-shift[h[l-1]];
> +                     if (k) {
> +                             if (k < mem) k = mem;
> +                             h += k;
> +                             mem = 0;
> +                             continue;
> +                     }
> +             } else {
> +                     h += l;
> +                     mem = 0;
> +                     continue;
> +             }
> +
> +             /* Compare right half */
> +             for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
> +             if (n[k]) {
> +                     h += k-ms;
> +                     mem = 0;
> +                     continue;
> +             }
> +             /* Compare left half */
> +             for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
> +             if (k <= mem) return (char *)h;
> +             h += p;
> +             mem = mem0;
> +     }
> +}
> +
> +char *strstr(const char *h, const char *n)
> +{
> +     /* Return immediately on empty needle */
> +     if (!n[0]) return (char *)h;
> +
> +     /* Use faster algorithms for short needles */
> +     h = strchr(h, *n);
> +     if (!h || !n[1]) return (char *)h;
> +     if (!h[1]) return 0;
> +     if (!n[2]) return twobyte_strstr((void *)h, (void *)n);
> +     if (!h[2]) return 0;
> +     if (!n[3]) return threebyte_strstr((void *)h, (void *)n);
> +     if (!h[3]) return 0;
> +     if (!n[4]) return fourbyte_strstr((void *)h, (void *)n);
> +
> +     return twoway_strstr((void *)h, (void *)n);
> +}
> diff --git a/mingw-w64-crt/string/wcschr.c 
> b/mingw-w64-crt/string/wcschr.c
> new file mode 100644
> index 000000000..5fd1910ad
> --- /dev/null
> +++ b/mingw-w64-crt/string/wcschr.c
> @@ -0,0 +1,31 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <wchar.h>
> +
> +wchar_t *wcschr(const wchar_t *s, wchar_t c)
> +{
> +     if (!c) return (wchar_t *)s + wcslen(s);
> +     for (; *s && *s != c; s++);
> +     return *s ? (wchar_t *)s : 0;
> +}
> diff --git a/mingw-w64-crt/string/wcsrchr.c 
> b/mingw-w64-crt/string/wcsrchr.c
> new file mode 100644
> index 000000000..17b9ac14e
> --- /dev/null
> +++ b/mingw-w64-crt/string/wcsrchr.c
> @@ -0,0 +1,31 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <wchar.h>
> +
> +wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
> +{
> +     const wchar_t *p;
> +     for (p=s+wcslen(s); p>=s && *p!=c; p--);
> +     return p>=s ? (wchar_t *)p : 0;
> +}
> diff --git a/mingw-w64-crt/string/wcsstr.c 
> b/mingw-w64-crt/string/wcsstr.c
> new file mode 100644
> index 000000000..7590c147e
> --- /dev/null
> +++ b/mingw-w64-crt/string/wcsstr.c
> @@ -0,0 +1,128 @@
> +/*
> +    Copyright © 2005-2020 Rich Felker, et al.
> +
> +    Permission is hereby granted, free of charge, to any person 
> obtaining
> +    a copy of this software and associated documentation files (the
> +    "Software"), to deal in the Software without restriction, including
> +    without limitation the rights to use, copy, modify, merge, publish,
> +    distribute, sublicense, and/or sell copies of the Software, and to
> +    permit persons to whom the Software is furnished to do so, subject 
> to
> +    the following conditions:
> +
> +    The above copyright notice and this permission notice shall be
> +    included in all copies or substantial portions of the Software.
> +
> +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
> NONINFRINGEMENT.
> +    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
> ANY
> +    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
> CONTRACT,
> +    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> +    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +#include <wchar.h>
> +
> +#define MAX(a,b) ((a)>(b)?(a):(b))
> +#define MIN(a,b) ((a)<(b)?(a):(b))
> +
> +static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
> +{
> +     const wchar_t *z;
> +     size_t l, ip, jp, k, p, ms, p0, mem, mem0;
> +
> +     /* Computing length of needle */
> +     for (l=0; n[l] && h[l]; l++);
> +     if (n[l]) return 0; /* hit the end of h */
> +
> +     /* Compute maximal suffix */
> +     ip = -1; jp = 0; k = p = 1;
> +     while (jp+k<l) {
> +             if (n[ip+k] == n[jp+k]) {
> +                     if (k == p) {
> +                             jp += p;
> +                             k = 1;
> +                     } else k++;
> +             } else if (n[ip+k] > n[jp+k]) {
> +                     jp += k;
> +                     k = 1;
> +                     p = jp - ip;
> +             } else {
> +                     ip = jp++;
> +                     k = p = 1;
> +             }
> +     }
> +     ms = ip;
> +     p0 = p;
> +
> +     /* And with the opposite comparison */
> +     ip = -1; jp = 0; k = p = 1;
> +     while (jp+k<l) {
> +             if (n[ip+k] == n[jp+k]) {
> +                     if (k == p) {
> +                             jp += p;
> +                             k = 1;
> +                     } else k++;
> +             } else if (n[ip+k] < n[jp+k]) {
> +                     jp += k;
> +                     k = 1;
> +                     p = jp - ip;
> +             } else {
> +                     ip = jp++;
> +                     k = p = 1;
> +             }
> +     }
> +     if (ip+1 > ms+1) ms = ip;
> +     else p = p0;
> +
> +     /* Periodic needle? */
> +     if (wmemcmp(n, n+p, ms+1)) {
> +             mem0 = 0;
> +             p = MAX(ms, l-ms-1) + 1;
> +     } else mem0 = l-p;
> +     mem = 0;
> +
> +     /* Initialize incremental end-of-haystack pointer */
> +     z = h;
> +
> +     /* Search loop */
> +     for (;;) {
> +             /* Update incremental end-of-haystack pointer */
> +             if ((size_t)(z-h) < l) {
> +                     /* Fast estimate for MIN(l,63) */
> +                     size_t grow = l | 63;
> +                     const wchar_t *z2 = wmemchr(z, 0, grow);
> +                     if (z2) {
> +                             z = z2;
> +                             if ((size_t)(z-h) < l) return 0;
> +                     } else z += grow;
> +             }
> +
> +             /* Compare right half */
> +             for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
> +             if (n[k]) {
> +                     h += k-ms;
> +                     mem = 0;
> +                     continue;
> +             }
> +             /* Compare left half */
> +             for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
> +             if (k <= mem) return (wchar_t *)h;
> +             h += p;
> +             mem = mem0;
> +     }
> +}
> +
> +wchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n)
> +{
> +     /* Return immediately on empty needle or haystack */
> +     if (!n[0]) return (wchar_t *)h;
> +     if (!h[0]) return 0;
> +
> +     /* Use faster algorithms for short needles */
> +     h = wcschr(h, *n);
> +     if (!h || !n[1]) return (wchar_t *)h;
> +     if (!h[1]) return 0;
> +
> +     return twoway_wcsstr(h, n);
> +}
> -- 
> 2.17.1
> 
> 
> 
> _______________________________________________
> Mingw-w64-public mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>

-- 
Jean-Baptiste Kempf -  President
+33 672 704 734


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to