@@ -76,7 +76,7 @@ macro_rules! define_rust_probestack {
7676 } ;
7777}
7878
79- #[ cfg( target_os = "uefi" ) ]
79+ #[ cfg( all ( target_os = "uefi" , target_arch = "x86_64" ) ) ]
8080macro_rules! define_rust_probestack {
8181 ( $body: expr) => {
8282 concat!(
@@ -104,6 +104,20 @@ macro_rules! define_rust_probestack {
104104 } ;
105105}
106106
107+ // In UEFI x86 arch, triple underscore is deliberate.
108+ #[ cfg( all( target_os = "uefi" , target_arch = "x86" ) ) ]
109+ macro_rules! define_rust_probestack {
110+ ( $body: expr) => {
111+ concat!(
112+ "
113+ .globl ___rust_probestack
114+ ___rust_probestack:
115+ " ,
116+ $body
117+ )
118+ } ;
119+ }
120+
107121// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
108122// ensuring that if any pages are unmapped we'll make a page fault.
109123//
@@ -231,7 +245,7 @@ global_asm!(define_rust_probestack!(
231245 "
232246) ) ;
233247
234- #[ cfg( target_arch = "x86" ) ]
248+ #[ cfg( all ( target_arch = "x86" , not ( target_os = "uefi" ) ) ) ]
235249// This is the same as x86_64 above, only translated for 32-bit sizes. Note
236250// that on Unix we're expected to restore everything as it was, this
237251// function basically can't tamper with anything.
@@ -270,3 +284,53 @@ global_asm!(define_rust_probestack!(
270284 .cfi_endproc
271285 "
272286) ) ;
287+
288+ #[ cfg( all( target_arch = "x86" , target_os = "uefi" ) ) ]
289+ // UEFI target is windows like target. LLVM will do _chkstk things like windows.
290+ // probestack function will also do things like _chkstk in MSVC.
291+ // So we need to sub %ax %sp in probestack when arch is x86.
292+ //
293+ // REF: Rust commit(74e80468347)
294+ // rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805
295+ // Comments in LLVM:
296+ // MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves.
297+ // MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
298+ // themselves.
299+ global_asm ! ( define_rust_probestack!(
300+ "
301+ .cfi_startproc
302+ push %ebp
303+ .cfi_adjust_cfa_offset 4
304+ .cfi_offset %ebp, -8
305+ mov %esp, %ebp
306+ .cfi_def_cfa_register %ebp
307+ push %ecx
308+ push %edx
309+ mov %eax,%ecx
310+
311+ cmp $0x1000,%ecx
312+ jna 3f
313+ 2:
314+ sub $0x1000,%esp
315+ test %esp,8(%esp)
316+ sub $0x1000,%ecx
317+ cmp $0x1000,%ecx
318+ ja 2b
319+
320+ 3:
321+ sub %ecx,%esp
322+ test %esp,8(%esp)
323+ mov 4(%ebp),%edx
324+ mov %edx, 12(%esp)
325+ add %eax,%esp
326+ pop %edx
327+ pop %ecx
328+ leave
329+
330+ sub %eax, %esp
331+ .cfi_def_cfa_register %esp
332+ .cfi_adjust_cfa_offset -4
333+ ret
334+ .cfi_endproc
335+ "
336+ ) ) ;
0 commit comments