Page 1 of 1

Very strange GCC/Linker problem!

Posted: Fri Dec 08, 2006 12:14 am
by chorakm
Hi! I got really interested in OS development and wanted to make a simple kernel. I noticed a very strange and annoying case with gcc and ld. Say I create a function called strlen() to calculate the length of a string that is passed to it. If I create the string using a literal string like...

char string[] = "Hello World!";
strlen(string);

and then I pass it to the function, the program goes from normally compiling to about 8kb to about 1.0mb!!! And then when I try to load the kernel with GRUB, it says that it's an invalid kernel. Here is an interesting case however, If I initialize the string like this

char string[16];

string[0] = 'H';
string[1] = 'e';
and so on

and then I append it with
string[x] = 0 (Null terminator)
strlen(string);

And compile, the code compiles back down to 8kb and is successfully loaded by GRUB. The interesting thing is that the program will not increase in size and become corrupt if I merely declare the variable:

char string[16] = "Hello World!";

But it happens when I pass the variable to a function, i.e. strlen (that I have created). I believe it has something to do with the stack but I don't have enough knowledge in this area and I was wondering if someone could give me some insight! I am using a linker script.

http://www.osdever.net/bkerndev/Docs/intro.htm

This is the site that I'm following, so the source code I'm using is basically exactly what he has, except edited a bit because he sucks at proof reading :-P. Thanks for the help!

Posted: Fri Dec 08, 2006 12:57 am
by Solar
Rule 0, the chance of you finding a bug in the compiler or linker is next to non-existent. Look for an error of your own.

The usual suspects:
  • Strings usually end up in a different section of the binary (.rodata).
  • Sections are usually page-aligned. Adding a section to the binary significantly increases its size, at least when the binary is very small still.
  • Learn to use objdump, it is a great help with many debugging problems.
You may also have mis-edited some code. Never say "it's like that, just different"...

Posted: Fri Dec 08, 2006 4:39 am
by urxae
My educated guess: You forgot to add .rodata to your linker script (you are using a linker script, aren't you?)

That would be the first option Solar mentioned, by the way.
And I second his suggestion to learn to use objdump, it's a very useful tool.

Great!

Posted: Fri Dec 08, 2006 1:15 pm
by chorakm
That is getting me on the right track! I searched google high and low for documentation on ld scripts and the different sections. I'm assuming rodata is read only data but I'm having trouble finding any documentation on explanations of the different sections, and generally how to create linker scripts in general. If anyone could point me to some resources that would be great. I.e. How did you come across the knowledge of the different sections?

Woooh!

Posted: Fri Dec 08, 2006 2:13 pm
by chorakm
Guys I have to thank you. You steered me in the right direction about the rodata section. I added that, my kernel compiles correctly, and can display text onto the string! Woooh exciting! Hahah, thanks a lot guys!