diff --git a/.github/workflows/build.bat b/.github/workflows/build.bat index 3aac9fd..fd81435 100644 --- a/.github/workflows/build.bat +++ b/.github/workflows/build.bat @@ -19,9 +19,6 @@ if exist ucxxrt rd /s /q ucxxrt %msbuild% -m -p:Configuration=Debug -p:Platform=x64 ..\..\ucxxrt.sln -t:ucxxrt %msbuild% -m -p:Configuration=Release -p:Platform=x64 ..\..\ucxxrt.sln -t:ucxxrt -%msbuild% -m -p:Configuration=Debug -p:Platform=ARM ..\..\ucxxrt.sln -t:ucxxrt -%msbuild% -m -p:Configuration=Release -p:Platform=ARM ..\..\ucxxrt.sln -t:ucxxrt - %msbuild% -m -p:Configuration=Debug -p:Platform=ARM64 ..\..\ucxxrt.sln -t:ucxxrt %msbuild% -m -p:Configuration=Release -p:Platform=ARM64 ..\..\ucxxrt.sln -t:ucxxrt diff --git a/msvc/ucxxrt.test.vcxproj b/msvc/ucxxrt.test.vcxproj index 7f69dfd..3403320 100644 --- a/msvc/ucxxrt.test.vcxproj +++ b/msvc/ucxxrt.test.vcxproj @@ -32,217 +32,41 @@ v4.5 12.0 Debug - Win32 + x64 unittest_kernel ucxxrt.test - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - WDM - Universal - Spectre - - + Windows10 false + true WindowsKernelModeDriver10.0 Driver WDM Universal Spectre + - - - - - - - - - - - - - - - - - - - - - - - - - - - - DbgengKernelDebugger - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - false - true - - - DbgengKernelDebugger - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - false - true - - - DbgengKernelDebugger - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - false - true - - + DbgengKernelDebugger $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ false true - - DbgengKernelDebugger - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - false - true - - - DbgengKernelDebugger - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - false - true - - - DbgengKernelDebugger - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - false - true - - - DbgengKernelDebugger - $(SolutionDir)bin\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ - $(SolutionDIr).vs\$(ProjectName)\$(PlatformShortName.ToLower()).$(Configuration.ToLower())\ - false - true - - - - - + sha256 - - - - - - - sha256 - - - - - - - - - sha256 - - - - - - - - - sha256 - - - - - - - - - - - - - - + + $(SolutionDir);%(AdditionalIncludeDirectories) + diff --git a/msvc/ucxxrt.vcxproj b/msvc/ucxxrt.vcxproj index f65c5cd..3f0b26f 100644 --- a/msvc/ucxxrt.vcxproj +++ b/msvc/ucxxrt.vcxproj @@ -26,176 +26,94 @@ ARM64 + + {8D969184-788F-48AA-BF18-2898FC167C91} + {0a049372-4c4d-4ea0-a64e-dc6ad88ceca1} + v4.5 + 12.0 + Debug + x64 + ucxxrt_kernel + ExportDriver + ucxxrt + + + Windows10 + false + true + WindowsKernelModeDriver10.0 + StaticLibrary + + + Unicode + 1 + Universal + Spectre + + + + + + + + + + + + false + + + - - - - - - - - + - - - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - - - - true - true - true - true - true - true - - - true - true - true - true - true - true + + Create - - true - true - true - true - true - true + + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - true - true - true - true - true - true + true + true - - true - + @@ -268,6 +186,9 @@ + + NotUsing + @@ -296,7 +217,9 @@ - + + NotUsing + @@ -328,20 +251,12 @@ - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true @@ -367,7 +282,6 @@ - @@ -384,427 +298,119 @@ - - Create - - - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - - Document - true - true - true - true - true - true - - Document - true - true - true - true - true - true + true + true - Document - true - true - true - true - true - true + true + true - Document - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true + + + true + true + + + true + true + + + true + true + + + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - true - true - true - true - true - true + true + true - - {8D969184-788F-48AA-BF18-2898FC167C91} - {0a049372-4c4d-4ea0-a64e-dc6ad88ceca1} - v4.5 - 12.0 - Debug - Win32 - ucxxrt_kernel - ExportDriver - ucxxrt - - - - Windows10 - true - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - true - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - true - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - true - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - Windows10 - false - WindowsKernelModeDriver10.0 - StaticLibrary - Unicode - 1 - Universal - Spectre - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - false - - - - - false - - - - - false - - diff --git a/msvc/ucxxrt.vcxproj.filters b/msvc/ucxxrt.vcxproj.filters index c209121..3f486b3 100644 --- a/msvc/ucxxrt.vcxproj.filters +++ b/msvc/ucxxrt.vcxproj.filters @@ -32,9 +32,6 @@ {8a13a5c8-6a3f-4f0b-a9f1-7202d66baeb0} - - {94aa2a52-3958-4e4e-a4dd-fa8ea7f32081} - {617b7471-9d4f-4df9-b7af-fee21c064cfe} @@ -55,9 +52,6 @@ - - ucxxrt - ucxxrt\crt\vcruntime @@ -79,30 +73,6 @@ ucxxrt\crt\stl - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - - - ucxxrt\crt\stl - ucxxrt\ucrt\inc @@ -127,29 +97,12 @@ ucxxrt\crt\stl - - - + ucxxrt - - - ucxxrt\ucrt\inc\i386 - - - ucxxrt\crt\i386 - - - ucxxrt\crt\i386 - - - ucxxrt\crt\i386 - - - ucxxrt\crt\i386 - - + + ucxxrt\crt\vcruntime - + @@ -212,12 +165,6 @@ ucxxrt\ucrt\startup - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - ucxxrt\crt\arm64 @@ -326,9 +273,6 @@ ucxxrt\crt\vcruntime - - ucxxrt\crt\vcruntime - ucxxrt\crt\vcruntime @@ -635,9 +579,6 @@ ucxxrt\crt\vcruntime - - ucxxrt\ucrt\startup - ucxxrt\ucrt\internal @@ -713,32 +654,14 @@ ucxxrt\ucrt\startup + + ucxxrt\crt\vcruntime + + + ucxxrt\crt\vcruntime + - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - - - ucxxrt\crt\arm - ucxxrt\crt\arm64 diff --git a/src/crt/misc/cfg_support.inc b/src/crt/misc/cfg_support.inc new file mode 100644 index 0000000..f369568 --- /dev/null +++ b/src/crt/misc/cfg_support.inc @@ -0,0 +1,65 @@ +#pragma once + + +extern PVOID __guard_check_icall_fptr; + +extern +__forceinline +void +__fastcall +_guard_check_icall_nop ( + _In_ uintptr_t Target + ) + +/*++ + +Routine Description: + + This function performs a no-op check when invoked by the compiler to check + the integrity of a function pointer for Control Flow Guard (/guard). + +Arguments: + + Target - Supplies the function pointer to check. + +Return Value: + + None. + +--*/ + +{ + + UNREFERENCED_PARAMETER(Target); + return; +} + +extern +__forceinline +int +_guard_icall_checks_enforced ( + VOID + ) + +/*++ + +Routine Description: + + This function determines whether Control Flow Guard is enforced for the + current module. + +Arguments: + + None. + +Return Value: + + A nonzero value is returned as the function value if Control Flow Guard + is enforced for the current module. + +--*/ + +{ + + return (ReadPointerNoFence(&__guard_check_icall_fptr) != (PVOID)_guard_check_icall_nop); +} diff --git a/src/crt/stl/xdint.cpp b/src/crt/stl/xdint.cpp index 8e3d001..a3032a3 100644 --- a/src/crt/stl/xdint.cpp +++ b/src/crt/stl/xdint.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _Dint(double* px, short xexp) { // test and drop (scaled) fraction bits +short _Dint(double* px, short xexp) noexcept { // test and drop (scaled) fraction bits const auto ps = reinterpret_cast<_Dval*>(px); short xchar = (ps->_Sh[_D0] & _DMASK) >> _DOFF; diff --git a/src/crt/stl/xdnorm.cpp b/src/crt/stl/xdnorm.cpp index d333fd0..7bd7038 100644 --- a/src/crt/stl/xdnorm.cpp +++ b/src/crt/stl/xdnorm.cpp @@ -7,11 +7,10 @@ _EXTERN_C_UNLESS_PURE -short _Dnorm(_Dval* ps) { // normalize double fraction - short xchar; +short _Dnorm(_Dval* ps) noexcept { // normalize double fraction + short xchar = 1; unsigned short sign = static_cast(ps->_Sh[_D0] & _DSIGN); - xchar = 1; if ((ps->_Sh[_D0] &= _DFRAC) != 0 || ps->_Sh[_D1] || ps->_Sh[_D2] || ps->_Sh[_D3]) { // nonzero, scale for (; ps->_Sh[_D0] == 0; xchar -= 16) { // shift left by 16 ps->_Sh[_D0] = ps->_Sh[_D1]; diff --git a/src/crt/stl/xdscale.cpp b/src/crt/stl/xdscale.cpp index d435b0a..f1bcbdf 100644 --- a/src/crt/stl/xdscale.cpp +++ b/src/crt/stl/xdscale.cpp @@ -7,14 +7,13 @@ _EXTERN_C_UNLESS_PURE -short _Dscale(double* px, long lexp) { // scale *px by 2^xexp with checking +short _Dscale(double* px, long lexp) noexcept { // scale *px by 2^xexp with checking const auto ps = reinterpret_cast<_Dval*>(px); short xchar = static_cast((ps->_Sh[_D0] & _DMASK) >> _DOFF); if (xchar == _DMAX) { - return static_cast( - (ps->_Sh[_D0] & _DFRAC) != 0 || ps->_Sh[_D1] != 0 || ps->_Sh[_D2] != 0 || ps->_Sh[_D3] != 0 ? _NANCODE - : _INFCODE); + return (ps->_Sh[_D0] & _DFRAC) != 0 || ps->_Sh[_D1] != 0 || ps->_Sh[_D2] != 0 || ps->_Sh[_D3] != 0 ? _NANCODE + : _INFCODE; } else if (xchar == 0 && 0 < (xchar = _Dnorm(ps))) { return 0; } @@ -47,7 +46,8 @@ short _Dscale(double* px, long lexp) { // scale *px by 2^xexp with checking ps->_Sh[_D1] = ps->_Sh[_D0]; ps->_Sh[_D0] = 0; } - if ((xexp = static_cast(-xexp)) != 0) { // scale by bits + if (xexp != 0) { // scale by bits + xexp = -xexp; psx = (ps->_Sh[_D3] << (16 - xexp)) | (psx != 0 ? 1 : 0); ps->_Sh[_D3] = static_cast(ps->_Sh[_D3] >> xexp | ps->_Sh[_D2] << (16 - xexp)); ps->_Sh[_D2] = static_cast(ps->_Sh[_D2] >> xexp | ps->_Sh[_D1] << (16 - xexp)); diff --git a/src/crt/stl/xdtest.cpp b/src/crt/stl/xdtest.cpp index 8ea68c3..cd28fa2 100644 --- a/src/crt/stl/xdtest.cpp +++ b/src/crt/stl/xdtest.cpp @@ -7,13 +7,12 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double* px) { // categorize *px +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double* px) noexcept { // categorize *px const auto ps = reinterpret_cast<_Dval*>(px); if ((ps->_Sh[_D0] & _DMASK) == _DMAX << _DOFF) { - return static_cast( - (ps->_Sh[_D0] & _DFRAC) != 0 || ps->_Sh[_D1] != 0 || ps->_Sh[_D2] != 0 || ps->_Sh[_D3] != 0 ? _NANCODE - : _INFCODE); + return (ps->_Sh[_D0] & _DFRAC) != 0 || ps->_Sh[_D1] != 0 || ps->_Sh[_D2] != 0 || ps->_Sh[_D3] != 0 ? _NANCODE + : _INFCODE; } else if ((ps->_Sh[_D0] & ~_DSIGN) != 0 || ps->_Sh[_D1] != 0 || ps->_Sh[_D2] != 0 || ps->_Sh[_D3] != 0) { return (ps->_Sh[_D0] & _DMASK) == 0 ? _DENORM : _FINITE; } else { @@ -21,7 +20,7 @@ _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double* px) { // categorize * } } -unsigned short* _Pmsw(double* px) { // get pointer to msw +unsigned short* _Pmsw(double* px) noexcept { // get pointer to msw return &reinterpret_cast<_Dval*>(px)->_Sh[_D0]; } diff --git a/src/crt/stl/xdunscal.cpp b/src/crt/stl/xdunscal.cpp index 031a389..f511003 100644 --- a/src/crt/stl/xdunscal.cpp +++ b/src/crt/stl/xdunscal.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _Dunscale(short* pex, double* px) { // separate *px to 1/2 <= |frac| < 1 and 2^*pex +short _Dunscale(short* pex, double* px) noexcept { // separate *px to 1/2 <= |frac| < 1 and 2^*pex const auto ps = reinterpret_cast<_Dval*>(px); short xchar = (ps->_Sh[_D0] & _DMASK) >> _DOFF; diff --git a/src/crt/stl/xfdint.cpp b/src/crt/stl/xfdint.cpp index 202df8c..1845903 100644 --- a/src/crt/stl/xfdint.cpp +++ b/src/crt/stl/xfdint.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _FDint(float* px, short xexp) { // test and drop (scaled) fraction bits +short _FDint(float* px, short xexp) noexcept { // test and drop (scaled) fraction bits const auto ps = reinterpret_cast<_Fval*>(px); short xchar = (ps->_Sh[_F0] & _FMASK) >> _FOFF; diff --git a/src/crt/stl/xfdnorm.cpp b/src/crt/stl/xfdnorm.cpp index ae4015e..398ef48 100644 --- a/src/crt/stl/xfdnorm.cpp +++ b/src/crt/stl/xfdnorm.cpp @@ -7,11 +7,10 @@ _EXTERN_C_UNLESS_PURE -short _FDnorm(_Fval* ps) { // normalize float fraction - short xchar; +short _FDnorm(_Fval* ps) noexcept { // normalize float fraction + short xchar = 1; unsigned short sign = static_cast(ps->_Sh[_F0] & _FSIGN); - xchar = 1; if ((ps->_Sh[_F0] &= _FFRAC) != 0 || ps->_Sh[_F1]) { // nonzero, scale if (ps->_Sh[_F0] == 0) { ps->_Sh[_F0] = ps->_Sh[_F1]; diff --git a/src/crt/stl/xfdscale.cpp b/src/crt/stl/xfdscale.cpp index 6120efa..59a08ff 100644 --- a/src/crt/stl/xfdscale.cpp +++ b/src/crt/stl/xfdscale.cpp @@ -7,12 +7,12 @@ _EXTERN_C_UNLESS_PURE -short _FDscale(float* px, long lexp) { // scale *px by 2^xexp with checking +short _FDscale(float* px, long lexp) noexcept { // scale *px by 2^xexp with checking const auto ps = reinterpret_cast<_Fval*>(px); short xchar = static_cast((ps->_Sh[_F0] & _FMASK) >> _FOFF); if (xchar == _FMAX) { - return static_cast((ps->_Sh[_F0] & _FFRAC) != 0 || ps->_Sh[_F1] != 0 ? _NANCODE : _INFCODE); + return (ps->_Sh[_F0] & _FFRAC) != 0 || ps->_Sh[_F1] != 0 ? _NANCODE : _INFCODE; } else if (xchar == 0 && 0 < (xchar = _FDnorm(ps))) { return 0; } @@ -42,7 +42,9 @@ short _FDscale(float* px, long lexp) { // scale *px by 2^xexp with checking ps->_Sh[_F0] = 0; xexp += 16; } - if ((xexp = static_cast(-xexp)) != 0) { // scale by bits + + if (xexp != 0) { // scale by bits + xexp = -xexp; psx = (ps->_Sh[_F1] << (16 - xexp)) | (psx != 0 ? 1 : 0); ps->_Sh[_F1] = static_cast(ps->_Sh[_F1] >> xexp | ps->_Sh[_F0] << (16 - xexp)); ps->_Sh[_F0] >>= xexp; diff --git a/src/crt/stl/xfdtest.cpp b/src/crt/stl/xfdtest.cpp index 968d87e..07b04ee 100644 --- a/src/crt/stl/xfdtest.cpp +++ b/src/crt/stl/xfdtest.cpp @@ -7,11 +7,11 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float* px) { // categorize *px +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float* px) noexcept { // categorize *px const auto ps = reinterpret_cast<_Fval*>(px); if ((ps->_Sh[_F0] & _FMASK) == _FMAX << _FOFF) { - return static_cast((ps->_Sh[_F0] & _FFRAC) != 0 || ps->_Sh[_F1] != 0 ? _NANCODE : _INFCODE); + return (ps->_Sh[_F0] & _FFRAC) != 0 || ps->_Sh[_F1] != 0 ? _NANCODE : _INFCODE; } else if ((ps->_Sh[_F0] & ~_FSIGN) != 0 || ps->_Sh[_F1] != 0) { return (ps->_Sh[_F0] & _FMASK) == 0 ? _DENORM : _FINITE; } else { @@ -19,7 +19,7 @@ _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float* px) { // categorize * } } -unsigned short* _FPmsw(float* px) { // get pointer to msw +unsigned short* _FPmsw(float* px) noexcept { // get pointer to msw return &reinterpret_cast<_Fval*>(px)->_Sh[_F0]; } diff --git a/src/crt/stl/xfdunsca.cpp b/src/crt/stl/xfdunsca.cpp index 6c46d42..4e29e02 100644 --- a/src/crt/stl/xfdunsca.cpp +++ b/src/crt/stl/xfdunsca.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _FDunscale(short* pex, float* px) { // separate *px to 1/2 <= |frac| < 1 and 2^*pex +short _FDunscale(short* pex, float* px) noexcept { // separate *px to 1/2 <= |frac| < 1 and 2^*pex const auto ps = reinterpret_cast<_Fval*>(px); short xchar = (ps->_Sh[_F0] & _FMASK) >> _FOFF; diff --git a/src/crt/stl/xferaise.cpp b/src/crt/stl/xferaise.cpp index 1a6e24f..8611fc2 100644 --- a/src/crt/stl/xferaise.cpp +++ b/src/crt/stl/xferaise.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -void __CLRCALL_PURE_OR_CDECL _Feraise(int except) { // report floating-point exception +void __CLRCALL_PURE_OR_CDECL _Feraise(int except) noexcept { // report floating-point exception if ((except & (_FE_DIVBYZERO | _FE_INVALID)) != 0) { errno = EDOM; } else if ((except & (_FE_UNDERFLOW | _FE_OVERFLOW)) != 0) { diff --git a/src/crt/stl/xldint.cpp b/src/crt/stl/xldint.cpp index a6d6378..68d99bf 100644 --- a/src/crt/stl/xldint.cpp +++ b/src/crt/stl/xldint.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _LDint(long double* px, short xexp) { // test and drop (scaled) fraction bits -- 64-bit +short _LDint(long double* px, short xexp) noexcept { // test and drop (scaled) fraction bits -- 64-bit return _Dint(reinterpret_cast(px), xexp); } diff --git a/src/crt/stl/xldscale.cpp b/src/crt/stl/xldscale.cpp index fbf3943..e0af821 100644 --- a/src/crt/stl/xldscale.cpp +++ b/src/crt/stl/xldscale.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _LDscale(long double* px, long lexp) { // scale *px by 2^lexp with checking -- 64-bit +short _LDscale(long double* px, long lexp) noexcept { // scale *px by 2^lexp with checking -- 64-bit return _Dscale(reinterpret_cast(px), lexp); } diff --git a/src/crt/stl/xldtest.cpp b/src/crt/stl/xldtest.cpp index e94f581..bb4dddb 100644 --- a/src/crt/stl/xldtest.cpp +++ b/src/crt/stl/xldtest.cpp @@ -11,7 +11,7 @@ _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LDtest(long double* px) noexcept { return _Dtest(reinterpret_cast(px)); } -unsigned short* _LPmsw(long double* px) { // get pointer to msw +unsigned short* _LPmsw(long double* px) noexcept { // get pointer to msw return &reinterpret_cast<_Lval*>(px)->_Sh[_L0]; } diff --git a/src/crt/stl/xldunsca.cpp b/src/crt/stl/xldunsca.cpp index 814f934..40313fc 100644 --- a/src/crt/stl/xldunsca.cpp +++ b/src/crt/stl/xldunsca.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _LDunscale(short* pex, long double* px) { // separate *px to 1/2 <= |frac| < 1 and 2^*pex -- 64-bit +short _LDunscale(short* pex, long double* px) noexcept { // separate *px to 1/2 <= |frac| < 1 and 2^*pex -- 64-bit return _Dunscale(pex, reinterpret_cast(px)); } diff --git a/src/crt/stl/xlgamma.cpp b/src/crt/stl/xlgamma.cpp index 706b7f7..c77cbe1 100644 --- a/src/crt/stl/xlgamma.cpp +++ b/src/crt/stl/xlgamma.cpp @@ -9,11 +9,11 @@ // #include _STD_BEGIN -_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _XLgamma(float); -_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _XLgamma(double); -_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double); +_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _XLgamma(float) noexcept; +_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _XLgamma(double) noexcept; +_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double) noexcept; -float __CLRCALL_PURE_OR_CDECL _XLgamma(float x) { // moderately accurate log gamma +float __CLRCALL_PURE_OR_CDECL _XLgamma(float x) noexcept { // moderately accurate log gamma static const float coeff[6] = {76.18009172947146F, -86.50532032941677F, 24.01409824083091F, -1.23173972450155F, 0.1208650973866179E-2F, -0.5395239384953E-5F}; @@ -29,7 +29,7 @@ float __CLRCALL_PURE_OR_CDECL _XLgamma(float x) { // moderately accurate log gam return -val0 + _STD log(2.5066282746310005F * val1 / x); } -double __CLRCALL_PURE_OR_CDECL _XLgamma(double x) { // moderately accurate log gamma +double __CLRCALL_PURE_OR_CDECL _XLgamma(double x) noexcept { // moderately accurate log gamma static const double coeff[6] = {76.18009172947146, -86.50532032941677, 24.01409824083091, -1.23173972450155, 0.1208650973866179E-2, -0.5395239384953E-5}; @@ -45,7 +45,7 @@ double __CLRCALL_PURE_OR_CDECL _XLgamma(double x) { // moderately accurate log g return -val0 + _STD log(2.5066282746310005 * val1 / x); } -long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double x) { // moderately accurate log gamma +long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double x) noexcept { // moderately accurate log gamma static const long double coeff[6] = {76.18009172947146, -86.50532032941677, 24.01409824083091, -1.23173972450155, 0.1208650973866179E-2, -0.5395239384953E-5}; diff --git a/src/crt/stl/xlpoly.cpp b/src/crt/stl/xlpoly.cpp index 7460c39..2e35def 100644 --- a/src/crt/stl/xlpoly.cpp +++ b/src/crt/stl/xlpoly.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -long double _LPoly(long double x, const long double* tab, int n) { // compute polynomial +long double _LPoly(long double x, const long double* tab, int n) noexcept { // compute polynomial long double y; for (y = *tab; 0 <= --n;) { diff --git a/src/crt/stl/xlsinh.cpp b/src/crt/stl/xlsinh.cpp index 932a034..b6b7ace 100644 --- a/src/crt/stl/xlsinh.cpp +++ b/src/crt/stl/xlsinh.cpp @@ -3,16 +3,18 @@ // _LSinh function +#include + #include "xmath.hpp" _EXTERN_C_UNLESS_PURE // coefficients -static const long double p[] = {0.0000000000000028486835L, 0.0000000000007646464279L, 0.0000000001605905091647L, +static constexpr long double p[] = {0.0000000000000028486835L, 0.0000000000007646464279L, 0.0000000001605905091647L, 0.0000000250521083436962L, 0.0000027557319224130455L, 0.0001984126984126956009L, 0.0083333333333333336073L, 0.1666666666666666666564L, 1.0000000000000000000001L}; -static constexpr size_t NP = sizeof(p) / sizeof(p[0]) - 1; +static constexpr size_t NP = std::size(p) - 1; _CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LSinh(long double x, long double y) noexcept { // compute y * sinh(x), |y| <= 1 @@ -40,7 +42,7 @@ _CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LSinh(long double x, long dou if (x < _LRteps._Long_double) { x *= y; // x tiny } else if (x < 1.0L) { - long double w = x * x; + const long double w = x * x; x += x * w * _LPoly(w, p, NP - 1); x *= y; diff --git a/src/crt/stl/xmath.hpp b/src/crt/stl/xmath.hpp index 4c1f16e..9baabaa 100644 --- a/src/crt/stl/xmath.hpp +++ b/src/crt/stl/xmath.hpp @@ -1,13 +1,18 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#ifndef _XMATH -#define _XMATH +#pragma once + #include #include #include #include +// fix: MSC_VER < 14.38 +#if _MSC_VER < 1938 +#define noexcept +#endif + // macros for _Feraise argument #define _FE_DIVBYZERO 0x04 #define _FE_INVALID 0x01 @@ -55,18 +60,16 @@ _EXTERN_C_UNLESS_PURE -void __CLRCALL_PURE_OR_CDECL _Feraise(int); +void __CLRCALL_PURE_OR_CDECL _Feraise(int) noexcept; -#if _MSC_VER >= 1934 // 17.4 union _Dconst { // pun float types as integer array unsigned short _Word[8]; // TRANSITION, ABI: Twice as large as necessary. float _Float; double _Double; long double _Long_double; }; -#endif -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double*); +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double*) noexcept; extern _CRTIMP2_PURE _Dconst _Denorm; extern _CRTIMP2_PURE _Dconst _Hugeval; @@ -74,7 +77,7 @@ extern _CRTIMP2_PURE _Dconst _Inf; extern _CRTIMP2_PURE _Dconst _Nan; extern _CRTIMP2_PURE _Dconst _Snan; -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float*); +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float*) noexcept; extern _CRTIMP2_PURE _Dconst _FDenorm; extern _CRTIMP2_PURE _Dconst _FInf; @@ -86,16 +89,16 @@ extern _CRTIMP2_PURE _Dconst _LInf; extern _CRTIMP2_PURE _Dconst _LNan; extern _CRTIMP2_PURE _Dconst _LSnan; -int _Stopfx(const char**, char**); +int _Stopfx(const char**, char**) noexcept; _In_range_(0, maxsig) int _Stoflt( - const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; _In_range_(0, maxsig) int _Stoxflt( - const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; int _WStopfx(const wchar_t**, wchar_t**); _In_range_(0, maxsig) int _WStoflt( - const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; _In_range_(0, maxsig) int _WStoxflt( - const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; // double declarations union _Dval { // pun floating type as integer array @@ -103,28 +106,28 @@ union _Dval { // pun floating type as integer array double _Val; }; -unsigned short* _Pmsw(double*); +unsigned short* _Pmsw(double*) noexcept; -short _Dint(double*, short); -short _Dnorm(_Dval*); -short _Dscale(double*, long); -short _Dunscale(short*, double*); +short _Dint(double*, short) noexcept; +short _Dnorm(_Dval*) noexcept; +short _Dscale(double*, long) noexcept; +short _Dunscale(short*, double*) noexcept; -double _Poly(double, const double*, int); +double _Poly(double, const double*, int) noexcept; extern const _Dconst _Eps; extern const _Dconst _Rteps; extern const double _Xbig; -double _Xp_getw(const double*, int); -double* _Xp_setn(double*, int, long); -double* _Xp_setw(double*, int, double); -double* _Xp_addh(double*, int, double); -double* _Xp_mulh(double*, int, double); -double* _Xp_movx(double*, int, const double*); -double* _Xp_addx(double*, int, const double*, int); -double* _Xp_ldexpx(double*, int, int); -double* _Xp_mulx(double*, int, const double*, int, double*); +double _Xp_getw(const double*, int) noexcept; +double* _Xp_setn(double*, int, long) noexcept; +double* _Xp_setw(double*, int, double) noexcept; +double* _Xp_addh(double*, int, double) noexcept; +double* _Xp_mulh(double*, int, double) noexcept; +double* _Xp_movx(double*, int, const double*) noexcept; +double* _Xp_addx(double*, int, const double*, int) noexcept; +double* _Xp_ldexpx(double*, int, int) noexcept; +double* _Xp_mulx(double*, int, const double*, int, double*) noexcept; // float declarations union _Fval { // pun floating type as integer array @@ -132,28 +135,26 @@ union _Fval { // pun floating type as integer array float _Val; }; -unsigned short* _FPmsw(float*); - -short _FDint(float*, short); -short _FDnorm(_Fval*); -short _FDscale(float*, long); -short _FDunscale(short*, float*); +unsigned short* _FPmsw(float*) noexcept; -float _FPoly(float, const float*, int); +short _FDint(float*, short) noexcept; +short _FDnorm(_Fval*) noexcept; +short _FDscale(float*, long) noexcept; +short _FDunscale(short*, float*) noexcept; extern const _Dconst _FEps; extern const _Dconst _FRteps; extern const float _FXbig; -float _FXp_getw(const float*, int); -float* _FXp_setn(float*, int, long); -float* _FXp_setw(float*, int, float); -float* _FXp_addh(float*, int, float); -float* _FXp_mulh(float*, int, float); -float* _FXp_movx(float*, int, const float*); -float* _FXp_addx(float*, int, const float*, int); -float* _FXp_ldexpx(float*, int, int); -float* _FXp_mulx(float*, int, const float*, int, float*); +float _FXp_getw(const float*, int) noexcept; +float* _FXp_setn(float*, int, long) noexcept; +float* _FXp_setw(float*, int, float) noexcept; +float* _FXp_addh(float*, int, float) noexcept; +float* _FXp_mulh(float*, int, float) noexcept; +float* _FXp_movx(float*, int, const float*) noexcept; +float* _FXp_addx(float*, int, const float*, int) noexcept; +float* _FXp_ldexpx(float*, int, int) noexcept; +float* _FXp_mulx(float*, int, const float*, int, float*) noexcept; // long double declarations union _Lval { // pun floating type as integer array @@ -161,27 +162,26 @@ union _Lval { // pun floating type as integer array long double _Val; }; -unsigned short* _LPmsw(long double*); +unsigned short* _LPmsw(long double*) noexcept; -short _LDint(long double*, short); -short _LDnorm(_Lval*); -short _LDscale(long double*, long); -short _LDunscale(short*, long double*); -long double _LPoly(long double, const long double*, int); +short _LDint(long double*, short) noexcept; +short _LDscale(long double*, long) noexcept; +short _LDunscale(short*, long double*) noexcept; +long double _LPoly(long double, const long double*, int) noexcept; extern const _Dconst _LEps; extern const _Dconst _LRteps; extern const long double _LXbig; -long double _LXp_getw(const long double*, int); -long double* _LXp_setn(long double*, int, long); -long double* _LXp_setw(long double*, int, long double); -long double* _LXp_addh(long double*, int, long double); -long double* _LXp_mulh(long double*, int, long double); -long double* _LXp_movx(long double*, int, const long double*); -long double* _LXp_addx(long double*, int, const long double*, int); -long double* _LXp_ldexpx(long double*, int, int); -long double* _LXp_mulx(long double*, int, const long double*, int, long double*); +long double _LXp_getw(const long double*, int) noexcept; +long double* _LXp_setn(long double*, int, long) noexcept; +long double* _LXp_setw(long double*, int, long double) noexcept; +long double* _LXp_addh(long double*, int, long double) noexcept; +long double* _LXp_mulh(long double*, int, long double) noexcept; +long double* _LXp_movx(long double*, int, const long double*) noexcept; +long double* _LXp_addx(long double*, int, const long double*, int) noexcept; +long double* _LXp_ldexpx(long double*, int, int) noexcept; +long double* _LXp_mulx(long double*, int, const long double*, int, long double*) noexcept; _END_EXTERN_C_UNLESS_PURE @@ -190,15 +190,17 @@ _END_EXTERN_C_UNLESS_PURE #pragma float_control(except, on, push) #endif -template -_NODISCARD T _Xfe_overflow(const T sign) noexcept { +template +[[nodiscard]] T _Xfe_overflow(const T sign) noexcept +{ static_assert(_STD is_floating_point_v, "Expected is_floating_point_v."); constexpr T huge = _STD numeric_limits::max(); return _STD copysign(huge, sign) * huge; } -template -_NODISCARD T _Xfe_underflow(const T sign) noexcept { +template +[[nodiscard]] T _Xfe_underflow(const T sign) noexcept +{ static_assert(_STD is_floating_point_v, "Expected is_floating_point_v."); constexpr T tiny = _STD numeric_limits::min(); return _STD copysign(tiny, sign) * tiny; @@ -207,5 +209,3 @@ _NODISCARD T _Xfe_underflow(const T sign) noexcept { #ifndef _M_CEE_PURE #pragma float_control(pop) #endif - -#endif // _XMATH diff --git a/src/crt/stl/xpoly.cpp b/src/crt/stl/xpoly.cpp index 89407c3..a0bfe97 100644 --- a/src/crt/stl/xpoly.cpp +++ b/src/crt/stl/xpoly.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -double _Poly(double x, const double* tab, int n) { // compute polynomial +double _Poly(double x, const double* tab, int n) noexcept { // compute polynomial double y; for (y = *tab; 0 <= --n;) { diff --git a/src/crt/stl/xrngabort.cpp b/src/crt/stl/xrngabort.cpp index 0971ed7..3d74630 100644 --- a/src/crt/stl/xrngabort.cpp +++ b/src/crt/stl/xrngabort.cpp @@ -12,8 +12,7 @@ _STD_BEGIN // TRANSITION, ABI: _Rng_abort() is preserved for binary compatibility [[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Rng_abort(_In_z_ const char* _Msg) { // abort on precondition failure - _CSTD fputs(_Msg, stderr); - _CSTD fputc('\n', stderr); + DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, "%hs\n", _Msg); _CSTD abort(); } _STD_END diff --git a/src/crt/stl/xsinh.cpp b/src/crt/stl/xsinh.cpp index 21aff82..b7b161c 100644 --- a/src/crt/stl/xsinh.cpp +++ b/src/crt/stl/xsinh.cpp @@ -3,6 +3,8 @@ // _Sinh function +#include + #include "xmath.hpp" _EXTERN_C_UNLESS_PURE @@ -11,7 +13,7 @@ _EXTERN_C_UNLESS_PURE static constexpr double p[] = {0.0000000001632881, 0.0000000250483893, 0.0000027557344615, 0.0001984126975233, 0.0083333333334816, 0.1666666666666574, 1.0000000000000001}; -static constexpr size_t NP = sizeof(p) / sizeof(p[0]) - 1; +static constexpr size_t NP = std::size(p) - 1; _CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Sinh(double x, double y) noexcept { // compute y * sinh(x), |y| <= 1 short neg; diff --git a/src/crt/stl/xstod.cpp b/src/crt/stl/xstod.cpp index e3ffbc0..8ea9506 100644 --- a/src/crt/stl/xstod.cpp +++ b/src/crt/stl/xstod.cpp @@ -13,9 +13,11 @@ _EXTERN_C_UNLESS_PURE +// TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _Stodx(const CTYPE* s, CTYPE** endptr, long pten, int* perr) #include "xxstod.hpp" + // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _Stod(const CTYPE* s, CTYPE** endptr, long pten) { // convert string, discard error code return _Stodx(s, endptr, pten, nullptr); diff --git a/src/crt/stl/xstof.cpp b/src/crt/stl/xstof.cpp index c08118a..277fe18 100644 --- a/src/crt/stl/xstof.cpp +++ b/src/crt/stl/xstof.cpp @@ -13,9 +13,11 @@ _EXTERN_C_UNLESS_PURE +// TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _Stofx(const CTYPE* s, CTYPE** endptr, long pten, int* perr) #include "xxstod.hpp" + // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _Stof(const CTYPE* s, CTYPE** endptr, long pten) { // convert string, discard error code return _Stofx(s, endptr, pten, nullptr); diff --git a/src/crt/stl/xstoflt.cpp b/src/crt/stl/xstoflt.cpp index 10413ae..7ee089a 100644 --- a/src/crt/stl/xstoflt.cpp +++ b/src/crt/stl/xstoflt.cpp @@ -15,8 +15,8 @@ constexpr int _Base = 10; // decimal constexpr int _Ndig = 9; // decimal digits per long word constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -_In_range_(0, maxsig) int _Stoflt( - const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { +_In_range_(0, maxsig) int _Stoflt(const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], + _In_range_(1, 4) int maxsig) noexcept { // convert string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen diff --git a/src/crt/stl/xstol.cpp b/src/crt/stl/xstol.cpp index ab24be9..344041c 100644 --- a/src/crt/stl/xstol.cpp +++ b/src/crt/stl/xstol.cpp @@ -36,8 +36,7 @@ _CRTIMP2_PURE long __CLRCALL_PURE_OR_CDECL _Stolx( *endptr = const_cast(s); } - if (s == *endptr && x != 0 || sign == '+' && LONG_MAX < x - || sign == '-' && 0 - static_cast(LONG_MIN) < x) { // overflow + if (s == *endptr && x != 0 || sign == '+' && LONG_MAX < x || sign == '-' && (1ul << 31) < x) { // overflow errno = ERANGE; if (perr != nullptr) { *perr = 1; diff --git a/src/crt/stl/xstold.cpp b/src/crt/stl/xstold.cpp index 9b42464..f15daf3 100644 --- a/src/crt/stl/xstold.cpp +++ b/src/crt/stl/xstold.cpp @@ -13,9 +13,11 @@ _EXTERN_C_UNLESS_PURE +// TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _Stoldx(const CTYPE* s, CTYPE** endptr, long pten, int* perr) #include "xxstod.hpp" + // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _Stold(const CTYPE* s, CTYPE** endptr, long pten) { // convert string, discard error code return _Stoldx(s, endptr, pten, nullptr); diff --git a/src/crt/stl/xstoll.cpp b/src/crt/stl/xstoll.cpp index 63e6508..3cf71de 100644 --- a/src/crt/stl/xstoll.cpp +++ b/src/crt/stl/xstoll.cpp @@ -36,8 +36,7 @@ _CRTIMP2_PURE long long __CLRCALL_PURE_OR_CDECL _Stollx( *endptr = const_cast(s); } - if (s == *endptr && x != 0 || sign == '+' && LLONG_MAX < x - || sign == '-' && 0 - static_cast(LLONG_MIN) < x) { // overflow + if (s == *endptr && x != 0 || sign == '+' && LLONG_MAX < x || sign == '-' && (1ull << 63) < x) { // overflow errno = ERANGE; if (perr != nullptr) { *perr = 1; diff --git a/src/crt/stl/xstopfx.cpp b/src/crt/stl/xstopfx.cpp index 91ddc41..858c951 100644 --- a/src/crt/stl/xstopfx.cpp +++ b/src/crt/stl/xstopfx.cpp @@ -9,7 +9,7 @@ _EXTERN_C_UNLESS_PURE -int _Stopfx(const char** ps, char** endptr) { // parse prefix of floating-point field +int _Stopfx(const char** ps, char** endptr) noexcept { // parse prefix of floating-point field const char* s = *ps; int code = 0; @@ -42,6 +42,7 @@ int _Stopfx(const char** ps, char** endptr) { // parse prefix of floating-point } } } + if (endptr != nullptr) { *endptr = const_cast(s); } diff --git a/src/crt/stl/xstoxflt.cpp b/src/crt/stl/xstoxflt.cpp index 7ab3ea7..ac7e185 100644 --- a/src/crt/stl/xstoxflt.cpp +++ b/src/crt/stl/xstoxflt.cpp @@ -16,18 +16,17 @@ constexpr int _Base = 16; // hexadecimal constexpr int _Ndig = 7; // hexadecimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -_In_range_(0, maxsig) int _Stoxflt( - const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { +_In_range_(0, maxsig) int _Stoxflt(const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], + _In_range_(1, 4) int maxsig) noexcept { // convert string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen int seen = 0; // any valid field characters seen - int word = 0; // current long word to fill const char* pd; - static const char digits[] = "0123456789abcdefABCDEF"; - static const char vals[] = {// values of hex digits - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15}; + static constexpr char digits[] = "0123456789abcdefABCDEF"; // hex digits in both cases + static constexpr char vals[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15}; // values of hex digits maxsig *= _Ndig; // convert word count to digit count if (_Maxsig < maxsig) { @@ -63,11 +62,14 @@ _In_range_(0, maxsig) int _Stoxflt( } } - for (; (pd = static_cast(memchr(&digits[0], *s, 22))) != nullptr; ++s, seen = 1) { + while ((pd = static_cast(memchr(&digits[0], *s, 22))) != nullptr) { if (nsig <= maxsig) { // accumulate a fraction digit buf[nsig++] = vals[pd - digits]; --lo[0]; } + + ++s; + seen = 1; } if (maxsig < nsig) { // discard excess digit after rounding up @@ -88,6 +90,9 @@ _In_range_(0, maxsig) int _Stoxflt( } lo[0] <<= 2; // change hex exponent to binary exponent + + int word; // current long word to fill + if (seen) { // convert digit sequence to words int bufidx = 0; // next digit in buffer int wordidx = _Ndig - nsig % _Ndig; // next digit in word (% _Ndig) @@ -122,9 +127,7 @@ _In_range_(0, maxsig) int _Stoxflt( s = ssav; // roll back if incomplete exponent } } - } - - if (!seen) { + } else { word = 0; // return zero if bad parse } diff --git a/src/crt/stl/xwstod.cpp b/src/crt/stl/xwstod.cpp index 29b717c..531ea67 100644 --- a/src/crt/stl/xwstod.cpp +++ b/src/crt/stl/xwstod.cpp @@ -12,9 +12,11 @@ _EXTERN_C_UNLESS_PURE +// TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _WStodx(const CTYPE* s, CTYPE** endptr, long pten, int* perr) #include "xxstod.hpp" + // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _WStod(const CTYPE* s, CTYPE** endptr, long pten) { // convert string, discard error code return _WStodx(s, endptr, pten, nullptr); diff --git a/src/crt/stl/xwstof.cpp b/src/crt/stl/xwstof.cpp index b228470..2c5cc9c 100644 --- a/src/crt/stl/xwstof.cpp +++ b/src/crt/stl/xwstof.cpp @@ -11,9 +11,11 @@ _EXTERN_C_UNLESS_PURE +// TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _WStofx(const CTYPE* s, CTYPE** endptr, long pten, int* perr) #include "xxstod.hpp" + // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _WStof(const CTYPE* s, CTYPE** endptr, long pten) { // convert string, discard error code return _WStofx(s, endptr, pten, nullptr); diff --git a/src/crt/stl/xwstoflt.cpp b/src/crt/stl/xwstoflt.cpp index ec4894d..41dcc71 100644 --- a/src/crt/stl/xwstoflt.cpp +++ b/src/crt/stl/xwstoflt.cpp @@ -16,7 +16,7 @@ constexpr int _Ndig = 9; // decimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep _In_range_(0, maxsig) int _WStoflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, - _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) noexcept { // convert wide string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen diff --git a/src/crt/stl/xwstold.cpp b/src/crt/stl/xwstold.cpp index eafc09d..7368634 100644 --- a/src/crt/stl/xwstold.cpp +++ b/src/crt/stl/xwstold.cpp @@ -11,9 +11,11 @@ _EXTERN_C_UNLESS_PURE +// TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _WStoldx(const CTYPE* s, CTYPE** endptr, long pten, int* perr) #include "xxstod.hpp" + // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL _WStold(const CTYPE* s, CTYPE** endptr, long pten) { // convert string, discard error code return _WStoldx(s, endptr, pten, nullptr); diff --git a/src/crt/stl/xwstoxfl.cpp b/src/crt/stl/xwstoxfl.cpp index 63b471c..6d4df60 100644 --- a/src/crt/stl/xwstoxfl.cpp +++ b/src/crt/stl/xwstoxfl.cpp @@ -17,19 +17,16 @@ constexpr int _Ndig = 7; // hexadecimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep _In_range_(0, maxsig) int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, - _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) noexcept { // convert wide string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen int seen = 0; // any valid field characters seen - int word = 0; // current long word to fill const wchar_t* pd; - static const wchar_t digits[] = {// hex digits in both cases - L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'a', L'b', L'c', L'd', L'e', L'f', L'A', L'B', - L'C', L'D', L'E', L'F', L'\0'}; - static const char vals[] = {// values of hex digits - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15}; + static constexpr wchar_t digits[] = L"0123456789abcdefABCDEF"; // hex digits in both cases + static constexpr char vals[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15}; // values of hex digits maxsig *= _Ndig; // convert word count to digit count if (_Maxsig < maxsig) { @@ -55,7 +52,7 @@ _In_range_(0, maxsig) int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t seen = 1; } - if (*s == localeconv()->decimal_point[0]) { + if (*s == localeconv()->_W_decimal_point[0]) { ++s; } @@ -93,6 +90,9 @@ _In_range_(0, maxsig) int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t } lo[0] <<= 2; // change hex exponent to binary exponent + + int word; // current long word to fill + if (seen) { // convert digit sequence to words int bufidx = 0; // next digit in buffer int wordidx = _Ndig - nsig % _Ndig; // next digit in word (% _Ndig) @@ -127,9 +127,7 @@ _In_range_(0, maxsig) int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t s = ssav; // roll back if incomplete exponent } } - } - - if (!seen) { + } else { word = 0; // return zero if bad parse } diff --git a/src/crt/stl/xxxprec.hpp b/src/crt/stl/xxxprec.hpp index 13288e2..952e260 100644 --- a/src/crt/stl/xxxprec.hpp +++ b/src/crt/stl/xxxprec.hpp @@ -39,7 +39,7 @@ static void printit(const char* s, FTYPE* p, int n) { // print xp array } #endif // 0 -FTYPE FNAME(Xp_getw)(const FTYPE* p, int n) { // get total value +FTYPE FNAME(Xp_getw)(const FTYPE* p, int n) noexcept { // get total value if (n == 0) { return FLIT(0.0); } else if (n == 1 || p[0] == FLIT(0.0) || p[1] == FLIT(0.0)) { @@ -62,7 +62,7 @@ FTYPE FNAME(Xp_getw)(const FTYPE* p, int n) { // get total value } } -FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) { // load a full-precision value +FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) noexcept { // load a full-precision value FTYPE x0 = x; short errx; short xexp; @@ -111,7 +111,7 @@ FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) { // load a full-precision value return p; } -FTYPE* FNAME(Xp_addh)(FTYPE* p, int n, FTYPE x0) { // add a half-precision value +FTYPE* FNAME(Xp_addh)(FTYPE* p, int n, FTYPE x0) noexcept { // add a half-precision value FTYPE xscaled = x0; short errx; short xexp; @@ -219,7 +219,7 @@ FTYPE* FNAME(Xp_addh)(FTYPE* p, int n, FTYPE x0) { // add a half-precision value return p; } -FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) { // multiply by a half-precision value +FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) noexcept { // multiply by a half-precision value short errx; int j; int k; @@ -280,7 +280,7 @@ FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) { // multiply by a half-precisi return p; } -FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) { // load a long integer +FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) noexcept { // load a long integer #if FBITS == 53 FNAME(Xp_setw)(p, n, static_cast(x)); @@ -295,12 +295,12 @@ FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) { // load a long integer return p; } -FTYPE* FNAME(Xp_movx)(FTYPE* p, int n, const FTYPE* q) { // copy an extended precision value +FTYPE* FNAME(Xp_movx)(FTYPE* p, int n, const FTYPE* q) noexcept { // copy an extended precision value memcpy(p, q, n * sizeof(FTYPE)); return p; } -FTYPE* FNAME(Xp_addx)(FTYPE* p, int n, const FTYPE* q, int m) { // add an extended precision value +FTYPE* FNAME(Xp_addx)(FTYPE* p, int n, const FTYPE* q, int m) noexcept { // add an extended precision value int k; for (k = 0; k < m && q[k] != FLIT(0.0); ++k) { @@ -310,7 +310,7 @@ FTYPE* FNAME(Xp_addx)(FTYPE* p, int n, const FTYPE* q, int m) { // add an extend return p; } -FTYPE* FNAME(Xp_ldexpx)(FTYPE* p, int n, int m) { // scale an extended precision value +FTYPE* FNAME(Xp_ldexpx)(FTYPE* p, int n, int m) noexcept { // scale an extended precision value int k; for (k = 0; k < n; ++k) { p[k] = static_cast(FFUN(ldexp)(p[k], m)); @@ -322,7 +322,7 @@ FTYPE* FNAME(Xp_ldexpx)(FTYPE* p, int n, int m) { // scale an extended precision return p; } -FTYPE* FNAME(Xp_mulx)(FTYPE* p, int n, const FTYPE* q, int m, FTYPE* ptemp2) { +FTYPE* FNAME(Xp_mulx)(FTYPE* p, int n, const FTYPE* q, int m, FTYPE* ptemp2) noexcept { // multiply by an extended precision value (needs 2 * n temp) if (n != 0 && m != 0) { if (q[0] == FLIT(0.0) || q[1] == FLIT(0.0)) { diff --git a/src/crt/vcruntime/cpu_disp.c b/src/crt/vcruntime/cpu_disp.c new file mode 100644 index 0000000..53262a4 --- /dev/null +++ b/src/crt/vcruntime/cpu_disp.c @@ -0,0 +1,228 @@ +#include + +// Thunks: +#if defined _KERNEL_MODE +#define IsProcessorFeaturePresent ExIsProcessorFeaturePresent +#endif + +unsigned int __isa_available = __ISA_AVAILABLE_X86; + +#if defined(_M_ARM) + +int __cdecl __isa_available_init() +{ + if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) + __isa_available = __ISA_AVAILABLE_NEON; + return 0; +} + +#elif defined(_M_ARM64) + +int __cdecl __isa_available_init() +{ + return 0; +} + +#else // _M_AMD64 || _M_X86 + +#include +#include + +typedef enum _CPUID +{ + CPUID_BASIC_INFORMATION = 0x00000000, + CPUID_PROCESSOR_INFO_AND_FEATURE_BITS = 0x00000001, + CPUID_CACHE_AND_TLB_DESCRIPTOR_INFORMATION = 0x00000002, + CPUID_PROCESSOR_SERIAL_NUMBER = 0X00000003, + CPUID_INTEL_THREAD_CORE_AND_CACHE_TOPOLOGY = 0x00000004, + CPUID_MONITOR_MWAIT_INFORMATION = 0x00000005, + CPUID_THERMAL_POWER_MANAGEMENT = 0x00000005, + CPUID_EXTENDED_FEATURES = 0x00000007, + CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING = 0x0000000A, + CPUID_HYPERVISOR_VENDOR = 0x40000000, + CPUID_GET_HIGHEST_EXTENDED_FUNCTION_IMPLEMENTED = 0x80000000, + CPUID_EXTENDED_PROCESSOR_INFO_AND_FEATURE_BITS = 0x80000001, + CPUID_PROCESSOR_BRAND_STRING_2 = 0x80000002, + CPUID_PROCESSOR_BRAND_STRING_3 = 0x80000003, + CPUID_PROCESSOR_BRAND_STRING_4 = 0x80000004, + CPUID_L1_CACHE_AND_TLB_IDENTIFIERS = 0x80000005, + CPUID_EXTENDED_L2_CACHE_FEATURES = 0x80000006, + CPUID_ADVANCED_POWER_MANAGEMENT_INFORMATION = 0x80000007, + CPUID_VIRTUAL_AND_PHYSICAL_ADDRESS_SIZES = 0x80000008, + CPUID_AMD_EASTER_EGG = 0x8FFFFFFF, + CPUID_SECURE_VIRTUAL_MACHINE_SPECIFICATIONS = 0x8000000A, +} CPUID; + +typedef union _CPUID_INFO +{ + struct + { + int EAX; + int EBX; + int ECX; + int EDX; + + #pragma warning(suppress: 4201) + }; + + int Data[4]; +} CPUID_INFO; + +/* Features in ecx for leaf 1 */ +#define CF_SSE42 0x00100000 +#define CF_OSXSAVE 0x08000000 +#define CF_AVX 0x10000000 + +/* Features in ebx for leaf 7 sub-leaf 0 */ +#define CX_AVX2 0x00000020 +#define CX_ERMS 0x00000200 +#define CX_AVX512F 0x00010000 +#define CX_AVX512DQ 0x00020000 +#define CX_AVX512CD 0x10000000 +#define CX_AVX512BW 0x40000000 +#define CX_AVX512VL 0x80000000 + +/* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ +#define XCR_XFEATURE_ENABLED_MASK 0x00000000 +#define XSTATE_FP 0x00000001 +#define XSTATE_SSE 0x00000002 +#define XSTATE_YMM 0x00000004 +#define XSTATE_OPMASK 0x00000020 +#define XSTATE_ZMM 0x00000040 +#define XSTATE_HI_ZMM 0x00000080 + +#define __ISA_ENABLED_X86 (1 << __ISA_AVAILABLE_X86) +#define __ISA_ENABLED_SSE2 (1 << __ISA_AVAILABLE_SSE2) +#define __ISA_ENABLED_SSE42 (1 << __ISA_AVAILABLE_SSE42) +#define __ISA_ENABLED_AVX (1 << __ISA_AVAILABLE_AVX) +#define __ISA_ENABLED_AVX2 (1 << __ISA_AVAILABLE_AVX2) +#define __ISA_ENABLED_AVX512 (1 << __ISA_AVAILABLE_AVX512) + +unsigned int __favor = __FAVOR_ATOM; + +#if defined(_M_AMD64) || defined(_M_IX86) + +unsigned int __isa_enabled = __ISA_ENABLED_X86; + +#if defined(_M_AMD64) +size_t __memset_nt_threshold = 0x2000000; +size_t __memset_fast_string_threshold = 0x80000; +#endif + +int __cdecl __isa_available_init() +{ +#define C1_AVX (CF_OSXSAVE | CF_AVX) +#define C7_AVX512 (CX_AVX512F | CX_AVX512DQ | CX_AVX512CD | CX_AVX512BW | CX_AVX512VL) +#define XCR_AVX (XSTATE_SSE | XSTATE_YMM) +#define XCR_AVX512F (XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) + + CPUID_INFO CpuId = { 0 }; + + int Features = 0; + int FeaturesEx = 0; + int XFeatures = 0; + int MaxId = 0; + bool Intel = false; + + if (!IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) { + goto ISA_AVAILABLE_X86; + } + + __cpuid(CpuId.Data, CPUID_BASIC_INFORMATION); + + MaxId = CpuId.EAX; + Intel = !(CpuId.EBX ^ 'uneG' | CpuId.EDX ^ 'Ieni' | CpuId.ECX ^ 'letn'); // GenuineIntel + + __cpuid(CpuId.Data, CPUID_PROCESSOR_INFO_AND_FEATURE_BITS); + + if (Intel) { + #if defined(_M_AMD64) + __memset_fast_string_threshold = 0x8000; + __memset_nt_threshold = ~0ull; + #endif + + switch (CpuId.EAX & 0x0FFF3FF0) { + default: + { + break; + } + case 0x000106C0: + case 0x00020660: + case 0x00020670: + case 0x00030650: + case 0x00030660: + case 0x00030670: + { + __favor = 1 << __FAVOR_ATOM; + break; + } + } + } + + Features = CpuId.ECX; + + if (MaxId >= 7) { + __cpuid(CpuId.Data, CPUID_EXTENDED_FEATURES); + + FeaturesEx = CpuId.EBX; + if (FeaturesEx & CX_ERMS) { + __favor = 1 << __FAVOR_ENFSTRG; + } + } + + if (Features & CF_SSE42) { + if ((Features & C1_AVX) == C1_AVX) { + XFeatures = (uint32_t)_xgetbv(_XCR_XFEATURE_ENABLED_MASK); + if ((XFeatures & XCR_AVX) == XCR_AVX) { + if (FeaturesEx & CX_AVX2) { + if ((FeaturesEx & C7_AVX512) == C7_AVX512 && (XFeatures & XCR_AVX512F) == XCR_AVX512F) { + goto ISA_AVAILABLE_AVX512; + } + goto ISA_AVAILABLE_AVX2; + } + goto ISA_AVAILABLE_AVX; + } + // goto ISA_AVAILABLE_SSE42; + } + goto ISA_AVAILABLE_SSE42; + } + goto ISA_AVAILABLE_SSE2; + +ISA_AVAILABLE_X86: + __isa_available = __ISA_AVAILABLE_X86; + __isa_enabled = __ISA_ENABLED_X86; + return 0; + +ISA_AVAILABLE_SSE2: + __isa_available = __ISA_AVAILABLE_SSE2; + __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2; + return 0; + +ISA_AVAILABLE_SSE42: + __isa_available = __ISA_AVAILABLE_SSE42; + __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42; + return 0; + +ISA_AVAILABLE_AVX: + __isa_available = __ISA_AVAILABLE_AVX; + __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42 | __ISA_ENABLED_AVX; + return 0; + +ISA_AVAILABLE_AVX2: + __isa_available = __ISA_AVAILABLE_AVX2; + __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42 | __ISA_ENABLED_AVX | __ISA_ENABLED_AVX2; + return 0; + +ISA_AVAILABLE_AVX512: + __isa_available = __ISA_AVAILABLE_AVX512; + __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42 | __ISA_ENABLED_AVX | __ISA_ENABLED_AVX2 | __ISA_ENABLED_AVX512; + return 0; + +#undef C1_AVX +#undef C7_AVX512 +#undef XCR_AVX +#undef XCR_AVX512F +} + +#endif +#endif diff --git a/src/crt/vcruntime/jbcxrval.c b/src/crt/vcruntime/jbcxrval.c new file mode 100644 index 0000000..3164fe7 --- /dev/null +++ b/src/crt/vcruntime/jbcxrval.c @@ -0,0 +1,286 @@ +/*++ + +Copyright (c) Microsoft Corporation + +Module Name: + + jbcxrval.c + +Abstract: + + This module implements C support code for jump buffer and context record + validation. + +Environment: + + Kernel mode only. + +--*/ + +#include +#include +#include + +#if defined(_AMD64_) +#include "../misc/cfg_support.inc" // To inline _guard_icall_checks_enforced() +#endif + +#if defined(_AMD64_) +#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Rsp) +#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame) + +#elif defined(_ARM_) +#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Sp) +#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame) + +#elif defined(_ARM64_) +#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Sp) +#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame) + +#elif defined(_X86_) +#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Esp) +#else +#error Unsupported architecture. +#endif + +#define CONTEXT_TO_STACK_POINTER(Context) JUMP_BUFFER_TO_STACK_POINTER(Context) + +#if !defined(NTOS_KERNEL_RUNTIME) +void +__cdecl +__except_validate_context_record( + _In_ PCONTEXT ContextRecord +) + +/*++ + +Routine Description: + + This function validates a context record for exception handling support. + +Arguments: + + ContextRecord - Supplies a pointer to the context record to validate. + +Return Value: + + None. If the context record was not valid, a fast fail event is raised if + CFG was enforced. + +--*/ + +{ + PVOID StackPointer; + PNT_TIB Tib; + + // + // If guard ICall checks are enforced, then validate the stack extents of + // the context record and raise a fast fail exception if the extents are + // invalid. If checks are not enforced or the jump buffer was valid, then + // return. + // + if (_guard_icall_checks_enforced()) { + Tib = (PNT_TIB)NtCurrentTeb(); + + // + // HYB-TODO: Validate both chpe and guest context. + // + + StackPointer = (PVOID)CONTEXT_TO_STACK_POINTER(ContextRecord); + if ((StackPointer < Tib->StackLimit) || + (StackPointer > Tib->StackBase)) { + + __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); + } + } +} + +__forceinline +void +__except_validate_jump_buffer_common( + _In_reads_(_JBLEN) jmp_buf JumpBuffer, + _In_ PVOID(*ExceptGetJbSpRoutine)(jmp_buf) +) + +/*++ + +Routine Description: + + This function validates a jump buffer for exception handling support. + +Arguments: + + JumpBuffer - Supplies a pointer to the jump buffer to validate. + +Return Value: + + None. If the jump buffer was not valid, a fast fail event is raised if + CFG was enforced. + +--*/ + +{ + + PVOID StackPointer; + PNT_TIB Tib; + + // + // If guard ICall checks are enforced, then validate the stack extents of + // the jump buffer and raise a fast fail exception if the extents are + // invalid. If checks are not enforced or the jump buffer was valid, then + // return. + // + + if (_guard_icall_checks_enforced()) { + Tib = (PNT_TIB)NtCurrentTeb(); + StackPointer = ExceptGetJbSpRoutine(JumpBuffer); + + if ((StackPointer < Tib->StackLimit) || + (StackPointer > Tib->StackBase)) { + + __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); + } + + #if defined(JB_FRAME) + if (JB_FRAME(JumpBuffer) == 0) { + + __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); + } + #endif + } +} + +__forceinline +static PVOID __except_get_jumpbuf_sp(_In_reads_(_JBLEN) jmp_buf JumpBuffer) +{ + return (PVOID)JUMP_BUFFER_TO_STACK_POINTER((_JUMP_BUFFER*)JumpBuffer); +} + +void +__cdecl +__except_validate_jump_buffer( + _In_reads_(_JBLEN) jmp_buf JumpBuffer +) +{ + __except_validate_jump_buffer_common(JumpBuffer, __except_get_jumpbuf_sp); +} + +#else // defined(NTOS_KERNEL_RUNTIME) + +void +__cdecl +__except_validate_context_record( + _In_ PCONTEXT ContextRecord +) + +/*++ + +Routine Description: + + This function validates a context record for exception handling support. + +Arguments: + + ContextRecord - Supplies a pointer to the context record to validate. + +Return Value: + + None. If the context record was not valid, a fast fail event is raised if + CFG was enforced. + +--*/ + +{ + PVOID StackPointer; + PVOID StackBase = NULL; + PVOID StackLimit = NULL; + + // + // If guard ICall checks are enforced, then validate the stack extents of + // the context record and raise a fast fail exception if the extents are + // invalid. If checks are not enforced or the jump buffer was valid, then + // return. + // + if (_guard_icall_checks_enforced()) { + IoGetStackLimits((PULONG_PTR)&StackBase, (PULONG_PTR)&StackLimit); + + StackPointer = (PVOID)CONTEXT_TO_STACK_POINTER(ContextRecord); + if ((StackPointer < StackLimit) || + (StackPointer > StackBase)) { + + __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); + } + } +} + +__forceinline +void +__except_validate_jump_buffer_common( + _In_reads_(_JBLEN) jmp_buf JumpBuffer, + _In_ PVOID(*ExceptGetJbSpRoutine)(jmp_buf) +) + +/*++ + +Routine Description: + + This function validates a jump buffer for exception handling support. + +Arguments: + + JumpBuffer - Supplies a pointer to the jump buffer to validate. + +Return Value: + + None. If the jump buffer was not valid, a fast fail event is raised if + CFG was enforced. + +--*/ + +{ + + PVOID StackPointer; + PVOID StackBase = NULL; + PVOID StackLimit = NULL; + + // + // If guard ICall checks are enforced, then validate the stack extents of + // the jump buffer and raise a fast fail exception if the extents are + // invalid. If checks are not enforced or the jump buffer was valid, then + // return. + // + + if (_guard_icall_checks_enforced()) { + IoGetStackLimits((PULONG_PTR)&StackBase, (PULONG_PTR)&StackLimit); + + StackPointer = ExceptGetJbSpRoutine(JumpBuffer); + if ((StackPointer < StackLimit) || + (StackPointer > StackBase)) { + + __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); + } + + #if defined(JB_FRAME) + if (JB_FRAME(JumpBuffer) == 0) { + + __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); + } + #endif + } +} + +__forceinline +static PVOID __except_get_jumpbuf_sp(_In_reads_(_JBLEN) jmp_buf JumpBuffer) +{ + return (PVOID)JUMP_BUFFER_TO_STACK_POINTER((_JUMP_BUFFER*)JumpBuffer); +} + +void +__cdecl +__except_validate_jump_buffer( + _In_reads_(_JBLEN) jmp_buf JumpBuffer +) +{ + __except_validate_jump_buffer_common(JumpBuffer, __except_get_jumpbuf_sp); +} +#endif // !defined(NTOS_KERNEL_RUNTIME) \ No newline at end of file diff --git a/src/crt/vcruntime/jbcxrval.cpp b/src/crt/vcruntime/jbcxrval.cpp deleted file mode 100644 index 3d0b113..0000000 --- a/src/crt/vcruntime/jbcxrval.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation - -Module Name: - - jbcxrval.c - -Abstract: - - This module implements C support code for jump buffer and context record - validation. - -Environment: - - Kernel mode only. - ---*/ - -#include -#include - -_CRT_BEGIN_C_HEADER - -int _guard_icall_checks_enforced(); - -//#if defined(_AMD64_) - -#if defined(_AMD64_) -#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Rsp) -#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame) - -#elif defined(_ARM_) -#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Sp) -#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame) - -#elif defined(_ARM64_) -#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Sp) -#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame) - -#elif defined(_X86_) -#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Esp) -#else -#error Unsupported architecture. -#endif - -#define CONTEXT_TO_STACK_POINTER(Context) JUMP_BUFFER_TO_STACK_POINTER(Context) - -void -__except_validate_context_record ( - _In_ PCONTEXT ContextRecord - ) - -/*++ - -Routine Description: - - This function validates a context record for exception handling support. - -Arguments: - - ContextRecord - Supplies a pointer to the context record to validate. - -Return Value: - - None. If the context record was not valid, a fast fail event is raised if - CFG was enforced. - ---*/ - -{ - PVOID StackPointer = nullptr; - PVOID StackLowLimit = nullptr; - PVOID StackHighLimit = nullptr; - - // - // If guard ICall checks are enforced, then validate the stack extents of - // the context record and raise a fast fail exception if the extents are - // invalid. If checks are not enforced or the jump buffer was valid, then - // return. - // - if (_guard_icall_checks_enforced()) { - - IoGetStackLimits((PULONG_PTR)&StackLowLimit, (PULONG_PTR)&StackHighLimit); - - StackPointer = (PVOID)CONTEXT_TO_STACK_POINTER(ContextRecord); - - if ((StackPointer < StackLowLimit) || - (StackPointer > StackHighLimit)) { - - __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); - } - } -} - -__forceinline -void -__except_validate_jump_buffer_common ( - _In_reads_(_JBLEN) jmp_buf JumpBuffer, - _In_ PVOID (*ExceptGetJbSpRoutine)(jmp_buf) - ) - -/*++ - -Routine Description: - - This function validates a jump buffer for exception handling support. - -Arguments: - - JumpBuffer - Supplies a pointer to the jump buffer to validate. - -Return Value: - - None. If the jump buffer was not valid, a fast fail event is raised if - CFG was enforced. - ---*/ - -{ - - PVOID StackPointer = nullptr; - PVOID StackLowLimit = nullptr; - PVOID StackHighLimit = nullptr; - - // - // If guard ICall checks are enforced, then validate the stack extents of - // the jump buffer and raise a fast fail exception if the extents are - // invalid. If checks are not enforced or the jump buffer was valid, then - // return. - // - - if (_guard_icall_checks_enforced()) { - - IoGetStackLimits((PULONG_PTR)&StackLowLimit, (PULONG_PTR)&StackHighLimit); - - StackPointer = ExceptGetJbSpRoutine(JumpBuffer); - - if ((StackPointer < StackLowLimit) || - (StackPointer > StackHighLimit)) { - - __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); - } - -#if defined(JB_FRAME) - if (JB_FRAME(JumpBuffer) == 0) { - - __fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT); - } -#endif - } -} - -__forceinline -static PVOID __except_get_jumpbuf_sp(_In_reads_(_JBLEN) jmp_buf JumpBuffer) -{ - return (PVOID)JUMP_BUFFER_TO_STACK_POINTER((_JUMP_BUFFER*)JumpBuffer); -} - -void -__except_validate_jump_buffer ( - _In_reads_(_JBLEN) jmp_buf JumpBuffer - ) -{ - __except_validate_jump_buffer_common(JumpBuffer, __except_get_jumpbuf_sp); -} - -//#endif - -_CRT_END_C_HEADER - diff --git a/src/crt/vcruntime/vcruntime_internal.h b/src/crt/vcruntime/vcruntime_internal.h index feb08f5..7ef831e 100644 --- a/src/crt/vcruntime/vcruntime_internal.h +++ b/src/crt/vcruntime/vcruntime_internal.h @@ -25,6 +25,7 @@ #include #include #include +#include @@ -86,28 +87,6 @@ extern int __isa_available; -//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// Guard -// -//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -#if !defined _M_CEE - typedef void (__fastcall *GUARDCF_CHECK_ROUTINE)(uintptr_t); - extern void* __guard_check_icall_fptr; - - #define _GUARD_CHECK_ICALL(FPTR) \ - (((GUARDCF_CHECK_ROUTINE)(__guard_check_icall_fptr))((uintptr_t)(FPTR))) -#else - #define _GUARD_CHECK_ICALL(FPTR) -#endif - -// This is defined in the Windows 10 SDK but not in the Windows 8.1 SDK. -#if !defined DECLSPEC_GUARD_SUPPRESS - #define DECLSPEC_GUARD_SUPPRESS __declspec(guard(suppress)) -#endif - - - //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // Multi-threading diff --git a/src/ucrt/misc/message.cpp b/src/ucrt/misc/message.cpp index f584e88..907af05 100644 --- a/src/ucrt/misc/message.cpp +++ b/src/ucrt/misc/message.cpp @@ -10,6 +10,13 @@ * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com) */ +namespace ucxxrt +{ + extern PVOID PsSystemDllBase; +} + +using namespace ucxxrt; + EXTERN_C NTSTATUS NTAPI RtlFindAndFormatMessage( _In_ UINT32 Flags, _In_opt_ LPCVOID Source, @@ -55,7 +62,7 @@ EXTERN_C NTSTATUS NTAPI RtlFindAndFormatMessage( __try { - PVOID BaseDllHandle = ucxxrt::PsSystemDllBase; + PVOID BaseDllHandle = PsSystemDllBase; MaximumWidth = Flags & FORMAT_MESSAGE_MAX_WIDTH_MASK; if (MaximumWidth == FORMAT_MESSAGE_MAX_WIDTH_MASK) diff --git a/src/ucrt/startup/cpu_disp.cpp b/src/ucrt/startup/cpu_disp.cpp deleted file mode 100644 index 2c023af..0000000 --- a/src/ucrt/startup/cpu_disp.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * PROJECT: Universal C++ RunTime (UCXXRT) - * FILE: cpu_disp.cpp - * DATE: 2021/04/25 - * - * PURPOSE: Universal C++ RunTime - * - * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License - * - * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com) - */ - -/* - * Reference: https://github.com/SpoilerScriptsGroup/RetrievAL/blob/master/SpoilerAL-winmm.dll/crt/msvc/isa_available_init.c - */ - -#if defined(_M_IX86) || defined(_M_X64) - -#include -#include -#include - - -// BitScanForward -// -// for constant value -#define _BSF8(x, default) ( \ - ((x) & 0x01) ? 0 : \ - ((x) & 0x02) ? 1 : \ - ((x) & 0x04) ? 2 : \ - ((x) & 0x08) ? 3 : \ - ((x) & 0x10) ? 4 : \ - ((x) & 0x20) ? 5 : \ - ((x) & 0x40) ? 6 : \ - ((x) & 0x80) ? 7 : \ - (default)) -#define _BSF16(x, default) _BSF8(x, _BSF8((x) >> 8, (default) - 8) + 8) -#define _BSF32(x, default) _BSF16(x, _BSF16((x) >> 16, (default) - 16) + 16) -#define _BSF64(x, default) _BSF32(x, _BSF32((x) >> 32, (default) - 32) + 32) -#define BSF8(x) _BSF8(x, -1) -#define BSF16(x) _BSF16(x, -1) -#define BSF32(x) _BSF32(x, -1) -#define BSF64(x) _BSF64(x, -1) - -// for constant value -#define MASM_BSF32(x) ( -1 + \ - ( (x) and 1 ) + \ - ((((x) shr 1) and 1) and (((x) and 0x00000001) eq 0)) * 2 + \ - ((((x) shr 2) and 1) and (((x) and 0x00000003) eq 0)) * 3 + \ - ((((x) shr 3) and 1) and (((x) and 0x00000007) eq 0)) * 4 + \ - ((((x) shr 4) and 1) and (((x) and 0x0000000F) eq 0)) * 5 + \ - ((((x) shr 5) and 1) and (((x) and 0x0000001F) eq 0)) * 6 + \ - ((((x) shr 6) and 1) and (((x) and 0x0000003F) eq 0)) * 7 + \ - ((((x) shr 7) and 1) and (((x) and 0x0000007F) eq 0)) * 8 + \ - ((((x) shr 8) and 1) and (((x) and 0x000000FF) eq 0)) * 9 + \ - ((((x) shr 9) and 1) and (((x) and 0x000001FF) eq 0)) * 10 + \ - ((((x) shr 10) and 1) and (((x) and 0x000003FF) eq 0)) * 11 + \ - ((((x) shr 11) and 1) and (((x) and 0x000007FF) eq 0)) * 12 + \ - ((((x) shr 12) and 1) and (((x) and 0x00000FFF) eq 0)) * 13 + \ - ((((x) shr 13) and 1) and (((x) and 0x00001FFF) eq 0)) * 14 + \ - ((((x) shr 14) and 1) and (((x) and 0x00003FFF) eq 0)) * 15 + \ - ((((x) shr 15) and 1) and (((x) and 0x00007FFF) eq 0)) * 16 + \ - ((((x) shr 16) and 1) and (((x) and 0x0000FFFF) eq 0)) * 17 + \ - ((((x) shr 17) and 1) and (((x) and 0x0001FFFF) eq 0)) * 18 + \ - ((((x) shr 18) and 1) and (((x) and 0x0003FFFF) eq 0)) * 19 + \ - ((((x) shr 19) and 1) and (((x) and 0x0007FFFF) eq 0)) * 20 + \ - ((((x) shr 20) and 1) and (((x) and 0x000FFFFF) eq 0)) * 21 + \ - ((((x) shr 21) and 1) and (((x) and 0x001FFFFF) eq 0)) * 22 + \ - ((((x) shr 22) and 1) and (((x) and 0x003FFFFF) eq 0)) * 23 + \ - ((((x) shr 23) and 1) and (((x) and 0x007FFFFF) eq 0)) * 24 + \ - ((((x) shr 24) and 1) and (((x) and 0x00FFFFFF) eq 0)) * 25 + \ - ((((x) shr 25) and 1) and (((x) and 0x01FFFFFF) eq 0)) * 26 + \ - ((((x) shr 26) and 1) and (((x) and 0x03FFFFFF) eq 0)) * 27 + \ - ((((x) shr 27) and 1) and (((x) and 0x07FFFFFF) eq 0)) * 28 + \ - ((((x) shr 28) and 1) and (((x) and 0x0FFFFFFF) eq 0)) * 29 + \ - ((((x) shr 29) and 1) and (((x) and 0x1FFFFFFF) eq 0)) * 30 + \ - ((((x) shr 30) and 1) and (((x) and 0x3FFFFFFF) eq 0)) * 31 + \ - ((((x) shr 31) and 1) and (((x) and 0x7FFFFFFF) eq 0)) * 32) - -// for constant value -#define MASM_BSWAP16(value) ( \ - (((value) shr 8) and 0x00FF) or \ - (((value) shl 8) and 0xFF00)) - -// for constant value -#define MASM_BSWAP24(value) ( \ - (((value) shr 16) and 0x000000FF) or \ - ( (value) and 0x0000FF00) or \ - (((value) shl 16) and 0x00FF0000)) - -// for constant value -#define MASM_BSWAP32(value) ( \ - (((value) shr 24) and 0x000000FF) or \ - (((value) shr 8) and 0x0000FF00) or \ - (((value) shl 8) and 0x00FF0000) or \ - (((value) shl 24) and 0xFF000000)) - - -_CRT_BEGIN_C_HEADER - -#define __ISA_ENABLED_X86 0x00000001 -#define __ISA_ENABLED_SSE2 0x00000002 -#define __ISA_ENABLED_SSE42 0x00000004 -#define __ISA_ENABLED_AVX 0x00000008 -#define __ISA_ENABLED_AVX2 0x00000020 -#define __ISA_ENABLED_AVX512 0x00000040 - -#define __FAVOR_ATOM 0 -#define __FAVOR_ENFSTRG 1 -#define __FAVOR_XMMLOOP 2 - -/* Features in ecx for leaf 1 */ -#define CF_SSE42 0x00100000 -#define CF_OSXSAVE 0x08000000 -#define CF_AVX 0x10000000 - -/* Features in ebx for leaf 7 sub-leaf 0 */ -#define CX_AVX2 0x00000020 -#define CX_ERMS 0x00000200 -#define CX_AVX512F 0x00010000 -#define CX_AVX512DQ 0x00020000 -#define CX_AVX512CD 0x10000000 -#define CX_AVX512BW 0x40000000 -#define CX_AVX512VL 0x80000000 - -/* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ -#define XCR_XFEATURE_ENABLED_MASK 0x00000000 -#define XSTATE_FP 0x00000001 -#define XSTATE_SSE 0x00000002 -#define XSTATE_YMM 0x00000004 -#define XSTATE_OPMASK 0x00000020 -#define XSTATE_ZMM 0x00000040 -#define XSTATE_HI_ZMM 0x00000080 - -unsigned int __isa_available = __ISA_AVAILABLE_X86; -unsigned int __isa_enabled = __ISA_ENABLED_X86; -unsigned int __favor = 0; - -BOOLEAN __stdcall __IsProcessorFeaturePresent(_In_ ULONG ProcessorFeature) -{ - return (BOOLEAN)ExIsProcessorFeaturePresent(ProcessorFeature); -} - -#if defined(_AMD64_) -#pragma intrinsic(__cpuid) -#pragma intrinsic(__cpuidex) - -void __cdecl __isa_available_init() -{ - #define C1_AVX (CF_OSXSAVE | CF_AVX) - #define C7_AVX512 (CX_AVX512F | CX_AVX512DQ | CX_AVX512CD | CX_AVX512BW | CX_AVX512VL) - #define XCR_AVX (XSTATE_SSE | XSTATE_YMM) - #define XCR_AVX512F (XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) - - struct { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - } cpuInfo; - uint32_t cpuid_0_eax; - uint32_t cpuid_1_ecx; - uint32_t cpuid_7_ebx; - uint32_t xgetbv_eax; - uint32_t intel_outside; - - __favor = 0; - if (!__IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) - goto ISA_AVAILABLE_X86; - __cpuid((int *)&cpuInfo, 0); - cpuid_0_eax = cpuInfo.eax; - intel_outside = - (cpuInfo.ebx ^ _ByteSwap32('Genu')) | - (cpuInfo.edx ^ _ByteSwap32('ineI')) | - (cpuInfo.ecx ^ _ByteSwap32('ntel')); - __cpuid((int *)&cpuInfo, 1); - cpuid_1_ecx = cpuInfo.ecx; - if (!intel_outside) - switch (cpuInfo.eax & 0x0FFF3FF0) { - case 0x000106C0: - case 0x00020660: - case 0x00020670: - case 0x00030650: - case 0x00030660: - case 0x00030670: - __favor = 1 << __FAVOR_ATOM; - } - cpuid_7_ebx = 0; - if (cpuid_0_eax >= 7) { - __cpuidex((int *)&cpuInfo, 7, 0); - __favor |= ((cpuid_7_ebx = cpuInfo.ebx) & CX_ERMS) >> (BSF32(CX_ERMS) - __FAVOR_ENFSTRG); - } - if (cpuid_1_ecx & CF_SSE42) - if ((cpuid_1_ecx & C1_AVX) == C1_AVX && ((xgetbv_eax = (uint32_t)_xgetbv(0)) & XCR_AVX) == XCR_AVX) - if (cpuid_7_ebx & CX_AVX2) - if ((cpuid_7_ebx & C7_AVX512) == C7_AVX512 && (xgetbv_eax & XCR_AVX512F) == XCR_AVX512F) - goto ISA_AVAILABLE_AVX512; - else - goto ISA_AVAILABLE_AVX2; - else - goto ISA_AVAILABLE_AVX; - else - goto ISA_AVAILABLE_SSE42; - else - goto ISA_AVAILABLE_SSE2; - -ISA_AVAILABLE_X86: - __isa_available = __ISA_AVAILABLE_X86; - __isa_enabled = __ISA_ENABLED_X86; - return; - -ISA_AVAILABLE_SSE2: - __isa_available = __ISA_AVAILABLE_SSE2; - __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2; - return; - -ISA_AVAILABLE_SSE42: - __isa_available = __ISA_AVAILABLE_SSE42; - __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42; - return; - -ISA_AVAILABLE_AVX: - __isa_available = __ISA_AVAILABLE_AVX; - __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42 | __ISA_ENABLED_AVX; - return; - -ISA_AVAILABLE_AVX2: - __isa_available = __ISA_AVAILABLE_AVX2; - __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42 | __ISA_ENABLED_AVX | __ISA_ENABLED_AVX2; - return; - -ISA_AVAILABLE_AVX512: - __isa_available = __ISA_AVAILABLE_AVX512; - __isa_enabled = __ISA_ENABLED_X86 | __ISA_ENABLED_SSE2 | __ISA_ENABLED_SSE42 | __ISA_ENABLED_AVX | __ISA_ENABLED_AVX2 | __ISA_ENABLED_AVX512; - return; - - #undef C1_AVX - #undef C7_AVX512 - #undef XCR_AVX - #undef XCR_AVX512F -} -#elif defined(_X86_) -__declspec(naked) void __cdecl __isa_available_init() -{ - __asm - { - #define C1_AVX (CF_OSXSAVE or CF_AVX) - #define C7_AVX512 (CX_AVX512F or CX_AVX512DQ or CX_AVX512CD or CX_AVX512BW or CX_AVX512VL) - #define XCR_AVX (XSTATE_SSE or XSTATE_YMM) - #define XCR_AVX512F (XSTATE_OPMASK or XSTATE_ZMM or XSTATE_HI_ZMM) - - #define cpuid_0_eax eax - #define cpuid_1_ecx ecx - #define cpuid_7_ebx ebx - - mov dword ptr [__favor], 0 - push PF_XMMI64_INSTRUCTIONS_AVAILABLE - call __IsProcessorFeaturePresent - test eax, eax - jz ISA_AVAILABLE_X86 - push ebx - xor eax, eax - cpuid - xor ebx, MASM_BSWAP32('Genu') - xor edx, MASM_BSWAP32('ineI') - xor ecx, MASM_BSWAP32('ntel') - or ebx, edx - push cpuid_0_eax - or ebx, ecx - mov eax, 1 - push ebx - cpuid - pop ebx - mov edx, eax - and eax, 0FFF3FF0H and (not (000106C0H or 00020660H or 00020670H or 00030650H or 00030660H or 00030670H)) - and edx, 000106C0H or 00020660H or 00020670H or 00030650H or 00030660H or 00030670H - or eax, ebx - jnz L2 - mov eax, edx - and edx, 000106C0H and 00020660H and 00020670H and 00030650H and 00030660H and 00030670H - cmp edx, 000106C0H and 00020660H and 00020670H and 00030650H and 00030660H and 00030670H - jne L2 - sub eax, 000106C0H - jz L1 - sub eax, 00020660H - 000106C0H - jz L1 - sub eax, 00020670H - 00020660H - jz L1 - sub eax, 00030650H - 00020670H - jz L1 - sub eax, 00030660H - 00030650H - jz L1 - cmp eax, 00030670H - 00030660H - jne L2 - L1: - mov dword ptr [__favor], 1 shl __FAVOR_ATOM - L2: - pop cpuid_0_eax - xor cpuid_7_ebx, cpuid_7_ebx - cmp cpuid_0_eax, 7 - jb L3 - push cpuid_1_ecx - mov eax, 7 - xor ecx, ecx - cpuid - mov ecx, cpuid_7_ebx - and ebx, CX_ERMS - shr ebx, MASM_BSF32(CX_ERMS) - __FAVOR_ENFSTRG - mov eax, dword ptr [__favor] - or eax, ebx - mov cpuid_7_ebx, ecx - mov dword ptr [__favor], eax - pop cpuid_1_ecx - L3: - mov eax, cpuid_1_ecx - and ecx, C1_AVX - test eax, CF_SSE42 - jz ISA_AVAILABLE_SSE2 - xor ecx, C1_AVX - jnz ISA_AVAILABLE_SSE42 - xgetbv - mov ecx, eax - and eax, XCR_AVX - cmp eax, XCR_AVX - jne ISA_AVAILABLE_SSE42 - test cpuid_7_ebx, CX_AVX2 - jz ISA_AVAILABLE_AVX - and ebx, C7_AVX512 - and ecx, XCR_AVX512F - cmp ebx, C7_AVX512 - jne ISA_AVAILABLE_AVX2 - cmp ecx, XCR_AVX512F - jne ISA_AVAILABLE_AVX2 - pop ebx - jmp ISA_AVAILABLE_AVX512 - - align 16 - ISA_AVAILABLE_X86: - mov dword ptr [__isa_available], __ISA_AVAILABLE_X86 - mov dword ptr [__isa_enabled], __ISA_ENABLED_X86 - ret - - align 16 - ISA_AVAILABLE_SSE2: - mov dword ptr [__isa_available], __ISA_AVAILABLE_SSE2 - mov dword ptr [__isa_enabled], __ISA_ENABLED_X86 or __ISA_ENABLED_SSE2 - pop ebx - ret - - align 16 - ISA_AVAILABLE_SSE42: - mov dword ptr [__isa_available], __ISA_AVAILABLE_SSE42 - mov dword ptr [__isa_enabled], __ISA_ENABLED_X86 or __ISA_ENABLED_SSE2 or __ISA_ENABLED_SSE42 - pop ebx - ret - - align 16 - ISA_AVAILABLE_AVX: - mov dword ptr [__isa_available], __ISA_AVAILABLE_AVX - mov dword ptr [__isa_enabled], __ISA_ENABLED_X86 or __ISA_ENABLED_SSE2 or __ISA_ENABLED_SSE42 or __ISA_ENABLED_AVX - pop ebx - ret - - align 16 - ISA_AVAILABLE_AVX2: - mov dword ptr [__isa_available], __ISA_AVAILABLE_AVX2 - mov dword ptr [__isa_enabled], __ISA_ENABLED_X86 or __ISA_ENABLED_SSE2 or __ISA_ENABLED_SSE42 or __ISA_ENABLED_AVX or __ISA_ENABLED_AVX2 - pop ebx - ret - - align 16 - ISA_AVAILABLE_AVX512: - mov dword ptr [__isa_available], __ISA_AVAILABLE_AVX512 - mov dword ptr [__isa_enabled], __ISA_ENABLED_X86 or __ISA_ENABLED_SSE2 or __ISA_ENABLED_SSE42 or __ISA_ENABLED_AVX or __ISA_ENABLED_AVX2 or __ISA_ENABLED_AVX512 - ret - - #undef C1_AVX - #undef C7_AVX512 - #undef XCR_AVX - #undef XCR_AVX512F - #undef cpuid_0_eax - #undef cpuid_1_ecx - #undef cpuid_7_ebx - } -} -#endif - -_CRT_END_C_HEADER - -#endif diff --git a/src/ucxxrt.cpp b/src/ucxxrt.cpp index 0ad33e9..606ecce 100644 --- a/src/ucxxrt.cpp +++ b/src/ucxxrt.cpp @@ -18,4 +18,4 @@ // Global -extern"C" ULONG __ucxxrt_tag = static_cast(_ByteSwap32('ucrt')); +extern"C" ULONG __ucxxrt_tag = 'trcu'; diff --git a/src/ucxxrt.h b/src/ucxxrt.h index 1a6b461..7c6c88c 100644 --- a/src/ucxxrt.h +++ b/src/ucxxrt.h @@ -1,89 +1 @@ -/* - * PROJECT: Universal C++ RunTime (UCXXRT) - * FILE: ucxxrt.h - * DATE: 2021/05/03 - * - * PURPOSE: Universal C++ RunTime - * - * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License - * - * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com) - */ - -#pragma once - - // Warnings which disabled for compiling -#if _MSC_VER >= 1200 -#pragma warning(push) -// nonstandard extension used : nameless struct/union -#pragma warning(disable:4201) -// 'struct_name' : structure was padded due to __declspec(align()) -#pragma warning(disable:4324) -// 'enumeration': a forward declaration of an unscoped enumeration must have an -// underlying type (int assumed) -#pragma warning(disable:4471) -#endif - - -#ifdef __KERNEL_MODE -# ifndef _KERNEL_MODE -# define _KERNEL_MODE __KERNEL_MODE -# endif -#else -# error user mode is not supported. -#endif - -#ifndef _CRTIMP -# define _CRTIMP -#endif - -#ifndef _VCRTIMP -#define _VCRTIMP _CRTIMP -#endif - - -#include -#include - - -namespace ucxxrt -{ -#ifdef _KERNEL_MODE - extern PVOID PsSystemDllBase; -#endif -} - - -#ifndef _ByteSwap16 -#define _ByteSwap16(x) ( \ - ((uint16_t(x) & uint16_t(0xFF << 8)) >> 8) | \ - ((uint16_t(x) & uint16_t(0xFF >> 0)) << 8) \ -) -#endif - -#ifndef _ByteSwap32 -#define _ByteSwap32(x) ( \ - ((uint32_t(x) & uint32_t(0xFF << 24)) >> 24) | \ - ((uint32_t(x) & uint32_t(0xFF << 16)) >> 8) | \ - ((uint32_t(x) & uint32_t(0xFF << 8)) << 8) | \ - ((uint32_t(x) & uint32_t(0xFF << 0)) << 24) \ -) -#endif - -#ifndef _ByteSwap64 -#define _ByteSwap64(x) ( \ - ((uint64_t(x) & uint64_t(0xFF << 56)) >> 56) | \ - ((uint64_t(x) & uint64_t(0xFF << 48)) >> 40) | \ - ((uint64_t(x) & uint64_t(0xFF << 40)) >> 24) | \ - ((uint64_t(x) & uint64_t(0xFF << 32)) >> 8) | \ - ((uint64_t(x) & uint64_t(0xFF << 24)) << 8) | \ - ((uint64_t(x) & uint64_t(0xFF << 16)) << 24) | \ - ((uint64_t(x) & uint64_t(0xFF << 8)) << 40) | \ - ((uint64_t(x) & uint64_t(0xFF << 0)) << 56) | \ -) -#endif - - -#if _MSC_VER >= 1200 -#pragma warning(pop) -#endif +#pragma once \ No newline at end of file diff --git a/src/ucxxrt.inl b/src/ucxxrt.inl index 6925c83..6578962 100644 --- a/src/ucxxrt.inl +++ b/src/ucxxrt.inl @@ -97,7 +97,6 @@ #include #include #include -#include "ucxxrt.h" #if _MSC_VER >= 1200 #pragma warning(pop) diff --git a/test/unittest.cpp b/test/unittest.cpp index 93a9f98..2069fcf 100644 --- a/test/unittest.cpp +++ b/test/unittest.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include