Подтвердить что ты не робот

Какие функции gcc добавляют в linux ELF?

При связывании программы hello-world в c (или asm) с gcc она добавит некоторые вещи в файл исполняемого файла результата. Я знаю только о динамическом компоновщике времени выполнения и точке входа _start, но каковы эти дополнительные функции?

00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
0000000000400470 t __do_global_dtors_aux
0000000000400490 t frame_dummy
00000000004004e0 T __libc_csu_init
0000000000400550 T __libc_csu_fini
0000000000400554 T _fini
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end

Что они и зачем? Описывается ли это где-то? Googling не помогает.

4b9b3361

Ответ 1

Большинство из них представляют собой различные методы для выполнения кода до или после самой "основной" программы и большинство из них живут в crtstuff.c (https://github.com/gcc-mirror/gcc/blob/master/libgcc/crtstuff.c). Они существуют для поддержки функций различных C-подобных языков программирования, но к ним также можно получить доступ на C. Возможно, это кажется сложным, потому что некоторые из них представляют собой устаревший багаж и некоторые изменения, необходимые для поддержки различных архитектур, на которых работает GCC.

 

Из списка, один за другим (или два на два):

00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones

Транзакционная память предназначена для упрощения программирования с потоками. Это альтернатива синхронизации на основе блокировки. Эти подпрограммы сбрасывают и устанавливают, соответственно, таблицу, используемую библиотекой (libitm), которая поддерживает эти функции. Подробнее о ТМ здесь https://gcc.gnu.org/wiki/TransactionalMemory и здесь http://pmarlier.free.fr/gcc-tm-tut.html

 

0000000000400470 t __do_global_dtors_aux

Запускает все глобальные деструкторы при выходе из программы в системах, где .fini_array недоступен.

 

0000000000400490 t frame_dummy

Эта функция находится в разделе .init. Он определяется как void frame_dummy ( void ), и вся его точка в жизни - это вызов __register_frame_info_bases, который имеет аргументы. Очевидно, что вызов функций с аргументами из раздела .init может быть ненадежным, поэтому эта функция так __register_frame_info_bases не вызывается непосредственно из .init section. Информационные базы .eh_frame используются для обработки исключений и аналогичных функций (например, функций, объявленных с помощью __attribute__((cleanup(..)))).

 

00000000004004e0 T __libc_csu_init
0000000000400550 T __libc_csu_fini

Они запускают любые инициализаторы и финализаторы на уровне программ (вроде конструкторов/деструкторов для всей вашей программы). Если вы определяете такие функции, как:

void __attribute__ ((constructor)) mefirst () {
    /* ... do something here ... */
}

void __attribute__ ((destructor)) melast () {
    /* ... do something here ... */
}

они будут вызываться до и после main() соответственно этими подпрограммами. См. Также https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

 

0000000000400554 T _fini

Это устаревший способ запуска деструктора на уровне уровня файла (на самом деле) (немного информации об этом можно найти в man dlclose). Соответствующая устаревшая функция для конструкторов __init.

 

0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start

Они отмечают конец и начало раздела .init_array, который содержит указатели на все инициализаторы уровня программы (см. выше __libc_csu_init).

 

0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end

Они отмечают конец и начало раздела .fini_array, который содержит указатели на все финализаторы уровня программы (см. выше __libc_csu_fini).

 

[EDIT] Некоторые дополнительные примечания:

  • Ссылка http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html из комментария комментария Jester содержит хорошую диаграмму и небольшую выборку программа, иллюстрирующая общий порядок выполнения этих действий, а также для доступа к некоторым из этих функций из C.

  • Термины 'ctors' и 'dtors' являются аббревиатурами для "конструкторы" и "деструкторы" соответственно.

  • Разница между глобальными конструкторами/деструкторами и объектным файлом конструкторы/деструкторы наиболее очевидны, когда ваша программа построенный из нескольких объектных файлов.

  • Символы, отмеченные ' T' (__libc_csu_init, __libc_csu_fini, _fini) являются "глобальными" (внешне видимыми), остальные (отмеченные " t" ).