【问题标题】:STM32, Position independent code - function pointers not in GOT?STM32,与位置无关的代码 - GOT 中没有函数指针?
【发布时间】:2018-03-28 21:09:26
【问题描述】:

我需要一个在 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
   ...

R3 中的分支地址对于偏移量不同于 0 的代码是错误的。我在这里看不到 GOT 的使用。这是错误还是缺少编译器/链接器选项?


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

  • 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-相对 -mpic-register=r10 -Wno-strict-aliasing -lc

并与

链接

-fpic

【问题讨论】:

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

标签: gcc arm stm32 position-independent-code


【解决方案1】:

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

【讨论】:

  • 什么动态链接器使用uCs?精心制作
  • @0___________ 在 OP 的情况下,我相信他有自己的自定义运行时“链接器”(请注意他的问题中的“GOT 修复”、“中断表修复” - 这正是动态链接器典型的运行时重定位做)。更别提udynlink之类的东西了。
  • @0___________ 您是否同意 OP 有一段代码在启动时执行其代码的运行时重定位?我称它为运行时链接器。您可以建议一个更好的名称,但请避免人身攻击,它们对任何人都没有帮助(是的,我为 uC 编写了引导加载程序)。
  • 不,他没有。这就是他想要 PIC 的原因
  • @0___________ 好吧,他确实有一个代码可以在启动时“修复”指针。在我的世界里,这叫做运行时重定位¯_(ツ)_/¯
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 2016-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 2012-10-10
相关资源
最近更新 更多