Очевидно, вы должны учитывать это, только если вы уже используете все другие регистры GP, включая lr
, и не можете перенести часть своей работы в регистры NEON например, использование упакованного целого числа, даже если вы заботитесь только о младших 32 битах.
(Использование SIMD-регистров для большего скалярного целого числа обычно полезно, только если в вашем алгоритме есть изолированный набор значений, которые не взаимодействуют с другими значениями, и вам не нужно переходить на них или использовать их в качестве указателей На некоторых процессорах ARM медленная передача между int и SIMD.)
Это очень нестандартный и только возможно безопасный в пользовательском пространстве, а не ядро
Если у вас установлены обработчики сигналов, указатель стека должен быть действителен при поступлении одного из этих сигналов. (И это асинхронно.)
В Linux нет другого асинхронного использования указателя стека пользовательского пространства, кроме обработчиков сигналов. (За исключением случаев, когда вы отлаживаете с помощью GDB и используете print foo(123)
, где foo - функция в целевом процессе .)
Как уже упоминалось в комментариях к Могу ли я использовать rsp в качестве регистра общего назначения (эквивалент этого вопроса в x86-64), есть обходной путь даже для сигналов:
Используйте sigaltstack
для настройки альтернативного стека и укажите SA_ONSTACK
в флагах для sigaction
при установке обработчика.
Как указывает @Timothy, если ваше начальное значение SP может быть целым числом, которое оказывается "точкой" в стеке alt, механизм диспетчеризации сигнала будет предполагать, что это вложенный сигнал, а не будет изменить SP (потому что в фактическом случае вложенного сигнала это перезапишет первый обработчик сигнала, все еще используемый в стеке). Таким образом, вы можете находиться на расстоянии push
от SP, переходя на непопечатанную страницу, если только вы не выделите в два раза больше, чем вам нужно, и только передаете верхнюю половину на sigaltstack
. (Может быть, только 2 КБ или 4 КБ для простых обработчиков сигналов, которые возвращаются после небольшого выполнения).
Это должно быть безопасно даже для вложенных сигналов: только самый внешний обработчик сигналов может запускаться около нижней части стека alt и использовать часть выделенного пространства за пределами фактического altstack. Другой сигнал будет использовать пространство ниже этого, если SP все еще находится в пределах altstack. Или он будет использовать верхнюю часть altstack, если SP вышел за пределы altstack.
Или вы можете избежать необходимости такого перераспределения, используя SP для хранения указателя на что-то другое, что определенно не является стеком alt, если любой из ваших регистров GP должен быть указателем. Наличие это будет действительный указатель, открывающий вас к повреждению, а не к сбоям, если отладчик для чего-то использует текущий SP, или если вы неправильно используете механизм altstack. Но это только разница в режиме отказа: либо катастрофически.
Аппаратные прерывания сохраняют состояние сохранения в стеке ядра, а не в стеке пользовательского пространства . Если они использовали пользовательский стек:
- пространство пользователя может привести к сбою ОС при наличии недопустимого SP.
- пространство пользователя может получить привилегии ядра, если другой поток пространства пользователя изменит данные стека ядра (включая адреса возврата).
(Все потоки пользовательского пространства процесса совместно используют одну и ту же таблицу страниц и могут читать / записывать сопоставления стека друг друга.)
Linux / Android очень отличается от облегченной ОСРВ без виртуальной памяти или строгого принудительного разделения привилегий.