microsoft / Microsoft-MPI

Microsoft MPI
MIT License
246 stars 74 forks source link

10.0 not usable in MSYS/mingw64 with gfortran #7

Open letmaik opened 5 years ago

letmaik commented 5 years ago
$ 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
jithinjosepkl commented 5 years ago

@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.

letmaik commented 5 years ago

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.

letmaik commented 5 years ago

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.

jithinjosepkl commented 5 years ago

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.

letmaik commented 5 years ago

@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
jithinjosepkl commented 5 years ago

@letmaik - Compiler team confirmed that this procedure is inside the VC runtime, and that explains the linker errors with non vc runtime.

letmaik commented 5 years ago

Which runtime exactly? Do you have a DLL filename? MinGW links against MSVCRT.

jithinjosepkl commented 5 years ago

Let me connect you with the compiler team and take this offline. I believe it is the MSVCRT itself.

KineticTheory commented 4 years ago

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?

zbeekman commented 4 years ago

@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.