Search code examples
carmpositionpicbootloader

Compiling and linking position independent code (PIC) for ARM M4


I'm working on making a bootloader and giving it the ability to update itself. This process involves copying the binary to a new location, jumping to it, and using it to flash the new bootloader in the original location. This is all being developed for an M4 processor in Eclipse, using the ARM GCC toolchain.

To do this, I've gathered that I need to compile as Position Independent Code (PIC).

I've searched around and found this excellent article, so when I added "-fPIC" to the ARM GCC compiler call I expected to see linker errors about GOT and PLT being missing https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/

In my linker script, I added these location to the .data section as follows:

.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* Create a global symbol at data start. */
*(.got*) /* .got and .plt for position independent code */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* Define a global symbol at data end. */
} > m_data

However, this code fails to copy-up from ROM to RAM.

My next thought was that perhaps my linker needed to be aware it was linking a PIC executable. To find out, I added "--pic-executable" to the LD linker script call. However, the linker now generated sections for "interp", "dyn", "rel.dyn" and "hash". I tried throwing these into the data section as well, but got the following errors:

gcc-arm-none-eabi-4_9/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: could not find output section .hash

gcc-arm-none-eabi-4_9/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: final link failed: Nonrepresentable section on output

I assume this means the compiler didn't actually fill the ".hash" section with anything, so the link failed.

Am I going about this correctly? Is there anything else I need to add to get the compiler to do? Any help would be greatly appreciated.


Solution

  • For what it's worth, neither I nor NXP's technical support team were able to get their S32DS IDE to compile truly position independent code.

    To this day, we have two bootloaders - one compiled for location A, the other is an intermediate for location B. Both of which are required for an update.