1 # Copyright 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 # This test creates a function 'foo' that contains an inline function
17 # 'bar'. Both 'foo' and 'bar' are split into two regions. The layout
18 # in memory looks something like this:
20 # <part-a> <gap> <part-b>
22 # bar: |------------| |---|
23 # foo: |------------------| |--------|
25 # We see things like this in "real" code where the parts after the gap
26 # (part-b) are cold paths within the function that have been moved
29 # However, in this test program we use 'goto' to jump directly from
30 # the first part of the function (part-a) to the second part (part-b).
32 # At the time we hit the goto we are inside 'bar'. After the goto we
33 # expect to still be in bar. At one point GDB would get this wrong
34 # and after the jump we would revert back to 'foo'.
36 # This bug will only trigger if both 'foo' and 'bar' are split, and
37 # both 'foo' and 'bar' must start at the same address for part-b.
41 require dwarf2_support
43 # The source program use 'goto *ADDR' which is a GCC extension.
44 require is_c_compiler_gcc
48 # This compiles the source file and starts and stops GDB, so run it
49 # before calling prepare_for_testing otherwise GDB will have exited.
52 # Make some DWARF for the test.
53 set asm_file [standard_output_file "$::testfile-dw.S"]
54 Dwarf::assemble $asm_file {
57 # Create local varibles BAR_SRC_* containing the line number for
58 # the four souce lines of 'foo' and 'bar'. These will be
59 # referenced in the generated DWARF.
60 for { set i 1 } { $i <= 4 } { incr i } {
61 set bar_src_$i [gdb_get_line_number "bar line $i"]
62 set foo_src_$i [gdb_get_line_number "foo line $i"]
65 # More line numbers needed for the generated DWARF.
66 set foo_decl_line [gdb_get_line_number "foo decl line"]
67 set bar_decl_line [gdb_get_line_number "bar decl line"]
69 # Labels used to link parts of the DWARF together.
70 declare_labels lines_table bar_label ranges_label_bar ranges_label_foo
78 {stmt_list $lines_table DW_FORM_sec_offset}
81 bar_label: subprogram {
85 {decl_line $bar_decl_line data1}
92 {decl_line $foo_decl_line data1}
94 {ranges ${ranges_label_foo} DW_FORM_sec_offset}
98 {abstract_origin %$bar_label}
100 {call_line $foo_src_3 data1}
101 {ranges ${ranges_label_bar} DW_FORM_sec_offset}
107 lines {version 2} lines_table {
108 include_dir "$::srcdir/$::subdir"
109 file_name "$srcfile" 1
111 DW_LNE_set_address "foo_label"
114 DW_LNE_set_address "foo_label_1"
117 DW_LNE_set_address "foo_label_2"
120 DW_LNE_set_address "foo_label_2"
123 DW_LNE_set_address "foo_label_3"
127 DW_LNE_set_address "foo_label_4"
130 DW_LNE_set_address "foo_label_6"
133 DW_LNE_set_address "foo_label_7"
138 DW_LNE_set_address "foo_label_7"
143 DW_LNE_set_address "foo_label_8"
147 DW_LNE_set_address $::foo_end
153 ranges_label_bar: sequence {
154 range foo_label_2 foo_label_4
155 range foo_label_6 foo_label_8
157 ranges_label_foo: sequence {
158 range foo_label_1 foo_label_4
159 range foo_label_6 foo_label_9
164 if {[prepare_for_testing "failed to prepare" "${::testfile}" \
165 [list $srcfile $asm_file] {nodebug}]} {
174 gdb_continue_to_breakpoint "continue to bar line 1" \
175 ".*bar line 1\[^\r\n\]+"
177 gdb_test "step" ".*bar line 2\[^\r\n\]+" \
180 # This is the interesting one. This step will take us over the goto
181 # and into the second range of both 'foo' and 'bar'. As we started
182 # the step in 'bar' GDB should reselect 'bar' after the step.
184 # If this goes wrong the GDB will claim we are at foo_line_3, which is
185 # the DW_AT_call_line for 'bar'.
186 gdb_test "step" ".*bar line 3\[^\r\n\]+" \
189 # These following steps should be straight forward, but lets just
190 # check we can step out of 'bar' and back to 'foo', there shouldn't be
191 # anything tricky going on here though.
192 gdb_test "step" ".*bar line 4\[^\r\n\]+" \
195 gdb_test "step" ".*foo line 4\[^\r\n\]+" \
196 "step out of bar to foo line 4"