I am developing some bare metal application for a mipsel core. I supply -C relocation-model=static
to the compiler in order to generate absolutely positioned code. This is my LLVM spec:
{
"llvm-target": "mipsel-unknown-none",
"arch": "mips",
"cpu": "mips32r2",
"data-layout": "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
"executables": true,
"features": "+mips32r2,+soft-float",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"max-atomic-width": 32,
"os": "none",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "32"
}
However, when I use optimization levels < 2 rustc uses the global pointer $gp
some times to reference data. I do not set the value of $gp
at all in my startup code because it is my understanding that it should not be used in statically positioned code. Therefore the code does crash when it tries to use $gp
.
Is there some way to tell the compiler to stop using $gp
?
In my desperation I also tried to get it somehow working by setting $gp
to the correct value.
First I added _gp
to my linker script in order to tell the linker where $gp
will be positioned. It is my understanding that the linker should now relocate the offsets to $gp
properly in my code:
START_ADDR = 0xA0000000;
MEMORY_SIZE = 0x40000;
ASSERT(DEFINED(_start), "Cannot find entry point: fn _start() -> !");
ENTRY(_start);
SECTIONS
{
. = START_ADDR;
.text :
{
*(.init)
*(.text*)
}
.rodata :
{
*(.rodata*)
}
_gp = ALIGN(16);
.data :
{
*(.data*)
}
_BSS_START = .;
.bss :
{
*(.bss*)
}
_BSS_END = .;
.vectors ALIGN(0x1000) :
{
_VECTOR_START = .;
KEEP(*(.tlb_exception))
. = _VECTOR_START + 0x180;
KEEP(*(.exception))
}
_STACK_END = .;
_STACK_START = START_ADDR + MEMORY_SIZE;
}
Then I setup $gp
in my startup asm!() code:
lui $$gp, %hi(_gp)
ori $$gp, %lo(_gp)
This yields:
a000002c: 00 a0 1c 3c lui $gp, 40960
a0000030: 90 7a 9c 37 ori $gp, $gp, 31376
However, this also crashed because the instructions that load/store relatively to $gp use wrong offsets. Shouldn't the linker fixed that for me?.
How to properly setup $gp?