Page 1 of 1
undefined reference to `__umoddi3'
Posted: Sat Jun 22, 2013 7:07 am
by CocaCola
Hello.
I'm working on a 32-bit kernel. Some functions, for example
vsprintf() need to be able to print 64-bit integers.
However, when I try to use
uintmax_t or
uint64_t in the helper functions for
vsprintf() I get a linker error:
Code: Select all
libc/stdio/vsnprintf.o: In function `uint2cstr.part.0':
vsnprintf.c:(.text+0x40): undefined reference to `__umoddi3'
vsnprintf.c:(.text+0x66): undefined reference to `__udivdi3'
Adding
-lgcc -lc to the linker options does not work either:
Code: Select all
LDFLAGS := -T linker.ld -m elf_i386 -nostdlib -lgcc -lc
ld: cannot find -lgcc
ld: cannot find -lc
Should I try and write custom versions of these functions, or can they somehow be included still?
Thanks.
Re: undefined reference to `__umoddi3'
Posted: Sat Jun 22, 2013 7:15 am
by bluemoon
did you build libgcc yet?
Check the wiki:
GCC_Cross-Compiler
In some case, you may as well tell gcc the path of libgcc with -L
Re: undefined reference to `__umoddi3'
Posted: Sat Jun 22, 2013 7:44 am
by Griwes
-lc in kernel linker invocation is usually a sign you didn't RTFM.
Re: undefined reference to `__umoddi3'
Posted: Sat Jun 22, 2013 12:23 pm
by sortie
Note that due to the stupid way traditional Unix linking works, you have to put -lgcc after all libraries that could possibly use it (including libc).
The solution is, as previously pointed out, to build a full cross-compiler and use libgcc. The wiki has some information on transitioning to a cross-compiler at
http://wiki.osdev.org/Why_do_I_need_a_Cross_Compiler%3F
Re: undefined reference to `__umoddi3'
Posted: Fri Jun 28, 2013 9:48 am
by AbstractYouShudNow
These are functions from libgcc that allow it to perform 64-bit operations on a 32-bit processor.
This doesn't matter for addition or subtraction, because it can use the CARRY flag (ADD/ADC) on two 32-bit registers.
However, there is no hardware support for performing multiplication or division.
Typically, what you want to do is link to libgcc. For doing so, when building your GCC cross-compiler, once you have your target binutils instealled and target GCC configured, execute 'make all-target-libgcc' and 'make install-target-libgcc' to install it. After that, you should be able to use -lgcc option without getting errors.
More information on that on
The wiki article
Alternatively, if you don't want to use libgcc, you can implement them very simply using incremental calculation (e.g. 4*3 = 4+4+4) and simple loops. As an example, MikeOS uses that way to perform 32-bit operations on processors that are 16-bit (or more recent processors operating in real mode.