我正在尝试在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
答案 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的内存映射,所以如果你跟随任何有关此内容的教程或者有其他资源来帮助我帮助你 - 那就太棒了:)