LD won't move .rodata section with -Trodata OFFSET

38 views Asked by At

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.

1

There are 1 answers

0
TheYolocast On

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.elf

It's odd that it doesn't throw an error when trying to use -Trodata