使用不同的链接器会产生不同的机器代码吗? [关闭]
Posted
技术标签:
【中文标题】使用不同的链接器会产生不同的机器代码吗? [关闭]【英文标题】:Does using a different linker produce different machine code? [closed] 【发布时间】:2020-02-17 23:07:47 【问题描述】:如果我编写一个复杂的程序并构建它,如果我使用ld
vs lld
vs gold
,最终生成的机器代码会有所不同吗?
【问题讨论】:
您在问这样的问题:驾驶福特、本田或丰田更好?是的,驾驶每辆车都会略有不同。ld vs lld
- ld
我猜你的意思是“GNU 链接器”。 lld
是什么链接器?
@KamilCuk lld
是 LLVM 链接器。
“不同”是什么意思?不同的目标文件和库很可能以不同的顺序添加到可执行文件中,因此即使所有代码都相同,二进制文件也会有所不同。如果有任何链接时间代码生成,那么肯定会有差异。
@MarcoBonelli 我的意思是链接时间。评论已编辑。
【参考方案1】:
是的,很可能会。假设用不同的链接器链接会产生相同的机器代码是不正确的。
可能发生的最简单的事情是,最终可执行文件中的函数顺序可以随链接器的不同而任意变化,因此用于进行相关调用的机器代码可能会有所不同。一个链接器可能决定将func_a
放置在地址0x1000
上,从而将对该函数的调用转换为call 0x1000
之类的东西,而另一个链接器可以将相同的函数放置在不同的地址上,例如call 0x2000
。因此最终的机器代码会有所不同。
最重要的是,至少对于 ELF 可执行文件,对于外部符号引用应如何在二进制文件中排序或应使用什么机器代码进行运行时符号解析,确实没有规则。 PLT(过程链接表)存根可能因一个链接器而异。
【讨论】:
【参考方案2】:是和不是。例如,链接器不会在编译器之后更改优化级别。它对代码本身的影响非常轻微(主要是在它解析符号引用时)。但谈到最终可执行文件的结构,可能会有很大的不同。相同的代码块和其他资源可以以不同的方式重新排列(最明显的是“删除与保留死代码”)。
所以文件的二进制比较会发现很多差异,但就机器代码(它的结构和行为)而言,它们几乎相同。
【讨论】:
您似乎在自相矛盾,首先“谈到最终可执行文件的结构,它可能非常不同”,然后“就机器而言代码(它的结构和行为)它们几乎相同” 不是“描述为 EB FE DE AD C0 DE 的写入文件代码结构”,而是“描述为逻辑图的内部实际代码结构”。第一个会有所不同,第二个不会。以上是关于使用不同的链接器会产生不同的机器代码吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在虚拟函数周围使用#ifdef预处理器会导致与库链接的程序出现运行时错误[关闭]
MFC .exe 和 .dll 为相同的代码产生不同的结果 [关闭]
链接到不同版本的 .dll 的 .lib 可能会产生哪些副作用?