In rS307231, @emaste added a few libm functions to libgcc_s.so.1. They
are required because some of compiler-rt's routines contain calls to
them, in particular for complex operations.
However, while the object files are compiled and linked into the shared
library, the functions themselves are *not* visible, due to the symbol
versioning scripts used:
$ readelf -aW libgcc_s.so.1.full | grep -E -w '(fabs|fabsf|fabsl|fmax|fmaxf|fmaxl|logb|logbf|logbl|scalbn|scalbnf|scalbnl)' 4: 0000000000009da0 99 FUNC LOCAL DEFAULT 13 logbf 5: 0000000000009e10 118 FUNC LOCAL DEFAULT 13 logb 6: 0000000000009e90 106 FUNC LOCAL DEFAULT 13 fmaxf 7: 0000000000009f00 128 FUNC LOCAL DEFAULT 13 fmax 8: 0000000000009f80 30 FUNC LOCAL DEFAULT 13 fabsl 9: 0000000000009fa0 13 FUNC LOCAL DEFAULT 13 fabsf 10: 0000000000009fb0 13 FUNC LOCAL DEFAULT 13 fabs 139: 0000000000010670 142 FUNC LOCAL DEFAULT 13 fmaxl 140: 0000000000010590 212 FUNC LOCAL DEFAULT 13 logbl 141: 0000000000010450 315 FUNC LOCAL DEFAULT 13 scalbnl 144: 0000000000010700 192 FUNC LOCAL DEFAULT 13 scalbnf 148: 00000000000107c0 248 FUNC LOCAL DEFAULT 13 scalbn
I noticed the problem, because the LLVM test suite contains a test case
for complex handling from the GCC "torture test":
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/testsuite/gcc.c-torture/execute/complex-5.c
Attempting to compile and link this fails, with complaints about missing
scalbnf:
$ cc complex-5.c -o complex-5 ... ld: error: undefined symbol: scalbnf >>> referenced by divsc3.c:26 (/usr/src/contrib/llvm-project/compiler-rt/lib/builtins/divsc3.c:26) >>> divsc3.o:(__divsc3) in archive /usr/lib/libgcc.a >>> referenced by divsc3.c:27 (/usr/src/contrib/llvm-project/compiler-rt/lib/builtins/divsc3.c:27) >>> divsc3.o:(__divsc3) in archive /usr/lib/libgcc.a >>> referenced by divsc3.c:31 (/usr/src/contrib/llvm-project/compiler-rt/lib/builtins/divsc3.c:31) >>> divsc3.o:(__divsc3) in archive /usr/lib/libgcc.a >>> referenced by divsc3.c:33 (/usr/src/contrib/llvm-project/compiler-rt/lib/builtins/divsc3.c:33) >>> divsc3.o:(__divsc3) in archive /usr/lib/libgcc.a cc: error: linker command failed with exit code 1 (use -v to see invocation)
It seems that we must somehow place these math symbols in a version
node, and put global: in front of them.
This is an initial attempt to do so. It adds an FBSD_1.0 version node,
similar to the one used in libm itself, and puts the math symbols in
there. There are two .map files, the first contains the symbols that are
always included, the second the ones that are excluded on arm, mips and
powerpc.
The resulting libgcc_s.so.1 now has the math functions as global
symbols:
$ readelf -aW libgcc_s.so.1.full | grep -E -w '(fabs|fabsf|fabsl|fmax|fmaxf|fmaxl|logb|logbf|logbl|scalbn|scalbnf|scalbnl)' 0000000000019750 0000009100000007 R_X86_64_JUMP_SLOT 00000000000106e0 fmaxl@@FBSD_1.0 + 0 0000000000019758 0000006f00000007 R_X86_64_JUMP_SLOT 0000000000010600 logbl@@FBSD_1.0 + 0 0000000000019760 0000002d00000007 R_X86_64_JUMP_SLOT 00000000000104c0 scalbnl@@FBSD_1.0 + 0 0000000000019768 0000009500000007 R_X86_64_JUMP_SLOT 0000000000010770 scalbnf@@FBSD_1.0 + 0 0000000000019778 0000007a00000007 R_X86_64_JUMP_SLOT 0000000000010830 scalbn@@FBSD_1.0 + 0 26: 000000000000a020 13 FUNC GLOBAL DEFAULT 13 fabs@@FBSD_1.0 45: 00000000000104c0 315 FUNC GLOBAL DEFAULT 13 scalbnl@@FBSD_1.0 51: 000000000000a010 13 FUNC GLOBAL DEFAULT 13 fabsf@@FBSD_1.0 58: 0000000000009e80 118 FUNC GLOBAL DEFAULT 13 logb@@FBSD_1.0 74: 0000000000009ff0 30 FUNC GLOBAL DEFAULT 13 fabsl@@FBSD_1.0 78: 0000000000009e10 99 FUNC GLOBAL DEFAULT 13 logbf@@FBSD_1.0 84: 0000000000009f70 128 FUNC GLOBAL DEFAULT 13 fmax@@FBSD_1.0 111: 0000000000010600 212 FUNC GLOBAL DEFAULT 13 logbl@@FBSD_1.0 115: 0000000000009f00 106 FUNC GLOBAL DEFAULT 13 fmaxf@@FBSD_1.0 122: 0000000000010830 248 FUNC GLOBAL DEFAULT 13 scalbn@@FBSD_1.0 145: 00000000000106e0 142 FUNC GLOBAL DEFAULT 13 fmaxl@@FBSD_1.0 149: 0000000000010770 192 FUNC GLOBAL DEFAULT 13 scalbnf@@FBSD_1.0 141: 0000000000009e10 99 FUNC GLOBAL DEFAULT 13 logbf 142: 0000000000009e80 118 FUNC GLOBAL DEFAULT 13 logb 143: 0000000000009f00 106 FUNC GLOBAL DEFAULT 13 fmaxf 144: 0000000000009f70 128 FUNC GLOBAL DEFAULT 13 fmax 145: 0000000000009ff0 30 FUNC GLOBAL DEFAULT 13 fabsl 146: 000000000000a010 13 FUNC GLOBAL DEFAULT 13 fabsf 147: 000000000000a020 13 FUNC GLOBAL DEFAULT 13 fabs 250: 00000000000106e0 142 FUNC GLOBAL DEFAULT 13 fmaxl 251: 0000000000010600 212 FUNC GLOBAL DEFAULT 13 logbl 252: 00000000000104c0 315 FUNC GLOBAL DEFAULT 13 scalbnl 254: 0000000000010770 192 FUNC GLOBAL DEFAULT 13 scalbnf 257: 0000000000010830 248 FUNC GLOBAL DEFAULT 13 scalbn
And linking the GCC test case against it works now.