Page 1 of 2

(Solved) 64 bit integer division

Posted: Fri Aug 18, 2017 7:40 am
by Octacone
Hey everyone.
I am having some problems with my print function. I tried to make a function that would print 64 bit integers, but GCC is not on my side.

Code: Select all

VGA.cpp:(.text+0x8e2): undefined reference to `__umoddi3'
VGA.cpp:(.text+0x902): undefined reference to `__udivdi3'
After some deeper investigation, I found out that GCC is very scared of 64 bit numbers and that it relies on libgcc, which I don't have/don't want to have.
So what are my options? I do not want to port any third party code.
How am I supposed to divide 64 bit numbers? I will also need this for my physical memory manager. (PAE section).
I will need both normal and modular division.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 7:52 am
by xenos
The standard way is using libgcc. It is an integral part of gcc, and gcc is not designed to work without it. Would you elaborate why you are not using it (but still want to use the pure compiler part of gcc without its companion library)?

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 8:08 am
by iansjack
Alternatively, you could use a different compiler.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 8:23 am
by LtG
Octacone wrote: After some deeper investigation, I found out that GCC is very scared of 64 bit numbers and that it relies on libgcc, which I don't have/don't want to have.
So what are my options? I do not want to port any third party code.
We've pretty much been here before. I don't understand how you find the use of GCC not "third party code", yet it's integral library is "third party code".

I mean, you realize GCC itself is code and it generates code for you. Some of the things it generates are "hard coded" into the GCC executables itself and some are in other files, like libgcc. The point I'm making is that the code that GCC uses to generate the code you want is split into more than one file and one of those files is libgcc.

What is the distinction you create between "gcc" and "libgcc"? It's part of the same thing. It seems like you want to use GCC provided division (eg. using GCC code for division), yet you don't want to use it because it's third party.

GCC also creates code for you for the assignments in your code, etc, I'd say that's pretty much as third party as the division. So, either you use GCC (or some other compiler, where they may have included the division in the main executable instead of a library) or you should start writing your own compiler if you don't want _any_ third party code.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 8:49 am
by Octacone
@XenOS @iansjack

What do you guys mean by internal? Already inside the compiler itself? So that means I don't have to actually port it, file by file.
Looks like I've been misinformed.
Then why can't GCC find it? Is there something special I have to do in order to enable it (there must be a switch or something)?
But! What about my own C++ library, will I be able to link my own library against GCC, if libgcc is enabled? That is my main concern.

@LtG
When I mean third party, I don't mean using something, but rather actively porting file by file and interconnecting it with my OS in a way.
I actually never refer to GCC or anything compiler related when I use that construction.
Why I said third party? Because I thought I would have to spend like 20 hours porting something to my OS for GCC to use, thus third party.
Maybe it does sound weird, just so you know for the future reference.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 9:06 am
by davidv1992
Libgcc is essentially a collection of functions that emulate instructions that gcc's intermediate language has, but for which result in too bulky a bunch of assembly instructions to properly handle during instruction generation. It also handles some other stuff, but for os development, this first use is why you need libgcc.

The compiler build instructions in the wiki already contain the instructions as to how you can build libgcc. Following these instructions there are no dependencies beyond the standard functions you need to implement for a freestanding environment (see the gcc manual for those). As for using it, you will need to link against it when linking your kernel, which is typically done with -lgcc.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 9:27 am
by lkurusa
Did you build a cross-compiler? If not, this page is your friend: http://wiki.osdev.org/GCC_Cross-Compiler

GCC relies on libgcc for a fair amount of 64-bit work, so you can either implement the functions it asks for yourself (keep in mind, that this may AND WILL break if you change your compiler), or you can just link with libgcc (which is what GCC assumes).

As for your C++ library, I'm not sure what you mean by "linking against GCC" ? Did you mean "linking into your kernel"? If so, then there shouldn't be any problem. Just remember to call global constructors.

Good luck!

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 10:05 am
by Octacone
@davidv1992 @lev

I was using a pre-built cross compiler for a while actually, until this happened.
So I managed to build the latest GCC with all the necessary dependencies including libgcc.
I still refuses to work. I am getting the same error.
Here are my switches:

Code: Select all

-ffreestanding -nostdlib -lgcc -O2 -Wall -Wextra -fno-exceptions -fno-rtti -m32 -c -iquote /... -std=c++14
libgcc exists at: .../Opt/Cross/lib/gcc/i686-elf/7.2.0/libgcc.a

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 10:11 am
by lkurusa
I think you should put the "-lgcc" flag at the end...

Also, wait this is a compile line, how does your linking step look?

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 10:23 am
by Octacone
lev wrote:I think you should put the "-lgcc" flag at the end...

Also, wait this is a compile line, how does your linking step look?
I did, nothing changed.
Looks like there is something else that I am obviously missing.
Hmm...

Code: Select all

Linker = ld
Linker_Flags = -m elf_i386 -T Sources/Bootloader/Linker.ld
This is what my makefile looks like: //only the important section

Code: Select all

...
Assembler = nasm
Assembler_Flags = -f elf32
GPP_Flags = -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti -m32 -c -iquote /location -std=c++14 -nostdlib -lgcc
Linker = ld
Linker_Flags = -m elf_i386 -T Sources/Bootloader/Linker.ld
Objects = Objects/Bootloader.o Objects/Kernel.o ...
Raw_Output = GRUB/Basic\ OS.elf

Objects/Bootloader.o:Sources/Bootloader/Bootloader.asm 
	$(Assembler) $(Assembler_Flags) Sources/Bootloader/Bootloader.asm -o Objects/Bootloader.o

Objects/Kernel.o:Sources/Kernel/Kernel.cpp
	$(GPP) $(GPP_Flags) Sources/Kernel/Kernel.cpp -o Objects/Kernel.o

compile: $(Objects)
	$(Linker) $(Linker_Flags) -o $(Raw_Output) $(Objects)
...

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 1:41 pm
by lkurusa
You are not linking your final kernel object with libgcc.

This line,

Code: Select all

$(Linker) $(Linker_Flags) -o $(Raw_Output) $(Objects)
should say,

Code: Select all

$(Linker) $(Linker_Flags) -o $(Raw_Output) $(Objects) -lgcc
Hope this helps.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 2:18 pm
by Octacone
lev wrote:You are not linking your final kernel object with libgcc.

This line,

Code: Select all

$(Linker) $(Linker_Flags) -o $(Raw_Output) $(Objects)
should say,

Code: Select all

$(Linker) $(Linker_Flags) -o $(Raw_Output) $(Objects) -lgcc
Hope this helps.
ld: cannot find -lgcc
Looks like I can't use that linker.

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 2:21 pm
by lkurusa
Why is your linker ld? It should be the linker from the cross-compilers. (coming from binutils).

(Solved) 64 bit integer division

Posted: Fri Aug 18, 2017 2:54 pm
by Octacone
lkurusa wrote:Why is your linker ld? It should be the linker from the cross-compilers. (coming from binutils).
You are right. That was the main issue.
It is all good now.

Thank you guys for helping.

To other people in the future possibly reading this:
1.Make sure to follow: GCC Cross Compiler and do everything as stated.
2.Don't use GNU LD, use the compiler itself. Like this

Code: Select all

i686-elf-gcc (or -g++) -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc //Wiki example
//or in my case:
Linker = /path_to_your_cross_compiler/Opt/Cross/bin/i686-elf-g++
Linker_Flags = -T Sources/Bootloader/Linker.ld
$(Linker) $(Linker_Flags) -o $(Raw_Output) $(Objects) -ffreestanding -O2 -nostdlib -lgcc
That is basically how I fixed it.
This is the result:
64BitPrinting.png
64BitPrinting.png (813 Bytes) Viewed 5968 times
Being able to print 64 bit numbers. :D

Re: 64 bit integer division

Posted: Fri Aug 18, 2017 2:54 pm
by lkurusa
Excellent! Glad to hear it works.