STM32,位置无关代码-函数指针不在GOT中?

10
我需要一个在STM32F401上工作的位置独立代码(PIC)。但是我在指向结构体中使用的函数指针方面遇到了问题。
简单示例:
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);
}

拆卸后:

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
   ...

在偏移量不为0的代码中,R3分支地址错误。我没有看到GOT的使用。这是一个bug还是缺少编译器/链接器选项?

我可能已经成功解决的问题:

  • GOT修复
  • 中断表修复
  • 使用适当的cflags编译Newlib

使用的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

并且链接时使用:

-fpic


看起来你期望在从“process”结构中检索分支地址后对其进行修改。但事实并非如此。必须在初始化“process”结构时进行修复。为什么你的环境需要位置无关代码呢?这对于微控制器来说相当不寻常。 - Codo
数据段的初始化很简单,只需将值从闪存复制到RAM即可。但我不知道给定的值是否为闪存地址。我正在开发物联网设备,我们需要OTA固件更新。在STM32的闪存中将有两个或三个不同位置的固件。如果出现任何错误,引导加载程序将运行另一个固件。 - Robert Sedláček
因此,当您将Flash中的值复制到RAM中(即process结构体中),您必须修复分支地址。最简单的方法是通过代码进行初始化:etimer_process.pt = my_func;。然后编译器将创建必要的代码来计算正确的地址。 - Codo
与问题无关,但我认为您写的是-Wno-strict-aliasing,而您可能想要的是-fno-strict-aliasing。-fno-strict-aliasing表示不要让编译器假设变量没有别名。-Wno-strict-aliasing表示当变量有别名时不打印警告! - Tom V
1个回答

0
在这种情况下,不需要使用GOT。相反,编译器将添加一个运行时重定位,该重定位将指示动态链接器在启动时修补etimer_process.thread(我假设它在定义etimer_process时初始化)。

使用什么动态链接器来进行uCs开发?请详细说明。 - 0___________
在OP的情况下,我相信他有自己的定制运行时“链接器”(请注意他的问题中的“GOT fixup”,“Interrupt table fixup” - 这正是动态链接器通常执行的运行时重定位)。更不用说像udynlink等东西了。 - yugr
@0___________ 你认为OP有一段代码可以在启动时执行运行时重定位吗?我称之为运行时链接器。你可以提出更好的名称,但请避免人身攻击,这对任何人都没有帮助(是的,我确实为微控制器编写过引导加载程序)。 - yugr
不,他不想这样做。这就是他想要使用PIC的原因。 - 0___________
@0___________ 嗯,他确实有一个在启动时“修复”指针的代码。在我的世界里,这被称为运行时重定位 ¯_(ツ)_/¯ - yugr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接