Skip to content

Commit 10ffd32

Browse files
committed
Add control flow information to __rust_probestack
1 parent 0df0cf5 commit 10ffd32

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

src/probestack.rs

+50-4
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,36 @@
4343
4444
#![cfg(not(windows))] // Windows already has builtins to do this
4545

46+
extern "C" {
47+
pub fn __rust_probestack();
48+
}
49+
4650
#[naked]
4751
#[no_mangle]
4852
#[cfg(all(target_arch = "x86_64", not(feature = "mangled-names")))]
49-
pub unsafe extern "C" fn __rust_probestack() {
53+
pub unsafe extern "C" fn __rust_probestack_wrapper() {
5054
// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
5155
// ensuring that if any pages are unmapped we'll make a page fault.
5256
//
53-
// The ABI here is that the stack frame size is located in `%eax`. Upon
54-
// return we're not supposed to modify `%esp` or `%eax`.
57+
// The ABI here is that the stack frame size is located in `%rax`. Upon
58+
// return we're not supposed to modify `%rsp` or `%rax`.
5559
asm!("
60+
// We are about to define a 'function within a function.' Because the
61+
// compiler will have emitted a .cfi_startproc at the beginning of
62+
// __rust_probestack_wrapper, we need .cfi_endproc before we can define
63+
// the contents of __rust_probestack.
64+
.cfi_endproc
65+
66+
.pushsection .text.__rust_probestack
67+
.globl __rust_probestack
68+
.type __rust_probestack, @function
69+
__rust_probestack:
70+
.cfi_startproc
5671
pushq %rbp
72+
.cfi_adjust_cfa_offset 8
73+
.cfi_offset %rbp, -16
5774
movq %rsp, %rbp
75+
.cfi_def_cfa_register %rbp
5876
5977
mov %rax,%r11 // duplicate %rax as we're clobbering %r11
6078
@@ -93,23 +111,43 @@ pub unsafe extern "C" fn __rust_probestack() {
93111
add %rax,%rsp
94112
95113
leave
114+
.cfi_def_cfa_register %rsp
115+
.cfi_adjust_cfa_offset -8
96116
ret
117+
.cfi_endproc
118+
119+
.size __rust_probestack, . - __rust_probestack
120+
.popsection
121+
122+
// Similar to above, we add .cfi_startproc here to match the
123+
// .cfi_endproc emitted at the end of __rust_probestack_wrapper.
124+
.cfi_startproc
97125
" ::: "memory" : "volatile");
98126
::core::intrinsics::unreachable();
99127
}
100128

101129
#[naked]
102130
#[no_mangle]
103131
#[cfg(all(target_arch = "x86", not(feature = "mangled-names")))]
104-
pub unsafe extern "C" fn __rust_probestack() {
132+
pub unsafe extern "C" fn __rust_probestack_wrapper() {
105133
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
106134
// that on Unix we're expected to restore everything as it was, this
107135
// function basically can't tamper with anything.
108136
//
109137
// The ABI here is the same as x86_64, except everything is 32-bits large.
110138
asm!("
139+
.cfi_endproc
140+
141+
.pushsection .text.__rust_probestack
142+
.globl __rust_probestack
143+
.type __rust_probestack, @function
144+
__rust_probestack:
145+
.cfi_startproc
111146
push %ebp
147+
.cfi_adjust_cfa_offset 4
148+
.cfi_offset %ebp, -8
112149
mov %esp, %ebp
150+
.cfi_def_cfa_register %ebp
113151
push %ecx
114152
mov %eax,%ecx
115153
@@ -129,7 +167,15 @@ pub unsafe extern "C" fn __rust_probestack() {
129167
add %eax,%esp
130168
pop %ecx
131169
leave
170+
.cfi_def_cfa_register %esp
171+
.cfi_adjust_cfa_offset -4
132172
ret
173+
.cfi_endproc
174+
175+
.size __rust_probestack, . - __rust_probestack
176+
.popsection
177+
178+
.cfi_startproc
133179
" ::: "memory" : "volatile");
134180
::core::intrinsics::unreachable();
135181
}

0 commit comments

Comments
 (0)