Skip to content

Commit 0f34e3b

Browse files
author
Xiaoyu Lu
committed
Add uefi arch x86 probestack support
1. In UEFI x86 arch, probestack need triple underscore. 2. In UEFI, probestack function do things like _chkstk(in MSVC). MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp themselves. But current probestack doesn't adjust esp. And LLVM doesn't generate sub %eax, %esp after probestack. So we adjust esp in probestack like MSVC x32's _chkstk.
1 parent f4c7940 commit 0f34e3b

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

src/probestack.rs

+66-2
Original file line numberDiff line numberDiff line change
@@ -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"))]
8080
macro_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

Comments
 (0)