I'm building code for NXP S32K148 MCU (Arm Cortex M4F) and I need to build code which is position independent. I'm using gcc 6.3.1 provided by NXP.I've almost managed to make it work...
1. I set the compile options "-fpic -msingle-pic-base -mno-pic-data-is-text-relative -mpic-register=r9". 2. I modified startup code: a. Calculate offset between compile time and run-time program counter (relocation offset). b. Copy the global offsets table to RAM while fixing code addresses by the relocation offset. c. Fix the interrupts vectors table pointers by the relocation offset. d. Set R9 to point to the global offsets table.
It worked - except that any function pointers inside initialized variable/structs were not relocated and were not accessed through the global offsets table. When execution reached such a pointer the system of course crashed.
Does anyone have a solution?
From my understanding I think you don't need to fix code addresses or even the pointers stored within the vector table as they are all using relative addresses.
That said, if you aim to build an executable and not a library, you may focus on compiling and linking your code as for a position independent executable:
- for compilation use -fPIE
- for linking user -fPIE -pie
For any library used by your executable, make sure they have been compiled and linked with -fPIC argument. Note sure about standard libs though...
Since the libraries are shared PIC, they shall be loaded separately before your PIE. For both libraries and the final executable, parse the respective GOT base addresses during startup code.
Before handoff to the executable, make sure the vector base address (VBAR) is set to the right address.
View all questions in GNU Toolchain forum