我编译两次相同的.c和.h文件并获取具有相同大小但不同md5sums的目标文件。
这是与objdump -d
的唯一区别:
1)cpcidskephemerissegment.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_ZN68_GLOBAL__N_sdk_segment_cpcidskephemerissegment.cpp_00000000_B8B9E66611MinFunctionEii>:
2)cpcidskephemerissegment.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_ZN68_GLOBAL__N_sdk_segment_cpcidskephemerissegment.cpp_00000000_8B65537811MinFunctionEii>:
可能是什么原因?谢谢!
答案 0 :(得分:2)
原因可能很多:
__DATE__
和__TIME__
.comments
ELF部分中嵌入的时间戳(或类似的可变数量)。执行此操作的编译器的一个示例是AIX上的xlC编译器。要生成相同的构建版本,可以使用GCC的-frandom-seed
参数。有些情况下它可能会破坏GCC 4.3之前的事情,但是GCC现在将匿名命名空间中定义的函数转换为静态符号。但是,如果使用-frandom-seed
的不同值编译每个文件,则始终是安全的,这是最简单的方法
文件名本身就是种子。
答案 1 :(得分:2)
我想,编译器不知道如何命名这个命名空间并使用路径到源文件加一些随机数。
编译器必须保证未命名的命名空间中的符号不会与程序中的任何其他符号冲突。 默认情况下这是通过获取源的完整文件名并向其附加随机哈希值来实现的(两次编译相同的源(例如使用不同的宏)是合法的,并将两个对象链接到一个单个程序,以及未命名的命名空间符号必须仍然是不同的,所以仅使用没有种子的源文件名是不够的。)
如果您知道您没有多次链接同一个源文件,并希望在重新编译时使用相同的目标文件,那么解决方法是将-frandom-seed="abcd"
添加到您的编译行中(替换“abcd”包含你想要的任何东西;通常使用文件名作为随机种子的值)。文档here。
答案 2 :(得分:1)
最后我找到了答案!
c++filt
命令给出了函数的原始名称:
{unnamed namespace}: MinFunction(int, int)
来源是:
namespace
{
MinFunction(int a, int b) { ... }
}
我命名了命名空间并获得了对象文件的稳定校验和! 我猜,编译器不知道如何命名这个命名空间,并使用路径到源文件加一些随机数。