Skip to content

Commit 1605ab3

Browse files
committed
Add support for naked functions
1 parent 0215681 commit 1605ab3

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

src/doc/reference.md

+2
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,8 @@ type int8_t = i8;
19051905
- `should_panic` - indicates that this test function should panic, inverting the success condition.
19061906
- `cold` - The function is unlikely to be executed, so optimize it (and calls
19071907
to it) differently.
1908+
- `naked` - The function utilizes a custom ABI or custom inline ASM that requires
1909+
epilogue and prologue to be skipped.
19081910

19091911
### Static-only attributes
19101912

src/librustc_trans/trans/attributes.rs

+14
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
8181
}
8282
}
8383

84+
/// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue.
85+
#[inline]
86+
pub fn naked(val: ValueRef, is_naked: bool) {
87+
if is_naked {
88+
llvm::SetFunctionAttribute(val, llvm::Attribute::Naked);
89+
} else {
90+
unsafe {
91+
llvm::LLVMRemoveFunctionAttr(val, llvm::Attribute::Naked.bits() as c_ulonglong);
92+
}
93+
}
94+
}
95+
8496
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
8597
/// attributes.
8698
pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
@@ -105,6 +117,8 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
105117
if attr.check_name("cold") {
106118
llvm::Attributes::default().set(llvm::Attribute::Cold)
107119
.apply_llfn(llvm::FunctionIndex as usize, llfn)
120+
} else if attr.check_name("naked") {
121+
naked(llfn, true);
108122
} else if attr.check_name("allocator") {
109123
llvm::Attributes::default().set(llvm::Attribute::NoAlias)
110124
.apply_llfn(llvm::ReturnIndex as usize, llfn)

src/libsyntax/feature_gate.rs

+6
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
212212
// rust runtime internal
213213
("unwind_attributes", "1.4.0", None, Active),
214214

215+
// allow the use of `#[naked]` on functions.
216+
("naked_functions", "1.9.0", None, Active),
217+
215218
// allow empty structs and enum variants with braces
216219
("braced_empty_structs", "1.5.0", Some(29720), Accepted),
217220

@@ -376,6 +379,9 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
376379
// FIXME: #14406 these are processed in trans, which happens after the
377380
// lint pass
378381
("cold", Whitelisted, Ungated),
382+
("naked", Whitelisted, Gated("naked_functions",
383+
"the `#[naked]` attribute \
384+
is an experimental feature")),
379385
("export_name", Whitelisted, Ungated),
380386
("inline", Whitelisted, Ungated),
381387
("link", Whitelisted, Ungated),

0 commit comments

Comments
 (0)