Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows build fails on MinGW GCC 13 due to libssp changes #51740

Closed
maleadt opened this issue Oct 17, 2023 · 10 comments · Fixed by #52820
Closed

Windows build fails on MinGW GCC 13 due to libssp changes #51740

maleadt opened this issue Oct 17, 2023 · 10 comments · Fixed by #52820
Labels
building Build system, or building Julia or its dependencies system:windows Affects only Windows

Comments

@maleadt
Copy link
Member

maleadt commented Oct 17, 2023

Compiling Julia on Windows with GCC 13 from MSYS2 (which is the only available compiler) fails during linking:

    LINK build2/usr/bin/libjulia-codegen.dll
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ./codegen.o: in function `add_named_global':
C:/Users/Tim/Julia/src/julia/src/codegen.cpp:549:(.text+0x26a53): undefined reference to `__imp___stack_chk_guard'
collect2.exe: error: ld returned 1 exit status
make[1]: *** [/c/Users/Tim/Julia/src/julia/src/Makefile:412: /c/Users/Tim/Julia/src/julia/build2/usr/bin/libjulia-codegen.dll] Error 1
make: *** [/c/Users/Tim/Julia/src/julia/Makefile:97: julia-src-release] Error 2

This is on #51698, because otherwise the CSL static libraries break the build.

I'm not entirely sure where we should be getting __stack_chk_guard from; it's defined in rtutils.c, but HAVE_SSP is set, so that code isn't activated:

julia/src/rtutils.c

Lines 218 to 228 in 4d2d849

#ifndef HAVE_SSP
JL_DLLEXPORT uintptr_t __stack_chk_guard = (uintptr_t)0xBAD57ACCBAD67ACC; // 0xBADSTACKBADSTACK
JL_DLLEXPORT void __stack_chk_fail(void)
{
/* put your panic function or similar in here */
fprintf(stderr, "fatal error: stack corruption detected\n");
jl_gc_debug_critical_error();
abort(); // end with abort, since the compiler destroyed the stack upon entry to this function, there's no going back now
}
#endif

Meanwhile, libssp.dll from CSL has the symbol:

❯ objdump -p ./usr/bin/libssp-0.dll | grep stack
        [   6] __stack_chk_fail
        [   7] __stack_chk_guard

... and we do link this DLL, but that somehow doesn't seem to help:

g++ -march=native -mtune=native -m64 -shared   -Wl,--out-implib,/c/Users/Tim/Julia/src/julia/build2/usr/lib/libjulia-codegen.dll.a -pipe  -fno-rtti -std=c++14 -fno-gnu-unique   -O3 -ggdb2 -falign-functions -momit-leaf-frame-pointer -D_GNU_SOURCE -I. -I/c/Users/Tim/Julia/src/julia/src -I/c/Users/Tim/Julia/src/julia/src/flisp -I/c/Users/Tim/Julia/src/julia/src/support -I/c/Users/Tim/Julia/src/julia/build2/usr/include -I/c/Users/Tim/Julia/src/julia/build2/usr/include -I/c/Users/Tim/Julia/src/julia/deps/valgrind -Wall -Wno-strict-aliasing -fno-omit-frame-pointer -fvisibility=hidden -fno-common -Wno-comment -Wpointer-arith -Wundef -Wno-unused-result -DJL_BUILD_ARCH='"x86_64"' -DJL_BUILD_UNAME='"NT"' -IC:\Users\Tim\Julia\src\julia\build2\usr\include -DLLVM_SHLIB "-DJL_SYSTEM_IMAGE_PATH=\"../lib/julia/sys.dll\"" "-DJL_LIBJULIA_SONAME=\"libjulia.dll\"" ./codegen.o ./jitlayers.o ./aotcompile.o ./debuginfo.o ./disasm.o ./llvm-simdloop.o ./llvm-muladd.o ./llvm-final-gc-lowering.o ./llvm-pass-helpers.o ./llvm-late-gc-lowering.o ./llvm-ptls.o ./llvm-lower-handlers.o ./llvm-gc-invariant-verifier.o ./llvm-propagate-addrspaces.o ./llvm-multiversioning.o ./llvm-alloc-opt.o ./llvm-alloc-helpers.o ./cgmemmgr.o ./llvm-remove-addrspaces.o ./llvm-remove-ni.o ./llvm-julia-licm.o ./llvm-demote-float16.o ./llvm-cpufeatures.o ./pipeline.o ./llvm_api.o  -o /c/Users/Tim/Julia/src/julia/build2/usr/bin/libjulia-codegen.dll -Wl,--stack,8388608  -L/c/Users/Tim/Julia/src/julia/build2/usr/lib -L/c/Users/Tim/Julia/src/julia/build2/usr/bin  -LC:\Users\Tim\Julia\src\julia\build2\usr/lib  -lLLVM-15jl -Wl,--export-all-symbols -Wl,--version-script=/c/Users/Tim/Julia/src/julia/build2/src/julia.expmap -Wl,--no-whole-archive -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -lssp   -ljulia -ljulia-internal

cc @vtjnash


See below for a MWE, and the link to upstream changes causing this.

Workaround: override HAVE_SSP := 0 in Make.user.

@maleadt maleadt added building Build system, or building Julia or its dependencies system:windows Affects only Windows labels Oct 17, 2023
@vtjnash
Copy link
Member

vtjnash commented Oct 17, 2023

The symbol is __imp____stack_chk_guard with 4 _ not 3. Who stole your _?

@maleadt
Copy link
Member Author

maleadt commented Oct 18, 2023

The symbol is __imp____stack_chk_guard with 4 _ not 3.

Is it? Even using GCC 12, from our CI's environment, codegen.o contains __imp___stack_chk_guard with 3 _:

# objdump -t ../../build/src/codegen.o | grep stack_chk_guard
[158](sec  1)(fl 0x00)(ty   20)(scl   3) (nx 0) 0x0000000000003950 _ZNL21jlstack_chk_guard_varMUlPN4llvm4TypeEE_4_FUNES1_
[650](sec  3)(fl 0x00)(ty    0)(scl   3) (nx 0) 0x0000000000000598 _ZL21jlstack_chk_guard_var
[1614](sec  0)(fl 0x00)(ty    0)(scl   2) (nx 0) 0x0000000000000000 __imp___stack_chk_guard

And the codegen.o produced by GCC 13 links fine using GCC 12:

❯ g++ --version
g++.exe (Rev2, Built by MSYS2 project) 13.2.0
❯ g++ -march=native -mtune=native -m64 -shared   -Wl,--out-implib,/c/Users/Tim/Julia/src/julia/build2/usr/lib/libjulia-codegen.dll.a -pipe -lssp -fno-rtti -std=c++14 -fno-gnu-unique   -O3 -ggdb2 -falign-functions -momit-leaf-frame-pointer -D_GNU_SOURCE -I. -I/c/Users/Tim/Julia/src/julia/src -I/c/Users/Tim/Julia/src/julia/src/flisp -I/c/Users/Tim/Julia/src/julia/src/support -I/c/Users/Tim/Julia/src/julia/build2/usr/include -I/c/Users/Tim/Julia/src/julia/build2/usr/include -I/c/Users/Tim/Julia/src/julia/deps/valgrind -Wall -Wno-strict-aliasing -fno-omit-frame-pointer -fvisibility=hidden -fno-common -Wno-comment -Wpointer-arith -Wundef -Wno-unused-result -DJL_BUILD_ARCH='"x86_64"' -DJL_BUILD_UNAME='"NT"' -IC:\Users\Tim\Julia\src\julia\build2\usr\include -DLLVM_SHLIB "-DJL_SYSTEM_IMAGE_PATH=\"../lib/julia/sys.dll\"" "-DJL_LIBJULIA_SONAME=\"libjulia.dll\"" ./codegen.o ./jitlayers.o ./aotcompile.o ./debuginfo.o ./disasm.o ./llvm-simdloop.o ./llvm-muladd.o ./llvm-final-gc-lowering.o ./llvm-pass-helpers.o ./llvm-late-gc-lowering.o ./llvm-ptls.o ./llvm-lower-handlers.o ./llvm-gc-invariant-verifier.o ./llvm-propagate-addrspaces.o ./llvm-multiversioning.o ./llvm-alloc-opt.o ./llvm-alloc-helpers.o ./cgmemmgr.o ./llvm-remove-addrspaces.o ./llvm-remove-ni.o ./llvm-julia-licm.o ./llvm-demote-float16.o ./llvm-cpufeatures.o ./pipeline.o ./llvm_api.o  -o /c/Users/Tim/Julia/src/julia/build2/usr/bin/libjulia-codegen.dll -Wl,--stack,8388608  -L/c/Users/Tim/Julia/src/julia/build2/usr/lib -L/c/Users/Tim/Julia/src/julia/build2/usr/bin  -LC:\Users\Tim\Julia\src\julia\build2\usr/lib  -lLLVM-15jl -Wl,--export-all-symbols -Wl,--version-script=/c/Users/Tim/Julia/src/julia/build2/src/julia.expmap -Wl,--no-whole-archive -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -ljulia -ljulia-internal
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ./codegen.o: in function `add_named_global':
C:/Users/Tim/Julia/src/julia/src/codegen.cpp:549:(.text+0x26a53): undefined reference to `__imp___stack_chk_guard'
collect2.exe: error: ld returned 1 exit status

# from within the same folder, i.e., using the same objects

# g++ --version
g++.exe (Rev1, Built by MSYS2 project) 12.2.0
#  g++ -march=native -mtune=native -m64 -shared   -Wl,--out-implib,/c/Users/Tim/Julia/src/julia/build2/usr/lib/libjulia-codegen.dll.a -pipe  -fno-rtti -std=c++14 -fno-gnu-unique   -O3 -ggdb2 -falign-functions -momit-leaf-frame-pointer -D_GNU_SOURCE -I. -I/c/Users/Tim/Julia/src/julia/src -I/c/Users/Tim/Julia/src/julia/src/flisp -I/c/Users/Tim/Julia/src/julia/src/support -I/c/Users/Tim/Julia/src/julia/build2/usr/include -I/c/Users/Tim/Julia/src/julia/build2/usr/include -I/c/Users/Tim/Julia/src/julia/deps/valgrind -Wall -Wno-strict-aliasing -fno-omit-frame-pointer -fvisibility=hidden -fno-common -Wno-comment -Wpointer-arith -Wundef -Wno-unused-result -DJL_BUILD_ARCH='"x86_64"' -DJL_BUILD_UNAME='"NT"' -IC:\Users\Tim\Julia\src\julia\build2\usr\include -DLLVM_SHLIB "-DJL_SYSTEM_IMAGE_PATH=\"../lib/julia/sys.dll\"" "-DJL_LIBJULIA_SONAME=\"libjulia.dll\"" ./codegen.o ./jitlayers.o ./aotcompile.o ./debuginfo.o ./disasm.o ./llvm-simdloop.o ./llvm-muladd.o ./llvm-final-gc-lowering.o ./llvm-pass-helpers.o ./llvm-late-gc-lowering.o ./llvm-ptls.o ./llvm-lower-handlers.o ./llvm-gc-invariant-verifier.o ./llvm-propagate-addrspaces.o ./llvm-multiversioning.o ./llvm-alloc-opt.o ./llvm-alloc-helpers.o ./cgmemmgr.o ./llvm-remove-addrspaces.o ./llvm-remove-ni.o ./llvm-julia-licm.o ./llvm-demote-float16.o ./llvm-cpufeatures.o ./pipeline.o ./llvm_api.o  -o /c/Users/Tim/Julia/src/julia/build2/usr/bin/libjulia-codegen.dll -Wl,--stack,8388608  -L/c/Users/Tim/Julia/src/julia/build2/usr/lib -L/c/Users/Tim/Julia/src/julia/build2/usr/bin  -LC:\Users\Tim\Julia\src\julia\build2\usr/lib  -lLLVM-15jl -Wl,--export-all-symbols -Wl,--version-script=/c/Users/Tim/Julia/src/julia/build2/src/julia.expmap -Wl,--no-whole-archive -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -lssp   -ljulia -ljulia-internal
# success

@maleadt
Copy link
Member Author

maleadt commented Oct 18, 2023

Looks like libssp.a on GCC 13 is... empty?

❯ objdump -t /mingw64/lib/libssp.a
In archive C:/msys64/mingw64/lib/libssp.a:

❯ stat /mingw64/lib/libssp.a
  File: /mingw64/lib/libssp.a
  Size: 8               Blocks: 1          IO Block: 65536  regular file

vs

# objdump -t /mingw64/lib/libssp.a | grep __stack_chk_guard
[ 36](sec  3)(fl 0x00)(ty    0)(scl   2) (nx 0) 0x0000000000000000 __stack_chk_guard

@maleadt
Copy link
Member Author

maleadt commented Oct 18, 2023

MWE:

extern __declspec(dllimport) int __stack_chk_guard;

int* foo(void)
{
    return &__stack_chk_guard;
}
❯ gcc -shared test.c -lssp -o test.dll
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccq7LnXo.o:test.c:(.text+0x1b): undefined reference to `__imp___stack_chk_guard'
collect2.exe: error: ld returned 1 exit status

Works on GCC 12, fails on 13. Tried some combinations of -fstack-protector instead of -lssp, to no avail.

@maleadt
Copy link
Member Author

maleadt commented Oct 18, 2023

Looks like the static libssp libraries were intentionally removed and replaced with empty alternatives: msys2/MINGW-packages#13414 msys2/MINGW-packages#13405

AFAICT, the stack protector implementation is now provided by libmingwex: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/10394c9a966f8e93e9e2f09677dab273a0f6c00c/

❯ objdump -t /mingw64/lib/libmingwex.a | grep stack_chk
lib64_libmingwex_a-stack_chk_fail.o:     file format pe-x86-64
[  0](sec -2)(fl 0x00)(ty    0)(scl 103) (nx 1) 0x0000000000000000 stack_chk_fail
[  2](sec  1)(fl 0x00)(ty   20)(scl   2) (nx 1) 0x0000000000000000 __stack_chk_fail

Simply adding -lmingwex doesn't help though... It also shouldn't be required; -Wl,-verbose reveals that libmingwex.a was already being linked.

@maleadt maleadt changed the title Windows build fails using GCC 13 from MSYS2 Windows build fails on MinGW GCC 13 due to libssp changes Oct 18, 2023
@awson
Copy link

awson commented Dec 19, 2023

❯ objdump -t /mingw64/lib/libmingwex.a | grep stack_chk
lib64_libmingwex_a-stack_chk_fail.o: file format pe-x86-64
[ 0](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x0000000000000000 stack_chk_fail
[ 2](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x0000000000000000 __stack_chk_fail

It is outdated libmingwex apparently, the new one (corresponding to the new libssp) contains __stack_chk_guard.

@mkitti
Copy link
Contributor

mkitti commented Jan 5, 2024

Is this related to this news announcement?

https://www.msys2.org/news/#2022-10-10-libssp-is-no-longer-required

2022-10-10 - libssp is no longer required

Building with _FORTIFY_SOURCE no longer requires explicitly linking with libssp (-lssp) and enabling stack protection no longer pulls in libssp. This brings things in line with other platforms. Thanks to Martin Storsjö for implementing this in mingw-w64. Once all our affected packages are rebuilt we will remove the libssp package from our repo.

2022-10-13: We have decided to keep just the libssp DLL around for some more time to avoid breaking existing users

@mkitti
Copy link
Contributor

mkitti commented Jan 5, 2024

Yes.

mingw-w64/mingw-w64@10394c9

While the compiler drivers do add -lssp automatically when
linking with -fstack-protector-strong, this also allows relying
entirely on libmingwex. This implementation should be functionally
equivalent to GCC's libssp for a mingw build configuration.

This allows toolchains that don't otherwise use GCC's runtime libraries
(such as LLVM based ones) to skip building libssp from GCC (and
replacing it with empty/dummy libssp.a and libssp_nonshared.a).

@mkitti
Copy link
Contributor

mkitti commented Jan 5, 2024

We ship libssp.dll.a with the CompilerSupportLibraries (CSL) dependency, so we just need to append that to COMMON_LIBPATHS:

diff --git a/src/Makefile b/src/Makefile
index c78df75bdc..b433fbfdee 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -163,7 +163,7 @@ else
 LIBJULIA_PATH_REL := libjulia
 endif

-COMMON_LIBPATHS := -L$(build_libdir) -L$(build_shlibdir)
+COMMON_LIBPATHS := -L$(build_libdir) -L$(build_shlibdir) -L$(build_private_libdir)
 RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI)
 CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI)
 RT_DEBUG_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp-debug.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport-debug.a -ljulia-debug $(RT_LIBS)

nevermind: this goes back to the beginning.

@mkitti
Copy link
Contributor

mkitti commented Jan 5, 2024

My current work around is as follows.

cp julia/usr/lib/gcc/x86_64-w64-mingw32/13/libssp.dll.a julia/usr/lib

I think the following should fix it.

diff --git a/deps/csl.mk b/deps/csl.mk
index aaebc8f50c..c3bbede366 100644
--- a/deps/csl.mk
+++ b/deps/csl.mk
@@ -110,7 +110,7 @@ install-csl:
        cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc_s.a $(build_private_libdir)/
        cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc.a $(build_private_libdir)/
        cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libmsvcrt.a $(build_private_libdir)/
-       cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_private_libdir)/
+       cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_libdir)/
 endif
 endif
 ifeq ($(OS),WINNT)
@@ -119,5 +119,5 @@ uninstall-gcc-libraries:
        -rm -f $(build_private_libdir)/libgcc_s.a
        -rm -f $(build_private_libdir)/libgcc.a
        -rm -f $(build_private_libdir)/libmsvcrt.a
-       -rm -f $(build_private_libdir)/libssp.dll.a
+       -rm -f $(build_libdir)/libssp.dll.a
 endif

vtjnash pushed a commit that referenced this issue Jan 14, 2024
…dir (#52820)

Fix #51740 

Since we are providing libssp.dll on Windows and we want to dynamically
link to it, exposing libssp.dll.a is necessary. The inconsistency is
that libjulia-codegen.so looks in build_libdir and build_private_libdir
while standard library precompilation looks in build_shlibdir and
build_private_dir.
KristofferC pushed a commit that referenced this issue Aug 2, 2024
…dir (#52820)

Fix #51740

Since we are providing libssp.dll on Windows and we want to dynamically
link to it, exposing libssp.dll.a is necessary. The inconsistency is
that libjulia-codegen.so looks in build_libdir and build_private_libdir
while standard library precompilation looks in build_shlibdir and
build_private_dir.

(cherry picked from commit c3836e1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
building Build system, or building Julia or its dependencies system:windows Affects only Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants