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