|
19 | 19 | # This option places an `endbr32`/`endbr64` instruction at the start of |
20 | 20 | # all functions, which can interfere with prologue analysis. |
21 | 21 |
|
22 | | -standard_testfile .c |
23 | | -set binfile ${binfile} |
| 22 | +standard_testfile .c -stackalign.c |
24 | 23 |
|
25 | 24 | require {is_any_target x86_64-*-* i?86-*-*} |
26 | | - |
27 | 25 | require supports_fcf_protection |
28 | 26 |
|
29 | | -set opts {debug additional_flags=-fcf-protection=full} |
| 27 | +# Tests if breakpoint set on main is placed past main's entry. |
| 28 | +proc test_run {} { |
| 29 | + # Get start address of function main. |
| 30 | + set main_addr [get_integer_valueof &main -1] |
| 31 | + gdb_assert {$main_addr != -1} |
30 | 32 |
|
31 | | -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $opts] != "" } { |
32 | | - untested "failed to compile" |
33 | | - return |
34 | | -} |
| 33 | + set bp_addr -1 |
35 | 34 |
|
36 | | -clean_restart ${binfile} |
| 35 | + # Put breakpoint on main, get the address where the breakpoint was installed. |
| 36 | + gdb_test_multiple "break -q main" "break on main, get address" { |
| 37 | + -re -wrap "Breakpoint $::decimal at ($::hex).*" { |
| 38 | + set bp_addr $expect_out(1,string) |
37 | 39 |
|
38 | | -# Get start address of function main. |
39 | | -set main_addr [get_integer_valueof &main -1] |
40 | | -gdb_assert {$main_addr != -1} |
| 40 | + # Convert to decimal. |
| 41 | + set bp_addr [expr $bp_addr] |
41 | 42 |
|
42 | | -set bp_addr -1 |
| 43 | + pass $gdb_test_name |
| 44 | + } |
| 45 | + } |
43 | 46 |
|
44 | | -# Put breakpoint on main, get the address where the breakpoint was installed. |
45 | | -gdb_test_multiple "break -q main" "break on main, get address" { |
46 | | - -re -wrap "Breakpoint $decimal at ($hex).*" { |
47 | | - set bp_addr $expect_out(1,string) |
| 47 | + # Make sure some prologue was skipped. |
| 48 | + gdb_assert {$bp_addr != -1 && $bp_addr > $main_addr} \ |
| 49 | + "breakpoint placed past main's entry" |
| 50 | +} |
48 | 51 |
|
49 | | - # Convert to decimal. |
50 | | - set bp_addr [expr $bp_addr] |
| 52 | +with_test_prefix "skip-cf-protection" { |
| 53 | + set opts {debug additional_flags=-fcf-protection=full} |
51 | 54 |
|
52 | | - pass $gdb_test_name |
| 55 | + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ |
| 56 | + $opts] != "" } { |
| 57 | + untested "failed to compile" |
| 58 | + return |
53 | 59 | } |
| 60 | + |
| 61 | + clean_restart ${binfile} |
| 62 | + |
| 63 | + test_run |
54 | 64 | } |
55 | 65 |
|
56 | | -if { $bp_addr != -1 } { |
57 | | - # Make sure some prologue was skipped. |
58 | | - gdb_assert {$bp_addr > $main_addr} |
| 66 | +# Now, make sure that the prologue analysis does not end up at function's entry |
| 67 | +# when stack alignment sequence is generated right after 'endbr64'/'endbr32'. |
| 68 | +# That could happen if GDB handled those incorrectly - there was a bug that |
| 69 | +# checked for those two in incorrect order, which caused such issue. |
| 70 | +with_test_prefix "skip-cf-protection-stackalign" { |
| 71 | + # gcc is easier to make it produce the sequence of interest. |
| 72 | + if { ![is_c_compiler_gcc] } { |
| 73 | + unsupported "stackalign test part requires gcc compiler" |
| 74 | + return |
| 75 | + } |
| 76 | + |
| 77 | + if { [prepare_for_testing "failed to prepare" "${testfile}-stackalign" \ |
| 78 | + $srcfile2 [list optimize=-O0 additional_flags=-fcf-protection=full]] } { |
| 79 | + return |
| 80 | + } |
| 81 | + |
| 82 | + test_run |
59 | 83 | } |
0 commit comments