6.52 Получение адреса возврата или кадра функции
Эти функции могут использоваться для получения информации о вызывающих функциях.
-
Встроенная функция:
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-14.2.0/gcc/Return-Address.html