43
43
44
44
#![ cfg( not( windows) ) ] // Windows already has builtins to do this
45
45
46
+ extern "C" {
47
+ pub fn __rust_probestack ( ) ;
48
+ }
49
+
46
50
#[ naked]
47
51
#[ no_mangle]
48
52
#[ 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 ( ) {
50
54
// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
51
55
// ensuring that if any pages are unmapped we'll make a page fault.
52
56
//
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 `.
55
59
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
56
71
pushq %rbp
72
+ .cfi_adjust_cfa_offset 8
73
+ .cfi_offset %rbp, -16
57
74
movq %rsp, %rbp
75
+ .cfi_def_cfa_register %rbp
58
76
59
77
mov %rax,%r11 // duplicate %rax as we're clobbering %r11
60
78
@@ -93,23 +111,43 @@ pub unsafe extern "C" fn __rust_probestack() {
93
111
add %rax,%rsp
94
112
95
113
leave
114
+ .cfi_def_cfa_register %rsp
115
+ .cfi_adjust_cfa_offset -8
96
116
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
97
125
" :: : "memory" : "volatile" ) ;
98
126
:: core:: intrinsics:: unreachable ( ) ;
99
127
}
100
128
101
129
#[ naked]
102
130
#[ no_mangle]
103
131
#[ 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 ( ) {
105
133
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
106
134
// that on Unix we're expected to restore everything as it was, this
107
135
// function basically can't tamper with anything.
108
136
//
109
137
// The ABI here is the same as x86_64, except everything is 32-bits large.
110
138
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
111
146
push %ebp
147
+ .cfi_adjust_cfa_offset 4
148
+ .cfi_offset %ebp, -8
112
149
mov %esp, %ebp
150
+ .cfi_def_cfa_register %ebp
113
151
push %ecx
114
152
mov %eax,%ecx
115
153
@@ -129,7 +167,15 @@ pub unsafe extern "C" fn __rust_probestack() {
129
167
add %eax,%esp
130
168
pop %ecx
131
169
leave
170
+ .cfi_def_cfa_register %esp
171
+ .cfi_adjust_cfa_offset -4
132
172
ret
173
+ .cfi_endproc
174
+
175
+ .size __rust_probestack, . - __rust_probestack
176
+ .popsection
177
+
178
+ .cfi_startproc
133
179
" :: : "memory" : "volatile" ) ;
134
180
:: core:: intrinsics:: unreachable ( ) ;
135
181
}
0 commit comments