I am trying to build a static position-independent executable with gcc
provided option -static-pie
. The target is bare-metal risc-v, so no OS, no dynamic loader. I have a linker script similar to following:
ENTRY(_start)SECTIONS { .text (READONLY) : ALIGN(64) { startup.o(.text.startup) *(EXCLUDE_FILE(startup.o) .text .text.*) } .rodata (READONLY) : ALIGN(64) { *(.srodata .srodata.*) *(.rodata .rodata.*) *(.got .got.plt) } .data ALIGN(64): { __global_pointer$ = . + 0x800; *(.sdata .sdata.*) *(.data .data.*) } .bss (NOLOAD): ALIGN(64) { _bss_start = .; *(.sbss .sbss.*) *(.bss .bss.*) _bss_end = .; } .stack (NOLOAD): ALIGN(64) { _stack_start = .; . = . + 0x400; _stack_end = .; }}
and when compiling with -fpie
and linking with -static-pie
it seems to produce a correct PIE binary which seems to function correctly from any address it is loaded to.
Now, to the problem. Consider we have a special memory region at fixed address which I want the program to use (for example some shared memory with another processor) and I want to define it via the linker script. With position dependent code I would do something like this:
In the code:
__attribute__((section(".special_section"))) volatile uint8_t shared_mem[100];
In the linker script:
SECTIONS {..... .special_section 0x12340000 (NOLOAD): { *(.special_section) }.....}
and this will ensure that the array shared_mem
is located at the fixed address 0x12340000
.
However this does not work with static-pie
. The accesses to shared_mem
which are generated by the compiler are relative to the address the binary is loaded to (that's the idea of PIE, right?). The question is - is there a way to define a specific output section to have an absolute address?