Page 1 of 1
Cross-Linker doesn't resolve references
Posted: Sun Jun 11, 2006 8:14 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Sun Jun 11, 2006 8:46 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Sun Jun 11, 2006 10:29 pm
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...
Re:Cross-Linker doesn't resolve references
Posted: Sun Jun 11, 2006 10:48 pm
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..
Re:Cross-Linker doesn't resolve references
Posted: Sun Jun 11, 2006 11:09 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Mon Jun 12, 2006 12:12 am
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?
Re:Cross-Linker doesn't resolve references
Posted: Mon Jun 12, 2006 3:42 am
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.
Re:Cross-Linker doesn't resolve references
Posted: Mon Jun 12, 2006 3:42 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Mon Jun 12, 2006 3:51 pm
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).
Re:Cross-Linker doesn't resolve references
Posted: Mon Jun 12, 2006 4:11 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Tue Jun 13, 2006 3:53 am
by mystran
What does mbchk say about your kernel?
Re:Cross-Linker doesn't resolve references
Posted: Tue Jun 13, 2006 3:09 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Tue Jun 20, 2006 12:15 pm
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?
Re:Cross-Linker doesn't resolve references
Posted: Tue Jun 20, 2006 3:28 pm
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
Re:Cross-Linker doesn't resolve references
Posted: Tue Jun 20, 2006 6:58 pm
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 ::)