Page 1 of 1

Problem with ld (?)

Posted: Mon Apr 03, 2006 11:00 pm
by heikki
Hello, there is a newbies problem:

I'm writting a small "hello world" operating system according to this-howto. Now I have problem with my linker (ld):
This is my main.c:

Code: Select all

#include "include/system.h" /* just extern int strlen(char *str); */

int strlen(char *str)
{
    /* This loops through character array 'str', returning how
    *  many characters it needs to check before it finds a 0.
    *  In simple words, it returns the length in bytes of a string */
    int retval;
    for(retval = 0; *str != '\0'; str++) retval++;
    return retval;
    /* I have tried my own strlen function but it didn't help, this is a copy from howto */
}

/* This is a very simple main() function. */
void main()
{
    int i= strlen("Hello");
    /* ...and leave this loop in. There is an endless loop in
    *  'start.asm' also, if you accidentally delete this next line */
    for (;;);
}
Now when I compile my "kernel", gcc and nasm seems to work (there are main.o and start.o binary files), but when ld links these files, the result is 1MB plain text file which includes just "Hello"-string. If I remove line int i = strlen("Hello"); result is correct (4kB binary and it works).

I have same problem with every other functions which takes a char* parameter. If I use that parameter in the function, result is similar plain text file.

And my Makefile:

Code: Select all

all:
	nasm -f aout -o start.o start.asm
	gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -fleading-underscore -finline-functions -nostdinc -fno-builtin -c -o main.o main.c
	ld -T link.ld -o kernel.bin main.o start.o
Link.ld is same than in the howto: link.ld.
And start.asm is similar than in the howto: start.asm (I have just added extern _main and call _main).

I have tried to update my ld (bintools-package) but it didn't work. I tried versions 2.15.92.0.2-r10, 2.16.1-r2 and 2.16.91.0.7. My gcc is version 3.4.5-r1 (I have tried version 3.3). System is Gentoo Linux.


So have I done something wrong or is it a ld's bug? I have used Google but i havn't found any similar problems...

Re: Problem with ld (?)

Posted: Mon Apr 03, 2006 11:00 pm
by blackcatcoder
try to use this for strlen:

int strlen(char *string)
{
int count=0;
while(string[count] != '\0')
{
count++;
}

return count;

}


hmm.. does ld gives you any error messages or warnings ?

Re: Problem with ld (?)

Posted: Mon Apr 03, 2006 11:00 pm
by heikki
I tried, and it didnt help.

Ld doesn't give me any errors:

Code: Select all

[heikki (14:01:49):~/ohjelmointi/kernu ]$make
nasm -f aout -o start.o start.asm
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -fleading-underscore -finline-functions -nostdinc -fno-builtin -c -o main.o main.c
main.c:20: warning: return type of 'main' is not `int'
main.c: In function `main':
main.c:21: warning: unused variable `i'
ld -T link.ld -o kernel.bin main.o start.o
[heikki (14:01:50):~/ohjelmointi/kernu ]$              

Re: Problem with ld (?)

Posted: Mon Apr 03, 2006 11:00 pm
by carbonBased
You're link script looks faulty to me.

Take a look at the data section:

Code: Select all

  
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
To me, this says place data section at:
=phys + (data - code)
=0x100000 + (data - 0x100000)
Given that data isn't defined at the point of this equation:
=0x100000 + (0 - 0x100000)
=0

As such, your code is being put at 1mb, and your data is being placed right at 0, and padded with NULLs.

I would suggest using a link script simliar to the one in my GRUB tutorial (http://www.neuraldk.org/document.php?grubKernel):

Code: Select all

SECTIONS {
  .text 0x00100000 :{
    *(.text)
  }
  textEnd = .;
  .data :{
    *(.data)
    *(.rodata)
  }
  dataEnd = .;
  .bss :{
    *(.common)
    *(.bss)
  }
  bssEnd = .;
}
This defines the code segment at the same location, and the others simply follow afterwards (ld will place sections after each other unless you tell it otherwise). If you want, you can also insert your 4kb alignment directives, as well.

--Jeff

Re: Problem with ld (?)

Posted: Mon Apr 03, 2006 11:00 pm
by carbonBased
By the way, the reason your line:

int i= strlen("Hello");

Triggers this behaviour is because this is the only line that actually includes data that isn't placed on the stack. "Hello" is a string which would be contained within the .data section, and hense forces LD to include that section, thus creating the 1MB padding inbetween in order to ensure both .data and .code are included in the resultant object.

Also, it should be noted that I really doubt the file has *nothing* other then the string... you're probably viewing it in an app which is interpretting \0 as the end of buffer, perhaps?

--Jeff

Re: Problem with ld (?)

Posted: Tue Apr 04, 2006 11:00 pm
by heikki
Thank you carbonBased... now it seems to work!

I had looked my output file in KHexEdit, and just scrolled it down too fast. Now I reviewed it and I found some other binary data.

I'll read your tutorial soon.