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