我正在编写一个可加载的内核模块,当尝试编译它时,链接器失败并显示以下消息:
*** Warning: "__floatsidf" [/testing/Something.ko] undefined!
我没有使用浮点变量,所以不是这样。此类错误的原因是什么?
注意:我正在使用Linux ubuntu kernel v. 3.5.0-23-generic
我正在编写一个可加载的内核模块,当尝试编译它时,链接器失败并显示以下消息:
*** Warning: "__floatsidf" [/testing/Something.ko] undefined!
我没有使用浮点变量,所以不是这样。此类错误的原因是什么?
注意:我正在使用Linux ubuntu kernel v. 3.5.0-23-generic
__floatsidf
是将 32 位有符号整数转换为双精度浮点数的运行时例程。在您的项目中某处有一行如下所示:
double foo = bar;
或类似的东西,其中bar
是 32 位整数。也可能是您正在调用libm
期望 adouble
带有整数参数的函数之一(或任何其他函数,实际上):
foo = pow(bar, baz);
其中一个bar
或baz
(或两者)是整数。
如果不显示一些代码,我们就无能为力了。
要缩小范围,请检查编译器生成的目标文件(在链接它们之前)并在反汇编中查看对该符号的引用——这应该告诉你它发生在什么函数中。
这是我的意思的一个例子。首先 - 源代码:
#include <math.h>
int function(int x, int y)
{
return pow(x, y);
}
很简单,对吧?现在,我将为 ARM 编译它并反汇编:
$ 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
看一下 - 两次调用 to__floatsidf
和一次 to __fixdfsi
,匹配 and 的两次转换,x
然后将返回类型转换回y
to 。double
int
您在某处使用浮点数 - 您的模块包含从int
to的转换double
。它可能就像调用一个带double
参数的函数并传递一个int
.
您可以尝试在您的代码中搜索“double”。
您可以尝试将您的模块编译为汇编代码并查看它以找到使用的函数__floatsidf
。
请记住,double
可能在头文件中使用 ,可能是由其他人编写的。