Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"__floatsidf" undefined warning when compiling kernel module

Tags:

c

linux-kernel

I was writing a loadable kernel module and when trying to compile it, the linker fails with the following message:

*** Warning: "__floatsidf" [/testing/Something.ko] undefined!

I am NOT using floating point variables, so that's not it. What is the cause of such errors?

Note: I'm using Linux ubuntu kernel v. 3.5.0-23-generic

like image 737
Varda Elentári Avatar asked Jun 21 '13 15:06

Varda Elentári


2 Answers

__floatsidf is a runtime routine to convert a 32-bit signed integer into a double precision floating point number. Somewhere in your project is a line that looks like:

double foo = bar;

Or something similar, where bar is a 32-bit integer. It could also be that you're calling one of the libm functions (or any other function, really) that expects a double with an integer parameter:

foo = pow(bar, baz);

where either bar or baz (or both) is an integer.

Without showing some code, there's not much more we can do to help.

To narrow it down, check the object files your compiler generates (before you link them) and look in the disassembly for a reference to that symbol - that should tell you what function it's happening in.

Here's an example of what I mean. First up - source code:

#include <math.h>

int function(int x, int y)
{
    return pow(x, y);
}

Pretty straightforward, right? Now, I'm going to compile it for ARM and disassemble:

$ clang -arch arm -O2 -c -o example.o example.c
$ otool -tV example.o 
example.o:
(__TEXT,__text) section
_function:
00000000    e92d40f0    push    {r4, r5, r6, r7, lr}
00000004    e28d700c    add r7, sp, #12
00000008    e1a04001    mov r4, r1
0000000c    ebfffffb    bl  ___floatsidf
00000010    e1a05000    mov r5, r0
00000014    e1a00004    mov r0, r4
00000018    e1a06001    mov r6, r1
0000001c    ebfffff7    bl  ___floatsidf
00000020    e1a02000    mov r2, r0
00000024    e1a03001    mov r3, r1
00000028    e1a00005    mov r0, r5
0000002c    e1a01006    mov r1, r6
00000030    ebfffff2    bl  _pow
00000034    ebfffff1    bl  ___fixdfsi
00000038    e8bd40f0    pop {r4, r5, r6, r7, lr}
0000003c    e12fff1e    bx  lr

Look at that - two calls to __floatsidf and one to __fixdfsi, matching the two conversions of x and y to double and then the conversion of the return type back to int.

like image 152
Carl Norum Avatar answered Nov 16 '22 04:11

Carl Norum


You are using floating point somewhere - your module includes a conversion from int to double. It might be as simple as calling a function that takes a double parameter and passing an int.

You could try searching your code for "double".

You could try compiling your module to assembly code and looking at that to find which function uses __floatsidf.

Remember that the use of double might be in a header file, possibly one written by someone else.

like image 22
user9876 Avatar answered Nov 16 '22 03:11

user9876