Skip to content

Commit a548e1f

Browse files
committed
merge the sgx/fortanix __rust_probestack into the general x86_64 one
1 parent 260c31d commit a548e1f

File tree

1 file changed

+23
-73
lines changed

1 file changed

+23
-73
lines changed

compiler-builtins/src/probestack.rs

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

0 commit comments

Comments
 (0)