我从最近的这个答案中了解到,即使在未启用调试功能的情况下,gcc
和clang
仍会将源文件名作为元数据包含在二进制文件中。
我真的不明白为什么这是一个好主意。除了微小的隐私风险外,当人们优化生成的二进制文件的大小(-Os
)时,这也看起来效率低下。
编译器为什么要包含此信息?
我从最近的这个答案中了解到,即使在未启用调试功能的情况下,gcc
和clang
仍会将源文件名作为元数据包含在二进制文件中。
我真的不明白为什么这是一个好主意。除了微小的隐私风险外,当人们优化生成的二进制文件的大小(-Os
)时,这也看起来效率低下。
编译器为什么要包含此信息?
STT_FILE
部分的示例由此SO问题提供。-g0
,GCC和Clang仍然都包括它,但您可以使用-s
停止包括STT_FILE
。我没有找到这方面的任何解释,也没有找到STT_FILE
被包含在ELF规范中的“正式原因”(非常简洁)。$ 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
进行编译/链接。--as-needed
,但它仍然保留了特定带有文件名的符号。我认为更好的解决方案是找到一种方法防止它们最初进入 .o
文件。 - Trevor Hickey
STT_FILE
可能过于强硬,只是因为一些程序员需要该功能,所以大多数流行的编译器似乎会实现它。 - cyphar