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