Appears that clang maintains .rodata sections that may have trailing characters on the name. In the linker script you should use
*(.rodata*) instead. With LD linker you should consider aligning the Load Memory Address (to the right of a colon on a section definition) to 4K if you want the LMA and VMA to match up. If you set the VMA (value to the left of the colon in the section definition), the LMA remains untouched. If you set both LMA and VMA in a section definition they are set separately. In your case you want to modify your
linker.ld to look like:
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(_start)
SECTIONS
{
. = 0x100000;
.text : ALIGN(4096) {
*(multiboot)
*(.text)
}
.data : ALIGN(4096) {
*(.data)
}
.rodata : ALIGN (4096) {
*(.rodata*)
}
.bss : ALIGN (4096) {
*(.bss)
}
}
The linkers may create the PHDRS differently, so to see the individual sections using LD you may want to use
objdump -x kernel to view the full headers. The output is more readable than
readelf IMHO Modify your linker line to add -nostartfiles and -nostdlib. We don't have C runtime initialization nor do we have standard library support. The command could look like this:
Code: Select all
ld -Tlinker.ld -nostartfiles -nostdlib *.o -o kernel -melf_i386
Be aware that if you are going to use C++ you will need to enhance the linkers script to deal with static construct and destructors. Your assembly code would have to loop through that data and call all the static constructiors. If you ever put class objects at global scope for example, to have them initialized these constructors have to be called. Normally the startupfiles do that, but since we are in a freestanding environment it is up to us to do that ourselves. I believe there is a forum post or OSDev wiki discussing this.