Re: (arm64) link_elf: symbol __floatundidf undefined ...
- In reply to: Dimitry Andric : "Re: (arm64) link_elf: symbol __floatundidf undefined ..."
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 26 May 2025 13:24:32 UTC
On 26 May 2025, at 15:15, Dimitry Andric <dim@FreeBSD.org> wrote:
>
> On 26 May 2025, at 15:05, Bjoern A. Zeeb <bzeeb-lists@lists.zabbadoz.net> wrote:
>>
>> On Mon, 26 May 2025, Dimitry Andric wrote:
>>
>> Hi,
>>
>> thanks for the quick answer.
>>
>>> On 26 May 2025, at 14:25, Bjoern A. Zeeb <bzeeb-lists@lists.zabbadoz.net> wrote:
>>>>
>>>> I've just compiled and installed a new arm64/main with my own kernel
>>>> config to have wifi bits as modules.
>>>>
>>>> I am a bit puzzed as to where this comes from in the kernel.
>>>>
>>>> # kldload wlan
>>>> link_elf: symbol __floatundidf undefined: 0xffff000143ed1370 0xffff000143ecf9f0 11496 0xffff000143ed26d8 0x2
>>>> kldload: can't load wlan: No such file or directory
>>>>
>>>> % nm modules/usr/src/sys/modules/wlan/wlan.ko.full | grep float
>>>> U __floatundidf
>>>>
>>>> Anyone any idea?
>>>
>>> _Something_ is converting a unsigned long to a double, but what? Can you figure out which object file it is?
>>
>> % nm ieee80211_ioctl.o | grep __floatundidf
>> U __floatundidf
>>
>> This may be a local change I have adding an extra 10% of space in the
>> ioctl code to accomodate for enlargement of a result set for testing.
>> size_t space;
>> ...
>> space *= 1.10;
>>
>> Given it's likely that it's that I think the real question is, why is this
>> not an issue on amd64 but on arm64 as I've been running that change for
>> days on amd64?
>
> My guess is that it's inlined on amd64. For me simple cases also inline on arm64, but maybe you are doing something more complicated:
>
> $ cat convert.c
> #include <stddef.h>
>
> size_t f(size_t s)
> {
> return s * 1.10;
> }
>
> $ cc -target aarch64-freebsd -S convert.c -o -
> .text
> .file "convert.c"
> .section .rodata.cst8,"aM",@progbits,8
> .p2align 3, 0x0 // -- Begin function f
> .LCPI0_0:
> .xword 0x3ff199999999999a // double 1.1000000000000001
> .text
> .globl f
> .p2align 2
> .type f,@function
> f: // @f
> .cfi_startproc
> // %bb.0: // %entry
> sub sp, sp, #16
> .cfi_def_cfa_offset 16
> str x0, [sp, #8]
> ldr d0, [sp, #8]
> ucvtf d0, d0
> adrp x8, .LCPI0_0
> ldr d1, [x8, :lo12:.LCPI0_0]
> fmul d0, d0, d1
> fcvtzu x0, d0
> add sp, sp, #16
> .cfi_def_cfa_offset 0
> ret
> .Lfunc_end0:
> .size f, .Lfunc_end0-f
> .cfi_endproc
> // -- End function
> .ident "FreeBSD clang version 19.1.7 (https://github.com/llvm/llvm-project.git llvmorg-19.1.7-0-gcd708029e0b2)"
> .section ".note.GNU-stack","",@progbits
> .addrsig
Aha, the behavior changes when you use -mgeneral-regs-only (as in https://cgit.freebsd.org/src/tree/sys/conf/kern.mk#n140):
f: // @f
.cfi_startproc
// %bb.0: // %entry
stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
.cfi_def_cfa_offset 16
mov x29, sp
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
bl __floatundidf
mov x1, #-7378697629483820647 // =0x9999999999999999
movk x1, #39322
movk x1, #16369, lsl #48
bl __muldf3
bl __fixunsdfdi
.cfi_def_cfa wsp, 16
ldp x29, x30, [sp], #16 // 16-byte Folded Reload
.cfi_def_cfa_offset 0
.cfi_restore w30
.cfi_restore w29
ret
Hence, try to refrain from using doubles. :) Your use case should also be covered with:
space = (space * 110 + 50) / 100
-Dimitry