Possible bug in binutils for MinGW-w64 related to linking weak symbols
Jan Beulich
jbeulich@suse.com
Thu Mar 19 08:31:19 GMT 2026
On 18.03.2026 17:24, Johannes Khoshnazar-Thoma wrote:
> Dear binutils developers,
>
> (note that I first posted this to the mingw-w64 mailing list:
>
> https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg26192.html
> )
>
> When compiling the Linux kernel with MinGW-w64,
Why would you even try to build the Linux kernel (or any Linux binary) with
other than a compiler targeting Linux?
> I came across something
> that looks like a linker (or maybe compiler) bug.
>
> When compiling and linking those 2 C files:
>
> // foo.c:
> #include "foo.h"
>
> int __attribute__((weak)) foo(void)
> {
> return 42;
> }
>
> int __attribute__((weak)) bar(void)
> {
> return 69;
> }
>
> // foobar.c:
> #include "foo.h"
> #include <stdio.h>
>
> int main(void)
> {
> printf("foo is %d\n", foo());
> printf("bar is %d\n", bar());
> }
>
> // header foo.h is:
> int foo(void);
> int __attribute__((weak)) bar(void);
>
> the foo symbol is not defined when linking. The error
> message is:
>
> /usr/lib/gcc/i686-w64-mingw32/14.2.1/../../../../i686-w64-mingw32/bin/ld:
> foobar.o:foobar.c:(.text+0x4b): undefined reference to `foo'
> collect2: error: ld returned 1 exit status
> make: *** [Makefile:4: foobar] Error 1
And that's when linking in both foobar.o and foo.o? The latter ought to
provide a definition of foo(). The above looks like it would be the
expected behavior when linking foobar.o alone into an executable.
> The difference is that bar is declared weak also in the foo.h
> header file while foo is not. The objdump of the foobar.o file
> lists a (suspicious) entry:
>
> [ 17](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._bar._main
>
> for bar but not for foo. This might be a hint for what is going wrong.
>
> I've put the reproducer project on github for your convenience:
>
> https://github.com/johannesthoma/mingw-weaktest.git
>
> Note that with a (for example) Linux gcc, this undefined reference does not
> happen. It also works with LLVM clang for MinGW.
>
> So, my questions are:
>
> * is this a real bug? Or is it just a different point of view onto how weak
> symbols are handled?
I think it's a COFF vs ELF difference, but as per above some aspects
are still unclear, so things may be different in the end.
Jan
> * If it is a bug, can I help somehow to fix it?
>
> * If it is not a bug, what (except for declaring all possible symbols as __weak
> which I want to avoid, because there are a LOT in the Linux kernel) would be
> a workaround (some compiler/linker flags maybe?)
>
> Thank you for your attention.
>
> Best regards,
>
> - Johannes
>
>
More information about the Binutils
mailing list