undefined reference to __udivdi3
During the last month I have been playing with real-time scheduling in the Linux kernel. Basically, I’ve downloaded the SCHED_DEADLINE implementation from their git repository and did some changes in some files in order to understand better how real-time task scheduling can be handled in Linux.
I used a 64-bit machine with Ubuntu and Eclipse CDT version to implement my modifications. You may wonder why did I use Eclipse? The answer to that is simply: Eclipse is one of the best tools that I know that besides being an excellent IDE (Integrated Development Environment) it has great code indexing and cross-reference capabilities. Moving on to the subject of this post, in my 64-bit machine I’m able to compile the modified version of kernel without any kind of problems but I’m not able to run my version. After some discussion with an expert in the subject, he told me that probably I wasn’t compiling the correct modules that would allow me to run the OS without any problems. After some thoughts on the subject, I decided to compile the same modified version in a 32-bit machine which I wasn’t using anymore, to see if I was able to, at least, run my modified version of the Linux kernel.
I confess that initially I thought that the compilation process would be smooth, but I got surprised when the code didn’t compile and gcc threw the error undefined reference to __udivdi3.
After some googling, I discovered that the error was thrown in a line where a division involving u64 data types was being conducted. Indeed I’ve found some good pointers to the problem, namely:
So, it looks like the problem is caused by a compatibility problem between the kernel sources and gcc v4.3. Well, that would make sense initially when I was using that version in the 32-bit machine. But after an upgrade of the gcc version to 4.4.3, I still get the error in my 32-bit machine and surprisingly with the same version in my 64-bit machine it compiles smoothly. So, is the error related to the machine’s architecture? Let’s see each machine’s architecture:
64-bit machine architecture: “model name : AMD Turion(tm) X2 Dual-Core Mobile RM-74”
32-bit machine architecture: “model name : Intel(R) M processor 1.60GHz”
After some googling (once again), I’ve found this thread that somehow fundaments my suspicions:
Indeed it was an architecture issue. After modifying my code, by using the do_div function to perform a 64 bit division in a 32-bit architecture, the code compiled like a charm.
Regarding this type of operations, the following pointer is also helpful: http://www.captain.at/howto-udivdi3-umoddi3.php
And now let’s run the kernel ;).