Page MenuHomeFreeBSD

libgcc_s: Add a linker script to link to libgcc
AcceptedPublic

Authored by andrew on May 20 2024, 12:01 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Apr 14, 10:54 AM
Unknown Object (File)
Sun, Apr 5, 1:33 PM
Unknown Object (File)
Sat, Apr 4, 3:16 AM
Unknown Object (File)
Fri, Mar 27, 12:10 AM
Unknown Object (File)
Mar 14 2026, 6:14 PM
Unknown Object (File)
Mar 14 2026, 3:03 PM
Unknown Object (File)
Mar 8 2026, 5:08 AM
Unknown Object (File)
Mar 7 2026, 6:21 AM
Subscribers
None

Details

Reviewers
brooks
imp
emaste
jhb
jrtc27
Group Reviewers
arm64
Summary

When using outline atomics on arm64 the compiler will create a call to
a function that performs the atomic operation. This allows us to use
the fastest operation depending on the hardware.

As these functions are implemented in libgcc create a linker script
so libraries that link against libgcc_s will include libgcc to pull
them in.

Sponsored by: Arm Ltd

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 57782
Build 54670: arc lint + arc unit

Event Timeline

andrew created this revision.
This revision is now accepted and ready to land.May 20 2024, 1:12 PM

I wonder if this would be useful on risc64 which has similar issues. There I have been trying (but not succeeding) to get GCC's libatomic.a to build and install as part of the freebsdN-gcc ports so that it could be linked to.

This seems to match what GCC does, though I'm not sure why either need it. Both drivers pass both of -lgcc and -lgcc_s, whether building an executable or shared library (well, testing with GCC 13.2 on arm64 Linux, as that's easily to hand). Can you elaborate on the exact issue you're seeing without this?

In D45268#1032769, @jhb wrote:

I wonder if this would be useful on risc64 which has similar issues. There I have been trying (but not succeeding) to get GCC's libatomic.a to build and install as part of the freebsdN-gcc ports so that it could be linked to.

GCC 13+ should inline subword atomics like LLVM on RISC-V. Don't bother working around the old stupid mess; even the Linux distros gave up on that one.

Without this some of the Google tests failed to link as the __aarch64_* atomic functions from lse.S are missing. These are in libgcc but not libgcc_s.

The errors I get from the linker without this change are similar to the following.

/usr/local/bin/aarch64-unknown-freebsd14.0-ld: gmock-actions_test: hidden symbol `__aarch64_ldadd8_acq_rel' in /usr/obj/home/andtur04/freebsd/repo/freebsd-gcc/arm64.aarch64/tmp/usr/lib/libgcc.a(outline_atomic_ldadd8_4.o) is referenced by DSO 
/usr/local/bin/aarch64-unknown-freebsd14.0-ld: final link failed: bad value
collect2: error: ld returned 1 exit status

As discussed on IRC it looks like in some cases gcc passes -lgcc and -lgcc_s when run as cc, but -lgcc_s -lgcc_s when run as c++

Was it decided if this was an acceptable approach? I found the sanitizer runtimes also need this to work correctly, so would like to push to fix them

This matches what Linux does (on all architectures it seems) and will fix aarch64 building with external GCC. Let's go ahead and land this. I think you might want to update the commit log a bit to note the following details:

G++ only links against -lgcc_s on most platforms whereas GCC links against both -lgcc and -lgcc_s. Clang mimics this behavior for most platforms except for FreeBSD where clang links against both libraries for C++. Linux appears to ship an identical linker script for libgcc_s on all architectures (not just aarch64). While GCC's behavior here is inconsistent and arguably a bit odd, following Linux and using a linker script is probably going to result in the least friction going forward.