Page MenuHomeFreeBSD

libgcc_s: export the IEEE-128 long double runtime on powerpc64le
Needs ReviewPublic

Authored by pkubaj on Wed, Jul 15, 5:48 AM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Jul 24, 10:16 AM
Unknown Object (File)
Thu, Jul 23, 1:51 AM
Unknown Object (File)
Tue, Jul 21, 3:17 AM
Unknown Object (File)
Tue, Jul 21, 12:36 AM
Unknown Object (File)
Tue, Jul 21, 12:27 AM
Unknown Object (File)
Mon, Jul 20, 10:29 PM
Unknown Object (File)
Mon, Jul 20, 7:19 AM
Unknown Object (File)
Sun, Jul 19, 2:22 AM
Subscribers

Details

Reviewers
jrtc27
imp
Group Reviewers
PowerPC
Summary

On powerpc64le with IEEE-128 long double, the long-double compiler-runtime
helpers are the *kf* soft-float functions (built from the tf sources,
renamed via -D in lib/libcompiler_rt/Makefile.inc) plus the complex
multc3/__divtc3. They are compiled into libgcc_s.so by the powerpc64le
SRCF block, but were never added to Symbol.map, so they stayed local and
unexported.

Every other IEEE-128 architecture already exports its scalar long-double
runtime -- aarch64 and riscv list the tf helpers in GCC_4.6.0. powerpc64le
was simply missed.

Because the helpers are unexported, any clang-built shared library that uses
long double leaves them undefined (permitted in a DSO), and linking an
executable against that DSO then fails under lld's default
--no-allow-shlib-undefined. For example science/harminv fails to link its
binary against its own libharminv.so with undefined multc3/divtc3; at
-O0, mulkf3/addkf3/__subkf3/__unordkf2 appear as well.

Export the full runtime, gated on the PowerPC-specific LONG_DOUBLE_IEEE128
predefine so no other architecture is affected: complex multc3/divtc3 in
GCC_4.0.0 (beside the other complex mul*c3), and the 28 scalar *kf*
functions in GCC_7.0.0. Node placement follows glibc/gcc symbol-versioning
history.

Test Plan

Re-link and confirm the 30 symbols now export (before, nm -D /lib/libgcc_s.so.1
shows none of them):

$ make -C lib/libgcc_s
$ nm -D obj/.../libgcc_s.so.1 | grep ' T ' | grep -E 'kf|tc3' | wc -l
30

Minimal reproduction (a .so that leaves the helpers undefined like a libtool
build, then an executable linked against it):

  $ cat > cl.c <<'EOF'
  long double _Complex fmul(long double _Complex a, long double _Complex b){ return a*b; }
  long double _Complex fdiv(long double _Complex a, long double _Complex b){ return a/b; }
  EOF
  $ cc -shared -fPIC -nodefaultlibs cl.c -o libcl.so   # __multc3/__divtc3 undefined
  $ cc main.c -L. -lcl -nodefaultlibs -lc /lib/libgcc_s.so.1 -o t

- old libgcc_s -> ld.lld: error: undefined reference: __multc3 ...
- rebuilt libgcc_s -> links cleanly.

End-to-end: science/harminv, which previously failed at the executable link
with undefined multc3/divtc3, builds cleanly via `poudriere testport
science/harminv` on a powerpc64le 16.0 jail with the rebuilt base.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 74822
Build 71705: arc lint + arc unit