如果我编写一个复杂的程序并构建它,如果我使用ld
与lld
与gold
,那么一天结束时生成的机器代码会有所不同吗?
是的,很可能会。假设使用不同的链接器进行链接会产生相同的机器代码是不正确的。
可能发生的最简单的事情是,最终可执行文件中函数的顺序可能因链接器而异,因此用于进行相对调用的机器代码可能会有所不同。一个链接器可以决定将func_a
放在地址0x1000
,从而将对该函数的调用转换为类似call 0x1000
的调用,而另一个链接程序可以将相同的函数放在不同的地址,例如生成call 0x2000
。因此,最终机器代码会有所不同。
最重要的是,至少对于ELF可执行文件来说,实际上没有关于外部符号引用应如何在二进制文件中排序的规则,也没有关于运行时符号解析应使用什么机器代码的规则。PLT(过程链接表(存根可能因链接器而异。
是和否。例如,Linker不会在编译器之后更改优化级别。它对代码本身的影响很小(主要是在解析符号引用时(。但说到最终可执行文件的结构,可能会有很大的不同。相同的代码块和其他资源可以以不同的方式重新排列(最令人讨厌的是"删除和保留死代码"(。
因此,文件的二进制比较会发现很多差异,但就机器代码(它的结构和行为(而言,它们几乎是相同的。