Microsoft-MPI
Microsoft-MPI copied to clipboard
10.0 not usable in MSYS/mingw64 with gfortran
$ gfortran -o example1 example.F90 -fno-range-check -lmsmpifec -lmsmpi -L"$MSMPI_LIB64" -I$MINGW_PREFIX/include
Warning: corrupt .drectve at end of def file
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\/msmpifec.lib(E:/bt/973263/repo/src/mpi/msmpi/fortran/msmpifec/obj/amd64/mpifbind.obj):(.text$mn+0x35): undefined reference to `__guard_check_icall_fptr'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\/msmpifec.lib(E:/bt/973263/repo/src/mpi/msmpi/fortran/msmpifec/obj/amd64/mpifbind.obj):(.text$mn+0x36): undefined reference to `__guard_check_icall_fptr'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\/msmpifec.lib(E:/bt/973263/repo/src/mpi/msmpi/fortran/msmpifec/obj/amd64/mpifbind.obj):(.text$mn+0x21): undefined reference to `__guard_check_icall_fptr'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\/msmpifec.lib(E:/bt/973263/repo/src/mpi/msmpi/fortran/msmpifec/obj/amd64/mpifbind.obj):(.text$mn+0x21): undefined reference to `__guard_check_icall_fptr'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\/msmpifec.lib(E:/bt/973263/repo/src/mpi/msmpi/fortran/msmpifec/obj/amd64/mpifbind.obj):(.text$mn+0x17): undefined reference to `__guard_check_icall_fptr'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\/msmpifec.lib(E:/bt/973263/repo/src/mpi/msmpi/fortran/msmpifec/obj/amd64/mpifbind.obj):(.text$mn+0x17): more undefined references to `__guard_check_icall_fptr' follow
collect2.exe: error: ld returned 1 exit status
It looks like this is caused by control flow guard being enabled since 10.0.
To reproduce, inside an MSYS MinGW 64-bit shell:
mkdir /tmp/msmpi && cd /tmp/msmpi
cp "$MSMPI_INC/mpi.h" $MINGW_PREFIX/include
cp "$MSMPI_INC/mpif.h" $MINGW_PREFIX/include
cp "$MSMPI_INC/x64/mpifptr.h" $MINGW_PREFIX/include
gfortran -c -fno-range-check -I$MINGW_PREFIX/include "$MSMPI_INC/mpi.f90"
cp mpi.mod $MINGW_PREFIX/include
mkdir /tmp/mpi_test && cd /tmp/mpi_test
wget https://raw.githubusercontent.com/coderefinery/autocmake/c5057f8aee65/test/fc_mpi/src/example.F90
gfortran -o example1 example.F90 -fno-range-check -lmsmpifec -lmsmpi -L"$MSMPI_LIB64" -I$MINGW_PREFIX/include
@letmaik - Yep, this is coming from the control flow guard. We added this as part of a security requirement from one of the partner s/w. Unfortunately we cannot disable it in official releases.
Is there a similar option for gfortran? I couldn't find one with a quick search, but you might know better on that. Other option will be to build MSMPI from this repo and use it.
Just to clarify, if control flow guard (CFG) was enabled during compilation of a static library (here MSMPI), does that mean that dependent libraries or executables have to be compiled with CFG as well? Is that why you are asking whether gfortran has a similar option? I'm also slightly surprised that I could use gcc without issues, which either means that gcc supports CFG and has it enabled by default, or that no CFG checks were inserted into the C msmpi static library, but rather only into the Fortran ones.
I just checked with dumpbin, indeed msmpi.lib does not have the __guard_check_icall_fptr symbol. Is this expected?
Regarding CFG in gcc/gfortran, there's no support for it as far as I see, but maybe it is enough to just link to additional system libraries (which?) from Windows to provide the unresolved symbol? That would mean the msmpi part is CFG-protected and the rest of the app is not, which would be fine in my case.
Yeah, I also couldn't see the symbol using dumpbin. The symbol is not there in the final exe as well, but CFG shows up in the headers.
C160 DLL characteristics
High Entropy Virtual Addresses
Dynamic base
NX compatible
Control Flow Guard
Let me check with the compiler team to see what their recommendation is for gfortran.
@jithinjosepkl You wanted to check with the compiler team. What was the result of that? In the meantime, I found the following work-around which simply stubs out the unavailable CFG check function:
cfg_stub.c:
void __guard_check_icall_fptr(unsigned long ptr) { }
Modified compile commands (see first post):
gcc -c cfg_stub.c
gfortran -o example1 example.F90 cfg_stub.o -fno-range-check -lmsmpifec -lmsmpi -L"$MSMPI_LIB64" -I$MINGW_PREFIX/include
@letmaik - Compiler team confirmed that this procedure is inside the VC runtime, and that explains the linker errors with non vc runtime.
Which runtime exactly? Do you have a DLL filename? MinGW links against MSVCRT.
Let me connect you with the compiler team and take this offline. I believe it is the MSVCRT itself.
I am also struggling this as I try to move from MS-MPI 8 to version 10. Is the cfg_stub.c work around the only path forward?
@jithinjosepkl
Let me connect you with the compiler team and take this offline. I believe it is the MSVCRT itself.
Please do report your findings in this thread. @letmaik is not the only one affected by this issue.