2013-03-13 63 views
1

我使用codesourcery g ++ lite(基于gcc4.7.2版本)为stm32(Cortex-m3)编程。我希望动态加载可执行文件。 我知道我有两个选项可用:
1.可重定位的精灵,需要一个精灵分析器。
2.位置独立代码(PIC)与全局偏移寄存器手臂位置独立可执行文件(-pie)(cortex-m3)

我更喜欢全局偏移寄存器的PIC,因为它看起来更容易实现,我不熟悉精灵或任何精灵库。另外,用一些工具从elf文件生成.bin文件也很容易。

我试图建立我的程序与 “-msingle-PIC-基地-fpic” 编译选项和 “-pie” 链接选项,但后来我得到一个链接错误:

...path...ld.exe: ...path...thumb2\libstdc++.a(pure.o): relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC

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

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



------------------------------------------ ----------------------------
- 增加20130314

  1. with the -msingle-pic-base option, I don't need to care too much about the GOT and ld script anymore, right?

从我的实验,寄存器(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部分中的指针是绝对指针,变量的寻址类似于文章中的描述:Position Independent Code (PIC) in shared libraries。所以我仍然需要修改加载时的“.got”部分。 我不知道什么是我的程序中使用的“.got.plt”部分。看来,函数调用正在使用PC相对寻址。
如何使用“-pie”构建或如何链接使用“-fpic”编译的标准库对我来说仍然是一个问题


+0

为什么你需要动态加载它? – stdcall 2013-03-14 18:49:35

+0

@Mellowcandle没有实际需要。只是想杀了我的业余时间。我已经实现了一个简单的循环调度程序,现在我想为它添加一个简单的动态加载功能。 – Pony279 2013-03-15 03:44:45

+0

也许我应该尝试arm-linux-gcc :-(而不是用arm-none-eabi来构建“-pie”链接选项,或者我应该放弃我的想法并获得嵌入式Linux开发平台。 – Pony279 2013-03-15 06:41:01

回答

1

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

因此,您必须使用-fPIC重新编译标准库(libstdC++,libgcc_ *,libc,libm和all),并将您的项目与它们相链接。

如果您依赖预构建的编译器包,那么您在微控制器领域大部分都不参与游戏。如果你自己构建你的编译器(顺便说一下,不是太难,而是一个高级/专家任务),你就是在忙碌中。

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

相关问题