Still problems when cross-compiling

Programming, for all ages and all languages.
Post Reply
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Still problems when cross-compiling

Post by Tomaka17 »

Hello,

I'm still having troubles with this ******* cross-compiler :(


I followed these guidelines: http://wiki.osdev.org/OS_Specific_Toolchain
And managed to build a (non-working) linux-to-myos binutils, compiler and libc

But I still have questions/problems:



1. I have the binaries i586-pc-myos-gcc, i586-pc-myos-as, i586-pc-myos-ld, etc. but not i586-pc-myos-cc
Why ?


2. When I compile a simple 'hello world' program using these command lines
i586-pc-myos-gcc -c -o main.o main.c
i586-pc-myos-ld -o helloworld main.o
The linker complains about an unresolved symbol 'printf'
I have to manually add:
i586-pc-myos-ld -o helloworld main.o /usr/i586-pc-myos/lib/libc.a
I can't tell if this work as I haven't finished implementing all the syscalls yet (I'm getting unresolved symbols for functions I have to implement)
But the question is: why do you have to manually tell the linker to include libc.a despite you don't have to when using the normal linker?


3. I typed autoscan ; mv configure.scan configure.am ; autoconf
I now have a classical unix-like source tree
When I try using:
./configure --host=i586-pc-myos
I get an error:
/usr/lib/gcc/i586-pc-myos/4.3.2/../../../../i586-pc-myos/bin/ld: cannot find -lgcc
ie: /usr/i586-pc-myos/bin/ld: cannot find -lgcc
I don't really know what this means :-/



4. Before the problem number 3, I had also the configure script complaining about not finding crtbegin.o
I compiled an empty crtbegin.s as I already had a crt0.o as described here: http://wiki.osdev.org/OS_Specific_Toolchain#crt0.S
I notice we tell GCC to include crtbegin.o and crtend.o (http://wiki.osdev.org/OS_Specific_Toolc ... config.gcc)
But why does the configure script not complain about not finding crtend.o?
And why does he complain about crt0.o if I remove it? We don't tell it anywhere to include crt0.o
And why did it not complain at step 2? crtbegin.o didn't exist at the moment



Thanks in advance :-/


EDIT : typo
Last edited by Tomaka17 on Thu Jan 15, 2009 4:34 am, edited 2 times in total.
MysteriOS
Currently working on: TCP/IP
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Still problems when cross-compiling

Post by Solar »

Haven't tried myself at the OS Specific Toolchain yet, so some of this is guesswork, but...
Tomaka17 wrote:1. I have the binaries i586-pc-myos-gcc, i586-pc-myos-as, i586-pc-myos-ld, etc. but not i586-pc-myos-cc
Why ?
Not sure, but in a normal system, /usr/bin/cc and /usr/bin/gcc are identical (hardlink).
why do you have to manually tell the linker to include libc.a despite you don't have to when using the normal linker?
Configuration of the linker / compiler, I'd guess. (I.e., something missing from the tutorial.)
/usr/lib/gcc/i586-pc-myos/4.3.2/../../../../i586-pc-myos/bin/ld: cannot find -lgcc
ie: /usr/i586-pc-myos/bin/ld: cannot find -lgcc
I don't really know what this means :-/
It cannot find libgcc.a, a support library that comes with GCC.
why does he complain about crt0.o if I remove it? We don't tell it anywhere to include crt0.o
crt0.o is the runtime environment for a C executable. There is no way an executable could work without it (while it might work fine without e.g. libc.a).

Can't help you with the other questions, though. Perhaps anyone who actually folowed that tutorial can help...?
Every good solution is obvious once you've found it.
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Re: Still problems when cross-compiling

Post by Tomaka17 »

Thank you for your answers

I found out that the directory /usr/lib/gcc/i486-linux-gnu/4.1.2 contains a lot of files including:
libgcc.a, crtbegin.o, crtend.o, libstdc++.o
While /usr/lib/gcc/i586-pc-myos/4.3.2 contains only .h files

I think this directory is included by default in LD, this is certainly the place where it founds its libraries

Just to try it, I copied libgcc.a and crtend.o to the second directory
(I copied crtend.o because it started complaining about not finding it, which is an answer to one of my questions)

Now it complains about syscalls I didn't implement yet... I'm working on it
MysteriOS
Currently working on: TCP/IP
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Still problems when cross-compiling

Post by Solar »

libgcc, libstdc++ and the environment files require porting to your OS. Your syscalls might be different, your environment might be different, your whole architecture might be different...
Every good solution is obvious once you've found it.
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Re: Still problems when cross-compiling

Post by Tomaka17 »

Solar wrote:libgcc, libstdc++ and the environment files require porting to your OS. Your syscalls might be different, your environment might be different, your whole architecture might be different...
I understand this

I have been testing a lot of things since this morning, and apparently everything is working well if I simply rename libc.a to libgcc.a
For my question "why do you have to manually add libc.a when compling", I think the answer is "because gcc doesn't include by default libc.a but libgcc.a which it considers is the libc"
MysteriOS
Currently working on: TCP/IP
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Still problems when cross-compiling

Post by Solar »

Hmmmm...

Not sure what's going on there, but take note that libc and libgcc are two very, very different things.

libgcc - a GCC low-level runtime library containing functions like __divsi3(), _Unwind_RaiseException() or __clear_cache().

Opposed to that is libc (provided by e.g. the glibc, newlib, uclib or - hopefully some day - yours truly PDCLib), which contains functions like printf(), strcpy() or malloc().

Simply renaming one into the other means there has been a major screwup beforehand...
Every good solution is obvious once you've found it.
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Re: Still problems when cross-compiling

Post by Tomaka17 »

Yeah I realized I was totally wrong a few hours after my last post, but forgot to post here

In fact a forgot a "--prefix" option when reconfiguring newlib
Consequently, libc.a went to /usr/local/i586-etc. instead of /usr/i586-etc.
This is fixed now


What you need in fact for compiling with your cross-compiler is:
- libc, which I have now at the right place
- libgcc, which I don't have
- crt0.o, which only contains the _start symbol
- crtbegin.o and crtend.o, which are created by compiling an empty .s file

As a temporary solution, I copy-pasted linux's libgcc
Do I really have to compile one for my o/s?
According to the webpage you linked, you only need one libgcc per machine
If I'm compiling an i686 o/s with an i686 machine, I think I can simply copy-paste the existing libgcc

With that configuration, I managed to compile my "hello world!" program :D
I think everything is clear in my head now, thank you :)

The last thing I don't understand is the purpose of crtbegin and crtend?
They are not mentionned on the wiki despite you have to create them
MysteriOS
Currently working on: TCP/IP
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Re: Still problems when cross-compiling

Post by Tomaka17 »

Well, now I can compile anything I want and make it run with my O/S (and I'm proud of this :) )

But I've got a new problem
This is a little off-topic but I thought it's not worth creating a new thread

Here is the content of my small program:

Code: Select all

#include <stdio.h>

char* text = "OMG it's working!\r";

void main() {
	printf("testing printf\r");
	asm("int $0x65" : : "eax"(0x0), "ebx"(text));
	while(1) ;
}
The line under printf is of course a syscall

My problem is that the syscall works (I see written "omg it's working") but not the printf function

All my syscalls are for the moment minimal implementations copy-pasted from http://sourceware.org/newlib/libc.html#Syscalls
Except the write function:

Code: Select all

int write(int file, char *ptr, int len) {
        asm("int $0x65" :: "eax"(0x0), "ebx"(ptr));
        return len;
}
(this implementation is of course temporary, I know that this function can also be used to write content in real files)


I added a debug code on the kernel-side in case where the syscall would in fact be made but no text displayed (for some reason)

I also checked that the write function was really included into my executable file, and I can confirm it is

Code: Select all

08048250 <write>:
 8048250:       55                      push   %ebp
 8048251:       89 e5                   mov    %esp,%ebp
 8048253:       53                      push   %ebx
 8048254:       8b 5d 0c                mov    0xc(%ebp),%ebx
 8048257:       cd 65                   int    $0x65
 8048259:       8b 45 10                mov    0x10(%ebp),%eax
 804825c:       5b                      pop    %ebx
 804825d:       5d                      pop    %ebp
 804825e:       c3                      ret
 804825f:       90                      nop
Does somebody have an idea? :(
MysteriOS
Currently working on: TCP/IP
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Still problems when cross-compiling

Post by pcmattman »

stdout is, by default, buffered. So you need to output a newline ("\n") before the buffer is flushed and output to the screen.

Example:

Code: Select all

printf("testing printf\r\n");
EDIT: You can use the setvbuf (iirc) call to change the stdout characteristics. You can turn off buffering using that (useful for a shell on stdin/stdout).
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Still problems when cross-compiling

Post by Solar »

pcmattman wrote:stdout is, by default, buffered. So you need to output a newline ("\n") before the buffer is flushed and output to the screen.
If you want to play it safe (as it's not guaranteed that stdout is line-buffered), call fflush() after your printf(). If that doesn't help, your libc is borked.
Every good solution is obvious once you've found it.
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Re: Still problems when cross-compiling

Post by Tomaka17 »

It's working thank you :)
MysteriOS
Currently working on: TCP/IP
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Still problems when cross-compiling

Post by pcmattman »

@Solar - thanks for pointing that out. Portable code would require that, but newlib's behavior is to use buffering by '\n' (I've checked with the developers, as I had the exact same problem).

Using fflush as Solar advised is the best way to go for portability, and should newlib change behavior (for whatever reason) the portable method is the one that's most likely to work.

Either way, it's an easy mistake to make, and congrats on getting it working - nice having a libc for your OS applications, isn't it?
User avatar
Tomaka17
Member
Member
Posts: 67
Joined: Thu Oct 02, 2008 8:20 am

Re: Still problems when cross-compiling

Post by Tomaka17 »

and congrats on getting it working - nice having a libc for your OS applications, isn't it
When you see that the thousands of codelines you wrote are working, you feel really happy :D

Next objective is to port lynx :)
And then Doom :p but that will be a bit more complicated
MysteriOS
Currently working on: TCP/IP
Post Reply