Войти
ФлеймФорумПрограммирование

Расстановка точек над Ӥнициализацией CRT

Страницы: 1 2 Следующая »
#0
15:25, 9 июля 2015

Как бы давно уже периодически балуюсь с написание своего рантайма.
Ну с первого конкурса про 64k где то.
Хочется до конца для себя выяснить один момент.
Начнем с gcc.
https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
Вот в этой статье говорится о каких то двух путях инициализации и двух вариантах каждого пути.
Но в основном суть в чем
Компоновщик генерирует два списка
__CTOR_LIST__
и
__DTOR_LIST__
эти списки строятся компоновщиком на основе секций .ctors и .dtors объектного файла который выдал компилятор.
А вот дальше я не совсем понимаю магию.
По мимо этого я так понимаю есть некоторые системы, которые поддерживают секции .init и .fini
в эти секции, как я понимаю встраивается какая то магия из GCC + компоновщик строит там последовательность вызовов, как я понял
и в итоге в этих секциях получаются функции __init и __fini которые вызывает рантайм и все пучком.
если нету .init и .fini то начинаются пляски над встраиванием вызова функции которая вызывает конструкторы в функцию main
и на последок есть какая то магия с генерацией кода для вызова деструкоров компоновщиком.

Так вот в чем вопрос, ни где не приводятся примеры подобных систем, как понять на какой случай должны рассчитывать те кто пишут новый рантайм?
я так понимаю libgcc рассчитана на все случаи, но вот допустим копаясь в коде newlib я так понял, что они сводят все к какому то одному варианту используя прослойку в виде libgloss
и как я понял в libgloss создаются функции __init и __fini по аналогии с теми которые генерирует gcc только в разных комбинациях для разных платформ и случаев.

дальше идет CRT VC++
https://msdn.microsoft.com/en-us/library/bb918180%28v=vs.140%29.aspx
в принципе в статье все четко описывается
но есть одно но
в статье описываются секции
.CRT$XCA - .CRT$XCZ
при этом говорится что пользовательские конструкторы помещаются в .CRT$XCU
шарясь по коду CRT я так понял, что другие секции из этого промежутка могут использоваться для нужд рантайма

да что уж там говорить )

extern "C" _CRTALLOC(".CRT$XIA") _PIFV __xi_a[] = { nullptr }; // C initializers (first)
extern "C" _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[] = { nullptr }; // C initializers (last)
extern "C" _CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { nullptr }; // C++ initializers (first)
extern "C" _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = { nullptr }; // C++ initializers (last)
extern "C" _CRTALLOC(".CRT$XPA") _PVFV __xp_a[] = { nullptr }; // C pre-terminators (first)
extern "C" _CRTALLOC(".CRT$XPZ") _PVFV __xp_z[] = { nullptr }; // C pre-terminators (last)
extern "C" _CRTALLOC(".CRT$XTA") _PVFV __xt_a[] = { nullptr }; // C terminators (first)
extern "C" _CRTALLOC(".CRT$XTZ") _PVFV __xt_z[] = { nullptr }; // C terminators (last)
+
http://wiki.osdev.org/Visual_C++_Runtime
я как бы не копенгаген, но из того что я понял по коду тут запасено говнокода на все случае жизни с запасом и M$ по тихоньку пихает куда в голову взбредет то, что нужно
там даже есть файлик со списком секций которые используются
#pragma section(".CRT$XCA",long,read)
#pragma section(".CRT$XCAA",long,read)
#pragma section(".CRT$XCC",long,read)
#pragma section(".CRT$XCZ",long,read)
#pragma section(".CRT$XDA",long,read)
#pragma section(".CRT$XDC",long,read)
#pragma section(".CRT$XDZ",long,read)
#pragma section(".CRT$XIA",long,read)
#pragma section(".CRT$XIAA",long,read)
#pragma section(".CRT$XIC",long,read)
#pragma section(".CRT$XID",long,read)
#pragma section(".CRT$XIY",long,read)
#pragma section(".CRT$XIZ",long,read)
#pragma section(".CRT$XLA",long,read)
#pragma section(".CRT$XLC",long,read)
#pragma section(".CRT$XLD",long,read)
#pragma section(".CRT$XLZ",long,read)
#pragma section(".CRT$XPA",long,read)
#pragma section(".CRT$XPB",long,read)
#pragma section(".CRT$XPX",long,read)
#pragma section(".CRT$XPXA",long,read)
#pragma section(".CRT$XPZ",long,read)
#pragma section(".CRT$XTA",long,read)
#pragma section(".CRT$XTB",long,read)
#pragma section(".CRT$XTX",long,read)
#pragma section(".CRT$XTZ",long,read)

но если я правильно понял, то компилятор может пхать только в ".CRT$XCU"
или есть еще варианты?

и по сути если я пишу свой рантайм, мне просто нужно свести все к виду подобному GCC?

и на последок, в интернете порой мелькают такие секции как
.init_array и .fini_array
это вообще о чем?
и до кучи есть какие то
#pragma init
#pragma fini
я так понял что GCC поддерживает их только для соляриса, но я так же понял что есть какие то компиляторы которые их поддерживают,
что это за компиляторы тогда?
в vc++ есть еще
#pragma init_seg
https://msdn.microsoft.com/ru-ru/library/vstudio/7977wcck%28v=vs.120%29.aspx
я так понял это немного не о том, но как она влияет на рантайм?

#1
15:32, 9 июля 2015

а да забыл
в статье
http://wiki.osdev.org/Visual_C++_Runtime
дословно говорится

// Linker puts constructors between these sections, and we use them to locate constructor pointers.
#pragma section(".CRT$XIA",long,read)
#pragma section(".CRT$XIZ",long,read)
#pragma section(".CRT$XCA",long,read)
#pragma section(".CRT$XCZ",long,read)
т.е. компилятор таки помещает глобальные конструкторы не только в .CRT$XCU?
или при компиляции в режиме си используется другая секция?
или к чему вообще разделение на C initializers и на C++ initializers в статье, которая написана для работы без рантайма?
т.е. статью просто писал не шарящий, просто на основе исходников CRT?
потому как мне показалось что в CRT разделение как раз для того что бы в ручную разделить инициализаторы необходимые для C рантайма, от глобальных конструкторов С++
но все это разделение делается руками, компилятор сует глобальные конструкторы только в .CRT$XCU
ну на сколько я понял по крайней мере
т.е. секция .CRT$XIA - .CRT$XIZ не особо то и нужна

или может в VC++ есть еще какой то способ поместить что то в какую либо из этих секций? кроме ручного указания имени секции?

#2
15:42, 9 июля 2015

и еще кое что забыл...
зачем я сравнивал GCC и VC++
я так понял в VC++ множество секций, что бы руками решать очередность вызовов инициализаторов,
в gcc же я так понимаю эта очередность решается через приоритеты у функций инициализаторов
я про вот это
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.htm… on-Attributes
__attribute__((constructor (priority)))
или так же влияет очередность файлов при подаче компоновщику?
я просто как то не нашел частого употребления аттрибутов с приоритетом в libgcc
получается у них там не так остро стоит данная проблема?

#3
15:58, 9 июля 2015

cNoNim
> Так вот в чем вопрос, ни где не приводятся примеры подобных систем, как понять
> на какой случай должны рассчитывать те кто пишут новый рантайм?

Скомпилируй с ключом -S, посмотри что будет на выхлопе в асме, думаю можно будет догадаться по наличию или отсутствию тех или иных секций.

#4
16:04, 9 июля 2015

=A=L=X=
так это то я давно сделал, но это же только конкретная система и конкретный случай

#5
16:04, 9 июля 2015

cNoNim
> компилятор сует глобальные конструкторы только в .CRT$XCU
На сколько я помню, как говорила Алена С++, компиль студии сует в порядке, перечисленном в модуле, а между модулей в лексикографическом порядке их имен.

#6
16:10, 9 июля 2015

laMer007
> а между модулей в лексикографическом порядке их имен.
да в каком порядке он их сует не столь важно, важно определиться с секцией, ну допустим что глобальные конструкторы попадают XCU я уже проверил
вопрос заключается в том, может ли компилятор что нибудь куда нибудь еще сунуть и в каком случае?
исключая ручное указание секции

#7
16:20, 9 июля 2015

Как ты это сделал с заголовком?

#8
16:22, 9 июля 2015

laMer007
> На сколько я помню, как говорила Алена С++, компиль студии сует в порядке,
> перечисленном в модуле, а между модулей в лексикографическом порядке их имен.
тут еще важно понимать
.CRT$XCU
это не один указатель на функцию, это секция в которую попадают все конструкторы
а
.CRT$XCA и .CRT$XCZ
это тоже секции в эти секции в ручную помещаются переменный, по адресам которых рантайм определяет границы списка функций
просто есть гарантия что секция
.CRT$XCU
будет после .CRT$XCA
и до .CRT$XCZ
и все

#9
16:25, 9 июля 2015

cNoNim
> там даже есть файлик со списком секций которые используются
когда я писал свой crt на тот же конкурс, то заметил что секции выстраиваются в алфавитном порядке, поэтому то что попало в секцию XCAA уже находится между XCA и XCZ поэтому большая часть списка из osdev сокращается к тем 4 промежуткам из msdn.
ни разу не встречал XDA и XLA, возможно это из области CLI или WinRT

#10
16:26, 9 июля 2015
TarasB
> Как ты это сделал с заголовком?
юникод? не, не слышал
Ӥ
#11
16:28, 9 июля 2015

Pushkoff
ну секции выставляются по определению в алфавитном порядке, компоновщиком,
список большой не в osdev это в исходниках CRT и возможно правда какие то секции лишние,
но ведь по факту если компилятор сует все только в XCU
то можно обойтись двумя секциями и не париться
или мы чего то таки не знаем?

#12
16:45, 9 июля 2015

cNoNim
секция XI пуста из-за того что в С нет конструирования глобальных переменных как такового. константы либо линкер запиливает на свои места, либо если ее вычисление довольно сложное то это ошибка компиляции. я думаю секция оставлена для инициализации флоатов, но в связи с развитием компиляторов, необходимость в этом отпала.

#13
16:49, 9 июля 2015

cNoNim
> так это то я давно сделал, но это же только конкретная система и конкретный
> случай

Ну подозреваю именно потому в той либе которую ты смотрел всё так как ты смотрел.

#14
16:58, 9 июля 2015

Pushkoff
ну по факту XI не совсем пустая, туда руками в CRT много чего запихивается
хотя идея в принципе понятна

в общем то можно наверное забить, на все секции кроме XCU если они не нужны рантайму
у нас ведь нет цели обеспечивать обратную совместимость.

=A=L=X=
вопрос появился потому, что нет смысла наверное париться с кучей вариаций инициализации,
а сделать один допустим вызовы функций __init и__fini и сделать две заглушки для GCC через __CTOR_LIST__ и для VC++ через секции и не париться
хочется просто немного кросс платформа, а кому надо тот сам набабахает заглушки для всех остальных вариантов
как вобщем поступили в newlib

Страницы: 1 2 Следующая »
ФлеймФорумПрограммирование

Тема в архиве.