2016-02-04 3 views
1

Я видел код, как показано ниже в проекте:Что такое «my_main()» в коде

extern void my_main(void) __attribute__ ((__noreturn__, asection(".main","f=ax"))); 

Что это делать?

В проекте нет прямой функции main(). Описанный выше код указывает компилятору, что my_main() следует рассматривать как main()?

Кроме того, что указывает раздел памяти .main?

+0

Не могли бы вы указать используемый компилятор/идеал? – Superlokkus

+0

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

+0

это функция void, объявленная атрибутами функции. [Читать здесь] (https://gcc.gnu.org/onlinedocs/gcc-3.2.1/gcc/Function-Attributes.html) – Michi

ответ

3

В чем заключается вышеуказанная декларация, объявляется функция extern с именем my_main() без аргументов.

Раздел __attribute__ является GNU/LLVM attribute syntax. Атрибуты - это в основном прагмы, описывающие нестандартную или расширенную функцию рассматриваемой функции - в данном случае - my_main().


К my_main() относятся два атрибута.

__noreturn__ (поиск по noreturn) указывает, что функция будет никогда возвращение.

Это отличное от возврата void - в void -type функции, вызовы функции все еще return в какой-то момент, даже без значения. Это означает, что выполнение будет возвращаться/возвращаться к вызывающему абоненту.

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

Он также используется в тех местах, где добавление обратного адреса в стек приведет к нарушению стека таким образом, что это помешает вызываемой функции (хотя это редко, и я только когда-либо видел, что это использовалось по этой причине один раз) ,


Второй атрибут, asection(".main","f=ax"), немного более расплывчатым. Кажется, я не могу найти конкретную документацию, но кажется более или менее довольно простой.

Что это, кажется, делает это указание на linker section, а также то, что появляется быть unix filemode указав, что в результате двоичный E х ecutable, хотя я могу ошибаться.


При написании собственного кода, все функциональные возможности помещены в соответствующие разделы целевого двоичного формата (например, ELF, Маха-O, PE и т.д.) Наиболее распространенные секции .text, .rodata и .data.

Однако при вызове ld, компоновщик GCC, вы можете указать linker script указать точно как вы хотите целевой двоичный будет построен.

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

Одним из распространенных заблуждений является то, что вы никогда не используете ld. Это не так; при запуске gcc или g++ или clang -семейком компиляторов без флага -c, вы непреднамеренно вызываете ld с помощью default linker script, используемого для связи ваших двоичных файлов.

Сценарии компоновщика важны, особенно для встроенных аппаратных средств, где ПЗУ должно быть создано для спецификации памяти.


Итак, вернемся к вашей строке кода: он помещает my_func() в произвольный раздел под названием .main. Это все, что он делает. В конечном счете, где-то в вашем проекте есть сценарий компоновщика, который указывает, как используется .main и где он идет.

Я предположил бы, что цель этого кода в том, чтобы разместить my_main() на точный адрес в целевом двоичном/исполняемый файл, поэтому все, что использует его знает точное местонахождение этой функции (asection(".main")) и может использовать его в качестве точка входа (__noreturn__).

+0

Надеюсь, это поможет. Я могу объяснить немного лучше, если это необходимо, поскольку вы действительно задали несколько вопросов в одном! – Qix

+0

Спасибо за ваш ответ. Обычно для проекта должен присутствовать один 'main()'. Но здесь, в этом проекте, я вижу только этот 'my_main()'. Непонятно, что раздел '.main' сделает' my_main() 'как' main() ' –

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