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.


Booting a code and relocating involves many careful steps and initialization of configuration of RAM, SPI and other necessary peripherals.

I know U-Boot does the sequence you are trying to achieve. So a better starting is to walk through u-boot documentation and sources in, machine specific folders for the processor or board of interest.

Bare-metal Position Independent Executables, All objects and libraries linked into the image must be compiled to be position independent. Compiling and linking a bare-metal PIE. Consider the following simple  Compiling with the -fpic option fails when using GCC compilers Issue. Failure can occur at the linking stage when building Position-Independent Code (PIC) on AArch64 using the lower-case -fpic compiler flag with GCC compilers (gfortran, gcc, g++), in preference to using the upper-case -fPIC flag.


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.

Arm Compiler for Linux, CryptoIsland · CryptoCell-300 family · CryptoCell-700 family · Cortex-M35P · TrustZone · Platform Security Architecture Building Position Independent Code (PIC) on AArch64 Compiling with the -fpic option fails when using GCC compilers the build can fail at the executable linking stage because the GOT overflows. --fpic. Enables you to link Position-Independent Code (PIC), that is, code that has been compiled using the -fbare-metal-pie or -fpic compiler command-line options. The --fpic option is implicitly specified when the --bare_metal_pie option is used. Bare-metal PIE support is deprecated in this release.


TI does this with the Tivaware bootloader. You can do it with linker gnu ld trickery:

.text 0x20000000 : AT (0x00000000)
{
_text = .;
KEEP(*(.isr_vector))
*(.text*)
*(.rodata*)
_etext = .;
}

Startup code that copies this code from Flash at 0x0 to SRAM at 0x2000_0000 is left as an exercise to the reader.

Position independent code with fixed data and bss, The only part of the > image that needs to be position independent is the code itself. be able to just link against whatever defines the positions of the global data. (ARM Cortex M4) >> Build environment: arm-none-eabi-gcc 4.8.4 Maybe I am demanding too much from the compiler and linker, but I was  Home Documentation 100748 0612 - Arm Compiler User Guide Version 6.12 Mapping Code and Data to the Target Bare-metal Position Independent Executables Arm Compiler User Guide Version 6.12 Developer Documentation


Question #585437 : Questions : GNU Arm Embedded Toolchain, Hello, I am using a Cortex m4 CPU with a flash starting from 0x0 and RAM This would mean having the text section being position independent, but Generate PIC for TEXT but absolute addresses for DATA/BSS with -fpiX all static/global variables are relative to PC, so code will Link existing bug  Home > Compiling C and C++ Code > Bare-metal Position Independent Executables 3.6 Bare-metal Position Independent Executables A bare-metal Position Independent Executable (PIE) is an executable that does not need to be executed at a specific address but can be executed at any suitably aligned address.


STM32, Position independent code, I need a position independent code (PIC) working on STM32F401. It is a bug or missing compiler/linker option? -mlittle-endian -mthumb -mthumb-interwork -​mcpu=cortex-m4 -fsingle-precision-constant and linking with. All references to symbols must be resolved at link time. The image must be linked Position Independent with a base address of 0x0. The code and data must be linked at a fixed offset from each other. The stack must be set up before the runtime relocation routine __arm_relocate_pie_ is called. This means that the stack initialization code must only use PC-relative addressing if it is part of the image code.


bogdanm/udynlink: Dynamic linker for Cortex-M MCUs, udynlink is a dynamic linker for ARM Cortex-M MCUs. When linking this code, the linker will change the value in line 11 (which resides in arm-none-eabi-gcc -O0 -c -mcpu=cortex-m4 -mthumb -msingle-pic-base -fno-inline The compilation flags are chosen to generate a position-independent code and data object file. Both code and data can be position-independent: To enable code to execute at different addresses, it must be position-independent or relocatable. However, it can only access a single set of static data at a fixed address.