Skip to content

Commit 5197856

Browse files
committed
Set -Cpanic=abort in windows-msvc stack protector tests
1 parent 2636cb4 commit 5197856

File tree

3 files changed

+93
-61
lines changed

3 files changed

+93
-61
lines changed

tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//@ [strong] compile-flags: -Z stack-protector=strong
88
//@ [basic] compile-flags: -Z stack-protector=basic
99
//@ [none] compile-flags: -Z stack-protector=none
10-
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
10+
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort
1111

1212
#![crate_type = "lib"]
1313
#![allow(internal_features)]
@@ -26,6 +26,7 @@ pub fn emptyfn() {
2626
// CHECK-LABEL: array_char
2727
#[no_mangle]
2828
pub fn array_char(f: fn(*const char)) {
29+
// CHECK-DAG: .cv_fpo_endprologue
2930
let a = ['c'; 1];
3031
let b = ['d'; 3];
3132
let c = ['e'; 15];
@@ -39,11 +40,14 @@ pub fn array_char(f: fn(*const char)) {
3940
// basic: __security_check_cookie
4041
// none-NOT: __security_check_cookie
4142
// missing-NOT: __security_check_cookie
43+
44+
// CHECK-DAG: .cv_fpo_endproc
4245
}
4346

4447
// CHECK-LABEL: array_u8_1
4548
#[no_mangle]
4649
pub fn array_u8_1(f: fn(*const u8)) {
50+
// CHECK-DAG: .cv_fpo_endprologue
4751
let a = [0u8; 1];
4852
f(&a as *const _);
4953

@@ -55,11 +59,14 @@ pub fn array_u8_1(f: fn(*const u8)) {
5559
// basic-NOT: __security_check_cookie
5660
// none-NOT: __security_check_cookie
5761
// missing-NOT: __security_check_cookie
62+
63+
// CHECK-DAG: .cv_fpo_endproc
5864
}
5965

6066
// CHECK-LABEL: array_u8_small:
6167
#[no_mangle]
6268
pub fn array_u8_small(f: fn(*const u8)) {
69+
// CHECK-DAG: .cv_fpo_endprologue
6370
let a = [0u8; 2];
6471
let b = [0u8; 7];
6572
f(&a as *const _);
@@ -72,11 +79,14 @@ pub fn array_u8_small(f: fn(*const u8)) {
7279
// basic-NOT: __security_check_cookie
7380
// none-NOT: __security_check_cookie
7481
// missing-NOT: __security_check_cookie
82+
83+
// CHECK-DAG: .cv_fpo_endproc
7584
}
7685

7786
// CHECK-LABEL: array_u8_large:
7887
#[no_mangle]
7988
pub fn array_u8_large(f: fn(*const u8)) {
89+
// CHECK-DAG: .cv_fpo_endprologue
8090
let a = [0u8; 9];
8191
f(&a as *const _);
8292

@@ -88,6 +98,8 @@ pub fn array_u8_large(f: fn(*const u8)) {
8898
// basic: __security_check_cookie
8999
// none-NOT: __security_check_cookie
90100
// missing-NOT: __security_check_cookie
101+
102+
// CHECK-DAG: .cv_fpo_endproc
91103
}
92104

93105
#[derive(Copy, Clone)]
@@ -96,6 +108,7 @@ pub struct ByteSizedNewtype(u8);
96108
// CHECK-LABEL: array_bytesizednewtype_9:
97109
#[no_mangle]
98110
pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
111+
// CHECK-DAG: .cv_fpo_endprologue
99112
let a = [ByteSizedNewtype(0); 9];
100113
f(&a as *const _);
101114

@@ -107,11 +120,14 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
107120
// basic: __security_check_cookie
108121
// none-NOT: __security_check_cookie
109122
// missing-NOT: __security_check_cookie
123+
124+
// CHECK-DAG: .cv_fpo_endproc
110125
}
111126

112127
// CHECK-LABEL: local_var_addr_used_indirectly
113128
#[no_mangle]
114129
pub fn local_var_addr_used_indirectly(f: fn(bool)) {
130+
// CHECK-DAG: .cv_fpo_endprologue
115131
let a = 5;
116132
let a_addr = &a as *const _ as usize;
117133
f(a_addr & 0x10 == 0);
@@ -134,37 +150,27 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) {
134150
// basic-NOT: __security_check_cookie
135151
// none-NOT: __security_check_cookie
136152
// missing-NOT: __security_check_cookie
153+
154+
// CHECK-DAG: .cv_fpo_endproc
137155
}
138156

139157
// CHECK-LABEL: local_string_addr_taken
140158
#[no_mangle]
141159
pub fn local_string_addr_taken(f: fn(&String)) {
160+
// CHECK-DAG: .cv_fpo_endprologue
142161
let x = String::new();
143162
f(&x);
144163

145164
// Taking the address of the local variable `x` leads to stack smash
146-
// protection with the `strong` heuristic, but not with the `basic`
147-
// heuristic. It does not matter that the reference is not mut.
148-
//
149-
// An interesting note is that a similar function in C++ *would* be
150-
// protected by the `basic` heuristic, because `std::string` has a char
151-
// array internally as a small object optimization:
152-
// ```
153-
// cat <<EOF | clang++ -O2 -fstack-protector -S -x c++ - -o - | grep stack_chk
154-
// #include <string>
155-
// void f(void (*g)(const std::string&)) {
156-
// std::string x;
157-
// g(x);
158-
// }
159-
// EOF
160-
// ```
161-
//
165+
// protection. It does not matter that the reference is not mut.
162166

163167
// all: __security_check_cookie
164-
// strong-NOT: __security_check_cookie
165-
// basic-NOT: __security_check_cookie
168+
// strong: __security_check_cookie
169+
// basic: __security_check_cookie
166170
// none-NOT: __security_check_cookie
167171
// missing-NOT: __security_check_cookie
172+
173+
// CHECK-DAG: .cv_fpo_endproc
168174
}
169175

170176
pub trait SelfByRef {
@@ -180,6 +186,7 @@ impl SelfByRef for i32 {
180186
// CHECK-LABEL: local_var_addr_taken_used_locally_only
181187
#[no_mangle]
182188
pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) {
189+
// CHECK-DAG: .cv_fpo_endprologue
183190
let x = factory();
184191
let g = x.f();
185192
sink(g);
@@ -194,6 +201,8 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32
194201
// basic-NOT: __security_check_cookie
195202
// none-NOT: __security_check_cookie
196203
// missing-NOT: __security_check_cookie
204+
205+
// CHECK-DAG: .cv_fpo_endproc
197206
}
198207

199208
pub struct Gigastruct {
@@ -207,6 +216,7 @@ pub struct Gigastruct {
207216
// CHECK-LABEL: local_large_var_moved
208217
#[no_mangle]
209218
pub fn local_large_var_moved(f: fn(Gigastruct)) {
219+
// CHECK-DAG: .cv_fpo_endprologue
210220
let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 };
211221
f(x);
212222

@@ -231,11 +241,14 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) {
231241
// basic: __security_check_cookie
232242
// none-NOT: __security_check_cookie
233243
// missing-NOT: __security_check_cookie
244+
245+
// CHECK-DAG: .cv_fpo_endproc
234246
}
235247

236248
// CHECK-LABEL: local_large_var_cloned
237249
#[no_mangle]
238250
pub fn local_large_var_cloned(f: fn(Gigastruct)) {
251+
// CHECK-DAG: .cv_fpo_endprologue
239252
f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 });
240253

241254
// A new instance of `Gigastruct` is passed to `f()`, without any apparent
@@ -260,6 +273,8 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) {
260273
// basic: __security_check_cookie
261274
// none-NOT: __security_check_cookie
262275
// missing-NOT: __security_check_cookie
276+
277+
// CHECK-DAG: .cv_fpo_endproc
263278
}
264279

265280
extern "C" {
@@ -293,49 +308,57 @@ extern "C" {
293308
// CHECK-LABEL: alloca_small_compile_time_constant_arg
294309
#[no_mangle]
295310
pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
311+
// CHECK-DAG: .cv_fpo_endprologue
296312
f(unsafe { alloca(8) });
297313

298314
// all: __security_check_cookie
299315
// strong-NOT: __security_check_cookie
300316
// basic-NOT: __security_check_cookie
301317
// none-NOT: __security_check_cookie
302318
// missing-NOT: __security_check_cookie
319+
320+
// CHECK-DAG: .cv_fpo_endproc
303321
}
304322

305323
// CHECK-LABEL: alloca_large_compile_time_constant_arg
306324
#[no_mangle]
307325
pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
326+
// CHECK-DAG: .cv_fpo_endprologue
308327
f(unsafe { alloca(9) });
309328

310329
// all: __security_check_cookie
311330
// strong-NOT: __security_check_cookie
312331
// basic-NOT: __security_check_cookie
313332
// none-NOT: __security_check_cookie
314333
// missing-NOT: __security_check_cookie
334+
335+
// CHECK-DAG: .cv_fpo_endproc
315336
}
316337

317338
// CHECK-LABEL: alloca_dynamic_arg
318339
#[no_mangle]
319340
pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
341+
// CHECK-DAG: .cv_fpo_endprologue
320342
f(unsafe { alloca(n) });
321343

322344
// all: __security_check_cookie
323345
// strong-NOT: __security_check_cookie
324346
// basic-NOT: __security_check_cookie
325347
// none-NOT: __security_check_cookie
326348
// missing-NOT: __security_check_cookie
349+
350+
// CHECK-DAG: .cv_fpo_endproc
327351
}
328352

329353
// The question then is: in what ways can Rust code generate array-`alloca`
330354
// LLVM instructions? This appears to only be generated by
331355
// rustc_codegen_ssa::traits::Builder::array_alloca() through
332-
// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). FWICT
333-
// this is support for the "unsized locals" unstable feature:
334-
// https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html.
356+
// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized().
335357

336358
// CHECK-LABEL: unsized_fn_param
337359
#[no_mangle]
338360
pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
361+
// CHECK-DAG: .cv_fpo_endprologue
339362
let n = if l { 1 } else { 2 };
340363
f(*Box::<[u8]>::from(&s[0..n])); // slice-copy with Box::from
341364

@@ -346,14 +369,11 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
346369
// alloca, and is therefore not protected by the `strong` or `basic`
347370
// heuristics.
348371

349-
// We should have a __security_check_cookie call in `all` and `strong` modes but
350-
// LLVM does not support generating stack protectors in functions with funclet
351-
// based EH personalities.
352-
// https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4
353372
// all-NOT: __security_check_cookie
354373
// strong-NOT: __security_check_cookie
355-
356374
// basic-NOT: __security_check_cookie
357375
// none-NOT: __security_check_cookie
358376
// missing-NOT: __security_check_cookie
377+
378+
// CHECK-DAG: .cv_fpo_endproc
359379
}

0 commit comments

Comments
 (0)