Problem with ld (?)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
heikki
Posts: 3
Joined: Fri Mar 31, 2006 12:00 am

Problem with ld (?)

Post 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...
blackcatcoder
Member
Member
Posts: 132
Joined: Wed Nov 03, 2004 12:00 am
Location: Austria
Contact:

Re: Problem with ld (?)

Post 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 ?
heikki
Posts: 3
Joined: Fri Mar 31, 2006 12:00 am

Re: Problem with ld (?)

Post 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 ]$              
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Re: Problem with ld (?)

Post 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
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Re: Problem with ld (?)

Post 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
heikki
Posts: 3
Joined: Fri Mar 31, 2006 12:00 am

Re: Problem with ld (?)

Post 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.
Post Reply