SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world.
And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download two short videos (registration required) highlighting:

System Workbench for STM32

generating position independent code problem on STM32F4

Hi guys,

This question isn’t about system workbench specifically, but about getting gcc to generate position independent code on an stm32f4 platform.

My build line is this:

“arm-none-eabi-gcc -O -std=c99 -mthumb -mcpu=cortex-m4 -fpic -msingle-pic-base -mfloat-abi=hard -mfpu=fpv4-sp-d16 -specs=nano.specs -specs=nosys.specs -c pic.c”

The problem appears to be that while the generated code makes use of the r9-based GOT section, it still generates standard non-PIC references to function calls. And when I do the link phase (with the “-pie” flag) there’s also no relocation data in the resulting ELF file.

Am I grossly misunderstanding the way this is supposed to be working, or just doing something wrong?

The C code and resulting generated code is below.

Many thanks,

-Imre Magyar


C code:

int glob = 100;

int func(int b)
extern int EXT;

return b + EXT + 7;

int ml_func(int a, int b)
return glob + func(a + b);

Generated code:

Disassembly of section .text:

00000000 :
0: 4b03 ldr r3, pc, #12 ; (10 )
2: f859 3003 ldr.w r3, r9, r3
6: 681b ldr r3, r3, #0
8: 4418 add r0, r3
a: 3007 adds r0, #7
c: 4770 bx lr
e: bf00 nop
10: 00000000 .word 0x00000000

00000014 :
14: b508 push {r3, lr}
16: 4408 add r0, r1
18: f7ff fffe bl 0
1c: 4b02 ldr r3, pc, #8 ; (28 )
1e: f859 3003 ldr.w r3, r9, r3
22: 681b ldr r3, r3, #0
24: 4418 add r0, r3
26: bd08 pop {r3, pc}
28: 00000000 .word 0x00000000

Hi, I’m exploring the possibility of position independent code for STM32 and ran into the same problem. Have you figured it out? thanks


Dear ST support,

The same issue is met here:

STM32 GCC generated code with -fPIC option ONLY uses indirect addressing through the Global Offset Table to access global variables.
Function calls are still preformed using an absolute address to the function instead of using an address found in the GOT.

In addition, the generated code addresses the GOT with an absolute address instead of using an offset to the GOT.

As a result, it appears “fPIC” functionality is NOT fully implemented. Or maybe some other compilation options should be used ?

Otherwise, is the full implementation scheduled ?

Note: our current project includes a driver for which the code must NOT change. To be free from the flash mapping, the idea was to have the application copy the got just after the driver in flash at a fixed “offset” (and not an absolute address). But with the function call and the GOT addressing state of the art, it seems not possible.

Thanks for your help,
Best regards,


Hi Sylvain,

In fact function calls are never generated using absolute addressses, except whan calling a function through a pointer, where the pointer must, obviously, contain the absolute address of the function. All function calls (using the BL instruction) are using relative addresses, limited to +-16MB.

Only if the function is farther than 16MB from the call will the linker generate a veneer which loads an absolute address in the r12 register and branch using a BX instruction; the original BL will then call the veneer that will redirect to the proper function.

For a PIC driver, all your internal calls will thus be using relative addressing; however, if you need to call other functions, then you should create yourself (probably in the code providing these functions) a structure containing pointers to functions that will be used to call them from PIC code.

Bernard (Ac6)

Dear Bernard,

thanks for your quick reply, I did not see the post (did not receive the email).

I have in my project a part I’d like to compile with the fPIC option.
I made a call to a test_function from a function in the code compiled with the fPIC option. The test_function also resides in a file compiled with the fPIC option.

Here is an excerpt of the generated assembly (copied from the disassembly view in the eclipse plugin) when using -fPIC option:

135 int ret = test_function(4);
08050802: movs r0, #4
08050804: bl 0x8050964

It appears the generated fPIC code does NOT use relative call inside the fPIC compiled module.

But maybe I have been tricked by the assembly display or do I miss something?

Thanks for your help,
Best regards,

I would like to add that the call is made from address 0x8050802 so definitely not requiring a veneer.

Hi Sylvain,

As I said in my previous post, BL is ALWAYS using relative addressing; to use absolute adressing you would have to use code like this:
LD R12,=test_function
where the first instruction will in turn be displayed in disassembly as two instruction: a MOVW #xxxx to load the 16 lsb (setting the msb to 0) and a MOVT #xxxx to load the 16 msb

Thus the code you show is indeed using relative addressing, so is perfectly valid in PIC mode.

Bernard (Ac6)

Dear Bernard,

Thanks you for your answers.
I finally agree with you.
I was tricked by the disassembly listing which decodes the offset in the BL instruction to display an absolute address.
You are right, the BL instruction makes relative branch.

=> this code is PIC compliant !

Thanks for you help,
Best regards,