Skip to content

Commit c3e2cef

Browse files
committed
merge the sgx/fortanix __rust_probestack into the general x86_64 one
1 parent d6dd269 commit c3e2cef

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

0 commit comments

Comments
 (0)