Skip to content

Commit 45d649e

Browse files
committed
merge the sgx/fortanix __rust_probestack into the general x86_64 one
1 parent b6eb4f9 commit 45d649e

File tree

1 file changed

+23
-73
lines changed

1 file changed

+23
-73
lines changed

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

Lines changed: 23 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,31 @@
5757
//
5858
// The ABI here is that the stack frame size is located in `%rax`. Upon
5959
// return we're not supposed to modify `%rsp` or `%rax`.
60-
//
61-
// Any changes to this function should be replicated to the SGX version below.
62-
#[cfg(all(
63-
target_arch = "x86_64",
64-
not(all(target_env = "sgx", target_vendor = "fortanix"))
65-
))]
60+
#[cfg(target_arch = "x86_64")]
6661
#[unsafe(naked)]
6762
#[rustc_std_internal_symbol]
6863
pub unsafe extern "C" fn __rust_probestack() {
64+
#[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))]
65+
macro_rules! ret {
66+
() => {
67+
"ret"
68+
};
69+
}
70+
71+
#[cfg(all(target_env = "sgx", target_vendor = "fortanix"))]
72+
macro_rules! ret {
73+
// for this target, [manually patch for LVI].
74+
//
75+
// [manually patch for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
76+
() => {
77+
"
78+
pop %r11
79+
lfence
80+
jmp *%r11
81+
"
82+
};
83+
}
84+
6985
core::arch::naked_asm!(
7086
"
7187
.cfi_startproc
@@ -114,75 +130,9 @@ pub unsafe extern "C" fn __rust_probestack() {
114130
leave
115131
.cfi_def_cfa_register %rsp
116132
.cfi_adjust_cfa_offset -8
117-
ret
118-
.cfi_endproc
119133
",
120-
options(att_syntax)
121-
)
122-
}
123-
124-
// This function is the same as above, except that some instructions are
125-
// [manually patched for LVI].
126-
//
127-
// [manually patched for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
128-
#[cfg(all(
129-
target_arch = "x86_64",
130-
all(target_env = "sgx", target_vendor = "fortanix")
131-
))]
132-
#[unsafe(naked)]
133-
#[no_mangle]
134-
pub unsafe extern "C" fn __rust_probestack() {
135-
core::arch::naked_asm!(
134+
ret!(),
136135
"
137-
.cfi_startproc
138-
pushq %rbp
139-
.cfi_adjust_cfa_offset 8
140-
.cfi_offset %rbp, -16
141-
movq %rsp, %rbp
142-
.cfi_def_cfa_register %rbp
143-
144-
mov %rax,%r11 // duplicate %rax as we're clobbering %r11
145-
146-
// Main loop, taken in one page increments. We're decrementing rsp by
147-
// a page each time until there's less than a page remaining. We're
148-
// guaranteed that this function isn't called unless there's more than a
149-
// page needed.
150-
//
151-
// Note that we're also testing against `8(%rsp)` to account for the 8
152-
// bytes pushed on the stack orginally with our return address. Using
153-
// `8(%rsp)` simulates us testing the stack pointer in the caller's
154-
// context.
155-
156-
// It's usually called when %rax >= 0x1000, but that's not always true.
157-
// Dynamic stack allocation, which is needed to implement unsized
158-
// rvalues, triggers stackprobe even if %rax < 0x1000.
159-
// Thus we have to check %r11 first to avoid segfault.
160-
cmp $0x1000,%r11
161-
jna 3f
162-
2:
163-
sub $0x1000,%rsp
164-
test %rsp,8(%rsp)
165-
sub $0x1000,%r11
166-
cmp $0x1000,%r11
167-
ja 2b
168-
169-
3:
170-
// Finish up the last remaining stack space requested, getting the last
171-
// bits out of r11
172-
sub %r11,%rsp
173-
test %rsp,8(%rsp)
174-
175-
// Restore the stack pointer to what it previously was when entering
176-
// this function. The caller will readjust the stack pointer after we
177-
// return.
178-
add %rax,%rsp
179-
180-
leave
181-
.cfi_def_cfa_register %rsp
182-
.cfi_adjust_cfa_offset -8
183-
pop %r11
184-
lfence
185-
jmp *%r11
186136
.cfi_endproc
187137
",
188138
options(att_syntax)

0 commit comments

Comments
 (0)