1# Copyright 2020 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# This test shows the importance of not corrupting the order of line 17# table information. When multiple lines are given for the same 18# address the compiler usually lists these in the order in which we 19# would expect to encounter them. When stepping through nested inline 20# frames the last line given for an address is assumed by GDB to be 21# the most inner frame, and this is what GDB displays. 22# 23# If we corrupt the order of the line table entries then GDB will 24# display the wrong line as being the inner most frame. 25 26load_lib dwarf.exp 27 28# This test can only be run on targets which support DWARF-2 and use gas. 29if {![dwarf2_support]} { 30 return 0 31} 32 33# The .c files use __attribute__. 34if [get_compiler_info] { 35 return -1 36} 37if !$gcc_compiled { 38 return 0 39} 40 41standard_testfile dw2-is-stmt-2.c dw2-is-stmt-2.S 42 43set asm_file [standard_output_file $srcfile2] 44Dwarf::assemble $asm_file { 45 global srcdir subdir srcfile 46 declare_labels lines_label 47 48 get_func_info main 49 50 cu {} { 51 compile_unit { 52 {language @DW_LANG_C} 53 {name dw2-is-stmt.c} 54 {low_pc 0 addr} 55 {stmt_list ${lines_label} DW_FORM_sec_offset} 56 } { 57 subprogram { 58 {external 1 flag} 59 {name main} 60 {low_pc $main_start addr} 61 {high_pc "$main_start + $main_len" addr} 62 } {} 63 } 64 } 65 66 lines {version 2 default_is_stmt 1} lines_label { 67 include_dir "${srcdir}/${subdir}" 68 file_name "$srcfile" 1 69 70 program { 71 {DW_LNE_set_address main} 72 {line [gdb_get_line_number "main prologue"]} 73 {DW_LNS_copy} 74 75 {DW_LNE_set_address line_label_0} 76 {line [gdb_get_line_number "main start"]} 77 {DW_LNS_copy} 78 79 {DW_LNE_set_address line_label_1} 80 {line [gdb_get_line_number "Line 1"]} 81 {DW_LNS_negate_stmt} 82 {DW_LNS_copy} 83 84 {DW_LNE_set_address line_label_2} 85 {DW_LNS_negate_stmt} 86 {DW_LNS_copy} 87 88 {DW_LNE_set_address line_label_3} 89 {line [gdb_get_line_number "Line 2"]} 90 {DW_LNS_negate_stmt} 91 {DW_LNS_copy} 92 93 {DW_LNE_set_address line_label_4} 94 {line [gdb_get_line_number "Line 1"]} 95 {DW_LNS_copy} 96 97 {DW_LNE_set_address line_label_5} 98 {line [gdb_get_line_number "Line 3"]} 99 {DW_LNS_copy} 100 101 {DW_LNE_set_address line_label_6} 102 {line [gdb_get_line_number "Line 4"]} 103 {DW_LNS_copy} 104 105 {DW_LNE_set_address line_label_7} 106 {DW_LNS_negate_stmt} 107 {DW_LNS_copy} 108 109 {DW_LNE_set_address line_label_8} 110 {line [gdb_get_line_number "Line 2"]} 111 {DW_LNS_copy} 112 113 {DW_LNE_set_address line_label_9} 114 {DW_LNS_negate_stmt} 115 {DW_LNS_copy} 116 117 {DW_LNE_set_address line_label_10} 118 {line [gdb_get_line_number "Line 3"]} 119 {DW_LNS_copy} 120 121 {DW_LNE_set_address line_label_11} 122 {line [gdb_get_line_number "Line 5"]} 123 {DW_LNS_copy} 124 125 {DW_LNE_set_address line_label_12} 126 {DW_LNS_negate_stmt} 127 {DW_LNS_copy} 128 129 {DW_LNE_set_address line_label_13} 130 {line [gdb_get_line_number "Line 3"]} 131 {DW_LNS_copy} 132 133 {DW_LNE_set_address line_label_14} 134 {line [gdb_get_line_number "Line 4"]} 135 {DW_LNS_negate_stmt} 136 {DW_LNS_copy} 137 138 {DW_LNE_set_address line_label_15} 139 {line [gdb_get_line_number "Line 5"]} 140 {DW_LNS_copy} 141 142 {DW_LNE_set_address line_label_16} 143 {line [gdb_get_line_number "main end"]} 144 {DW_LNS_negate_stmt} 145 {DW_LNS_copy} 146 147 {DW_LNE_set_address ${main_end}} 148 {DW_LNE_end_sequence} 149 } 150 } 151} 152 153if { [prepare_for_testing "failed to prepare" ${testfile} \ 154 [list $srcfile $asm_file] {nodebug}] } { 155 return -1 156} 157 158if ![runto_main] { 159 return -1 160} 161 162# Check stepping through the out of order lines gives the experience 163# we expect; lines in the correct order, and stop at the correct 164# labels.Q 165set locs { { "Line 1." "line_label_2" } \ 166 { "Line 4." "line_label_7" } \ 167 { "Line 2." "line_label_8" } \ 168 { "Line 5." "line_label_12" } \ 169 { "Line 3." "line_label_13" } } 170foreach entry $locs { 171 set pattern [lindex $entry 0] 172 set label [lindex $entry 1] 173 174 set linum [gdb_get_line_number "$pattern"] 175 gdb_test "step" "\r\n$linum\[ \t\]+/\\* $pattern \\*/" \ 176 "step to $pattern" 177 178 set pc [get_hexadecimal_valueof "\$pc" "NO-PC" \ 179 "read \$pc at $pattern"] 180 set val [get_hexadecimal_valueof "&${label}" "INVALID"] 181 gdb_assert { $pc == $val } \ 182 "check pc at $pattern" 183} 184 185# Now restart the test, and this time, single instruction step 186# through. This is checking that the is-stmt marked lines are 187# displayed differently (without addresses) to addresses that are 188# mid-way through a line, or not marked as is-stmt. 189clean_restart $binfile 190runto_main 191 192foreach entry $locs { 193 set pattern [lindex $entry 0] 194 set label [lindex $entry 1] 195 196 with_test_prefix "stepi to $label" { 197 # If can take many instruction steps to get to the next label. 198 set i 0 199 set pc [get_hexadecimal_valueof "\$pc" "NO-PC" ] 200 set val [get_hexadecimal_valueof "&${label}" "INVALID"] 201 while { $pc < $val } { 202 incr i 203 set line_changed -1 204 gdb_test_multiple "stepi" "stepi $i" { 205 -re "\r\n$hex\[ \t\]+$decimal\[^\r\n\]+\r\n$gdb_prompt" { 206 set line_changed 0 207 } 208 -re "\r\n$decimal\[ \t\]+/\\* $pattern \\*/\r\n$gdb_prompt" { 209 set line_changed 1 210 } 211 } 212 gdb_assert { $line_changed != -1 } \ 213 "ensure we saw a valid pattern, $i" 214 set pc [get_hexadecimal_valueof "\$pc" "NO-PC" \ 215 "get pc inside stepi loop, $i"] 216 if { $pc == $val } { 217 gdb_assert { $line_changed } \ 218 "line must change at $label" 219 } else { 220 gdb_assert { !$line_changed } "same line $i" 221 } 222 } 223 } 224} 225