ld:访问合并部分的末尾

时间:2013-11-08 18:22:01

标签: linker arm linker-errors ld elf

我正在尝试在arm debian机器(一个覆盆子pi)上链接一个简单的c程序,当链接ogject文件时,链接器返回主题中的错误。

我的程序就像

一样简单
simple.c:

 int main(){
   int a = 2;
   int b = 3;
   int c = a+b;
 }

我用

编译它
$>gcc -o simple.obj simple.c

然后将其与

链接
$>ld -o simple.elf simple.obj
ld: simple.obj: access beyond end of merged section (33872)

我无法理解为什么...... 如果我尝试用objdump -d读取elf文件,它就无法对.text部分进行反编译(它只打印地址,值,.word并再次输入前面带有0x的值)但是二进制数据与我从反编译的simple.obj获得的数据相同。

唯一的区别在于二进制数据的加载开始(和后续)地址:elf文件从0x8280开始,目标文件从0x82a0开始。

这一切意味着什么?

编辑:

这是obj文件的转储:http://pastebin.com/YZ94kRk4

这是elf文件的转储:http://pastebin.com/3C3sWqrC

我尝试使用-c选项进行编译,使得gcc在汇编时间后停止(它已经完成了链接部分)但现在我有一个不同的问题:它说我的目标文件中没有_start部分...

新转储是:

simple.obj:http://pastebin.com/t0TqmgPa

simple.elf:http://pastebin.com/qD35cnqw

2 个答案:

答案 0 :(得分:2)

您误解了所运行命令的效果。如果您运行:

$ gcc -o simple.obj simple.c

它已经创建了你想要运行的程序,它已经链接了。您无需再次链接它,尤其是直接运行ld,除非您知道自己在做什么。即使它的扩展名是obj,也没关系,它只是文件的名称,但文件的内容已经是一个完整的Linux程序。所以如果你跑:

$ ./simple.obj

它会执行你的代码。

您通常不直接调用ld,而是使用gcc作为前端进行编译和链接。这是因为gcc负责链接您没有链接的重要库,例如启动代码,这就是为什么您的第二次尝试导致“不_start部分”或类似内容的原因。

答案 1 :(得分:0)

你能打印objdump -d命令的输出吗?

不过,请注意33872 == 0x8450

我不熟悉raspberry PI的内存映射,所以如果你跟随任何有关此内容的教程或者有其他资源来帮助我帮助你 - 那就太棒了:)