From 99094b3069a45d60d4821e44bd73127f105fd497 Mon Sep 17 00:00:00 2001 From: x0rw Date: Tue, 18 Mar 2025 01:55:49 +0000 Subject: [PATCH] Add inline assembly guideline section --- .../exceptions-and-errors.rst | 40 ++++++++ .../src/coding-guidelines/inline-assembly.rst | 95 +++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/exceptions-and-errors.rst b/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/exceptions-and-errors.rst index be0fd7cb..d7b49397 100644 --- a/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/exceptions-and-errors.rst +++ b/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/exceptions-and-errors.rst @@ -5,3 +5,43 @@ Exceptions and Errors ===================== +.. guideline:: : + :id: gui_grekkB0SueIQ + :status: draft + :fls: fls_dzq9cdz4ibsz + :tags: reduce-human-error + :category: + :recommendation: required + + Description of the guideline goes here. + + .. rationale:: + :id: rat_ZpZJWgXjvs3N + :status: draft + + Explanation of why this guideline is important. + + .. bad_example:: + :id: bad_ex_FL4x7PkAk5gD + :status: draft + + Explanation of code example. + + .. code-block:: rust + + fn example_function() { + // Bad implementation + } + + .. good_example:: + :id: good_ex_QL6sOqjAM5Mn + :status: draft + + Explanation of code example. + + .. code-block:: rust + + fn example_function() { + // Bad implementation + } + diff --git a/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/inline-assembly.rst b/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/inline-assembly.rst index 3885903d..c9bbf65b 100644 --- a/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/inline-assembly.rst +++ b/subcommittee/coding-guidelines/initiatives/safety-critical-rust-coding-guidelines/src/coding-guidelines/inline-assembly.rst @@ -5,3 +5,98 @@ Inline Assembly =============== + +This document provides guidelines for using inline assembly in Rust code... + +.. guideline:: All usage of inline assembly must be thoroughly documented + :id: gui_vZE9kLPQ7m93 + :status: draft + :fls: fls_z1il3w9nulzy + :tags: security, reduce-human-error, readability + :category: + :recommendation: required + + .. note:: + **MISRA Reference** + All usage of assembly code must be documented, including the purpose, inputs, outputs, side effects, and safety considerations. + + .. rationale:: + :id: rat_Rb0kktvGhbVk + :status: draft + + Inline assembly can introduce undefined behavior if not properly documented. + - If the assembly fails to execute correctly, the return value may be uninitialized, leading to unpredictable results. + - Functions that assume success without error handling can cause silent failures in production. + - Without clear comments, maintainers may misuse the function, leading to integration errors or security issues. + + .. bad_example:: + :id: bad_ex_V1rThIfyrmTQ + :status: draft + + The following code is **non-compliant** with THE guidelines because: + - It does not specify `nomem` and `nostack` constraints. + - The return value `result` might be uninitialized if the inline assembly fails. + - It lacks documentation, making it hard to maintain. + + .. code-block:: rust + + pub fn bad_add_asm(a: u32, b: u32) -> u32 { + let result: u32; + unsafe { + asm!( + "add {0}, {1}, {2}", + out(reg) result, + in(reg) a, + in(reg) b + ); + } + result // Possible UB: result might be uninitialized if asm fails + } + + .. good_example:: + :id: good_ex_tDWewxl8qUE4 + :status: draft + + .. note:: + The following example adheres to THE guidelines by ensuring: + - The use of `options(nomem, nostack)` to prevent unexpected memory modifications. + - Proper inline documentation to describe inputs, outputs, and safety considerations. + + .. code-block:: rust + + /// # Safe Inline Assembly Addition + /// + /// This function takes two `u32` values and returns their sum using inline assembly. + /// - Adheres to Rust guidelines (structured, documented, and avoids undefined behavior). + /// - Uses explicit register constraints to prevent side effects. + /// + /// ## Safety Considerations: + /// - Inline assembly is carefully constrained to avoid modifying unintended registers. + /// - No undefined behavior (e.g., no division by zero, out-of-range values). + /// + /// # Arguments: + /// - `a`: First operand. + /// - `b`: Second operand. + /// + /// # Returns: + /// - Sum of `a` and `b` (`u32`). + /// + /// # Example: + /// ``` + /// let result = add_asm(2, 3); + /// assert_eq!(result, 5); + /// ``` + #[inline(always)] + pub fn add_asm(a: u32, b: u32) -> u32 { + let result: u32; + unsafe { + asm!( + "add {0}, {1}, {2}", // ARM syntax: add result, a, b + out(reg) result, // Output operand + in(reg) a, // Input operand a + in(reg) b, // Input operand b + options(nomem, nostack) // Ensures no memory or stack modifications + ); + } + result + }