https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83180
Bug ID: 83180 Summary: MINGW: Linking to libpq.dll produced with MSVC-x64 generates invalid code Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: l...@greiz-reinsdorf.de Target Milestone: --- Created attachment 42731 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42731&action=edit Test source code to link to libpq.dll Hi! I'm a maintainer of the Ruby binding to PostgreSQL. I'm faced with a linker issue when linking to PQgetvalue() in the libpq.dll for x64 provided by the PostgreSQL project. The DLL in question is attached. It is part of the official PostgreSQL download for Windows-x64: https://get.enterprisedb.com/postgresql/postgresql-10.0-1-windows-x64.exe The error can be reproduced by using the attached "segfault.c" file like so. It fails when auto-import is disabled: $ x86_64-w64-mingw32-gcc -o segfault.exe segfault.c -IC:/PROGRA~1/POSTGR~1/10/include -LC:/PROGRA~1/POSTGR~1/10/lib -Wl,--enable-auto-image-base,--disable-auto-import -lpq C:\Users\kanis\AppData\Local\Temp\cce46Itr.o:segfault.c:(.text+0x11e): undefined reference to `PQgetvalue' collect2.exe: error: ld returned 1 exit status When auto-import is enabled, then linking succeeds, but the generated code is invalid: $ x86_64-w64-mingw32-gcc -o segfault.exe segfault.c -IC:/PROGRA~1/POSTGR~1/10/include -LC:/PROGRA~1/POSTGR~1/10/lib -Wl,--enable-auto-image-base,--enable-auto-import -lpq $ objdump -d segfault.exe [...] 401650: 48 8b 45 f0 mov -0x10(%rbp),%rax 401654: 41 b8 00 00 00 00 mov $0x0,%r8d 40165a: ba 00 00 00 00 mov $0x0,%edx 40165f: 48 89 c1 mov %rax,%rcx 401662: e8 d9 17 00 00 callq 402e40 <PQgetlength> 401667: 89 45 ec mov %eax,-0x14(%rbp) 40166a: 8b 45 ec mov -0x14(%rbp),%eax 40166d: 89 c2 mov %eax,%edx 40166f: 48 8d 0d e4 29 00 00 lea 0x29e4(%rip),%rcx # 40405a <.rdata+0x5a> 401676: e8 25 16 00 00 callq 402ca0 <printf> 40167b: 48 8b 45 f0 mov -0x10(%rbp),%rax 40167f: 41 b8 00 00 00 00 mov $0x0,%r8d 401685: ba 00 00 00 00 mov $0x0,%edx 40168a: 48 89 c1 mov %rax,%rcx 40168d: e8 .byte 0xe8 000000000040168e <__fu0_PQgetvalue>: 40168e: 66 6d insw (%dx),%es:(%rdi) 401690: 00 00 add %al,(%rax) 401692: 48 89 45 e0 mov %rax,-0x20(%rbp) 401696: 48 8b 45 e0 mov -0x20(%rbp),%rax 40169a: 48 89 c2 mov %rax,%rdx 40169d: 48 8d 0d bf 29 00 00 lea 0x29bf(%rip),%rcx # 404063 <.rdata+0x63> 4016a4: e8 f7 15 00 00 callq 402ca0 <printf> [...] $ ./segfault.exe conn: 00000000007AA7D0 PQlibVersion: 100000 res: 00000000007B7120 len: 3 ... The call to PQgetlength() and printf() runs through, but it segfaults on 0x40168d, because the address of callq (opcode 0xe8) is invalid. Obviously the debug information also doesn't fit to the produced code, so that the opcodes are not properly decoded. Other functions like PQgetlength() are not affected. They link fine with auto-import being enabled or disabled. The only function with this odd behavior is PQgetvalue(). As a workaround "-l:libpq.lib" can be used to trigger linking to libpq.dll per MSVC import library. This works for gcc-7.2.0, but older versions of gcc (4.7.2) fail to link to any function of a MSVC produced libpq.lib file (for some obviously fixed reason). The issue doesn't appear when building for 32 bit x86 or when linking to a libpq.dll produced by MINGW. The root issue is also reproducible on Appveyor: https://ci.appveyor.com/project/larskanis/ruby-pg-xa3f5/build/1.0.65/job/b06idaids8el773r My environment: $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../gcc-7.2.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,objc,obj-c++,fortran,ada --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev1, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld Thread model: posix gcc version 7.2.0 (Rev1, Built by MSYS2 project) $ ver Microsoft Windows [Version 10.0.14393]