Bug 282705

Summary: Undefined symbols on armv7: "ld: error: undefined symbol: __truncdfsf2", "ld: error: undefined symbol: __nedf2", etc on the port graphics/oculante
Product: Base System Reporter: Yuri Victorovich <yuri>
Component: miscAssignee: freebsd-toolchain (Nobody) <toolchain>
Status: New ---    
Severity: Affects Only Me CC: dim, emaste, jfc
Priority: ---    
Version: 15.0-CURRENT   
Hardware: arm   
OS: Any   

Description Yuri Victorovich freebsd_committer freebsd_triage 2024-11-12 01:55:42 UTC
This port is a Rust port that also compiles some bundled C++ code.

Sample log: https://pkg-status.freebsd.org/ampere2/data/main-armv7-default/p711a2f7f1ca4_s0d965bc034/logs/oculante-0.9.1.log

These failures only occur on 15 (main-armv7-default) and not on 14 and 13.
Comment 1 Ed Maste freebsd_committer freebsd_triage 2024-11-12 13:29:07 UTC
In lib/libcompiler_rt/Makefile:

# These are already shipped by libc.a on some architectures.
.if ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "riscv"
...
SRCF+=          truncdfsf2

In lib/libc/softfloat/Symbol.map:

FBSDprivate_1.0 {
...
        __truncdfsf2;

I'm not sure where the implementation supposedly provided by libc comes/came from.
Comment 2 Dimitry Andric freebsd_committer freebsd_triage 2024-11-15 12:48:30 UTC
(In reply to Ed Maste from comment #1)
These are all in lib/libc/softfloat. However, the main libc Makefile has:

.if (${LIBC_ARCH} == "arm" && (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))
.include "${LIBC_SRCTOP}/softfloat/Makefile.inc"
.endif

so it won't apply to arm CPUs with hardware floating point support. As far as I remember, the "# These are already shipped by libc.a on some architectures." comment has always been in the compiler-rt Makefile.inc.

In fact, they were there when Ed Schouten imported the libcompiler-rt build infra in <https://cgit.freebsd.org/src/commit/?id=a3cf0ef5a295c>.

It might be good to check with somebody who knows 32-bit arm, if we can change the check in Makefile.inc to be similar to the one in libc's Makefile, so these functions are included in compiler-rt from that point onward.
Comment 3 Dimitry Andric freebsd_committer freebsd_triage 2024-11-15 18:00:57 UTC
Looks like the rabbit hole goes a little deeper. We already compile VFP versions of these, via the Makefile.inc fragment:

.for file in ${SRCF}
.if ${MACHINE_CPUARCH} == "arm" && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") \
    && exists(${CRTSRC}/${CRTARCH}/${file}vfp.S)
SRCS+=          ${file}vfp.S
. elif exists(${CRTSRC}/${CRTARCH}/${file}.S)
SRCS+=          ${file}.S
. else
SRCS+=          ${file}.c
. endif
.endfor

In contrib/llvm-project/compiler-rt/lib/builtins/arm there are:

adddf3vfp.S
addsf3vfp.S
divdf3vfp.S
divsf3vfp.S
extendsfdf2vfp.S
fixdfsivfp.S
fixsfsivfp.S
floatsidfvfp.S
floatsisfvfp.S
muldf3vfp.S
mulsf3vfp.S
subdf3vfp.S
subsf3vfp.S
truncdfsf2vfp.S

and a bunch more. However, llvm does not emit these on FreeBSD. In contrib/llvm-project/llvm/lib/Target/ARM/ARMISelLowering.cpp there is:

ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
                                     const ARMSubtarget &STI)
...
  if (Subtarget->isTargetMachO()) {
    // Uses VFP for Thumb libfuncs if available.
    if (Subtarget->isThumb() && Subtarget->hasVFP2Base() &&
        Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) {
      static const struct {
        const RTLIB::Libcall Op;
        const char * const Name;
        const ISD::CondCode Cond;
      } LibraryCalls[] = {
        // Single-precision floating-point arithmetic.
        { RTLIB::ADD_F32, "__addsf3vfp", ISD::SETCC_INVALID },
        { RTLIB::SUB_F32, "__subsf3vfp", ISD::SETCC_INVALID },
        { RTLIB::MUL_F32, "__mulsf3vfp", ISD::SETCC_INVALID },
        { RTLIB::DIV_F32, "__divsf3vfp", ISD::SETCC_INVALID },
...

I am unsure whether the VFP routines are ABI compatible with the non-VFP ones. If they are, we could alias them somehow. If they are not, we should stop compiling the VFP versions, and compile the regular versions.
Comment 4 John F. Carr 2024-11-15 19:09:50 UTC
Is the code using the wrong target, soft floating point (armv7-freebsd) instead of hardware FP (armv7-freebsd-gnueabihf)?  See, for example, bug 272806 and https://lists.freebsd.org/archives/freebsd-arm/2023-August/002933.html and replies.  FreeBSD-CURRENT no longer supports ARM versions older than armv7.