2013-06-18 5 views
7

В последнее время я хочу узнать о некоторых знаниях о файле elf, но когда я столкнулся с глобальной переменной, глобальной статической переменной и переменной статической переменной, у меня есть небольшая путаница, например:Где глобальная переменная в файле elf

int a = 2; 
int b; 

static int c = 4; 
static int d; 

void fun(){ 
    static int e = 6; 
    static int f; 
} 


int main(void){ 
    fun(); 
} 

Кто может определить, к какому сегменту принадлежит каждая переменная? По-моему, b, d, f принадлежат сегменту bss, a, c, e относятся к сегменту данных, но я не знаю разницы между глобальными статическими переменная и глобальная varibale в файле эльфа.

ответ

11

Вы можете использовать objdump -t для просмотра таблицы символов:

$ objdump -t foo | grep -P '  \b(a|b|c|d|e|f)\b' 
0000000000601034 l  O .data 0000000000000004    c 
0000000000601040 l  O .bss 0000000000000004    d 
0000000000601044 l  O .bss 0000000000000004    f.1710 
0000000000601038 l  O .data 0000000000000004    e.1709 
0000000000601048 g  O .bss 0000000000000004    b 
0000000000601030 g  O .data 0000000000000004    a 

Вы правы, что b, d и f являются .bss в то время как a, c и e являются .data. Независимо от того, является ли символ статическим или нет, он записывается в отдельный флаг таблицы символов - это флаг l или g во втором столбце.

elf(5) man page говорит, что они записаны с использованием значений STB_LOCAL и STB_GLOBAL для st_info элемента таблицы символов. /usr/include/elf.h говорит, что STB_GLOBAL равен 1, а STB_LOCAL равен 0. Существует макрос ST_BIND для извлечения битов привязки поля st_info.


Есть множество других флагов для objdump -см в man page. objdump работает со всеми архитектурами, но есть также инструмент elfdump, который немного улучшает работу с изображением эльфа. objdump и базовая библиотека BFD могут плохо работать с отображением определенных файлов.

7

В целом сегмент данных исполняемого файла содержит инициализированные глобальные/статические переменные, а сегмент BSS содержит неинициализированные глобальные/статические переменные.

Когда загрузчик загружает вашу программу в память, унифицированные глобальные/статические переменные автоматически заполняются нулями.

В C статические переменные (инициализированные или нет) внутри функции означают, что переменные имеют локальную/функциональную область (иногда называемую внутренней статикой), но они все еще живут в сегментах данных/BSS в зависимости от того, они инициализируются.

Так что независимо от того, сколько раз вызывается fun(), статические переменные инициализируются только один раз при загрузке программы.

Переменные, определенные как статические и вне любых функций, все еще живут в сегментах данных или bss, но имеют только область файлов.

Когда ваш код скомпилирован, есть список импорта и экспорта, который является частью каждого объектного файла и используется редактором связей. Ваши статические переменные не будут в списке экспорта и, следовательно, недоступны для других объектных файлов.

Исключая ключевое слово static, ваши глобальные переменные помещаются в список экспорта и могут ссылаться на другие объектные модули, и редактор связей сможет находить символы при создании исполняемого файла.

Для pictoral зрения:

+--------- TEXT ---------+ Low memory 
| main()     | 
| fun()     | 
+--------- DATA ---------+ 
| int a (global scope) | 
| int c (file scope)  | 
| int e (function scope) | 
+---------- BSS ---------+ 
| int b (global scope) | 
| int d (file scope)  | 
| int f (function scope) | 
+------------------------+ 
+0

Я не могу понять, что является экспорт list.Is IT таблица символов? – CrystalJake

+0

Короче говоря, часть каждого .o (object file) - это список экспорта (список внешних символов - глобальные переменные/функции), которые видны другим объектным файлам. Кроме того, есть список импорта (глобальные переменные/функции), которые являются символами, указанными в объектном файле, но определенными в другом месте. Во время этапа компоновки ссылки редактор связей использует эти списки для объединения символов вместе. – ffhaddad

Смежные вопросы