Cross-Linker doesn't resolve references

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
Candamir

Cross-Linker doesn't resolve references

Post by Candamir »

I built a cross-compiler and "cross-binutils" and everything compiles and assembles neatly, and ld does recognize the input format of the object files (i386-elf). However, none of the C-to-ASM and ASM-to-C references would work. For example (ld output):

Code: Select all

start.o: In function 'StartInHigherHalf':
start.asm:(.text+0x4d): undefined reference to '_kmain'
C-to-C references (through *.h files) do work.
Has anyone had a similar problem?

Candamir
Candamir

Re:Cross-Linker doesn't resolve references

Post by Candamir »

I already solved the problem; it was all about the leading underscores that the cross-compiler didn't add to c-function names. The only thing I had to do is to remove leading underscores in every 'extern' and 'global' declaration in the ASM files...

Does anyone know why this happens?

Candamir
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Cross-Linker doesn't resolve references

Post by Solar »

Whether or not leading underscores are added is depending on the GCC configuration. For one platform they're added, for the other they aren't... I never bothered much about it; find out what your current toolchain does, adjust your Makefile and never think about it again...
Every good solution is obvious once you've found it.
mystran

Re:Cross-Linker doesn't resolve references

Post by mystran »

Normally leading underscores are not added on ELF targets, while on more traditional targets they are added.

But I guess this can be configured when compiling the toolchain..
Candamir

Re:Cross-Linker doesn't resolve references

Post by Candamir »

Anyway, I feel more comfortable without those underscores;)

But my next problem is that GRUB tells me it won't support loading anything below 1mb (error 7, IRC). I already checked HigherHalf BareBones in the FAQ, there was the hint I should use objdump, and it produced the following output:

Code: Select all


kernel.elf:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00001541  c0100000  00100000  00001000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001120  c0102000  00102000  00003000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          000048dc  c0103120  00103120  00004120  2**5
                  ALLOC
  3 .comment      00000159  00000000  00000000  00004120  2**0
                  CONTENTS, READONLY

This puzzles me, as my linker script is the following:

Code: Select all

...
OUTPUT_FORMAT(elf32-i386)
SECTIONS
{
    . = 0xC0100000;

    .text : AT(ADDR(.text) - 0xC0000000)
    {
        *(.text)
        *(.rodata*)
    }

    .data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
    {
        *(.data)
    }

    .bss : AT(ADDR(.bss) - 0xC0000000)
    {
        _sbss = .;
        *(COMMON)
        *(.bss)
        _ebss = .;
    }
}
No .comments section... I already tried to solve the problems by removing the -O3 flag from my gcc commands, but it didn't result...

Can this be solved by properly including the .comments section in the linker script? Would that have to be done before or after the BSS section?

Candamir
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:Cross-Linker doesn't resolve references

Post by Colonel Kernel »

Candamir wrote:No .comments section... I already tried to solve the problems by removing the -O3 flag from my gcc commands, but it didn't result...

Can this be solved by properly including the .comments section in the linker script? Would that have to be done before or after the BSS section?
You may have encountered a bug in the linker script. Try adding the .comments section in there and see if it fixes the problem...

What versions of GCC and binutils are you using?
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
mystran

Re:Cross-Linker doesn't resolve references

Post by mystran »

GCC adds those .comment sections most of the time. Here's what is says about my kernel:
kernel: file format elf32-i386

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00005340 00100000 00100000 00001000 2**5
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000204 00105340 00105340 00006340 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00009500 00106000 00106000 00007000 2**12
ALLOC
3 .note.GNU-stack 00000000 00000000 00000000 00007000 2**0
CONTENTS, READONLY
4 .comment 00000484 00000000 00000000 00007000 2**0
CONTENTS, READONLY
GRUB loads that fine. .note.GNU-stack and .comment don't have bits sets to actually load them, so this is no problem.

If you dump contents of .comment, you'll see that it just lists what GCC versions where used to compile each object file. Each object contains the .comment, and linker puts all of that, one after another, into the file, you strip the whole section (with strip) if you feel like it.

The .note.GNU-stack is AFAIK specific to Linux and/or GLibC and only gets there because I use stock Linux GCC to compile my kernel.

In any case, your section headers look about right to me.
Candamir

Re:Cross-Linker doesn't resolve references

Post by Candamir »

I'll see what I can do...

BTW, I noticed that in my dump, the .comment section had the same offset in the file than the .bss section. Isn't there any space included for the .bss section? Is this realized dynamically, during program execution?

I already checked the binutils manuals, and they describe the options for objdump, but not the output format... I feel that everything has something to do with the 'algn' section, because the algn value of .comment is lower than the value of .text; maybe the .text, .data and .bss sections are at correct positions, but the .comment section is placed in a lower memory offset than the previously named sections... ??? Could anyone please explain how to interpret the 'algn' values?

Thanks

Candamir
bkilgore

Re:Cross-Linker doesn't resolve references

Post by bkilgore »

Candamir wrote: I'll see what I can do...

BTW, I noticed that in my dump, the .comment section had the same offset in the file than the .bss section. Isn't there any space included for the .bss section? Is this realized dynamically, during program execution?
Since the .bss section is for uninitialized data, there's not need to waste space in the file for it. In the objdump output the only flag for this section is ALLOC, which tells whatever is loading the file that it needs to reserve space for this section, but it doesn't need to load anything from the actual file. Thus the comment section actually starts at that address and just contains information that is ignored at load time, so I don't see how any of this could actually be the problem.

I'd instead look to verify that you have a valid magicboot header and entry point and all of that, and that the file that contains this is linked correctly towards the beginning of the kernel (try puttign it first to be safe).
Candamir

Re:Cross-Linker doesn't resolve references

Post by Candamir »

Yes, I do have got my multiboot header correctly included at the very beginning of the .text section of the first file included in the linker (well, the object file later on produced by the assembler) and the part is 4-byte aligned... But if the multiboot header weren't included, that wouldn't be GRUB error 7 anyway, because that is what I'm getting.

Candamir
mystran

Re:Cross-Linker doesn't resolve references

Post by mystran »

What does mbchk say about your kernel?
Candamir

Re:Cross-Linker doesn't resolve references

Post by Candamir »

Excellent, I worked it out! The main error was that I used a very old version of GRUB (duh!:-[), updating my disk image fixed the problem. As to the .comment section, it didn't really matter, but I removed it anyway with the following linker script:

Code: Select all

...
OUTPUT_FORMAT(elf32-i386)
SECTIONS
{
    . = 0xC0100000;

    .text : AT(ADDR(.text) - 0xC0000000)
    {
        *(.text)
        *(.rodata*)
    }

    .data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
    {
        *(.data)
    }

    .bss : AT(ADDR(.bss) - 0xC0000000)
    {
        _sbss = .;
        *(COMMON)
        *(.bss)
        _ebss = .;
    }
    /DISCARD/ :
    {
        *(.comment)
    }
}
Sorry for bothering you and thank you for your comprehension,

Candamir
axelolsson

Re:Cross-Linker doesn't resolve references

Post by axelolsson »

I also get the error message from grub saying Can't load anyting below 1mb.

But I check my kernel with objdump, and don't see any addresses below the 1mb mark...

Binary files/Kernel: file format elf32-i386

Sections:
Idx Name Size VMA LMA File off Algn
0 .setup 0000001e 00100000 00100000 00001000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00000e2a c0100020 00100020 00001020 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .data 000005d4 c0101000 00101000 00002000 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .bss 00001800 c0102000 00102000 000025d4 2**2
ALLOC

I have followed the wiki, used the exact same ld-script, by no.. Grub complains :-\

Candamir, which version of Grub are you using?
Candamir

Re:Cross-Linker doesn't resolve references

Post by Candamir »

I don't remember right now...

But I used the disk image available from Clicker's download section.

http://sourceforge.net/project/showfile ... p_id=10181 => Miscellaneous => GRUB bootdisk (by Solar)

Candamir
axelolsson

Re:Cross-Linker doesn't resolve references

Post by axelolsson »

Found a solution anyway ;D

It seems like the entry symbol must not be of any virtual addressing.

The exampel from the wiki does not specify a section at the beginning of the file (The assembly part..), i believe NASM assumes this is a .text section? Anyhow, start is the entry point, and if it is within .text that is virutally addressed at 0xC0100000 Grub complains.

One solution is to place our entry symbol (start) in the .setup section

Code: Select all

...
section .setup
...
align 4

   ; Actual header
   dd MULTIBOOT_HEADER_MAGIC
   dd MULTIBOOT_HEADER_FLAGS
   dd CHECKSUM
      
start:
  ; kernelEntry is inside .text, eg. will be at 0xC01xxxxx,
  ; If we add with the base then we have the real physical address.
   jmp  kernelEntry+0x40000000

section .text

kernelEntry:

; Same code as from the Wiki
   lgdt [trickgdt]
   mov  ax, 0x10
   mov  ds, ax
   mov  es, ax
     ....
     ....

section .setup

    trickgdt:
         dw gdt_end - gdt - 1 ; size of the GDT
         dd gdt ; linear address of GDT
    ....
    ....

Works like a charm and I could set up paging and a new GDT with base 0, and it just worked ::)
Post Reply