zig
zig copied to clipboard
lld-link: duplicate symbol: ___chkstk_ms with addSharedLibrary
Zig Version
0.11.0-dev.2298+5d63d1115
Steps to Reproduce and Observed Behavior
Operating System: Windows 10 Home 19045.2728
- Run
zig build
If you replace addSharedLibrary
with addStaticLibrary
, there are no errors.
zig build-exe sandbox Debug native: error: the following command failed with 1 compilation errors:
C:\Users\Personal\Programs\bin\zig\0.11.0-dev.2298+5d63d1115\files\zig.exe build-exe W:\c\duplicate_symbol_repro\source\main.c W:\c\duplicate_symbol_repro\zig-cache\o\068335d453b8dd6ae99ff5e57fc2a431\lib.lib -lc --cache-dir W:\c\duplicate_symbol_repro\zig-
cache --global-cache-dir C:\Users\Personal\AppData\Local\zig --name sandbox --enable-cache --listen=-
Build Summary: 1/4 steps succeeded; 1 failed (disable with -fno-summary)
install transitive failure
+- install sandbox transitive failure
+- zig build-exe sandbox Debug native 1 errors
+- zig build-lib lib Debug native success 1s MaxRSS:32M
error: lld-link: duplicate symbol: ___chkstk_ms
note: defined at compiler_rt.lib(compiler_rt.lib.obj)
note: defined at lib.dll
// build.zig
const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const mode = b.standardOptimizeOption(.{});
const lib = b.addSharedLibrary(.{
.name = "lib",
.target = target,
.optimize = mode,
});
lib.addCSourceFile("source/lib.c", &.{});
lib.linkLibC();
const exe = b.addExecutable(.{
.name = "sandbox",
.target = target,
.optimize = mode,
});
exe.addCSourceFile("source/main.c", &.{});
exe.linkLibC();
exe.linkLibrary(lib);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
// source/main.c
#include "lib.h"
int
main(void)
{
greeter("Fletcher");
return 0;
}
// source/lib.h
#if !defined(LIB_H)
#define LIB_H
void greeter(const char* name);
#endif // LIB_H
// source/lib.c
#include "lib.h"
#include <stdio.h>
void greeter(const char* name)
{
printf("Hello, %s!\n", name);
}
Expected Behavior
Compile with no warnings and errors.
Does it also happen when building an executable rather than a DLL? If so, we are probably re-exporting the offending symbols one too many times in our compiler-rt
implementation.
If I build the DLL as a separate executable, no.
In the current build script, I am linking the library to an executable. And that is what causes the issue.
I think I've gotten to the bottom of this. It comes down to behavior added here https://reviews.llvm.org/D38760 to LLD, which causes all symbols to be exported if none are explicitly marked for export. This is a mingw thing, link.exe doesn't do this.
This is the function that does this in COFF/Driver.cpp
:
// In MinGW, if no symbols are chosen to be exported, then all symbols are
// automatically exported by default. This behavior can be forced by the
// -export-all-symbols option, so that it happens even when exports are
// explicitly specified. The automatic behavior can be disabled using the
// -exclude-all-symbols option, so that lld-link behaves like link.exe rather
// than MinGW in the case that nothing is explicitly exported.
void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
...
So, on *-windows-gnu
, if you don't use __declspec(dllexport)
at all, then all symbols get exported, which includes ___chkstk__ms
. See the full comparison below.
If using *-windows-msvc
then the link.exe behaviour is replicated (nothing exported if no exports are explicit).
It seems there are a couple ways we could solve this issue:
- Mark the compiler_rt symbols as not being exported when included in a DLL, although I'm not sure how this would look.
- Pass
-exclude-all-symbols
to lld-link. I tested this and it replicates the link.exe behaviour. If nothing is explictly exported, then no symbols are exported. If explicit exports are used, only things explicitly exported are exported. However, this would change behaviour from the default mingw behaviour.
I can work on a PR for this, but it would be great to get your feedback on which direction to go @kubkon
Building the DLL with MSVC:
c:\cygwin64\home\kcbanner\temp\chkstk>dumpbin /EXPORTS zig-out\bin\msvc-shared.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30141.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file zig-out\bin\msvc-shared.dll
File Type: DLL
Section contains the following exports for msvc-shared.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 00001090 add
2 1 00001000 add_mult
Summary
2000 .data
1000 .pdata
9000 .rdata
1000 .reloc
C000 .text
1000 _RDATA
Building the DLL with zig build, using __declspec(dllexport) in the C code
c:\cygwin64\home\kcbanner\temp\chkstk>dumpbin /EXPORTS zig-out\bin\shared.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30141.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file zig-out\bin\shared.dll
File Type: DLL
Section contains the following exports for shared.dll
00000000 characteristics
0 time date stamp
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 00001190 add = add
2 1 00001000 add_mult = add_mult
Summary
1000 .buildid
2000 .data
2000 .pdata
5000 .rdata
1000 .reloc
21000 .text
1000 .tls
Building the DLL with zig, not using __declspec(dllexport) in the c code
c:\cygwin64\home\kcbanner\temp\chkstk>dumpbin /exports zig-out\bin\shared.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30141.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file zig-out\bin\shared.dll
File Type: DLL
Section contains the following exports for shared.dll
00000000 characteristics
0 time date stamp
0.00 version
1 ordinal base
49 number of functions
49 number of names
ordinal hint RVA name
1 0 000010C0 _CRT_INIT = _CRT_INIT
2 1 00028030 _CRT_MT = _CRT_MT
3 2 00002090 _FindPESection = _FindPESection
4 3 000020E0 _FindPESectionByName = _FindPESectionByName
5 4 00002220 _FindPESectionExec = _FindPESectionExec
6 5 00002290 _GetPEImageBase = _GetPEImageBase
7 6 000022D0 _IsNonwritableInCurrentImage = _IsNonwritableInCurrentImage
8 7 00002060 _ValidateImageBase = _ValidateImageBase
9 8 00024EC0 __RUNTIME_PSEUDO_RELOC_LIST_END__ = __RUNTIME_PSEUDO_RELOC_LIST_END__
10 9 00024EC0 __RUNTIME_PSEUDO_RELOC_LIST__ = __RUNTIME_PSEUDO_RELOC_LIST_END__
11 A 00003AF0 ___chkstk_ms = ___chkstk_ms
12 B 00001D80 ___w64_mingwthr_add_key_dtor = ___w64_mingwthr_add_key_dtor
13 C 00001E00 ___w64_mingwthr_remove_key_dtor = ___w64_mingwthr_remove_key_dtor
14 D 00001520 __do_global_ctors = __do_global_ctors
15 E 000014D0 __do_global_dtors = __do_global_dtors
16 F 00001620 __dyn_tls_init = __dyn_tls_init
17 10 000220B8 __dyn_tls_init_callback = __dyn_tls_init_callback
18 11 00001590 __main = __main
19 12 000021E0 __mingw_GetSectionCount = __mingw_GetSectionCount
20 13 00002170 __mingw_GetSectionForAddress = __mingw_GetSectionForAddress
21 14 00001E90 __mingw_TLScallback = __mingw_TLScallback
22 15 00028088 __mingw_app_type = __mingw_app_type
23 16 00002360 __mingw_enum_import_library_names = __mingw_enum_import_library_names
24 17 0002807C __mingw_initltsdrot_force = __mingw_initltsdrot_force
25 18 00028080 __mingw_initltsdyn_force = __mingw_initltsdyn_force
26 19 00028084 __mingw_initltssuo_force = __mingw_initltssuo_force
27 1A 00028000 __mingw_module_is_dll = __mingw_module_is_dll
28 1B 00028010 __native_dllmain_reason = __native_dllmain_reason
29 1C 00028070 __native_startup_lock = __native_startup_lock
30 1D 00028068 __native_startup_state = __native_startup_state
31 1E 00028014 __native_vcclrit_reason = __native_vcclrit_reason
32 1F 00001690 __tlregdtor = __tlregdtor
33 20 00024EC0 __xc_a = __RUNTIME_PSEUDO_RELOC_LIST_END__
34 21 00024EC8 __xc_z = __xc_z
35 22 00024EE0 __xi_a = __xi_a
36 23 00024EF0 __xi_z = __xi_z
37 24 00024EF8 __xl_a = __xl_a
38 25 00024F00 __xl_c = __xl_c
39 26 00024F08 __xl_d = __xl_d
40 27 00024F10 __xl_z = __xl_z
41 28 00003AB0 _alloca = _alloca
42 29 0002C008 _tls_end = _tls_end
43 2A 00028078 _tls_index = _tls_index
44 2B 0002C000 _tls_start = _tls_start
45 2C 00022090 _tls_used = _tls_used
46 2D 00001060 add = add
47 2E 00001000 add_mult = add_mult
48 2F 00021A10 fpreset = _fpreset
49 30 00024EE8 pcinit = pcinit
Summary
1000 .buildid
2000 .data
2000 .pdata
5000 .rdata
1000 .reloc
21000 .text
1000 .tls
I haven't looked in detail into this but here's my main observation with a suggestion of exploring the problem space a little more. The collision happens when trying to link an executable with a shared library. When linking executable, regardless if linking with a shared object or not, we always provide a static lib of compiler-rt symbols each marked as weak so that they can easily be overwritten by user's definition if available. Here, for some reason, we get a collision. When creating a shared object all compiler-rt symbols were re-exported (and their binding promoted to strong as is customary I believe tho not sure if required, we could investigate that in our self-hosted linkers). So we have a situation like this:
$ link main.o -llib -L. libcompiler_rt.a
Symbols in libcompiler_rt.a
are still supposed to be exported as weak, therefore why is the linker reporting a collision if it should take the stronger definition? If we rearrange the inputs, it becomes more tricky, but I would still not expect any collisions unless I am missing something vital here.
None of this is satisfactory as I don't want the shared object to re-export compiler-rt symbols ever. @kcbanner would you be up for some more investigation here? The next step would be to figure out why the collision is actually happening in the linker. I would also like to learn how the linker handles symbol binding promotion, in particular upgrading weak to strong. I realise it would have been so much simpler to reason about and fix if we had a working traditional COFF linker but sadly we are not there yet, and I currently don't have the cycles to spare - too deep in ELF currently. Also, I am happy to push this issue back to 0.12 milestone - I'd rather we solved it properly the first time round than put a bandaid on it and let it burst again in the near future.
Also, does this problem also repro when build a shared object from Zig sources and not C?
For comparison, it doesn't look like this problem happens with ELF:
$ zig cc lib.c -shared -o liblib.so --verbose
clang version 16.0.1 (https://github.com/llvm/llvm-project cd89023f797900e4492da58b7bed36f702120011)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/kubkon/dev/examples/shared
(in-process)
"/home/kubkon/opt/bin/zig" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -main-file-name lib.c -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -v -fcoverage-compilation-dir=/home/kubkon/dev/examples/shared -nostdsysteminc -nobuiltininc -resource-dir /home/kubkon/opt/lib/clang/16 -dependency-file /home/kubkon/.cache/zig/tmp/1baa910638a61bf9-lib.o.d -MT /home/kubkon/.cache/zig/tmp/1baa910638a61bf9-lib.o -sys-header-deps -MV -isystem /home/kubkon/opt/lib/zig/include -isystem /nix/store/dwsi3wsqpqm0hpzdm9fsxc7q732p9xwi-glibc-2.34-210-dev/include -isystem /nix/store/9bj5frjj62k1vqk68kk7rx0zxm2ip7mp-lldb-15.0.7-dev/include -isystem /nix/store/s1283aqd7i2spsq66c1w98mgijyjaycb-gdb-12.1/include -isystem /nix/store/pdllykvxhfqjpkn4samm89i61h613v9n-qemu-7.0.0/include -isystem /nix/store/xpwwghl72bb7f48m51amvqiv1l25pa01-python3-3.9.13/include -isystem /nix/store/579lkbash00ylhs8yaqfpvgnfrhjv67a-zlib-1.2.12-dev/include -isystem /nix/store/vakcc74vp08y1rb1rb1cla6885ayklk3-zstd-1.5.2-dev/include -isystem /nix/store/q2jrx19954l8qs8d6li8f6i27pbs6ykj-wasmtime-9.0.2-dev/include -isystem /nix/store/9bj5frjj62k1vqk68kk7rx0zxm2ip7mp-lldb-15.0.7-dev/include -isystem /nix/store/s1283aqd7i2spsq66c1w98mgijyjaycb-gdb-12.1/include -isystem /nix/store/pdllykvxhfqjpkn4samm89i61h613v9n-qemu-7.0.0/include -isystem /nix/store/xpwwghl72bb7f48m51amvqiv1l25pa01-python3-3.9.13/include -isystem /nix/store/579lkbash00ylhs8yaqfpvgnfrhjv67a-zlib-1.2.12-dev/include -isystem /nix/store/vakcc74vp08y1rb1rb1cla6885ayklk3-zstd-1.5.2-dev/include -isystem /nix/store/q2jrx19954l8qs8d6li8f6i27pbs6ykj-wasmtime-9.0.2-dev/include -D __GLIBC_MINOR__=34 -D _DEBUG -source-date-epoch 315532800 -O0 -fdebug-compilation-dir=/home/kubkon/dev/examples/shared -ferror-limit 19 -fsanitize=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound -fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound -fno-sanitize-memory-param-retval -fno-sanitize-address-use-odr-indicator -stack-protector 2 -stack-protector-buffer-size 4 -fgnuc-version=4.2.1 -fcolor-diagnostics -fno-spell-checking -target-cpu znver1 -target-feature -16bit-mode -target-feature -32bit-mode -target-feature -3dnow -target-feature -3dnowa -target-feature +64bit -target-feature +adx -target-feature +aes -target-feature +allow-light-256-bit -target-feature -amx-bf16 -target-feature -amx-fp16 -target-feature -amx-int8 -target-feature -amx-tile -target-feature +avx -target-feature +avx2 -target-feature -avx512bf16 -target-feature -avx512bitalg -target-feature -avx512bw -target-feature -avx512cd -target-feature -avx512dq -target-feature -avx512er -target-feature -avx512f -target-feature -avx512fp16 -target-feature -avx512ifma -target-feature -avx512pf -target-feature -avx512vbmi -target-feature -avx512vbmi2 -target-feature -avx512vl -target-feature -avx512vnni -target-feature -avx512vp2intersect -target-feature -avx512vpopcntdq -target-feature -avxifma -target-feature -avxneconvert -target-feature -avxvnni -target-feature -avxvnniint8 -target-feature +bmi -target-feature +bmi2 -target-feature +branchfusion -target-feature -cldemote -target-feature +clflushopt -target-feature +clwb -target-feature +clzero -target-feature +cmov -target-feature -cmpccxadd -target-feature +crc32 -target-feature +cx16 -target-feature +cx8 -target-feature -enqcmd -target-feature -ermsb -target-feature +f16c -target-feature -false-deps-getmant -target-feature -false-deps-lzcnt-tzcnt -target-feature -false-deps-mulc -target-feature -false-deps-mullq -target-feature -false-deps-perm -target-feature -false-deps-popcnt -target-feature -false-deps-range -target-feature -fast-11bytenop -target-feature +fast-15bytenop -target-feature -fast-7bytenop -target-feature +fast-bextr -target-feature -fast-gather -target-feature -fast-hops -target-feature +fast-lzcnt -target-feature +fast-movbe -target-feature +fast-scalar-fsqrt -target-feature +fast-scalar-shift-masks -target-feature -fast-shld-rotate -target-feature -fast-variable-crosslane-shuffle -target-feature +fast-variable-perlane-shuffle -target-feature +fast-vector-fsqrt -target-feature -fast-vector-shift-masks -target-feature +fma -target-feature -fma4 -target-feature +fsgsbase -target-feature -fsrm -target-feature +fxsr -target-feature -gfni -target-feature -harden-sls-ijmp -target-feature -harden-sls-ret -target-feature -hreset -target-feature -idivl-to-divb -target-feature -idivq-to-divl -target-feature -invpcid -target-feature -kl -target-feature -lea-sp -target-feature -lea-uses-ag -target-feature -lvi-cfi -target-feature -lvi-load-hardening -target-feature -lwp -target-feature +lzcnt -target-feature -macrofusion -target-feature +mmx -target-feature +movbe -target-feature -movdir64b -target-feature -movdiri -target-feature +mwaitx -target-feature +nopl -target-feature -pad-short-functions -target-feature +pclmul -target-feature -pconfig -target-feature -pku -target-feature +popcnt -target-feature -prefer-128-bit -target-feature -prefer-256-bit -target-feature -prefer-mask-registers -target-feature -prefetchi -target-feature -prefetchwt1 -target-feature +prfchw -target-feature -ptwrite -target-feature -raoint -target-feature +rdpid -target-feature -rdpru -target-feature +rdrnd -target-feature +rdseed -target-feature -retpoline -target-feature -retpoline-external-thunk -target-feature -retpoline-indirect-branches -target-feature -retpoline-indirect-calls -target-feature -rtm -target-feature +sahf -target-feature +sbb-dep-breaking -target-feature -serialize -target-feature -seses -target-feature -sgx -target-feature +sha -target-feature -shstk -target-feature -slow-3ops-lea -target-feature -slow-incdec -target-feature -slow-lea -target-feature -slow-pmaddwd -target-feature -slow-pmulld -target-feature +slow-shld -target-feature -slow-two-mem-ops -target-feature -slow-unaligned-mem-16 -target-feature -slow-unaligned-mem-32 -target-feature -soft-float -target-feature +sse -target-feature +sse2 -target-feature +sse3 -target-feature +sse4.1 -target-feature +sse4.2 -target-feature +sse4a -target-feature -sse-unaligned-mem -target-feature +ssse3 -target-feature -tagged-globals -target-feature -tbm -target-feature -tsxldtrk -target-feature -uintr -target-feature -use-glm-div-sqrt-costs -target-feature -use-slm-arith-costs -target-feature -vaes -target-feature -vpclmulqdq -target-feature +vzeroupper -target-feature -waitpkg -target-feature +wbnoinvd -target-feature -widekl -target-feature +x87 -target-feature -xop -target-feature +xsave -target-feature +xsavec -target-feature +xsaveopt -target-feature +xsaves -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/kubkon/.cache/zig/tmp/1baa910638a61bf9-lib.o -x c lib.c
clang -cc1 version 16.0.1 based upon LLVM 16.0.1 default target x86_64-unknown-linux-gnu
ignoring duplicate directory "/nix/store/9bj5frjj62k1vqk68kk7rx0zxm2ip7mp-lldb-15.0.7-dev/include"
ignoring duplicate directory "/nix/store/s1283aqd7i2spsq66c1w98mgijyjaycb-gdb-12.1/include"
ignoring duplicate directory "/nix/store/pdllykvxhfqjpkn4samm89i61h613v9n-qemu-7.0.0/include"
ignoring duplicate directory "/nix/store/xpwwghl72bb7f48m51amvqiv1l25pa01-python3-3.9.13/include"
ignoring duplicate directory "/nix/store/579lkbash00ylhs8yaqfpvgnfrhjv67a-zlib-1.2.12-dev/include"
ignoring duplicate directory "/nix/store/vakcc74vp08y1rb1rb1cla6885ayklk3-zstd-1.5.2-dev/include"
ignoring duplicate directory "/nix/store/q2jrx19954l8qs8d6li8f6i27pbs6ykj-wasmtime-9.0.2-dev/include"
#include "..." search starts here:
#include <...> search starts here:
/home/kubkon/opt/lib/zig/include
/nix/store/dwsi3wsqpqm0hpzdm9fsxc7q732p9xwi-glibc-2.34-210-dev/include
/nix/store/9bj5frjj62k1vqk68kk7rx0zxm2ip7mp-lldb-15.0.7-dev/include
/nix/store/s1283aqd7i2spsq66c1w98mgijyjaycb-gdb-12.1/include
/nix/store/pdllykvxhfqjpkn4samm89i61h613v9n-qemu-7.0.0/include
/nix/store/xpwwghl72bb7f48m51amvqiv1l25pa01-python3-3.9.13/include
/nix/store/579lkbash00ylhs8yaqfpvgnfrhjv67a-zlib-1.2.12-dev/include
/nix/store/vakcc74vp08y1rb1rb1cla6885ayklk3-zstd-1.5.2-dev/include
/nix/store/q2jrx19954l8qs8d6li8f6i27pbs6ykj-wasmtime-9.0.2-dev/include
End of search list.
LLD Link... ld.lld --error-limit=0 -O0 --gc-sections --eh-frame-hdr -znow -m elf_x86_64 -shared -o liblib.so /nix/store/scd5n7xsn0hh0lvhhnycr9gx0h8xfzsl-glibc-2.34-210/lib/crti.o -rpath /nix/store/mj25wmr1j5xj84n550lwabwmg0g2cxar-nix-shell/lib64 -rpath /nix/store/mj25wmr1j5xj84n550lwabwmg0g2cxar-nix-shell/lib -L /nix/store/anwb3ljfsn0pv0d0s0xxnx123flc7fdg-lldb-15.0.7-lib/lib -L /nix/store/s1283aqd7i2spsq66c1w98mgijyjaycb-gdb-12.1/lib -L /nix/store/xpwwghl72bb7f48m51amvqiv1l25pa01-python3-3.9.13/lib -L /nix/store/q7k32ydcqlram7f0l6b1y2c4cs07765y-zlib-1.2.12/lib -L /nix/store/l7j222k357y8fbh9gj283mv7s1nh1vrx-zstd-1.5.2/lib -L /nix/store/q2jrx19954l8qs8d6li8f6i27pbs6ykj-wasmtime-9.0.2-dev/lib -L /nix/store/anwb3ljfsn0pv0d0s0xxnx123flc7fdg-lldb-15.0.7-lib/lib -L /nix/store/s1283aqd7i2spsq66c1w98mgijyjaycb-gdb-12.1/lib -L /nix/store/xpwwghl72bb7f48m51amvqiv1l25pa01-python3-3.9.13/lib -L /nix/store/q7k32ydcqlram7f0l6b1y2c4cs07765y-zlib-1.2.12/lib -L /nix/store/l7j222k357y8fbh9gj283mv7s1nh1vrx-zstd-1.5.2/lib -L /nix/store/q2jrx19954l8qs8d6li8f6i27pbs6ykj-wasmtime-9.0.2-dev/lib -L /nix/store/scd5n7xsn0hh0lvhhnycr9gx0h8xfzsl-glibc-2.34-210/lib -dynamic-linker /nix/store/scd5n7xsn0hh0lvhhnycr9gx0h8xfzsl-glibc-2.34-210/lib/ld-linux-x86-64.so.2 /home/kubkon/.cache/zig/o/f5adcdd7a24666dd0b134420b164ad79/lib.o --as-needed -lm -lpthread -lc -ldl -lrt -lutil /home/kubkon/.cache/zig/o/eff376fbda2bc5f9441ee6d2d2de6780/libcompiler_rt.a /nix/store/scd5n7xsn0hh0lvhhnycr9gx0h8xfzsl-glibc-2.34-210/lib/crtn.o
$ readelf -s liblib.so Wed 31 May 2023 11:22:00 CEST
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [...]@GLIBC_2.2.5 (2)
3: 0000000000001430 36 FUNC GLOBAL DEFAULT 14 greeter
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS lib.c
2: 000000000000140c 0 FUNC LOCAL HIDDEN 12 _init
3: 0000000000001424 0 FUNC LOCAL HIDDEN 13 _fini
4: 00000000000025f8 0 NOTYPE LOCAL HIDDEN 18 _GLOBAL_OFFSET_TABLE_
5: 0000000000002480 0 NOTYPE LOCAL HIDDEN 16 _DYNAMIC
6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 0000000000001430 36 FUNC GLOBAL DEFAULT 14 greeter
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf
@marler8997 and I hit this while working on a build script for Orca (https://github.com/allyourcodebase/orca)
Doesn't seem to be limited to shared libraries, I also hit this while trying to link a Rust-built static library:
error: lld-link: duplicate symbol: ___chkstk_ms
note: defined at src/x86_64.rs:18
note: libicu_capi_staticlib.a(compiler_builtins-888a947cf30049df.compiler_builtins.b1c7720c06bbefd5-cgu.3.rcgu.o)
note: defined at compiler_rt.lib(compiler_rt.lib.obj)
And once more, this time due to compiler_rt.lib
being indirectly included via another Zig-built lib (https://github.com/kassane/winpthreads-zigbuild):
error: lld-link: duplicate symbol: ___chkstk_ms
note: defined at winpthreads.lib(compiler_rt.obj)
note: defined at src/x86_64.rs:18
note: libicu_capi_staticlib.a(compiler_builtins-73257fe88da021c4.compiler_builtins.c3351aefbf3c2e22-cgu.3.rcgu.o)
Also met this when I try to build djvulibre using zig c++
:
wget http://downloads.sourceforge.net/djvu/djvulibre-3.5.28.tar.gz
tar xzf djvulibre-3.5.28.tar.gz && cd djvulibre-3.5.28
./configure CC="zig cc" CXX="zig c++ -std=c++11" AR="zig ar" RANLIB="zig ranlib"
make
Log:
...
./GBitmap.h:623:3: warning: 'register' storage class specifier is deprecated and incompatible with C++17 [-Wdeprecated-register]
register int z=*data++;
^~~~~~~~~
./GBitmap.h:631:3: warning: 'register' storage class specifier is deprecated and incompatible with C++17 [-Wdeprecated-register]
register int z=*data++;
^~~~~~~~~
2 warnings generated.
CXX libdjvulibre_la-debug.lo
CXX libdjvulibre_la-miniexp.lo
CXXLD libdjvulibre.la
LLD Link... ld.lld: error: duplicate symbol: _init
>>> defined at /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/crti.o:(.init+0x0)
>>> defined at crti.S:66 (/usr/lib/zig/libc/glibc/sysdeps/x86_64/crti.S:66)
>>> /home/huzf/.cache/zig/o/905667224a4a4a5efcdacd5278c5af4b/crti.o:(.init+0x0)
ld.lld: error: duplicate symbol: _fini
>>> defined at /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/crti.o:(.fini+0x0)
>>> defined at crti.S:84 (/usr/lib/zig/libc/glibc/sysdeps/x86_64/crti.S:84)
>>> /home/huzf/.cache/zig/o/905667224a4a4a5efcdacd5278c5af4b/crti.o:(.fini+0x0)
make[2]: *** [Makefile:584: libdjvulibre.la] Error 1
make[2]: Leaving directory '/home/huzf/zigs/djvulibre-3.5.28/libdjvu'
make[1]: *** [Makefile:429: all-recursive] Error 1
make[1]: Leaving directory '/home/huzf/zigs/djvulibre-3.5.28'
make: *** [Makefile:361: all] Error 2
Also encountering this when linking wasmtime on windows:
error: lld-link: duplicate symbol: ___chkstk_ms
note: defined at src/x86_64.rs:18
note: libwasmtime.a(compiler_builtins-d13d1e3b0b541614.compiler_builtins.5d0826b571c4f15c-cgu.134.rcgu.o)
note: defined at compiler_rt.lib(compiler_rt.lib.obj)
Like @linusg and @dcov, hitting this when using Zig as the cross-compiler and linker for Rust. Temporary workaround for the crt symbols is to manually filter out the rust-provided crt object files from the link command. But I don't have a workaround for the ___chkstk_ms
issue when targeting windows (any ideas?).
I attempted to create a shared library, but encountered an error when running zig build
. I’m currently using Windows 11
and zig version 0.12.0-dev.3212+40e64245f
.
zig build
install
└─ install zlo
└─ zig build-lib zlo Debug native 1 errors
error: lld-link: ___chkstk_ms was replaced
error: the following command failed with 1 compilation errors:
//build.zig
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const lib = b.addSharedLibrary(.{
.name = "zlo",
.root_source_file = .{ .path = "src/root.zig" },
.target = target,
.optimize = optimize,
});
const ziglua = b.dependency("ziglua", .{
.target = target,
.optimize = optimize,
.lang = .lua53,
.shared = true,
});
lib.root_module.addImport("ziglua", ziglua.module("ziglua"));
b.installArtifact(lib);
}
//src/root.zig
const ziglua = @import("ziglua");
fn zlo(lua: *ziglua.Lua) i32 {
lua.newLib(&.{
.{ .name = "add", .func = ziglua.wrap(add) },
});
return 1;
}
fn add(lua: *ziglua.Lua) i32 {
const a = lua.toInteger(1) catch 0;
const b = lua.toInteger(2) catch 0;
lua.pushInteger(a + b);
return 1;
}
comptime {
_ = ziglua.exportFn("zlo", zlo);
}
So I thought I should be able to work around this by simply asking zig cc to skip including compiler_rt.lib
since as far as I can tell, it's including it automatically and I believe Rust already takes care of all the rt facilities it needs. I would have expected -nostdlib
and/or -nodefaultlibs
to skip the inclusion of compiler_rt
but that doesn't seem to work; I get the same error.
Bug or intended?
Also, @kubkon, you mentioned that the compiler_rt
symbols should have weak linkage, but they're marked with strong linkage here: https://github.com/ziglang/zig/blob/341857e5cd4fd4453cf9c7d1a6679feb66710d84/lib/compiler_rt/stack_probe.zig#L20
Bug or intended?
Hacky workaround for the rust case is to unpack the rust rlib (ar x
), rm the object file that contains __chkstk_ms
, repack the library ar rcs
, and replace it in the linker command line. Ugly but works.
I encountered the ___chkstk_ms duplicate symbol when trying to build zlib for windows.
In the specific case of zlib - defining ZLIB_DLL adds a dllexport attribute
(hint taken from https://mingw-users.narkive.com/Mu0lTkFW/all-symbols-exported-from-shared-library regarding qualifying any symbol with dllexport stopping all being exported by default)
Anyway - I'm generally grasping at straws with all this stuff - but the above flag allowed me to build an exe linked to the shared lib and it seems to work.
(edit: further reading suggests it's probably not a good idea to build zlib on windows anyway and the recommendation is to use the prebuilt zlib1.dll from the zlib website. That goes against the grain .. but anyway, interesting exercise)
I can confirm this is fixed for me by #20138 :tada: