I am making an x86 kernel, and I ran into an issue trying to use string literals. The gcc compiler puts them into .rodata, which I was not loading into RAM at the time. I thought it would be simple enough to set -Trodata 0x00009400 and then use objdump to extract the section and put it in the kernel image. For some reason, readelf shows me that, in fact, ld is not relocating the segment at all. Also, when I set -Tdata to overlap -Ttext, I get an error, but when I try to do the same with -Trodata, it doesn't error. It seems as if it's just outright ignoring the command line argument.
My kernel is loading the drive's data correctly, but the main function points to the wrong address (the rodata offset set by ld) when referencing the string literal rather than the rodata offset that I specified on the command line.
Makefile
kernel: kernel/init.c kernel/preinit.asm
gcc -ffreestanding -fno-pie -g -c kernel/init.c -m32 -o object/kernelinit.o
nasm -g -f elf32 ./kernel/preinit.asm -o object/kernelpreinit.o
ld -e kernelInit -Ttext 0x00007E00 -Tdata 0x00009200 -Trodata 0x00009400 object/kernelpreinit.o object/kernelinit.o -o build/kernel.elf
objcopy -O binary -j.text build/kernel.elf build/kernel_text
objcopy -O binary -j.data build/kernel.elf build/kernel_data
objcopy -O binary -j.rodata build/kernel.elf build/kernel_rodata
Screenshot of readelf showing wrong offset for rodata, but correct offset for text and data
I tried looking into the source code of ld from the Binutils repo, but I can't seem to find an issue except maybe that it is expecting the section to be called rodata-section instead of rodata, but I may be misreading the code. Google has not been helpful in finding an answer to this problem.
Tsyvarev had the answer. Thank you.
New ld line:
ld -e kernelInit -Ttext 0x00007E00 -Tdata 0x00009200 --section-start=.rodata=0x00009400 object/kernelpreinit.o object/kernelinit.o object/interrupts.o -o build/kernel.elfIt's odd that it doesn't throw an error when trying to use -Trodata