1# Copyright 2004-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# This file is part of the gdb testsuite.
17
18
19# Test handling of nullified instructions for the pa target.
20
21switch -glob -- [istarget] {
22    "hppa-*-*" {
23	set testfile "pa-nullify"
24    }
25    "hppa64-*-*" {
26	set testfile "pa64-nullify"
27    }
28    "*" {
29        verbose "Skipping hppa nullification tests."
30        return
31    }
32}
33
34set srcfile ${testfile}.s
35set binfile ${objdir}/${subdir}/${testfile}
36set gcorefile ${objdir}/${subdir}/${testfile}.gcore
37
38if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } {
39    unsupported "failed to compile"
40    return -1
41}
42
43gdb_exit
44gdb_start
45gdb_reinitialize_dir $srcdir/$subdir
46gdb_load ${binfile}
47
48# In the first test, we do a "step" on a function whose last instruction
49# contains a branch-with-nullify.  The instruction in the delay slot belongs
50# to the next function.  We verify that when we step off the first function
51# that we end up back at the caller and not at the second instruction.
52
53gdb_breakpoint foo
54gdb_test "run" "Breakpoint 1, .* in foo.*" "breakpoint at foo"
55
56set test "stepi till main"
57gdb_test_multiple "stepi" "${test}" {
58  -re ".*in foo.*$gdb_prompt $" {
59    send_gdb "stepi\n"
60    exp_continue -continue_timer
61  }
62  -re ".*in bar.*$gdb_prompt $" {
63    fail $test
64  }
65  -re ".*in main.*$gdb_prompt $" {
66    pass $test
67  }
68}
69
70# In the second test, we verify that we can get a proper backtrace
71# even when we are in a nullified instruction that belongs to the next function.
72# We also verify that when stepping over a branch-with-nullify insn that we
73# stay on the same insn for two steps.
74
75proc get_addr_of_sym { sym } {
76  set addr 0
77  global gdb_prompt
78  global hex
79
80  set test "get address of $sym"
81  gdb_test_multiple "print $sym" $test {
82    -re ".*($hex) <$sym>.*$gdb_prompt $" {
83      set addr $expect_out(1,string)
84      pass $test
85    }
86  }
87
88  return $addr
89}
90
91if  ![runto_main] then {
92    fail "can't run to main"
93    return 0
94}
95
96set foo [get_addr_of_sym "foo"]
97set bar [get_addr_of_sym "bar"]
98set foo_last "(bar - 4)"
99
100gdb_breakpoint "*$foo_last"
101
102gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*"
103gdb_test "backtrace" "in foo.*in main.*" "backtrace from last insn in foo"
104gdb_test "stepi" "in foo.*" "stepi to nullified instruction stays in foo"
105gdb_test "backtrace" "in foo.*in main.*" "backtrace from nullified insn"
106gdb_test "stepi" "in main.*" "stepi to main"
107
108# In the third test, we verify that backtraces from nullified instructions
109# work even in coredumps
110
111proc gen_core { test } {
112  global gcorefile
113
114  set gcore_works [gdb_gcore_cmd $gcorefile "$test: gcore"]
115  return $gcore_works
116}
117
118proc test_core_bt { test } {
119  global gcorefile
120
121  gdb_test "core $gcorefile" "Core was generated by.*" \
122    "$test: load core file" "A program is being debugged already.*" "y"
123
124  gdb_test "backtrace" ".*in foo.*in main.*" "$test: backtrace in gcore"
125}
126
127set test "core at last insn in foo"
128if ![runto_main] then {
129    fail "can't run to main"
130    return 0
131}
132gdb_breakpoint "*$foo_last"
133gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" "$test: continue to breakpoint"
134if [gen_core $test] {
135  test_core_bt $test
136}
137
138set test "core at nullified insn"
139if ![runto_main] then {
140    fail "can't run to main"
141    return 0
142}
143gdb_breakpoint "*$foo_last"
144gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" "$test: continue to breakpoint"
145gdb_test "stepi" ".*in foo.*" "$test: step to nullified instruction"
146if [gen_core $test] {
147  test_core_bt $test
148}
149