Заметки с плавающей запятой для драйверов

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

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

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

Заметка с плавающей запятой Описание
_Kernel_float_saved_ Функция с заметками сохраняет состояние оборудования с плавающей запятой при успешном возврате функции.
_Kernel_float_restored_ Функция с заметками восстанавливает состояние оборудования с плавающей запятой при успешном возврате функции.
_Kernel_float_used_ Если функция вызывается вызывающей функцией безопасно, можно использовать заметку _Kernel_float_used_ для подавления отчетов об ошибках. Однако если вызывающая функция также не помечена _Kernel_float_used_ или вызов функции не выполняется между функциями, помеченными _Kernel_float_saved_ и _Kernel_float_restored_ соответственно, средства анализа кода будут сообщать об ошибке.

Эти заметки уже применяются к состоянию KeSaveFloatingPoint и системным функциям KeRestoreFloatingPointState, а также к заметкам для получения и освобождения ресурсов для предотвращения утечек. Аналогичные функции EngXxx также примечаются таким образом. Однако функции, которые упаковывают эти функции, также должны использовать эти заметки.

Если функция в целом вызывается безопасно какой-то вызывающей функцией, ее можно примечать с помощью _Kernel_float_used_ заметки. Это отключает предупреждение, а также заставляет средства анализа кода подтвердить, что вызывающий объект безопасно использует функцию. При необходимости можно добавить дополнительные уровни _Kernel_float_used_. Заметка _Kernel_float_used_ автоматически предоставляется средствами анализа кода, если результат функции или один из параметров функции является типом с плавающей запятой, но это не повредит предоставить заметку явным образом.

Например, заметка _Kernel_float_saved_ указывает, что состояние с плавающей запятой хранится в параметре FloatingState системной функции KeSaveFloatingPointState.

_Must_inspect_result_  
_IRQL_requires_max_(DISPATCH_LEVEL)  
__drv_valueIs(<0;==0)  
_When_(return==0, _Kernel_float_saved_)  
_At_(*FloatingState, _Kernel_requires_resource_not_held_(FloatState) _When_(return==0, _Kernel_acquires_resource_(FloatState)))  
__forceinline  
NTSTATUS  
KeSaveFloatingPointState (  
    _Out_ PVOID FloatingState  
    )  

В следующем примере заметка _Kernel_float_used_ подавляет предупреждения об использовании состояния с плавающей запятой. Заметка также заставляет средства анализа кода подтвердить, что все вызовы MyDoesFloatingPoint происходят в безопасном контексте с плавающей запятой.

_Kernel_float_used_
void
    MyDoesFloatingPoint(arguments);

Заметки SAL 2.0 для драйверов Windows