我正在使用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):relocation R_ARM_THM_MOVW_ABS_NC针对“本地符号”时不能使用 制作共享对象;用-fPIC重新编译
我不太明白错误信息。似乎默认的标准c / c ++库不能与我的选项一起使用,我需要获取库的源代码并为自己的目的重建。
所以,
1.任何人都可以向我提供有关如何使用位置无关可执行文件的任何有用信息/链接吗?
2.使用-msingle-pic-base选项,我不需要太在意GOT和ld脚本了,对吧?
注意:如果没有“-pie”链接选项,我可以构建程序。但是当调用c ++虚函数时(当我使用IDE(keil)的模拟器调试我的程序时)程序失败了。我不明白发生了什么以及我一直在想什么。
-------------------------------------------------- --------------------
- 已添加20130314
- 使用 -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情况下使用的源代码g ++?我认为“-msingle-pic-base”,“ - fpie”,“ - pie”选项的行为记录得很差!
-------------------------------------------------- ---------------------
从解组装代码中,我只是想通了“-msingle-pic-base”,r9应该指向“.got”部分的基地址,.got部分中的指针是绝对指针变量的寻址类似于文章中的描述:Position Independent Code (PIC) in shared libraries。所以我仍然需要在加载时修改“.got”部分。 我不知道我的程序中使用的“.got.plt”部分是什么。似乎函数调用正在使用PC相对寻址
如何使用“-pie”进行构建或如何链接使用“-fpic”编译的标准库仍然是我的问题。
答案 0 :(得分:1)
错误消息告诉您在构建gcc编译器时重新编译最经常构建的libstdc ++库。
因此,您必须使用-fPIC重新编译标准库(libstdc ++,libgcc_ *,libc,libm和all)并将项目链接到它们。
如果您依赖于预构建的编译器软件包,那么您在微控制器世界中大部分时间都处于游戏之外。如果您自己构建编译器(顺便说一句,这不是太困难,而是高级/专家任务),那么您就可以随时随地进行编译。
也可以使用您拥有的编译器自己编译标准库。您将需要库的来源并弄清楚,编译器包构建系统如何构建它们并且您必须模仿它。也许这里有一些专家,他们可以这样建议你。
答案 1 :(得分:0)
在最初提出这个问题八年后,有一篇关于这个主题的不错的博客文章,但它在那里:https://mcuoneclipse.com/2021/06/05/position-independent-code-with-gcc-for-arm-cortex-m/
大纲是你必须:
-msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative -fPIC