Какой код в LLVM IR запускается перед main ()?

Кто-нибудь знает общее правило, для которого именно IR-код LLVM будет выполняться до main?

При использовании Clang ++ 3.6 создается впечатление, что конструкторы глобальных переменных класса вызываются через функцию в разделе ".text.startup" объектного файла. Например:

define internal void @__cxx_global_var_init() section ".text.startup" {
  call void @_ZN7MyClassC2Ev(%class.MyClass* @M)
  ret void
}

Исходя из этого примера, я предполагаю, что мне следует искать именно те определения функций IR, которые указывают section ".text.startup".

У меня есть две причины подозревать, что моя теория верна:

  • Я не вижу ничего другого в моем IR-файле LLVM (.ll) предлагает сначала запустить конструкторы глобальных объектов, если мы предположим, что LLVM не отслеживает специфические для C ++ имена функций, такие как "__cxx_global_var_init". Итак, section ".text.startup" - единственный очевидный способ сказать, что код должен выполняться до main(). Но даже если это верно, мы определили достаточное условие для запуска функции до main(), но не показали, что это единственный способ в LLVM IR, чтобы функция запускалась до main().

  • Компоновщик Gnu, в некоторых случаях , будет использовать первую инструкцию в разделе .text как точку входа в программу. Эта статья в программировании на Raspberry Pi описывается, как содержимое .text.startup становится первым телом кода, появляющимся в разделе программы .text, как средство, вызывающее выполнение кода .text.startup первым.

К сожалению, я не нашел ничего, что могло бы подтвердить мою теорию:

  • Когда я ищу в исходном коде LLVM 3.6 строку «.startup», я нахожу ее только в частях кода LLVM, специфичных для CLang. Чтобы моя теория была верной, я бы ожидал найти эту строку и в других частях кода LLVM; в частности, части вне интерфейса C ++.

  • Эта статья об инициализации данных в C ++, кажется, намекает на ".text.startup" имея особую роль, но это не сразу выходит и не говорит о том, что загрузчик программ Linux действительно ищет раздел с таким именем. Даже если бы это было так, я был бы удивлен, обнаружив потенциально специфичное для Linux имя раздела, имеющее особое значение в независимой от платформы LLVM IR.

  • Исходный код Linux 3.13.0, похоже, не содержит строку «.startup», что наводит на мысль, что загрузчик программы не ищет раздел с именем «.text.startup».


person Christian Convey    schedule 17.06.2015    source источник
comment
ОБНОВЛЕНИЕ: оказывается, что выполнение глобального c'tor, вероятно, было вызвано наличием _ 1_ глобальная переменная в этом IR-коде. Тем не менее, это оставляет два открытых вопроса: (1) почему clang также указывает section ".text.startup"? И (2), существуют ли другие способы, которыми ИК-код может указывать, что он должен быть запущен до main()?   -  person Christian Convey    schedule 17.06.2015


Ответы (1)


Ответ довольно прост - LLVM ничего не выполняет за кулисами. Задача runtime (CRT) C - выполнить все необходимые приготовления перед запуском main (). Это включает (но не ограничивается) статические ctors и подобные вещи. Среда выполнения обычно информируется об этих объектах через адреса конструкторов, создаваемых в специальных разделах (например, .init_array или .ctors). См., Например, http://wiki.osdev.org/Calling_Global_Constructors для получения дополнительной информации.

person Anton Korobeynikov    schedule 19.06.2015