2

我正在使用 codesourcery g++ lite(基于 gcc4.7.2 版本)为 stm32(Cortex-m3)编程。我希望动态加载可执行文件。我知道我有两种选择:
1. 可重定位精灵,它需要精灵解析器。
2. 具有全局偏移寄存器的位置无关代码(PIC)

我更喜欢带有全局偏移寄存器的 PIC,因为它似乎更容易实现,而且我不熟悉 elf 或任何 elf 库。此外,使用一些工具可以很容易地从 elf 文件生成 .bin 文件。

我尝试使用“-msingle-pic-base -fpic”编译选项和“-pie”链接选项构建我的程序,但随后出现链接错误:

...path...ld.exe: ...path...thumb2\libstdc++.a(pure.o): 重定位 R_ARM_THM_MOVW_ABS_NC 在制作共享对象时不能使用“本地符号”;使用 -fPIC 重新编译

我不太明白错误信息。似乎默认的标准 c/c++ 库不能与我的选项一起使用,我需要获取库的源代码并为自己的目的进行重建。
那么,
1. 任何人都可以向我提供有关如何使用与位置无关的可执行文件的任何有用信息/链接吗?
2. 有了 -msingle-pic-base 选项,我就不需要太在意 GOT 和 ld 脚本了,对吧?

注意:如果没有“-pie”链接选项,我可以构建程序。但是在调用 c++ 虚函数时程序会失败(当我使用 IDE(keil) 的模拟器来调试我的程序时)。我不明白发生了什么以及我错过了什么。



-------------------------------------------------- ------------------
-- 添加 20130314

  1. 使用-msingle-pic-base选项,我不再需要过多关心 GOT 和 ld 脚本,对吧?

根据我的实验,寄存器(我的程序中使用了 r9)应该指向 got.plt 部分的开头。删除“-pie”选项,链接将成功,(正确设置r9)然后成功调用c ++虚函数。不过,我仍然认为“-pie”选项很重要,它可以确保当前的标准库是位置无关的。谁能为我解释一下?



-------------------------------------------------- --------------------
-- 添加了 20130315
我查看了 ARM 网站上关于 ABI 的文档。但这没有什么帮助,因为他们没有针对特定平台。似乎有一个 EABI 的概念(我使用的是 sourcery 的 arm-none-eabi 版本),但我在 arm 的网站上找不到任何关于“EABI”的文档。我也无法从 sourcery 和 gcc 中找到有关此主题的文档。PIC 的实现不止一种,那么在非 eabi 情况下,sourcery g++ 使用的是哪一种?我认为“-msingle-pic-base”、“-fpie”、“-pie”选项的行为记录太差了

从反汇编代码中,我刚刚发现,在“-msingle-pic-base”中,r9 应该指向“.got”部分的基地址,.got 部分中的指针是绝对指针并且变量的寻址类似于文章中的描述:共享库中的位置独立代码(PIC)。所以我仍然需要在加载时修改“.got”部分。我不知道我的程序中使用的“.got.plt”部分是什么。似乎函数调用正在使用 PC 相对寻址。
如何使用“-pie”构建或如何链接使用“-fpic”编译的标准库对我来说仍然是一个问题


4

2 回答 2

2

错误消息告诉您在构建 gcc 编译器时重新编译最常构建的 libstdc++ 库。

因此,您必须使用 -fPIC 重新编译您的标准库(libstdc++、libgcc_*、libc、libm 等等)并将您的项目与它们链接起来。

如果您依赖预构建的编译器包,那么您在微控制器世界中大部分时间都在游戏之外。如果您自己构建编译器(顺便说一句,这不是太难,而是一项高级/专家任务),那么您就在旅途中。

也可以使用您拥有的编译器自己编译您的标准库。您将需要库的来源并弄清楚编译器包构建系统如何构建它们,并且您必须模仿这一点。也许这里有一些专家,他们可以通过这种方式为您提供建议。

于 2017-04-08T10:29:45.837 回答
0

在最初提出这个问题八年后,有一篇关于这个主题的不错的博客文章,但它就在那里:https ://mcuoneclipse.com/2021/06/05/position-independent-code-with-gcc-for-arm-cortex -m/

一般的大纲是你必须:

  1. 根据链接器生成的信息设置 GOT
  2. 从 Program Header 信息设置 PLT
  3. 实现基于 GOT 条目的活页夹
  4. 将您的库编译为共享的可重定位二进制文​​件:-msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative -fPIC
  5. 相应地设置 R9
于 2021-06-22T18:54:07.483 回答