__udivdi3 undefined - 如何找到使用它的代码?

时间:2009-06-30 13:07:31

标签: c linux linux-kernel kernel

在32位Linux内核上编译内核模块导致

"__udivdi3" [mymodule.ko] undefined!
"__umoddi3" [mymodule.ko] undefined!

64位系统上的一切都很好。据我所知,原因是32位Linux内核不支持64位整数除法和模数。

如何找到发出64位操作的代码。它们很难手动找到,因为我无法轻易检查“/”是32位宽还是64位宽。如果“正常”函数未定义,我可以grep它们,但这不可能在这里。还有另一种搜索引用的好方法吗?某种“机器代码grep”?

该模块由几千行代码组成。我真的不能手动检查每一行。

3 个答案:

答案 0 :(得分:21)

首先,您可以使用do_div宏进行64位除法。 (请注意原型为uint32_t do_div(uint64_t dividend, uint32_t divisor),并且可能会多次评估“dividend”。

{
    unsigned long long int x = 6;
    unsigned long int y = 4;
    unsigned long int rem;

    rem = do_div(x, y);
    /* x now contains the result of x/y */
}

此外,您应该能够在代码中找到long long int(或uint64_t)类型的用法,或者您可以使用-g标记构建模块并使用objdump -S获取源注释反汇编。

注意:这适用于2.6内核,我没有检查任何较低的使用情况

答案 1 :(得分:4)

编译阶段之后,您应该能够获得一些文档化的程序集,并查看是否调用了这些函数。尝试搞乱CFLAGS并添加-S标志。 编译应在装配阶段停止。然后,您可以在汇编文件中grep for违规函数调用。

答案 2 :(得分:3)

实际上,在32位Linux内核中支持64位整数除法和模 ;但是,您必须使用正确的宏(这取决于您的内核版本,因为最近新的更好的宏创建了IIRC)。对于您正在编译的任何体系结构,宏都将以最有效的方式执行正确的操作。

查找它们使用位置的最简单方法是(如@ shodanex的答案中所述)生成汇编代码; IIRC,这样做的方式类似于make directory/module.s(以及您必须传递给make的任何参数)。下一个最简单的方法是反汇编.o文件(类似objdump --disassemble)。这两种方式都将为您提供生成调用的函数(如果您知道如何阅读汇编,则可以了解函数在函数内的位置)。