I've been following this board for a long time and now it's about to ask my first question.
I'm developing a 64bit Kernel which is located in the negative 2GB memory area 0xffffffff8000000.
Every thing was working fine until I started to test global constructors (I have C++ code in use).
Once the kernel boots up and gets to the point where it calls the global constructors it would just reboot.
I tracked the issue down by dumping the address I was about to call which was when I encountered a strange "shift"..
When the constructor in question would reside at 0xffffffff80101040 my global constructors list would record it as
0xffff801010400000 which is *a little* off..
An attempt to link my kernel at 0xffff800000000000 resulted in the same shift..
After some more debugging I started looking at the binary itself and the address is wrong even there!
I'm out of ideas right now.. please help.
---
My C/C++ flags:
Code: Select all
CFLAGS:
-c -std=gnu99 -O2 -Wall -Wextra -Wpointer-arith -Wcast-align -Wwrite-strings -Wno-long-long -Wno-variadic-macros -ffreestanding -nostdinc -fno-builtin -fno-stack-protector -m64 -mcmodel=kernel -fdump-class-hierarchy -mno-red-zone
CXXFLAGS:
-std=gnu++0x -fno-exceptions -fno-rtti -O2 -Wall -Wextra -Wpointer-arith -Wcast-align -Wwrite-strings -Wno-long-long -Wno-variadic-macros -ffreestanding -nostdinc -fno-builtin -fno-stack-protector -m64 -mcmodel=kernel -fdump-class-hierarchy -mno-red-zone
My linker script:
Code: Select all
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(bootstrap)
SECTIONS {
. = 0x00100000;
.bootstrap : {
/* bootstrap code is handled in a seperate object file
* and doesn't really know about 64bit or virtual addresses
*/
KEEP (build/src/kernel/processor/x86_64/bootstrap.o (.multiboot))
KEEP (build/src/kernel/processor/x86_64/bootstrap.o (.text))
KEEP (build/src/kernel/processor/x86_64/bootstrap.o (.data))
KEEP (build/src/kernel/processor/x86_64/bootstrap.o (.bss))
KEEP (*(.bootstrap))
}
. = ALIGN(4096);
. += 0xffffffff80000000;
.text : AT(ADDR(.text) - 0xffffffff80000000) {
PROVIDE_HIDDEN(__init_start = .);
KEEP (*(.init))
PROVIDE_HIDDEN(__init_end = .);
. = ALIGN(4096);
PROVIDE_HIDDEN(__fini_start = .);
KEEP (*(.fini))
PROVIDE_HIDDEN(__fini_end = .);
. = ALIGN(4096);
*(.text* .gnu.linkonce.t*)
*(.rodata* .gnu.linkonce.r*)
. = ALIGN(4096);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
}
. = ALIGN(4096);
.data : AT(ADDR(.data) - 0xffffffff80000000) {
*(.data .data* .gnu.linkonce.d.*)
PROVIDE_HIDDEN (__ctors_array_start = .);
KEEP (*(.ctors))
PROVIDE_HIDDEN (__ctors_array_end = .);
PROVIDE_HIDDEN (__dtors_array_start = .);
KEEP (*(.dtors))
PROVIDE_HIDDEN (__dtors_array_end = .);
}
. = ALIGN(4096);
.bss : AT(ADDR(.bss) - 0xffffffff80000000) {
*(.dynbss)
*(.bss .bss* .gnu.linkonce.b.*)
*(COMMON)
}
/DISCARD/ : {
*(.note.GNU-stack)
*(.gnu_debuglink)
*(.eh_frame*)
*(.gcc_except*)
}
}