I need a position independent code (PIC) working on STM32F401. But i have problem with pointers to functions used e.g. in struct.
Short example:
struct process {
struct process *next;
const char *name;
PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t));
struct pt pt;
unsigned char state, needspoll;
};
process etimer_process...
static void call_process(struct process *p, process_event_t ev, process_data_t data) {
int ret;
ret = p->thread(&p->pt, ev, data);
}
After diassembly:
Disassembly of section .data:
...
20000768 <etimer_process>:
20000768: 00000000 andeq r0, r0, r0
2000076c: 0803b134 stmdaeq r3, {r2, r4, r5, r8, ip, sp, pc}
20000770: 08027435 stmdaeq r2, {r0, r2, r4, r5, sl, ip, sp, lr}
20000774: 00000000 andeq r0, r0, r0
...
Disassembly of section .text:
...
8027da4: 68fb ldr r3, [r7, #12] //R3 = 0x20000768
8027da6: 689b ldr r3, [r3, #8] //R3 = 0x8027435
...
8027db2: 4798 blx r3 //Branch to R3
...
Branch address in R3 is wrong for code at offset different than 0. I don't see use of GOT here. It is a bug or missing compiler/linker option?
Things which i have probably successfully solved:
- GOT fixup
- Interrupt table fixup
- Newlib compiled with appropriate cflags
Used CFLAGS:
-mlittle-endian -mthumb -mthumb-interwork -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion -msoft-float -fpic -msingle-pic-base -mpic-data-is-text-relative -mpic-register=r10 -Wno-strict-aliasing -lc
and linking with
-fpic
process
struct. That's not the case. It must be fixed up at the time theprocess
struct is initialized. Why does your environment require position independent code anyway? Pretty unusual for a microcontroller. – Hoseaprocess
struct), you have to fix the branch address. The simplest way is to have it initialized by code:etimer_process.pt = my_func;
. Then the compiler will create the necessary code to compute the correct address. – Hosea