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# Checks for a bug where a baddly formed ELF would cause GDB to crash. 17# A section containing executable code, for which there was DWARF is 18# accidentally marked as non-alloctable, GDB becomes unhappy. 19# 20# This test creates some fake DWARF pointing at some symbols in a 21# non-allocatable section that is still marked as executable. We then 22# start GDB and try to place a breakpoint on the symbol in the 23# non-allocatable section. 24# 25# It is not expected that the final debug experience really makes 26# sense, the symbol is in a non-allocatable section after all, but GDB 27# absolutely shouldn't crash. All we try to do after placing the 28# breakpoint is check that GDB is still alive. 29 30load_lib dwarf.exp 31 32# This test can only be run on targets which support DWARF-2 and use gas. 33if {![dwarf2_support]} { 34 return 0 35} 36 37standard_testfile main.c -other.S -dwarf.S 38 39if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { 40 untested "failed to compile" 41 return -1 42} 43 44set int_size [get_sizeof "int" 4] 45 46# Make some DWARF for the test. 47set asm_file [standard_output_file $srcfile3] 48Dwarf::assemble $asm_file { 49 global srcdir subdir srcfile srcfile2 int_size 50 51 declare_labels ranges_label_1 ranges_label_2 L1 L2 52 53 set main_result [function_range main ${srcdir}/${subdir}/${srcfile}] 54 set main_start [lindex $main_result 0] 55 set main_length [lindex $main_result 1] 56 57 cu {} { 58 DW_TAG_compile_unit { 59 {DW_AT_language @DW_LANG_C} 60 {DW_AT_name $srcfile} 61 {DW_AT_comp_dir ${srcdir}/${subdir}} 62 {stmt_list $L1 DW_FORM_sec_offset} 63 {ranges ${ranges_label_1} DW_FORM_sec_offset} 64 {DW_AT_low_pc 0 addr} 65 } { 66 declare_labels integer_label 67 68 DW_TAG_subprogram { 69 {name main} 70 {low_pc $main_start addr} 71 {high_pc $main_length data8} 72 {DW_AT_type :$integer_label} 73 {DW_AT_decl_file 1 data1} 74 {DW_AT_decl_line 10 data1} 75 } 76 77 integer_label: DW_TAG_base_type { 78 {DW_AT_byte_size $int_size DW_FORM_sdata} 79 {DW_AT_encoding @DW_ATE_signed} 80 {DW_AT_name integer} 81 } 82 } 83 } 84 85 cu {} { 86 DW_TAG_compile_unit { 87 {DW_AT_language @DW_LANG_C} 88 {DW_AT_name $srcfile2} 89 {DW_AT_comp_dir ${srcdir}/${subdir}} 90 {stmt_list $L2 DW_FORM_sec_offset} 91 {ranges ${ranges_label_2} DW_FORM_sec_offset} 92 {DW_AT_low_pc 0 addr} 93 } { 94 declare_labels integer_label 95 96 DW_TAG_subprogram { 97 {name some_func} 98 {low_pc some_func addr} 99 {high_pc some_func_end addr} 100 {DW_AT_type :$integer_label} 101 {DW_AT_decl_file 2 data1} 102 {DW_AT_decl_line 5 data1} 103 } 104 105 integer_label: DW_TAG_base_type { 106 {DW_AT_byte_size $int_size DW_FORM_sdata} 107 {DW_AT_encoding @DW_ATE_signed} 108 {DW_AT_name integer} 109 } 110 } 111 } 112 113 ranges {is_64 [is_64_target]} { 114 ranges_label_1: sequence { 115 base [lindex $main_result 0] 116 range 0 [lindex $main_result 1] 117 } 118 ranges_label_2: sequence { 119 base some_func 120 range 0 64 121 } 122 } 123 124 lines {version 2} L1 { 125 include_dir "${srcdir}/${subdir}" 126 file_name "$srcfile" 1 127 128 # Line data doens't need to be correct, just present. 129 program { 130 DW_LNE_set_address [lindex $main_result 0] 131 DW_LNS_advance_line 10 132 DW_LNS_copy 133 DW_LNS_advance_pc [lindex $main_result 1] 134 DW_LNS_advance_line 19 135 DW_LNS_copy 136 DW_LNE_end_sequence 137 } 138 } 139 140 lines {version 2} L2 { 141 include_dir "${srcdir}/${subdir}" 142 file_name "dw2-bad-elf-other.c" 1 143 144 # Line data doens't need to be correct, just present. 145 program { 146 DW_LNE_set_address some_func 147 DW_LNS_advance_line 5 148 DW_LNS_copy 149 DW_LNS_advance_pc 64 150 DW_LNS_advance_line 8 151 DW_LNS_copy 152 DW_LNE_end_sequence 153 } 154 } 155} 156 157if { [build_executable ${testfile}.exp ${testfile} \ 158 [list $srcfile $srcfile2 $asm_file] {nodebug}] } { 159 return -1 160} 161 162# Attempt to place a breakpoint on 'some_func', then check GDB is 163# still alive. This test can optionally set a breakpoint on 'main' 164# first (based on GOTO_MAIN), the original bug behaved differently 165# when there was already a breakpoint set. 166proc run_test { goto_main } { 167 global binfile decimal hex 168 169 clean_restart ${binfile} 170 171 if { $goto_main } { 172 if ![runto_main] { 173 return -1 174 } 175 } 176 177 # Place a breakpoint. 178 gdb_test "break some_func" \ 179 "Breakpoint $decimal at $hex: file .*dw2-bad-elf-other\\.c, line 6\\." 180 181 # Check GDB is still alive. 182 gdb_test "echo hello\\n" "hello" 183} 184 185# Run the tests. 186foreach_with_prefix goto_main { 0 1 } { 187 run_test $goto_main 188} 189