Работая над программой на C, я изменил свою сборку, чтобы создать файл .o вместо отдельного двоичного файла. При этом я заметил, что размер раздела .bss результирующего файла .o равен 0, согласно readelf -S
, хотя в исходнике явно есть неинициализированные глобальные переменные.
Я могу воспроизвести это с помощью простой программы test.c:
char arr[42];
int main(int argc, char **argv){
return 0;
}
Двоичный файл, полученный из gcc -o test test.c
, имеет восьмидесятибайтовый раздел .bss, согласно readelf, что примерно соответствует моим ожиданиям, поскольку я ожидал незначительных накладных расходов.
Однако, если я создам файл .o с помощью gcc -c -o test.o test.c
, размер раздела bss будет равен нулю. Ясно, что я что-то неправильно понимаю в природе объектных файлов ELF, но я не совсем уверен, что мне не хватает.
@Эксполярность; в моем случае я использовал readelf. Однако я вижу то же самое с размером. RE: размер 80, извините, я случайно забыл преобразовать из шестнадцатеричного.
О, я думаю, что readelf сообщает о двух разных наборах размеров, один должен быть под именем раздела в первом столбце (с именем Size) и один во втором столбце (с именем EntSize). EntSize часто обнулялся. Возможно ли, что вы читали другой размер, который был нулевым?
@Expolarity, это хорошая мысль, но нет! Это поле обычного размера в первом столбце. Я также дважды проверил с помощью команды size
, чтобы быть уверенным.
обратите внимание, что gcc реализует Приложение J.5.11, которое позволяет объединять неинициализированные глобальные переменные с инициализированными глобальными в другой единице трансляции, поэтому этот массив может вообще не попасть в BSS в окончательном исполняемом файле.
Объектные файлы ELF имеют фиктивный сегмент .bss. Их нельзя загрузить напрямую (в отличие от исполняемой или разделяемой библиотеки).
Информация о глобальных переменных хранится в разделе .symtab, который используется компоновщиком для создания .bss и других разделов в конечном двоичном файле.
Попробуйте сделать readelf -s test.o
, чтобы открыть таблицу символов.
Какую команду вы используете для получения размеров раздела? Для меня:
size test.o
сообщает о bss размером 42 байта, аsize test
сообщает о 80 байтах.