我从this recent answer了解到gcc
和clang
将二进制文件中的源文件名包含为元数据,即使未启用调试也是如此。
我真的不明白为什么这应该是一个好主意。除了微小的隐私风险之外,当一个人优化得到的二进制文件(-Os
)的大小时也会发生这种情况,这看起来效率很低。
为什么编译器会包含这些信息?
答案 0 :(得分:6)
GCC包含文件名的原因主要是出于调试目的,因为它允许程序员识别给定符号来自哪个源文件(简洁地)在ELF spec p1-17中概述,并进一步扩展到{ {3}}
使用STT_FILE
部分的示例由some Oracle docs on linking提供。
我仍然感到困惑的是,即使你指定-g0
,GCC和Clang仍会包含它,但你可以阻止STT_FILE
加-s
。我找不到任何解释,也没有找到“官方理由”为什么STT_FILE
包含在ELF规范中(非常简洁)。
答案 1 :(得分:5)
我从最近的回答中了解到,即使未启用调试,gcc也会将二进制文件中的源文件名包含为元数据。
不完全。在现代ELF目标文件中,文件名确实是FILE
类型的符号:
$ readelf bignum.o # Source bignum.c
[...]
Symbol table (.symtab) contains 36 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS bignum.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 8
9: 00000000000003f0 172 FUNC GLOBAL DEFAULT 1 add
10: 00000000000004a0 104 FUNC GLOBAL DEFAULT 1 copy
然而,一旦剥离,符号就消失了:
$ strip bignum.o
$ readelf -all bignum.o | grep bignum.c
$
为了保护您的隐私,删除可执行文件,或使用-s
编译/链接。