__udivdi3 undefined – 如何find使用它的代码?

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

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

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

我怎样才能find发布64位操作的代码。 他们很难find手动,因为我不能轻易地检查“/”是32位宽或64位宽。 如果“正常”函数未定义,我可以grep他们,但这是不可能的。 是否有另一种好的方法来search引用? 某种“机器码grep”?

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

首先,你可以使用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内核,我没有检查任何更低的用法

编译阶段后,你应该能够得到一些文件化的程序集,看看那些函数被调用。 尝试弄乱CFLAGS并添加-S标志。 汇编应该停止在汇编阶段。 然后,您可以grep在程序集文件中的有问题的函数调用。

实际上,在32位Linux内核支持64位整数除法和模数; 然而,你必须使用正确的宏来实现(哪一个取决于你的内核版本,因为最近新的更好的是创建IIRC)。 宏将以最有效的方式为正在编译的任何架构做正确的事情。

找到他们正在使用的最简单的方法是(如在@ shodanex的答案中所述)来生成汇编代码; IIRC,这样做的方式就像make directory/module.s (连同你必须传递的任何参数)。 下一个最简单的方法是反汇编.o文件(像objdump --disassemble )。 这两种方式都会为您提供调用正在生成的功能(如果您知道如何阅读程序集,可以了解该部门正在发生的功能)。