1# Copyright 2019-2023 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 ![is_c_compiler_gcc] { 35 return 0 36} 37 38standard_testfile .c .S 39 40set asm_file [standard_output_file $srcfile2] 41Dwarf::assemble $asm_file { 42 global srcdir subdir srcfile srcfile2 43 declare_labels ranges_label lines_label 44 declare_labels aaa_label bbb_label ccc_label 45 declare_labels ggg_label hhh_label iii_label 46 47 get_func_info main 48 get_func_info ddd 49 get_func_info eee 50 get_func_info fff 51 get_func_info jjj 52 get_func_info kkk 53 54 set call_in_main [gdb_get_line_number "main call aaa"] 55 set call_in_aaa [gdb_get_line_number "aaa return"] 56 set call_in_bbb [gdb_get_line_number "bbb return"] 57 set call_in_ccc [gdb_get_line_number "ccc return"] 58 set call_in_fff [gdb_get_line_number "fff return"] 59 set call_in_ggg [gdb_get_line_number "ggg return"] 60 set call_in_hhh [gdb_get_line_number "hhh return"] 61 set call_in_iii [gdb_get_line_number "iii return"] 62 63 cu {} { 64 compile_unit { 65 {language @DW_LANG_C} 66 {name dw2-inline-stepping.c} 67 {low_pc 0 addr} 68 {stmt_list ${lines_label} DW_FORM_sec_offset} 69 {ranges ${ranges_label} DW_FORM_sec_offset} 70 } { 71 subprogram { 72 {external 1 flag} 73 {name ddd} 74 {low_pc $ddd_start addr} 75 {high_pc "$ddd_start + $ddd_len" addr} 76 } 77 subprogram { 78 {external 1 flag} 79 {name eee} 80 {low_pc $eee_start addr} 81 {high_pc "$eee_start + $eee_len" addr} 82 } 83 subprogram { 84 {external 1 flag} 85 {name jjj} 86 {low_pc $jjj_start addr} 87 {high_pc "$jjj_start + $jjj_len" addr} 88 } 89 subprogram { 90 {external 1 flag} 91 {name kkk} 92 {low_pc $kkk_start addr} 93 {high_pc "$kkk_start + $kkk_len" addr} 94 } 95 aaa_label: subprogram { 96 {name aaa} 97 {inline 3 data1} 98 } 99 bbb_label: subprogram { 100 {name bbb} 101 {inline 3 data1} 102 } 103 ccc_label: subprogram { 104 {name ccc} 105 {inline 3 data1} 106 } 107 ggg_label: subprogram { 108 {name ggg} 109 {inline 3 data1} 110 } 111 hhh_label: subprogram { 112 {name hhh} 113 {inline 3 data1} 114 } 115 iii_label: subprogram { 116 {name iii} 117 {inline 3 data1} 118 } 119 subprogram { 120 {external 1 flag} 121 {name main} 122 {low_pc $main_start addr} 123 {high_pc "$main_start + $main_len" addr} 124 } { 125 inlined_subroutine { 126 {abstract_origin %$aaa_label} 127 {low_pc main_label2 addr} 128 {high_pc main_label3 addr} 129 {call_file 1 data1} 130 {call_line $call_in_main data1} 131 } { 132 inlined_subroutine { 133 {abstract_origin %$bbb_label} 134 {low_pc main_label2 addr} 135 {high_pc main_label3 addr} 136 {call_file 1 data1} 137 {call_line $call_in_aaa data1} 138 } { 139 inlined_subroutine { 140 {abstract_origin %$ccc_label} 141 {low_pc main_label2 addr} 142 {high_pc main_label3 addr} 143 {call_file 1 data1} 144 {call_line $call_in_bbb data1} 145 } 146 } 147 } 148 } 149 subprogram { 150 {external 1 flag} 151 {name fff} 152 {low_pc $fff_start addr} 153 {high_pc "$fff_start + $fff_len" addr} 154 } { 155 inlined_subroutine { 156 {abstract_origin %$ggg_label} 157 {low_pc fff_label addr} 158 {high_pc main_label2 addr} 159 {call_file 1 data1} 160 {call_line $call_in_fff data1} 161 } { 162 inlined_subroutine { 163 {abstract_origin %$hhh_label} 164 {low_pc fff_label addr} 165 {high_pc fff_label2 addr} 166 {call_file 1 data1} 167 {call_line $call_in_ggg data1} 168 } { 169 inlined_subroutine { 170 {abstract_origin %$iii_label} 171 {low_pc fff_label addr} 172 {high_pc fff_label2 addr} 173 {call_file 1 data1} 174 {call_line $call_in_hhh data1} 175 } 176 } 177 } 178 } 179 } 180 } 181 182 lines {version 2} lines_label { 183 include_dir "${srcdir}/${subdir}" 184 file_name "$srcfile" 1 185 186 program { 187 DW_LNE_set_address $main_start 188 line [gdb_get_line_number "main prologue"] 189 DW_LNS_copy 190 DW_LNE_set_address main_label 191 line [gdb_get_line_number "main set global_var"] 192 DW_LNS_copy 193 DW_LNE_set_address main_label2 194 line [gdb_get_line_number "main call aaa"] 195 DW_LNS_copy 196 DW_LNE_set_address main_label2 197 line [gdb_get_line_number "aaa return"] 198 DW_LNS_copy 199 DW_LNE_set_address main_label2 200 line [gdb_get_line_number "bbb return"] 201 DW_LNS_copy 202 DW_LNE_set_address main_label2 203 line [gdb_get_line_number "ccc return"] 204 DW_LNS_copy 205 DW_LNE_set_address main_label3 206 line [gdb_get_line_number "main end"] 207 DW_LNS_copy 208 DW_LNE_set_address $main_end 209 DW_LNE_end_sequence 210 211 DW_LNE_set_address $ddd_start 212 line [gdb_get_line_number "ddd prologue"] 213 DW_LNS_copy 214 DW_LNE_set_address ddd_label 215 line [gdb_get_line_number "ddd return"] 216 DW_LNS_copy 217 DW_LNE_set_address ddd_label2 218 line [gdb_get_line_number "ddd end"] 219 DW_LNS_copy 220 DW_LNE_set_address $ddd_end 221 DW_LNE_end_sequence 222 223 DW_LNE_set_address $eee_start 224 line [gdb_get_line_number "eee prologue"] 225 DW_LNS_copy 226 DW_LNE_set_address eee_label 227 line [gdb_get_line_number "eee return"] 228 DW_LNS_copy 229 DW_LNE_set_address eee_label2 230 line [gdb_get_line_number "eee end"] 231 DW_LNS_copy 232 DW_LNE_set_address $eee_end 233 DW_LNE_end_sequence 234 235 DW_LNE_set_address $fff_start 236 line [gdb_get_line_number "fff prologue"] 237 DW_LNS_copy 238 DW_LNE_set_address fff_label 239 line [gdb_get_line_number "fff return"] 240 DW_LNS_copy 241 DW_LNE_set_address fff_label 242 line [gdb_get_line_number "ggg return"] 243 DW_LNS_copy 244 DW_LNE_set_address fff_label 245 line [gdb_get_line_number "hhh return"] 246 DW_LNS_copy 247 DW_LNE_set_address fff_label 248 line [gdb_get_line_number "iii return"] 249 DW_LNS_copy 250 DW_LNE_set_address fff_label2 251 line [gdb_get_line_number "fff end"] 252 DW_LNS_copy 253 DW_LNE_set_address $fff_end 254 DW_LNE_end_sequence 255 256 DW_LNE_set_address $jjj_start 257 line [gdb_get_line_number "jjj prologue"] 258 DW_LNS_copy 259 DW_LNE_set_address jjj_label 260 line [gdb_get_line_number "jjj return"] 261 DW_LNS_copy 262 DW_LNE_set_address jjj_label2 263 line [gdb_get_line_number "jjj end"] 264 DW_LNS_copy 265 DW_LNE_set_address $jjj_end 266 DW_LNE_end_sequence 267 268 DW_LNE_set_address $kkk_start 269 line [gdb_get_line_number "kkk prologue"] 270 DW_LNS_copy 271 DW_LNE_set_address kkk_label 272 line [gdb_get_line_number "kkk return"] 273 DW_LNS_copy 274 DW_LNE_set_address $kkk_end 275 DW_LNE_end_sequence 276 } 277 } 278 279 ranges {is_64 [is_64_target]} { 280 ranges_label: sequence { 281 range ${main_start} ${main_end} 282 range ${ddd_start} ${ddd_end} 283 range ${eee_start} ${eee_end} 284 range ${fff_start} ${fff_end} 285 range ${jjj_start} ${jjj_end} 286 range ${kkk_start} ${kkk_end} 287 } 288 } 289} 290 291if { [prepare_for_testing "failed to prepare" ${testfile} \ 292 [list $srcfile $asm_file] {nodebug}] } { 293 return -1 294} 295 296if ![runto_main] { 297 return -1 298} 299 300# First we step through all of the functions until we get the 'kkk'. 301set patterns [list "main call aaa" \ 302 "aaa return" \ 303 "bbb return" \ 304 "ccc return" \ 305 "ddd return" \ 306 "eee return" \ 307 "fff return" \ 308 "ggg return" \ 309 "hhh return" \ 310 "iii return" \ 311 "jjj return" \ 312 "kkk return" ] 313foreach p $patterns { 314 gdb_test "step" "/\\* $p \\*/" \ 315 "step to '$p'" 316} 317 318# Now check the backtrace. 319set line_in_main [gdb_get_line_number "main call aaa"] 320set line_in_aaa [gdb_get_line_number "aaa return"] 321set line_in_bbb [gdb_get_line_number "bbb return"] 322set line_in_ccc [gdb_get_line_number "ccc return"] 323set line_in_ddd [gdb_get_line_number "ddd return"] 324set line_in_eee [gdb_get_line_number "eee return"] 325set line_in_fff [gdb_get_line_number "fff return"] 326set line_in_ggg [gdb_get_line_number "ggg return"] 327set line_in_hhh [gdb_get_line_number "hhh return"] 328set line_in_iii [gdb_get_line_number "iii return"] 329set line_in_jjj [gdb_get_line_number "jjj return"] 330set line_in_kkk [gdb_get_line_number "kkk return"] 331 332gdb_test "bt" [multi_line \ 333 "#0 kkk \\(\\) at \[^\r\n\]+${srcfile}:${line_in_kkk}" \ 334 "#1 $hex in jjj \\(\\) at \[^\r\n\]+${srcfile}:${line_in_jjj}" \ 335 "#2 $hex in iii \\(\\) at \[^\r\n\]+${srcfile}:${line_in_iii}" \ 336 "#3 hhh \\(\\) at \[^\r\n\]+${srcfile}:${line_in_hhh}" \ 337 "#4 ggg \\(\\) at \[^\r\n\]+${srcfile}:${line_in_ggg}" \ 338 "#5 fff \\(\\) at \[^\r\n\]+${srcfile}:${line_in_fff}" \ 339 "#6 $hex in eee \\(\\) at \[^\r\n\]+${srcfile}:${line_in_eee}" \ 340 "#7 $hex in ddd \\(\\) at \[^\r\n\]+${srcfile}:${line_in_ddd}" \ 341 "#8 $hex in ccc \\(\\) at \[^\r\n\]+${srcfile}:${line_in_ccc}" \ 342 "#9 bbb \\(\\) at \[^\r\n\]+${srcfile}:${line_in_bbb}" \ 343 "#10 aaa \\(\\) at \[^\r\n\]+${srcfile}:${line_in_aaa}" \ 344 "#11 main \\(\\) at \[^\r\n\]+${srcfile}:${line_in_main}" ] 345 346# Now check we can use 'up' to inspect each frame correctly. 347set patterns [list \ 348 "jjj return" \ 349 "iii return" \ 350 "hhh return" \ 351 "ggg return" \ 352 "fff return" \ 353 "eee return" \ 354 "ddd return" \ 355 "ccc return" \ 356 "bbb return" \ 357 "aaa return" \ 358 "main call aaa" ] 359foreach p $patterns { 360 gdb_test "up" "/\\* $p \\*/" \ 361 "up to '$p'" 362} 363