Вопрос по linux, kernel, c – __udivdi3 не определено - как найти код, который его использует?

17

Компиляция модуля ядра в 32-битном ядре Linux приводит к

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

Все хорошо на 64-битных системах. Насколько я знаю, причина этого в том, что 64-разрядное целочисленное деление и модуль не поддерживаются в 32-разрядном ядре Linux.

Как мне найти код выдачи 64-битных операций. Их трудно найти вручную, потому что я не могу легко проверить, есть ли & quot; / & quot; имеет ширину 32 бита или ширину 64 бита. Если & quot; нормальный & quot; функции не определены, я могу grep их, но здесь это невозможно. Есть ли другой хороший способ поиска по ссылкам? Какой-то "машинный код grep"?

Модуль состоит из нескольких тысяч строк кода. Я действительно не могу проверить каждую строку вручную.

Ваш Ответ

3   ответа
4

сборку и посмотреть, как эти функции вызываются. Попробуйте возиться с CFLAGS и добавьте флаги -S. Компиляция должна быть остановлена на этапе сборки. Затем вы можете использовать grep для вызывающего вызов функции в файле сборки.

3

are поддерживается в 32-битном ядре Linux; однако для этого вы должны использовать правильные макросы (которые зависят от версии вашего ядра, так как недавно были созданы новые более качественные макросы IIRC). Макросы будут делать правильные вещи наиболее эффективным способом для любой архитектуры, для которой вы компилируете.

Самый простой способ найти, где они используются (как указано в ответе @ shodanex), - сгенерировать код сборки; IIRC, способ сделать это что-то вродеmake directory/module.s (вместе с какими параметрами вы уже должны передатьmake). Следующий самый простой способ - разобрать.o файл (с чем-то вродеobjdump --disassemble). Оба способа дадут вам функции, где генерируются вызовы (и, если вы знаете, как читать сборку, общее представление о том, где внутри функции происходит разделение).

21

do_div макро. (обратите внимание, что прототипuint32_t do_div(uint64_t dividend, uint32_t divisor) и это & quot;dividend& Quot; может оцениваться несколько раз.

{
    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 чтобы получить источник аннотированной разборки.

note: это относится к ядрам 2.6, я не проверял использование для чего-либо ниже

@WilliBallenthin даже после использования & lt; asm / div64.h & gt; , сталкивайтесь с этой проблемой. так кто-нибудь предлагает мне, что нужно сделать, чтобы решить эту проблему?
@ Джордан:-g флаг для GCC (поэтому объект включает в себя отладочную информацию) и принадлежит вCFLAGS_MODULEError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded__udivdi3 и т.д. Их легко реализовать, и если вы сделаете это в asm, они будут намного эффективнее, чем версии libgcc (возможно, в 2-3 раза быстрее).
@Jordan: я не могу подтвердить это, но IIRCobjdump -SrError: User Rate Limit Exceeded__udivdi3 там.

Похожие вопросы