From 2908d9bb9afda3325ed778ce0ba3833d91ba438e Mon Sep 17 00:00:00 2001 From: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com> Date: Fri, 17 Jul 2026 09:02:38 +0300 Subject: [PATCH] aarch64-linux: link libgcc for outline atomic helpers rust_binary targets built with the ferrocene_aarch64_unknown_linux_gnu toolchain fail to link when they pull in C/C++ code that performs atomic operations (e.g. std::atomic, std::shared_ptr refcounts, mutexes via C++ interop): undefined reference to `__aarch64_ldadd4_acq_rel' undefined reference to `__aarch64_cas2_acq_rel' undefined reference to `__aarch64_swp4_acq_rel' Root cause: GCC 10+ defaults to "outline atomics" on aarch64. Rather than emitting LSE (ARMv8.1) or LL/SC atomics inline, the compiler emits calls to helper functions in libgcc that select an LSE or a backward-compatible path at runtime. Those helpers are defined only in the static libgcc.a; the shared libgcc_s.so does not export them. rustc links with -nodefaultlibs and adds -lgcc_s but not -lgcc, so the helpers are never offered to the linker. Fix: append -Clink-arg=-lgcc to the aarch64-unknown-linux-gnu toolchain's extra_rustc_flags so libgcc.a is on the link line. It is placed last because the linker resolves a static archive only against symbols already referenced to its left, so libgcc.a must follow the C/C++ objects and libraries (-lstdc++ etc.) that reference the helpers. This resolves the outline-atomics half of the aarch64 GCC link failure without requiring downstream repositories to inject the flag via .bazelrc. MODULE.bazel.lock is regenerated (bazel mod deps --lockfile_mode=update) to reflect the added flag. Refs: eclipse-score/toolchains_rust#27, eclipse-score/communication#328 --- MODULE.bazel | 1 + MODULE.bazel.lock | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 06f6b27..56fbf2a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -67,6 +67,7 @@ ferrocene.toolchain( "-Clink-arg=-lstdc++", "-Clink-arg=-lm", "-Clink-arg=-lc", + "-Clink-arg=-lgcc", ], miri_sysroot_sha256 = "74f90eabcb34809e44300535016f25eb0cf4a500763c0d18e7f587583b5b9908", miri_sysroot_strip_prefix = "aarch64-unknown-linux-gnu", diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 30d0d9e..27450e9 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -348,7 +348,7 @@ "//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_ext": { "general": { "bzlTransitiveDigest": "JTR6scmBZuukTYspnbvaNFU27CfBHiQyu6OywcI1QPE=", - "usagesDigest": "3kOi9ZQ7CwvyfvR2TUOe9FHbsxa796pSC1jmnoIxy/g=", + "usagesDigest": "rWEZaM0xWw7yeL7B75jmGTsU4xi83MP5olBN4FBicSo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -409,7 +409,8 @@ "-Clink-arg=-Wl,--no-as-needed", "-Clink-arg=-lstdc++", "-Clink-arg=-lm", - "-Clink-arg=-lc" + "-Clink-arg=-lc", + "-Clink-arg=-lgcc" ], "extra_exec_rustc_flags": [], "env": {},