1# Copyright 2016-2020 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# The purpose of this testcase is to verify that, when using a breakpoint
17# location of the form "*<EXPR>" (Eg: "*main"), GDB is able to start
18# the program and stop at the correct location.  With programs built
19# as PIE, this means that GDB needs to re-evaluate the location once
20# the program as started, since PIE ensures that the address of all
21# symbols have changed after load.
22#
23# PIE is not always supported by the target system, so instead of
24# creating a testcase building executables with PIE, this testcase
25# takes a slightly different approach.  It builds a first program,
26# breaks on *main, and then runs to that breakpoint. It then builds
27# a second program, different from the first one, and loads that
28# executable within the same GDB session.  Similarly to the PIE case,
29# the address of main should be different, and therefore GDB should
30# recalculate it.  We verify that by checking that running to that
31# breakpoint still works, and that we land at the first instruction
32# of that function in both cases.
33
34set testfile1 "break-fun-addr1"
35set srcfile1 ${testfile1}.c
36set binfile1 [standard_output_file ${testfile1}]
37
38if  { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {debug}] != "" } {
39    untested "failed to compile first testcase"
40    return -1
41}
42
43# Start the debugger with the first executable, put a breakpoint
44# on the first instruction of function "main" ("*main"), then
45# run to that breakpoint.
46
47clean_restart ${binfile1}
48
49with_test_prefix "${testfile1}" {
50
51    gdb_test "break *main" \
52        "Breakpoint.*at.* file .*$srcfile1, line .*" \
53
54    gdb_run_cmd
55    gdb_test "" \
56             "Breakpoint.* main \\(\\) at .*$srcfile1:.*" \
57             "run to breakpoint at *main"
58
59    # Verify also that we stopped at the start of the function...
60    gdb_test "p \$pc == main" " = 1"
61}
62
63set testfile2 "break-fun-addr2"
64set srcfile2 ${testfile2}.c
65set binfile2 [standard_output_file ${testfile2}]
66
67if  { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
68    untested "failed to compile second testcase"
69    return -1
70}
71
72# Now, keeping the same GDB process (so as to keep the same breakpoint),
73# start a new debugging session with a different executable.
74gdb_load ${binfile2}
75
76with_test_prefix "${testfile2}" {
77
78    gdb_run_cmd
79    gdb_test "" \
80             "Breakpoint.* main \\(\\) at .*$srcfile2:.*" \
81             "run to breakpoint at *main"
82
83    gdb_test "p \$pc == main" " = 1"
84}
85