setjmp/longjmp в ядре XNU/Darwin

Мне нужно longjmp/setjmp в файле .kext для OS X. К сожалению, я не думаю, что есть официальная поддержка этих функций в XNU. Есть ли какая-то фундаментальная причина, по которой это не может работать или просто не реализовано прямо сейчас?

Любые идеи, как я могу заставить это работать?

Если это поможет, я хочу попытаться заставить Lua работать в ядре OS X, но время выполнения, похоже, зависит либо от исключений longjmp/setjmp, либо от C++, оба из которых недоступны в XNU.


person Johannes Weiss    schedule 15.05.2016    source источник


Ответы (1)


В стандартном использовании setjmp/longjmp нет ничего, что мешало бы вам использовать его в контексте ядра. Главное, с чем следует быть осторожным в отношении контекста выполнения ядра, это то, что текущий поток обычно идентифицируется с помощью арифметики указателя на текущем указателе стека, поэтому, в отличие от пользовательского пространства, вы не можете использовать зеленые потоки или иным образом возиться с регистром rsp ( на х86-64). longjmp устанавливает указатель стека, но только на значение, ранее сохраненное setjmp, которое будет в том же стеке, если вы придерживаетесь стандартного использования, так что это безопасно.

Насколько мне известно, компиляторы не обрабатывают вызовы setjmp() специально, поэтому вы можете довольно легко реализовать свою собственную версию в виде функции на языке ассемблера. Setjmp потребуется сохранить указатель возврата, указатель стека и любые регистры, сохраненные вызываемым пользователем, в массив типа jmp_buf, переданный в функцию; все это определено в ABI для рассматриваемой платформы (x86-64 sysv в случае OS X). Затем верните 0 (установите rax равным 0 на x86-64). Ваша версия longjmp просто должна будет восстановить содержимое этого массива и вернуться в сохраненное место с переданным значением в качестве возвращаемого значения (скопируйте аргумент в rax на x86-64). Чтобы соответствовать стандарту, вы должны вернуть 1, если в longjmp передается 0.

В пользовательском пространстве setjmp/longjmp обычно также влияют на маску сигнала, которая не применяется в ядре.

person pmdj    schedule 17.05.2016
comment
По какому-то стечению обстоятельств, я рассматриваю портирование через ZFS Channel Programs на реализацию OSX ZFS, которая загружает lua в ядро, поэтому меня также интересует вывод на этот счет. В настоящее время он загружает lua без возможностей throw(), но это явно нежелательно. - person lundman; 06.10.2016