[Bug target/90826] New: Weak symbol does not work reliably on windows
yyc1992 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Mon Jun 10 23:49:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90826
Bug ID: 90826
Summary: Weak symbol does not work reliably on windows
Product: gcc
Version: 9.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: yyc1992 at gmail dot com
Target Milestone: ---
The following code does not link correctly with all optimization levels on
windows with the mingw-w64-x86_64-g++ compiler.
```
#include <stdint.h>
extern "C" void f() __attribute__((weak));
int main()
{
return (int)(uintptr_t)f;
}
```
The assembly generated is
```
.file "weak.cpp"
.text
.def __main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
.LFB1:
subq $56, %rsp
.seh_stackalloc 56
.seh_endprologue
call __main
movq .refptr.f(%rip), %rax
movq %rax, 40(%rsp)
addq $56, %rsp
ret
.seh_endproc
.ident "GCC: (Rev2, Built by MSYS2 project) 9.1.0"
.section .rdata$.refptr.f, "dr"
.globl .refptr.f
.linkonce discard
.refptr.f:
.quad f
```
and the error,
```
C:\msys64\tmp\ccQkPfOi.o:weak.cpp:(.rdata$.refptr.f[.refptr.f]+0x0): undefined
reference to `f'
```
This should not happen since `f` is declared weak. (I realized that the symbol
resolution happens at compile time for weak symbol, which is fine for me, but I
just want it to compile...)
Another case where the optimization actually makes this work is,
```
#include <stdio.h>
extern "C" void f() __attribute__((weak));
int main()
{
printf("%p\n", f);
return 0;
}
```
With -O0, the assembly generated is
```
.file "weak.cpp"
.text
.def __main; .scl 2; .type 32; .endef
.section .rdata,"dr"
.LC0:
.ascii "%p\12\0"
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
.LFB28:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
call __main
movq .refptr.f(%rip), %rdx
leaq .LC0(%rip), %rcx
call printf
movl $0, %eax
addq $32, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (Rev2, Built by MSYS2 project) 9.1.0"
.def printf; .scl 2; .type 32; .endef
.section .rdata$.refptr.f, "dr"
.globl .refptr.f
.linkonce discard
.refptr.f:
.quad f
```
with error,
```
C:\msys64\tmp\ccTiwMKh.o:weak.cpp:(.rdata$.refptr.f[.refptr.f]+0x0): undefined
reference to `f'
```
with -O1 or higher, the assembly produced is,
```
.file "weak.cpp"
.text
.def __main; .scl 2; .type 32; .endef
.section .rdata,"dr"
.LC0:
.ascii "%p\12\0"
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
.LFB30:
subq $40, %rsp
.seh_stackalloc 40
.seh_endprologue
call __main
leaq f(%rip), %rdx
leaq .LC0(%rip), %rcx
call printf
movl $0, %eax
addq $40, %rsp
ret
.seh_endproc
.weak f
.ident "GCC: (Rev2, Built by MSYS2 project) 9.1.0"
.def f; .scl 2; .type 32; .endef
.def printf; .scl 2; .type 32; .endef
.section .rdata$.refptr.f, "dr"
.globl .refptr.f
.linkonce discard
.refptr.f:
.quad f
```
The difference between the two assembly is
```
--- weak1.s 2019-06-10 19:42:27.039467600 -0400
+++ weak0.s 2019-06-10 19:42:23.709467500 -0400
@@ -9,21 +9,24 @@
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
-.LFB30:
- subq $40, %rsp
- .seh_stackalloc 40
+.LFB28:
+ pushq %rbp
+ .seh_pushreg %rbp
+ movq %rsp, %rbp
+ .seh_setframe %rbp, 0
+ subq $32, %rsp
+ .seh_stackalloc 32
.seh_endprologue
call __main
- leaq f(%rip), %rdx
+ movq .refptr.f(%rip), %rdx
leaq .LC0(%rip), %rcx
call printf
movl $0, %eax
- addq $40, %rsp
+ addq $32, %rsp
+ popq %rbp
ret
.seh_endproc
- .weak f
.ident "GCC: (Rev2, Built by MSYS2 project) 9.1.0"
- .def f; .scl 2; .type 32; .endef
.def printf; .scl 2; .type 32; .endef
.section .rdata$.refptr.f, "dr"
.globl .refptr.f
```
where weak1.s (-) is the working one and weak0.s (+) is the error one.
The missing `.weak f` seems to be the issue. With that added to `weak0.s` or
removed from `weak1.s` the compilation result changes to that of the other
version. So it seems that without optimization on gcc just forgot to put in the
weak attribute into the assembly file??
More information about the Gcc-bugs
mailing list