9

Я узнал от this recent answer, что gcc и clang включают исходное имя файла где-то в двоичном формате как метаданные, даже если отладка не включена.Почему общие компиляторы C включают исходное имя файла в выходном файле?

Я не могу понять, почему это должно быть хорошей идеей. Помимо крошечных рисков конфиденциальности, это происходит и при оптимизации размера полученного двоичного файла (-Os), который выглядит неэффективным.

Зачем компиляторы содержат эту информацию?

+2

Это не просто GCC, Clang делает это (и любая компиляторная компиляция, которая делает двоичные файлы ELF, которые следуют [спецификации] (http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf)). – cyphar

+1

@cyphar Я признаю, что я просто впился в него вместо того, чтобы читать все 60 страниц, но нашел FILE, упомянутый только на странице 25 этого документа, и он не говорит, что он является обязательным («Обычно имя символа дает имя исходный файл, связанный с объектным файлом »). –

+0

Я тоже не читал все 60 страниц. Но когда дело доходит до стандартов «условно», значит «вы, вероятно, должны это делать, потому что люди могут полагаться на него». В конце дня, если вам дана спецификация, проще просто следовать ей в письме (учитывая, что ваши пользователи могут решить использовать самые эзотерические функции, выраженные в стандарте), чем пытаться и ласкать ваш выход из реализуя то, что вам не нужно. ведь GNU - это край экстремальных сумм дополнительных возможностей. – cyphar

ответ

6

Причина, почему GCC включает в себя имя файла, в основном, для целей отладки, поскольку он позволяет программисту определить, из какого источника файла данный символ, как происходит от (сжато), изложенные в ELF spec p1-17 и далее расширены в some Oracle docs on linking.

Пример использования раздела STT_FILE приведен в таблице this SO question.

Я все еще смущен, почему GCC и Clang все еще включают его, даже если вы укажете -g0, но вы можете остановить его с включением STT_FILE с -s. Я не мог найти никаких объяснений по этому поводу, и я не мог найти «официальную причину», почему STT_FILE включен в спецификацию ELF (очень terse).

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.

+1

Почему «не совсем»?Я все еще считаю это «включенным в двоичный файл», хотя вы правильно указываете, что он встроен таким образом, который позволяет легко его удалить. Во всяком случае, мой вопрос касался мотивации. –

+1

@FedericoPoloni Только очень тонкая причина для «не совсем»: это мета-данные таблицы символов? Это необходимо * для успешной ссылки. Однако отладочные данные не имеют, имеют свой собственный раздел ELF и могут быть удалены. Это не большая проблема и не стоит мешать пониманию. – Jens

+1

Хотя для привязки требуется таблица символов вообще, этот конкретный символ не является. Таким образом, по существу, использование таблицы символов в качестве места для хранения некоторых метаданных. – Barmar