zig icon indicating copy to clipboard operation
zig copied to clipboard

lld-link: duplicate symbol: ___chkstk_ms with addSharedLibrary

Open DeadRobotDev opened this issue 1 year ago • 12 comments

Zig Version

0.11.0-dev.2298+5d63d1115

Steps to Reproduce and Observed Behavior

Operating System: Windows 10 Home 19045.2728

  1. 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.

DeadRobotDev avatar Mar 29 '23 06:03 DeadRobotDev

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.

kubkon avatar Mar 31 '23 08:03 kubkon

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.

DeadRobotDev avatar Mar 31 '23 15:03 DeadRobotDev

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

kcbanner avatar Apr 17 '23 22:04 kcbanner

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?

kubkon avatar May 31 '23 09:05 kubkon

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                                                                                                                                                                                

kubkon avatar May 31 '23 09:05 kubkon

@marler8997 and I hit this while working on a build script for Orca (https://github.com/allyourcodebase/orca)

kristoff-it avatar Nov 03 '23 08:11 kristoff-it

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)

linusg avatar Nov 19 '23 22:11 linusg

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)

linusg avatar Dec 09 '23 14:12 linusg

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

hammerfunctor avatar Dec 22 '23 15:12 hammerfunctor

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)

dcov avatar Feb 11 '24 07:02 dcov

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?).

rsepassi avatar Feb 26 '24 21:02 rsepassi

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);
}

maxxnino avatar Mar 12 '24 11:03 maxxnino

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?

rsepassi avatar Mar 26 '24 18:03 rsepassi

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.

rsepassi avatar Apr 02 '24 00:04 rsepassi

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)

juliannoble avatar Apr 10 '24 17:04 juliannoble

I can confirm this is fixed for me by #20138 :tada:

linusg avatar Jul 12 '24 20:07 linusg