@@ -87,17 +87,14 @@ any calling convention the compiler is compatible with, calls to naked functions
8787from within Rust code are forbidden unless the function is also declared with
8888a well-defined ABI.
8989
90- The function ` call_foo ` in the following code block is an error because the
91- default (Rust) ABI is unspecified and as such a programmer can never write code
92- in ` foo ` which is compatible:
90+ Defining a naked function with the default (Rust) ABI is an error, because the
91+ Rust ABI is unspecified and the programmer can never write a function which is
92+ guaranteed to be compatible. For example, The function declaration of ` foo ` in
93+ the following code block is an error.
9394
9495``` rust
9596#[naked]
96- fn foo () { }
97-
98- fn call_foo () {
99- foo ();
100- }
97+ unsafe fn foo () { }
10198```
10299
103100The following variant is not an error because the C calling convention is
@@ -107,28 +104,36 @@ function:
107104``` rust
108105#[naked]
109106extern " C" fn foo () { }
110-
111- fn call_foo () {
112- foo ();
113- }
114107```
115108
116109---
117110
118- The current support for ` extern ` functions in ` rustc ` generates a minimum of two
119- basic blocks for any function declared in Rust code with a non-default calling
120- convention: a trampoline which translates the declared calling convention to the
121- Rust convention, and a Rust ABI version of the function containing the actual
122- implementation. Calls to the function from Rust code call the Rust ABI version
123- directly.
111+ Because the compiler cannot verify the correctness of code written in a naked
112+ function (since it may have an unknown calling convention), naked functions must
113+ be declared ` unsafe ` or contain no non-` unsafe ` statements in the body. The
114+ function ` error ` in the following code block is a compile-time error, whereas
115+ the functions ` correct1 ` and ` correct2 ` are permitted.
124116
125- For naked functions, it is impossible for the compiler to generate a Rust ABI
126- version of the function because the implementation may depend on the calling
127- convention. In cases where calling a naked function from Rust is permitted, the
128- compiler must be able to use the target calling convention directly rather than
129- call the same function with the Rust convention.
117+ ```
118+ #[naked]
119+ extern "C" fn error(x: &mut u8) {
120+ *x += 1;
121+ }
130122
131- ---
123+ #[naked]
124+ unsafe extern "C" fn correct1(x: &mut u8) {
125+ *x += 1;
126+ }
127+
128+ #[naked]
129+ extern "C" fn correct2() {
130+ unsafe {
131+ *x += 1;
132+ }
133+ }
134+ ```
135+
136+ ## Example
132137
133138The following example illustrates the possible use of a naked function for
134139implementation of an interrupt service routine on 32-bit x86.
@@ -162,6 +167,21 @@ fn main() {
162167}
163168```
164169
170+ ## Implementation Considerations
171+
172+ The current support for ` extern ` functions in ` rustc ` generates a minimum of two
173+ basic blocks for any function declared in Rust code with a non-default calling
174+ convention: a trampoline which translates the declared calling convention to the
175+ Rust convention, and a Rust ABI version of the function containing the actual
176+ implementation. Calls to the function from Rust code call the Rust ABI version
177+ directly.
178+
179+ For naked functions, it is impossible for the compiler to generate a Rust ABI
180+ version of the function because the implementation may depend on the calling
181+ convention. In cases where calling a naked function from Rust is permitted, the
182+ compiler must be able to use the target calling convention directly rather than
183+ call the same function with the Rust convention.
184+
165185# Drawbacks
166186
167187The utility of this feature is extremely limited to most users, and it might be
@@ -179,8 +199,20 @@ external libraries such as `libffi`.
179199
180200It is easy to quietly generate wrong code in naked functions, such as by causing
181201the compiler to allocate stack space for temporaries where none were
182- anticipated. It may be desirable to require that all statements inside naked
183- functions be inside ` unsafe ` blocks (either by declaring the function ` unsafe `
184- or including ` unsafe { } ` in the function body) to reinforce the need for
185- extreme care in the use of this feature. Requiring that the function always be
186- marked ` unsafe ` is not desirable because its external API may be safe.
202+ anticipated. There is currently no restriction on writing Rust statements inside
203+ a naked function, while most compilers supporting similar features either
204+ require or strongly recommend that authors write only inline assembly inside
205+ naked functions to ensure no code is generated that assumes a particular stack
206+ layout. It may be desirable to place further restrictions on what statements are
207+ permitted in the body of a naked function, such as permitting only ` asm! `
208+ statements.
209+
210+ The ` unsafe ` requirement on naked functions may not be desirable in all cases.
211+ However, relaxing that requirement in the future would not be a breaking change.
212+
213+ Because a naked function may use a calling convention unknown to the compiler,
214+ it may be useful to add a "unknown" calling convention to the compiler which is
215+ illegal to call directly. Absent this feature, functions implementing an unknown
216+ ABI would need to be declared with a calling convention which is known to be
217+ incorrect and depend on the programmer to avoid calling such a function
218+ incorrectly since it cannot be prevented statically.
0 commit comments