Automatic date update in version.in
[binutils-gdb.git] / gdb / testsuite / gdb.reverse / map-to-same-line.exp
blob067fe0127029e76b5eb33ca9086722f69afbeb36
1 # Copyright 2023-2024 Free Software Foundation, Inc.
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.
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.
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/>.
16 # When stepping (forwards or backwards), GDB should step over the entire line
17 # and not just a particular entry in the line table. This test was added to
18 # verify the find_line_range_start function properly sets the step range for a
19 # line that consists of multiple statements, i.e. multiple entries in the line
20 # table.  This test creates a DWARF line table that contains two entries for
21 # the same line to do the needed testing.
23 # This test can only be run on targets which support DWARF-2 and use gas.
24 load_lib dwarf.exp
25 require dwarf2_support
27 # The DWARF assembler requires the gcc compiler.
28 require is_c_compiler_gcc
30 # This test suitable only for process that can do reverse execution
31 require supports_reverse
33 standard_testfile .c .S
35 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
36     return -1
39 set asm_file [standard_output_file $srcfile2]
40 Dwarf::assemble $asm_file {
41     global srcdir subdir srcfile
42     declare_labels integer_label L
44     # Find start address and length of program
45     lassign [function_range main [list ${srcdir}/${subdir}/$srcfile]] \
46         main_start main_len
47     set main_end "$main_start + $main_len"
49     cu {} {
50         compile_unit {
51             {language @DW_LANG_C}
52             {name map-to-same-line.c}
53             {stmt_list $L DW_FORM_sec_offset}
54             {low_pc 0 addr}
55         } {
56             subprogram {
57                 {external 1 flag}
58                 {name main}
59                 {low_pc $main_start addr}
60                 {high_pc $main_len DW_FORM_data4}
61             }
62         }
63     }
65     lines {version 2 default_is_stmt 1} L {
66         include_dir "${srcdir}/${subdir}"
67         file_name "$srcfile" 1
69         # Generate the line table program with distinct source lines being
70         # mapped to the same line entry. Line 1, 5 and 8 contain 1 statement
71         # each.  Line 2 contains 2 statements.  Line 3 contains 3 statements.
72         program {
73             DW_LNE_set_address $main_start
74             line [gdb_get_line_number "TAG: main prologue"]
75             DW_LNS_copy
76             DW_LNE_set_address line1
77             line [gdb_get_line_number "TAG: line 1" ]
78             DW_LNS_copy
79             DW_LNE_set_address line2
80             line [gdb_get_line_number "TAG: line 2" ]
81             DW_LNS_copy
82             DW_LNE_set_address line3
83             line [gdb_get_line_number "TAG: line 2" ]
84             DW_LNS_copy
85             DW_LNE_set_address line4
86             line [gdb_get_line_number "TAG: line 3" ]
87             DW_LNS_copy
88             DW_LNE_set_address line5
89             line [gdb_get_line_number "TAG: line 3" ]
90             DW_LNS_copy
91             DW_LNE_set_address line6
92             line [gdb_get_line_number "TAG: line 3" ]
93             DW_LNS_copy
94             DW_LNE_set_address line7
95             line [gdb_get_line_number "TAG: line 5" ]
96             DW_LNS_copy
97             DW_LNE_set_address line8
98             line [gdb_get_line_number "TAG: line 8" ]
99             DW_LNS_copy
100             DW_LNE_set_address main_return
101             line [gdb_get_line_number "TAG: main return"]
102             DW_LNS_copy
104             DW_LNE_set_address $main_end
105             DW_LNE_end_sequence
106         }
107     }
110 if { [prepare_for_testing "failed to prepare" ${testfile} \
111         [list $srcfile $asm_file] {nodebug} ] } {
112     return -1
115 if { ![runto_main] } {
116     return
119 # Print the line table
120 gdb_test_multiple "maint info line-table ${testfile}" "" {
121     -re "\r\n$decimal\[ \t\]+$decimal\[ \t\]+($hex)\[ \t\]+Y\[^\r\n\]*" {
122         lappend is_stmt $expect_out(1,string)
123         exp_continue
124     }
125     -re -wrap "" {
126     }
129 # Do the reverse-step and reverse-next tests
130 foreach_with_prefix cmd {step next} {
131     gdb_test_no_output "record" "turn on process record, test $cmd"
133     set bp_main_return [gdb_get_line_number "TAG: main return" $srcfile]
134     gdb_breakpoint $srcfile:$bp_main_return
135     gdb_continue_to_breakpoint  "run to end of main, reverse-$cmd test" ".*$srcfile:$bp_main_return.*"
136     gdb_test "display \$pc" ".*pc =.*" "display pc, reverse-$cmd test"
138     # At this point, GDB has already recorded the execution up until the return
139     # statement.  Reverse and test if GDB transitions between lines in the
140     # expected order.  It should reverse-step or reverse-next across lines 8,
141     # 5, 3, 2 and 1.
142     foreach line {8 5 3 2 1} {
143         gdb_test "reverse-$cmd" ".*TAG: line $line.*" "reverse $cmd to line $line"
144     }
146     if {$cmd =="step"} {
147         ## Clean restart, test reverse-next command
148         clean_restart ${testfile}
150         if { ![runto_main] } {
151             return
152         }
153     }