mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
This updates the copyright headers to include 2025. I did this by running gdb/copyright.py and then manually modifying a few files as noted by the script. Approved-By: Eli Zaretskii <eliz@gnu.org>
197 lines
5.6 KiB
Plaintext
197 lines
5.6 KiB
Plaintext
# Copyright 2024-2025 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 creates a function 'foo' that contains an inline function
|
|
# 'bar'. Both 'foo' and 'bar' are split into two regions. The layout
|
|
# in memory looks something like this:
|
|
#
|
|
# <part-a> <gap> <part-b>
|
|
#
|
|
# bar: |------------| |---|
|
|
# foo: |------------------| |--------|
|
|
#
|
|
# We see things like this in "real" code where the parts after the gap
|
|
# (part-b) are cold paths within the function that have been moved
|
|
# aside.
|
|
#
|
|
# However, in this test program we use 'goto' to jump directly from
|
|
# the first part of the function (part-a) to the second part (part-b).
|
|
#
|
|
# At the time we hit the goto we are inside 'bar'. After the goto we
|
|
# expect to still be in bar. At one point GDB would get this wrong
|
|
# and after the jump we would revert back to 'foo'.
|
|
#
|
|
# This bug will only trigger if both 'foo' and 'bar' are split, and
|
|
# both 'foo' and 'bar' must start at the same address for part-b.
|
|
|
|
load_lib dwarf.exp
|
|
|
|
require dwarf2_support
|
|
|
|
# The source program use 'goto *ADDR' which is a GCC extension.
|
|
require is_c_compiler_gcc
|
|
|
|
standard_testfile
|
|
|
|
# This compiles the source file and starts and stops GDB, so run it
|
|
# before calling prepare_for_testing otherwise GDB will have exited.
|
|
get_func_info foo
|
|
|
|
# Make some DWARF for the test.
|
|
set asm_file [standard_output_file "$::testfile-dw.S"]
|
|
Dwarf::assemble $asm_file {
|
|
global srcfile
|
|
|
|
# Create local varibles BAR_SRC_* containing the line number for
|
|
# the four souce lines of 'foo' and 'bar'. These will be
|
|
# referenced in the generated DWARF.
|
|
for { set i 1 } { $i <= 4 } { incr i } {
|
|
set bar_src_$i [gdb_get_line_number "bar line $i"]
|
|
set foo_src_$i [gdb_get_line_number "foo line $i"]
|
|
}
|
|
|
|
# More line numbers needed for the generated DWARF.
|
|
set foo_decl_line [gdb_get_line_number "foo decl line"]
|
|
set bar_decl_line [gdb_get_line_number "bar decl line"]
|
|
|
|
# Labels used to link parts of the DWARF together.
|
|
declare_labels lines_table bar_label ranges_label_bar ranges_label_foo
|
|
|
|
cu { version 4 } {
|
|
compile_unit {
|
|
{producer "gcc"}
|
|
{language @DW_LANG_C}
|
|
{name ${srcfile}}
|
|
{comp_dir /tmp}
|
|
{stmt_list $lines_table DW_FORM_sec_offset}
|
|
{low_pc 0 addr}
|
|
} {
|
|
bar_label: subprogram {
|
|
{external 1 flag}
|
|
{name bar}
|
|
{decl_file 1 data1}
|
|
{decl_line $bar_decl_line data1}
|
|
{decl_column 1 data1}
|
|
{inline 3 data1}
|
|
}
|
|
subprogram {
|
|
{name foo}
|
|
{decl_file 1 data1}
|
|
{decl_line $foo_decl_line data1}
|
|
{decl_column 1 data1}
|
|
{ranges ${ranges_label_foo} DW_FORM_sec_offset}
|
|
{external 1 flag}
|
|
} {
|
|
inlined_subroutine {
|
|
{abstract_origin %$bar_label}
|
|
{call_file 1 data1}
|
|
{call_line $foo_src_3 data1}
|
|
{ranges ${ranges_label_bar} DW_FORM_sec_offset}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lines {version 2} lines_table {
|
|
include_dir "$::srcdir/$::subdir"
|
|
file_name "$srcfile" 1
|
|
program {
|
|
DW_LNE_set_address "foo_label"
|
|
line $foo_src_1
|
|
DW_LNS_copy
|
|
DW_LNE_set_address "foo_label_1"
|
|
line $foo_src_2
|
|
DW_LNS_copy
|
|
DW_LNE_set_address "foo_label_2"
|
|
line $foo_src_3
|
|
DW_LNS_copy
|
|
DW_LNE_set_address "foo_label_2"
|
|
line $bar_src_1
|
|
DW_LNS_copy
|
|
DW_LNE_set_address "foo_label_3"
|
|
line $bar_src_2
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address "foo_label_4"
|
|
DW_LNE_end_sequence
|
|
|
|
DW_LNE_set_address "foo_label_6"
|
|
line $bar_src_3
|
|
DW_LNS_copy
|
|
DW_LNE_set_address "foo_label_7"
|
|
line $bar_src_4
|
|
DW_LNS_copy
|
|
|
|
DW_LNS_negate_stmt
|
|
DW_LNE_set_address "foo_label_7"
|
|
line $foo_src_3
|
|
DW_LNS_copy
|
|
|
|
DW_LNS_negate_stmt
|
|
DW_LNE_set_address "foo_label_8"
|
|
line $foo_src_4
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address $::foo_end
|
|
DW_LNE_end_sequence
|
|
}
|
|
}
|
|
|
|
ranges { } {
|
|
ranges_label_bar: sequence {
|
|
range foo_label_2 foo_label_4
|
|
range foo_label_6 foo_label_8
|
|
}
|
|
ranges_label_foo: sequence {
|
|
range foo_label_1 foo_label_4
|
|
range foo_label_6 foo_label_9
|
|
}
|
|
}
|
|
}
|
|
|
|
if {[prepare_for_testing "failed to prepare" "${::testfile}" \
|
|
[list $srcfile $asm_file] {nodebug}]} {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] {
|
|
return -1
|
|
}
|
|
|
|
gdb_breakpoint bar
|
|
gdb_continue_to_breakpoint "continue to bar line 1" \
|
|
".*bar line 1\[^\r\n\]+"
|
|
|
|
gdb_test "step" ".*bar line 2\[^\r\n\]+" \
|
|
"step to bar line 2"
|
|
|
|
# This is the interesting one. This step will take us over the goto
|
|
# and into the second range of both 'foo' and 'bar'. As we started
|
|
# the step in 'bar' GDB should reselect 'bar' after the step.
|
|
#
|
|
# If this goes wrong the GDB will claim we are at foo_line_3, which is
|
|
# the DW_AT_call_line for 'bar'.
|
|
gdb_test "step" ".*bar line 3\[^\r\n\]+" \
|
|
"step to bar line 3"
|
|
|
|
# These following steps should be straight forward, but lets just
|
|
# check we can step out of 'bar' and back to 'foo', there shouldn't be
|
|
# anything tricky going on here though.
|
|
gdb_test "step" ".*bar line 4\[^\r\n\]+" \
|
|
"step to bar line 4"
|
|
|
|
gdb_test "step" ".*foo line 4\[^\r\n\]+" \
|
|
"step out of bar to foo line 4"
|