Hardfault when accessing a global variable in a position independent program compiled with -fPIE
Hello board,
I seek to implement a position independent firmware to achieve a dual slot fota strategy:
- The application firmware can be saved into one among two possible memory areas, the firmware does not know at compile time where it will be stored so it must be able to run regardless of the position.
- A small bootloader is in charge of properly launching the firmware (the bootloader knows where the application firmware is stored).
I followed the steps described by the UM2609 guide for stm32CubeIDE chapter 2.8 which covers this exact requirement https://www.st.com/resource/en/user_manual/um2609-stm32cubeide-user-guide-stmicroelectronics.pdf .
- The application firmware is compiled with the -fPIE option
- The instruciton "bl __libc_init_array */"is eliminated from the application firmware startup code
- .got is inserted into the main firmware linker inside the .text section among GOT_START and GOT_END
- Stack pointer is loaded at _estack in application firmware reset handler
- A ram section is dedicated to holding the application firmware vector table
- The bootloader copies the application firmware vector table to ram and applies the appropriate offset to each entry.
- The bootloader deinits all peripherals and HAL and jumps to the application firmware
At this point:
- The main firmware reset handler is reached,
- Startup code executes,
- When it reaches the function HAL_Init inside main the application firmware goes into hardfault upon accessing a global variable, whose loaded address is outside ram memory space
instruction that triggers hardfault- Funnily enough, this exact variable location is properly displayed by the expression monitor

At this point I think I am maybe missing something regarding global variables relocation, or am I doing something else wrong?
I hope any of you can shed light on this mistery as online information regarding this subject is very scarce!
Regards, Matteo
