我正在尝试使GHC Haskell编译器的编译100%可复制(字节相同)。
目标文件已经是字节相同的,但是最终链接的二进制文件不是。
GHC将最终链接委托给gcc
,例如:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -o Main Main.o [..some more files..] /tmp/ghc21220_0/ghc21220_5.o /tmp/ghc21220_0/ghc21220_7.o [...] '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads
有趣的是,临时文件的文件名ghc21220_7.o
显示在链接的二进制文件中。
看来我可以使用该strip
工具将其删除。
为什么文件名出现在这里,目的是什么?
是否有一个标志告诉gcc
(或也许ld
?)不包括这些文件名?
更新:如果我objdump --syms
在二进制文件上运行,我会看到
0000000000000000 l df *ABS* 0000000000000000 ghc21220_5.c
0000000000000000 l df *ABS* 0000000000000000 ghc21220_7.c
根据这个 d
办法调试和f
手段的文件。我的问题仍然存在:为什么文件名以及文件名如何精确地.c
将其制成最终的二进制文件,我可以在编译时取消此操作(而不是strip
稍后运行)吗?
源文件名在可执行文件中显示为符号,因为在发出汇编程序时,GCC要做的第一件事是向.file
输出写入指令。然后,汇编器将其转换为目标文件中的符号,链接器将其与所有其他符号一起放入可执行文件中。我不确定它是否有用,但是它可能允许链接器错误地给出源文件名而不是目标文件名。
除了修改代码外,您无济于事,无法阻止GCC生成.file
指令或阻止汇编程序将其转换为目标文件中的符号。您可以使用-x
告诉其删除所有本地符号的选项,告诉链接器不要将它们包括在可执行文件中。
另一个更有针对性的选择是使用strip
命令从目标文件中仅剥离文件名符号:
strip -N ghc21220_5.c ghc21220_5.o
最终,当您认为C源文件相同时,可以选择给它们指定相同的名称。最终,您对文件名的选择是您在可执行文件中看到的差异的来源。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句