49
49
// We only define stack probing for these architectures today.
50
50
#![ cfg( any( target_arch = "x86_64" , target_arch = "x86" ) ) ]
51
51
52
- // SAFETY: defined in this module.
53
- // FIXME(extern_custom): the ABI is not correct.
54
- unsafe extern "C" {
55
- pub fn __rust_probestack ( ) ;
56
- }
57
-
58
- // A wrapper for our implementation of __rust_probestack, which allows us to
59
- // keep the assembly inline while controlling all CFI directives in the assembly
60
- // emitted for the function.
61
- //
62
- // This is the ELF version.
63
- #[ cfg( not( any( target_vendor = "apple" , target_os = "uefi" ) ) ) ]
64
- macro_rules! define_rust_probestack {
65
- ( $body: expr) => {
66
- concat!(
67
- "
68
- .pushsection .text.__rust_probestack
69
- .globl __rust_probestack
70
- .type __rust_probestack, @function
71
- .hidden __rust_probestack
72
- __rust_probestack:
73
- " ,
74
- $body,
75
- "
76
- .size __rust_probestack, . - __rust_probestack
77
- .popsection
78
- "
79
- )
80
- } ;
81
- }
82
-
83
- #[ cfg( all( target_os = "uefi" , target_arch = "x86_64" ) ) ]
84
- macro_rules! define_rust_probestack {
85
- ( $body: expr) => {
86
- concat!(
87
- "
88
- .globl __rust_probestack
89
- __rust_probestack:
90
- " ,
91
- $body
92
- )
93
- } ;
94
- }
95
-
96
- // Same as above, but for Mach-O. Note that the triple underscore
97
- // is deliberate
98
- #[ cfg( target_vendor = "apple" ) ]
99
- macro_rules! define_rust_probestack {
100
- ( $body: expr) => {
101
- concat!(
102
- "
103
- .globl ___rust_probestack
104
- ___rust_probestack:
105
- " ,
106
- $body
107
- )
108
- } ;
109
- }
110
-
111
- // In UEFI x86 arch, triple underscore is deliberate.
112
- #[ cfg( all( target_os = "uefi" , target_arch = "x86" ) ) ]
113
- macro_rules! define_rust_probestack {
114
- ( $body: expr) => {
115
- concat!(
116
- "
117
- .globl ___rust_probestack
118
- ___rust_probestack:
119
- " ,
120
- $body
121
- )
122
- } ;
123
- }
124
-
125
52
// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
126
53
// ensuring that if any pages are unmapped we'll make a page fault.
127
54
//
55
+ // This function is unsafe because it uses a custom ABI, it does not actually match `extern "C"`.
56
+ //
128
57
// The ABI here is that the stack frame size is located in `%rax`. Upon
129
58
// return we're not supposed to modify `%rsp` or `%rax`.
130
59
//
@@ -133,8 +62,10 @@ macro_rules! define_rust_probestack {
133
62
target_arch = "x86_64" ,
134
63
not( all( target_env = "sgx" , target_vendor = "fortanix" ) )
135
64
) ) ]
136
- core:: arch:: global_asm!(
137
- define_rust_probestack!(
65
+ #[ unsafe( naked) ]
66
+ #[ rustc_std_internal_symbol]
67
+ pub unsafe extern "C" fn __rust_probestack ( ) {
68
+ core:: arch:: naked_asm!(
138
69
"
139
70
.cfi_startproc
140
71
pushq %rbp
@@ -184,10 +115,10 @@ core::arch::global_asm!(
184
115
.cfi_adjust_cfa_offset -8
185
116
ret
186
117
.cfi_endproc
187
- "
188
- ) ,
189
- options ( att_syntax )
190
- ) ;
118
+ " ,
119
+ options ( att_syntax )
120
+ )
121
+ }
191
122
192
123
// This function is the same as above, except that some instructions are
193
124
// [manually patched for LVI].
@@ -197,8 +128,10 @@ core::arch::global_asm!(
197
128
target_arch = "x86_64" ,
198
129
all( target_env = "sgx" , target_vendor = "fortanix" )
199
130
) ) ]
200
- core:: arch:: global_asm!(
201
- define_rust_probestack!(
131
+ #[ unsafe( naked) ]
132
+ #[ no_mangle]
133
+ pub unsafe extern "C" fn __rust_probestack ( ) {
134
+ core:: arch:: naked_asm!(
202
135
"
203
136
.cfi_startproc
204
137
pushq %rbp
@@ -250,19 +183,23 @@ core::arch::global_asm!(
250
183
lfence
251
184
jmp *%r11
252
185
.cfi_endproc
253
- "
254
- ) ,
255
- options ( att_syntax )
256
- ) ;
186
+ " ,
187
+ options ( att_syntax )
188
+ )
189
+ }
257
190
258
191
#[ cfg( all( target_arch = "x86" , not( target_os = "uefi" ) ) ) ]
259
192
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
260
193
// that on Unix we're expected to restore everything as it was, this
261
194
// function basically can't tamper with anything.
262
195
//
196
+ // This function is unsafe because it uses a custom ABI, it does not actually match `extern "C"`.
197
+ //
263
198
// The ABI here is the same as x86_64, except everything is 32-bits large.
264
- core:: arch:: global_asm!(
265
- define_rust_probestack!(
199
+ #[ unsafe( naked) ]
200
+ #[ rustc_std_internal_symbol]
201
+ pub unsafe extern "C" fn __rust_probestack ( ) {
202
+ core:: arch:: naked_asm!(
266
203
"
267
204
.cfi_startproc
268
205
push %ebp
@@ -293,24 +230,28 @@ core::arch::global_asm!(
293
230
.cfi_adjust_cfa_offset -4
294
231
ret
295
232
.cfi_endproc
296
- "
297
- ) ,
298
- options ( att_syntax )
299
- ) ;
233
+ " ,
234
+ options ( att_syntax )
235
+ )
236
+ }
300
237
301
238
#[ cfg( all( target_arch = "x86" , target_os = "uefi" ) ) ]
302
239
// UEFI target is windows like target. LLVM will do _chkstk things like windows.
303
240
// probestack function will also do things like _chkstk in MSVC.
304
241
// So we need to sub %ax %sp in probestack when arch is x86.
305
242
//
243
+ // This function is unsafe because it uses a custom ABI, it does not actually match `extern "C"`.
244
+ //
306
245
// REF: Rust commit(74e80468347)
307
246
// rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805
308
247
// Comments in LLVM:
309
248
// MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves.
310
249
// MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
311
250
// themselves.
312
- core:: arch:: global_asm!(
313
- define_rust_probestack!(
251
+ #[ unsafe( naked) ]
252
+ #[ rustc_std_internal_symbol]
253
+ pub unsafe extern "C" fn __rust_probestack ( ) {
254
+ core:: arch:: naked_asm!(
314
255
"
315
256
.cfi_startproc
316
257
push %ebp
@@ -346,7 +287,7 @@ core::arch::global_asm!(
346
287
.cfi_adjust_cfa_offset -4
347
288
ret
348
289
.cfi_endproc
349
- "
350
- ) ,
351
- options ( att_syntax )
352
- ) ;
290
+ " ,
291
+ options ( att_syntax )
292
+ )
293
+ }
0 commit comments