From 0a89373cc3025667349a404d2825d9716503cef1 Mon Sep 17 00:00:00 2001 From: Jubilee <46493976+workingjubilee@users.noreply.github.com> Date: Mon, 27 Mar 2023 00:28:31 -0700 Subject: [PATCH 1/2] Explain typos in `asm!` can be unsound --- src/inline-assembly.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/inline-assembly.md b/src/inline-assembly.md index 09db2a285..f575a4e55 100644 --- a/src/inline-assembly.md +++ b/src/inline-assembly.md @@ -52,6 +52,16 @@ asm := "asm!(" format_string *("," format_string) *("," operand) [","] ")" global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")" ``` +## Correctness and Validity + +In addition to all of the rules that follow, the string argument to `asm!` must ultimately become; after all other arguments are evaluated, formatting is performed, and operands are translated; assembly that is both syntactically correct and semantically valid for the target architecture. The formatting rules allow Rust to generate assembly with correct syntax. Rules concerning operands permit valid translation of Rust operands into and out of `asm!`. Adherence to these rules is necessary, but not sufficient, for the final assembly to be correct and valid. For instance: + +- arguments may be placed in positions which are syntactically incorrect after formatting +- an instruction may be correctly written, but given architecturally invalid operands +- an architecturally unspecified instruction may be assembled into unspecified code +- a set of instructions, each correct and valid in isolation, may cause undefined behavior when placed in sequence + +As a result, the following rules are _non-exhaustive_. Rust is not required to check the correctness and validity of the initial string nor the final assembly that is generated. The assembler may check for correctness and validity but is not required to do so. When using `asm!`, a typographical error may be sufficient to make a program unsound, and the rules for assembly may include thousands of pages architectural reference manuals. Programmers should exercise appropriate care. ## Scope From aba56b9dd7b7e9e7a146fa98a8b70474b43759a5 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 7 Apr 2023 22:00:45 -0700 Subject: [PATCH 2/2] Move Correctness and Validity section --- src/inline-assembly.md | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/inline-assembly.md b/src/inline-assembly.md index f575a4e55..a12f495ff 100644 --- a/src/inline-assembly.md +++ b/src/inline-assembly.md @@ -52,17 +52,6 @@ asm := "asm!(" format_string *("," format_string) *("," operand) [","] ")" global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")" ``` -## Correctness and Validity - -In addition to all of the rules that follow, the string argument to `asm!` must ultimately become; after all other arguments are evaluated, formatting is performed, and operands are translated; assembly that is both syntactically correct and semantically valid for the target architecture. The formatting rules allow Rust to generate assembly with correct syntax. Rules concerning operands permit valid translation of Rust operands into and out of `asm!`. Adherence to these rules is necessary, but not sufficient, for the final assembly to be correct and valid. For instance: - -- arguments may be placed in positions which are syntactically incorrect after formatting -- an instruction may be correctly written, but given architecturally invalid operands -- an architecturally unspecified instruction may be assembled into unspecified code -- a set of instructions, each correct and valid in isolation, may cause undefined behavior when placed in sequence - -As a result, the following rules are _non-exhaustive_. Rust is not required to check the correctness and validity of the initial string nor the final assembly that is generated. The assembler may check for correctness and validity but is not required to do so. When using `asm!`, a typographical error may be sufficient to make a program unsound, and the rules for assembly may include thousands of pages architectural reference manuals. Programmers should exercise appropriate care. - ## Scope Inline assembly can be used in one of two ways. @@ -495,6 +484,29 @@ To avoid undefined behavior, these rules must be followed when using function-sc > **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call. +### Correctness and Validity + +In addition to all of the previous rules, the string argument to `asm!` must ultimately become— +after all other arguments are evaluated, formatting is performed, and operands are translated— +assembly that is both syntactically correct and semantically valid for the target architecture. +The formatting rules allow the compiler to generate assembly with correct syntax. +Rules concerning operands permit valid translation of Rust operands into and out of `asm!`. +Adherence to these rules is necessary, but not sufficient, for the final expanded assembly to be +both correct and valid. For instance: + +- arguments may be placed in positions which are syntactically incorrect after formatting +- an instruction may be correctly written, but given architecturally invalid operands +- an architecturally unspecified instruction may be assembled into unspecified code +- a set of instructions, each correct and valid, may cause undefined behavior if placed in immediate succession + +As a result, these rules are _non-exhaustive_. The compiler is not required to check the +correctness and validity of the initial string nor the final assembly that is generated. +The assembler may check for correctness and validity but is not required to do so. +When using `asm!`, a typographical error may be sufficient to make a program unsound, +and the rules for assembly may include thousands of pages of architectural reference manuals. +Programmers should exercise appropriate care, as invoking this `unsafe` capability comes with +assuming the responsibility of not violating rules of both the compiler or the architecture. + ### Directives Support Inline assembly supports a subset of the directives supported by both GNU AS and LLVM's internal assembler, given as follows.