dme*_*ter 18 c linux kernel linux-kernel
在32位Linux内核上编译内核模块会导致
"__udivdi3" [mymodule.ko] undefined!
"__umoddi3" [mymodule.ko] undefined!
Run Code Online (Sandbox Code Playgroud)
在64位系统上一切都很好.据我所知,原因是32位Linux内核不支持64位整数除法和模数.
如何找到发出64位操作的代码.它们很难手动找到,因为我无法轻易检查"/"是32位宽还是64位宽.如果"正常"函数未定义,我可以grep它们,但这不可能在这里.还有另一种搜索引用的好方法吗?某种"机器代码grep"?
该模块由几千行代码组成.我真的不能手动检查每一行.
Has*_*kun 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 */
}
Run Code Online (Sandbox Code Playgroud)
此外,您应该能够在代码中找到long long int(或uint64_t)类型的用法,或者,您可以-g使用标志构建模块并使用objdump -S来获取源注释的反汇编.
注意:这适用于2.6内核,我没有检查任何更低的用法
实际上, 32 位 Linux 内核支持64位整数除法和取模;但是,您必须使用正确的宏来执行此操作(哪些宏取决于您的内核版本,因为最近创建了新的更好的 IIRC)。无论您针对哪种架构进行编译,宏都会以最有效的方式执行正确的操作。
找到它们的使用位置的最简单方法是(如 @shodanex 的答案中所述)生成汇编代码;IIRC,这样做的方法类似于make directory/module.s(以及您已经必须传递给的任何参数make)。下一个最简单的方法是反汇编.o文件(使用类似的方法objdump --disassemble)。这两种方式都会为您提供生成调用的函数(并且,如果您知道如何阅读汇编,则可以了解函数内发生除法的位置)。
| 归档时间: |
|
| 查看次数: |
15954 次 |
| 最近记录: |