Чтобы понять, что можно сказать о входящем и выходящем из реализации POSIX lib c, я делал свой собственный в течение прошлого года или около того, покусывая края реализации единой Unix спецификации, которую я считал быть в моем наборе навыков, пытаясь наметить план движения вперед, и я подошел к моменту, когда следующим шагом будет создание библиотеки времени выполнения.
Теперь я пытаюсь понять логику c, объясняющую, как программы связаны с библиотекой времени выполнения c.
Чтение того, что руководство g cc также говорило о инициализации как текст формата elf и некоторые текстовые сообщения во встроенных системах, я в основном узнал, что код инициализации находится в своих собственных разделах .init и .fini, что crti.o и crtn.o обычно содержат заглушки функций crtbegin и crtend fle sh, вызывая серию функций, указанных в списке указателей функций, которые должен определить скрипт компоновщика.
Это подводит меня к моим вопросам, предполагая, что приведенное выше обобщение является правильным, в чем заключается логика c, лежащая в основе разработки функций init и fini таким образом, в частности описанным ниже способом:
Пролог функции (__init) появляется в разделе .init crti.o; эпилог появляется в crtn.o. Аналогично для функции __fini в разделе .fini. Обычно эти файлы предоставляются операционной системой или библиотекой GNU C, но предоставляются G CC для нескольких целей. Объекты crtbegin.o и crtend.o (для большинства целей) скомпилированы из crtstuff. c. Они содержат, среди прочего, фрагменты кода в разделах .init и .fini, которые переходят к подпрограммам в разделе .text. Компоновщик соберет все части раздела вместе, что приведет к полной функции __init, которая вызывает подпрограммы, которые нам нужны при запуске.
Почему бы функциям библиотеки init и fini просто не вызвать прямой вызов функции инициализации и уничтожения библиотеки напрямую вместо перечисления их в сценарии компоновщика и распределения битов раздела по нескольким объектным файлам?
Кроме того, откуда берутся функции, перечисленные в списке компоновщика. Из приведенной ниже цитаты я предполагаю, что эти функции определены c для crt, чтобы сказать, ассоциировать дескрипторы файла std [in, out, err] с файловыми потоками или инициализировать переменную locale_t равной C locale et c , если это тот случай, когда эти функции хранятся.
Компоновщик должен создать два списка этих функций - список функций инициализации, называемый CTOR_LIST , и список завершения функции, называемые DTOR_LIST .