Spec-Zone.ru › GCC 15

7.6 Получение адреса возврата или кадра функции

Эти функции можно использовать для получения информации о вызывающих функциях.

Встроенная функция: void * __builtin_return_address (unsigned int level)

Эта функция возвращает адрес возврата текущей функции или одной из вызывающих её функций. Аргумент level задаёт количество кадров для просмотра вверх по стеку вызовов. Значение 0 возвращает адрес возврата текущей функции, значение 1 — адрес возврата вызывающей функции, и так далее. При встраивании ожидаемое поведение заключается в том, что функция возвращает адрес функции, в которую происходит возврат. Чтобы обойти это поведение, используйте атрибут функции noinline.

Аргумент level должен быть целочисленной константой.

На некоторых машинах может быть невозможно определить адрес возврата любой функции, кроме текущей; в таких случаях или при достижении вершины стека эта функция возвращает неопределённое значение. Кроме того, __builtin_frame_address можно использовать для определения того, достигнута ли вершина стека.

Может потребоваться дополнительная постобработка возвращаемого значения; см. __builtin_extract_return_addr.

Представление адреса возврата, сохранённого в памяти, может отличаться от адреса, возвращаемого __builtin_return_address. Например, на AArch64 сохранённый адрес может быть искажён механизмом подписи адреса возврата, тогда как адрес, возвращаемый __builtin_return_address, — нет.

Вызов этой функции с ненулевым аргументом может привести к непредсказуемым последствиям, включая аварийное завершение вызывающей программы. Поэтому вызовы, считающиеся небезопасными, диагностируются, если задан параметр -Wframe-address. Такие вызовы следует выполнять только при отладке.

На целевых платформах, где адреса кода можно представить как void *,

void *addr = __builtin_extract_return_addr (__builtin_return_address (0));

возвращает адрес кода, по которому вернулась бы текущая функция. Например, такой адрес можно использовать с dladdr или другими интерфейсами, работающими с адресами кода.

Встроенная функция: void * __builtin_extract_return_addr (void *addr)

Адрес, возвращаемый __builtin_return_address, может потребоваться передать этой функции, чтобы получить фактически закодированный адрес. Например, на 31-разрядной платформе S/390 необходимо сбросить старший бит, а на платформах SPARC — прибавить смещение, чтобы получить адрес следующей выполняемой инструкции.

Если коррекция не требуется, эта функция просто возвращает addr без изменений.

Встроенная функция: void * __builtin_frob_return_addr (void *addr)

Эта функция выполняет обратное действие по отношению к __builtin_extract_return_addr.

Встроенная функция: void * __builtin_frame_address (unsigned int level)

Эта функция аналогична __builtin_return_address, но возвращает адрес кадра функции, а не её адрес возврата. Вызов __builtin_frame_address со значением 0 возвращает адрес кадра текущей функции, со значением 1 — адрес кадра вызывающей функции, и так далее.

Кадр — это область стека, в которой хранятся локальные переменные и сохранённые регистры. Обычно адрес кадра — это адрес первого слова, помещённого функцией в стек. Однако точное определение зависит от процессора и соглашения о вызовах. Если у процессора есть выделенный регистр указателя кадра и у функции есть кадр, то __builtin_frame_address возвращает значение регистра указателя кадра.

На некоторых машинах может быть невозможно определить адрес кадра любой функции, кроме текущей; в таких случаях или при достижении вершины стека эта функция возвращает 0, если начальный указатель кадра был правильно инициализирован кодом запуска.

Вызов этой функции с ненулевым аргументом может привести к непредсказуемым последствиям, включая аварийное завершение вызывающей программы. Поэтому вызовы, считающиеся небезопасными, диагностируются, если задан параметр -Wframe-address. Такие вызовы следует выполнять только при отладке.

Встроенная функция: void * __builtin_stack_address ()

Эта функция возвращает значение регистра указателя стека со смещением STACK_ADDRESS_OFFSET, если оно определено.

Концептуально возвращаемый этой встроенной функцией адрес является границей между областью стека, выделенной для использования вызывающей функцией, и областью, которую может изменить вызов функции и которую вызывающая функция может безопасно обнулить до или после (но не во время) последовательности вызова.

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

Даже если указатель стека смещён, результат не смещён. Область сохранения регистров в SPARC считается изменяемой при вызовах, а не выделенной для использования вызывающей функцией, поскольку она никогда не используется во время выполнения самой вызывающей функции.

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

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Return-Address.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API