Skip to content

Commit 8f9de82

Browse files
committed
use #[naked] for __rust_probestack
1 parent 076ec59 commit 8f9de82

File tree

2 files changed

+44
-26
lines changed

2 files changed

+44
-26
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_hir::def_id::DefId;
55
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
66
use rustc_middle::ty::{self, TyCtxt};
77
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
8+
use rustc_symbol_mangling::mangle_internal_symbol;
89
use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector};
910
use smallvec::SmallVec;
1011

@@ -256,11 +257,11 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
256257
StackProbeType::Inline => "inline-asm",
257258
// Flag our internal `__rust_probestack` function as the stack probe symbol.
258259
// This is defined in the `compiler-builtins` crate for each architecture.
259-
StackProbeType::Call => "__rust_probestack",
260+
StackProbeType::Call => &mangle_internal_symbol(cx.tcx, "__rust_probestack"),
260261
// Pick from the two above based on the LLVM version.
261262
StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
262263
if llvm_util::get_version() < min_llvm_version_for_inline {
263-
"__rust_probestack"
264+
&mangle_internal_symbol(cx.tcx, "__rust_probestack")
264265
} else {
265266
"inline-asm"
266267
}

library/compiler-builtins/compiler-builtins/src/probestack.rs

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
// We only define stack probing for these architectures today.
5050
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
5151

52+
<<<<<<< HEAD
5253
// SAFETY: defined in this module.
5354
// FIXME(extern_custom): the ABI is not correct.
5455
unsafe extern "C" {
@@ -122,9 +123,13 @@ macro_rules! define_rust_probestack {
122123
};
123124
}
124125

126+
=======
127+
>>>>>>> d6dd2696443 (use `#[naked]` for `__rust_probestack`)
125128
// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
126129
// ensuring that if any pages are unmapped we'll make a page fault.
127130
//
131+
// This function is unsafe because it uses a custom ABI, it does not actually match `extern "C"`.
132+
//
128133
// The ABI here is that the stack frame size is located in `%rax`. Upon
129134
// return we're not supposed to modify `%rsp` or `%rax`.
130135
//
@@ -133,8 +138,10 @@ macro_rules! define_rust_probestack {
133138
target_arch = "x86_64",
134139
not(all(target_env = "sgx", target_vendor = "fortanix"))
135140
))]
136-
core::arch::global_asm!(
137-
define_rust_probestack!(
141+
#[unsafe(naked)]
142+
#[rustc_std_internal_symbol]
143+
pub unsafe extern "C" fn __rust_probestack() {
144+
core::arch::naked_asm!(
138145
"
139146
.cfi_startproc
140147
pushq %rbp
@@ -184,10 +191,10 @@ core::arch::global_asm!(
184191
.cfi_adjust_cfa_offset -8
185192
ret
186193
.cfi_endproc
187-
"
188-
),
189-
options(att_syntax)
190-
);
194+
",
195+
options(att_syntax)
196+
)
197+
}
191198

192199
// This function is the same as above, except that some instructions are
193200
// [manually patched for LVI].
@@ -197,8 +204,10 @@ core::arch::global_asm!(
197204
target_arch = "x86_64",
198205
all(target_env = "sgx", target_vendor = "fortanix")
199206
))]
200-
core::arch::global_asm!(
201-
define_rust_probestack!(
207+
#[unsafe(naked)]
208+
#[no_mangle]
209+
pub unsafe extern "C" fn __rust_probestack() {
210+
core::arch::naked_asm!(
202211
"
203212
.cfi_startproc
204213
pushq %rbp
@@ -250,19 +259,23 @@ core::arch::global_asm!(
250259
lfence
251260
jmp *%r11
252261
.cfi_endproc
253-
"
254-
),
255-
options(att_syntax)
256-
);
262+
",
263+
options(att_syntax)
264+
)
265+
}
257266

258267
#[cfg(all(target_arch = "x86", not(target_os = "uefi")))]
259268
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
260269
// that on Unix we're expected to restore everything as it was, this
261270
// function basically can't tamper with anything.
262271
//
272+
// This function is unsafe because it uses a custom ABI, it does not actually match `extern "C"`.
273+
//
263274
// The ABI here is the same as x86_64, except everything is 32-bits large.
264-
core::arch::global_asm!(
265-
define_rust_probestack!(
275+
#[unsafe(naked)]
276+
#[rustc_std_internal_symbol]
277+
pub unsafe extern "C" fn __rust_probestack() {
278+
core::arch::naked_asm!(
266279
"
267280
.cfi_startproc
268281
push %ebp
@@ -293,24 +306,28 @@ core::arch::global_asm!(
293306
.cfi_adjust_cfa_offset -4
294307
ret
295308
.cfi_endproc
296-
"
297-
),
298-
options(att_syntax)
299-
);
309+
",
310+
options(att_syntax)
311+
)
312+
}
300313

301314
#[cfg(all(target_arch = "x86", target_os = "uefi"))]
302315
// UEFI target is windows like target. LLVM will do _chkstk things like windows.
303316
// probestack function will also do things like _chkstk in MSVC.
304317
// So we need to sub %ax %sp in probestack when arch is x86.
305318
//
319+
// This function is unsafe because it uses a custom ABI, it does not actually match `extern "C"`.
320+
//
306321
// REF: Rust commit(74e80468347)
307322
// rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805
308323
// Comments in LLVM:
309324
// MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves.
310325
// MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
311326
// themselves.
312-
core::arch::global_asm!(
313-
define_rust_probestack!(
327+
#[unsafe(naked)]
328+
#[rustc_std_internal_symbol]
329+
pub unsafe extern "C" fn __rust_probestack() {
330+
core::arch::naked_asm!(
314331
"
315332
.cfi_startproc
316333
push %ebp
@@ -346,7 +363,7 @@ core::arch::global_asm!(
346363
.cfi_adjust_cfa_offset -4
347364
ret
348365
.cfi_endproc
349-
"
350-
),
351-
options(att_syntax)
352-
);
366+
",
367+
options(att_syntax)
368+
)
369+
}

0 commit comments

Comments
 (0)