d01cb9f564568888cc1d47c01614dd93af760a09
[external/binutils.git] / gdb / testsuite / lib / trace-support.exp
1 # Copyright (C) 1998-2017 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
17 #
18 # Support procedures for trace testing
19 #
20
21
22 #
23 # Program counter / stack pointer / frame pointer for supported targets.
24 # Used in many tests, kept here to avoid duplication.
25 #
26
27 if [is_amd64_regs_target] {
28     set fpreg "rbp"
29     set spreg "rsp"
30     set pcreg "rip"
31 } elseif [is_x86_like_target] {
32     set fpreg "ebp"
33     set spreg "esp"
34     set pcreg "eip"
35 } elseif [is_aarch64_target] {
36     set fpreg "x29"
37     set spreg "sp"
38     set pcreg "pc"
39 } elseif [istarget "powerpc*-*-*"] {
40     set fpreg "r31"
41     set spreg "r1"
42     set pcreg "pc"
43 } elseif { [istarget "s390*-*-*"] } {
44     set fpreg "r11"
45     set spreg "r15"
46     set pcreg "pc"
47 } else {
48     set fpreg "fp"
49     set spreg "sp"
50     set pcreg "pc"
51 }
52
53 #
54 # Procedure: gdb_target_supports_trace
55 # Returns true if GDB is connected to a target that supports tracing.
56 # Allows tests to abort early if not running on a trace-aware target.
57 #
58
59 proc gdb_target_supports_trace { } {
60     global gdb_prompt
61
62     send_gdb "tstatus\n"
63     gdb_expect {
64         -re "\[Tt\]race can only be run on.*$gdb_prompt $" {
65             return 0
66         }
67         -re "\[Tt\]race can not be run on.*$gdb_prompt $" {
68             return 0
69         }
70         -re "\[Tt\]arget does not support.*$gdb_prompt $" {
71             return 0
72         }
73         -re ".*\[Ee\]rror.*$gdb_prompt $" {
74             return 0
75         }
76         -re ".*\[Ww\]arning.*$gdb_prompt $" {
77             return 0
78         }
79         -re ".*$gdb_prompt $" {
80             return 1
81         }
82         timeout {
83             return 0
84         }
85     }
86 }
87
88
89 #
90 # Procedure: gdb_delete_tracepoints
91 # Many of the tests depend on setting tracepoints at various places and
92 # running until that tracepoint is reached.  At times, we want to start
93 # with a clean slate with respect to tracepoints, so this utility proc 
94 # lets us do this without duplicating this code everywhere.
95 #
96
97 proc gdb_delete_tracepoints {} {
98     global gdb_prompt
99
100     send_gdb "delete tracepoints\n"
101     gdb_expect 30 {
102         -re "Delete all tracepoints.*y or n.*$" {
103             send_gdb "y\n"
104             exp_continue
105         }
106         -re ".*$gdb_prompt $" { # This happens if there were no tracepoints }
107         timeout { 
108             perror "Delete all tracepoints in delete_tracepoints (timeout)" 
109             return 
110         }
111     }
112     send_gdb "info tracepoints\n"
113     gdb_expect 30 {
114          -re "No tracepoints.*$gdb_prompt $" {}
115          -re "$gdb_prompt $" { perror "tracepoints not deleted" ; return }
116          timeout { perror "info tracepoints (timeout)" ; return }
117     }
118 }
119
120 #   Define actions for a tracepoint.
121 #   Arguments:
122 #       actions_command -- the command used to create the actions.
123 #                          either "actions" or "commands".
124 #       testname   -- identifying string for pass/fail output
125 #       tracepoint -- to which tracepoint(s) do these actions apply? (optional)
126 #       args       -- list of actions to be defined.
127 #   Returns:
128 #       zero       -- success
129 #       non-zero   -- failure
130
131 proc gdb_trace_setactions_command { actions_command testname tracepoint args } {
132     global gdb_prompt
133
134     set state 0
135     set passfail "pass"
136     send_gdb "$actions_command $tracepoint\n"
137     set expected_result ""
138     gdb_expect 5 {
139         -re "No tracepoint number .*$gdb_prompt $" {
140             fail $testname
141             return 1
142         }
143         -re "Enter actions for tracepoint $tracepoint.*>" {
144             if { [llength $args] > 0 } {
145                 set lastcommand "[lindex $args $state]"
146                 send_gdb "[lindex $args $state]\n"
147                 incr state
148                 set expected_result [lindex $args $state]
149                 incr state
150             } else {
151                 send_gdb "end\n"
152             }
153             exp_continue
154         }
155         -re "\(.*\)\[\r\n\]+\[ \t]*>$" {
156             if { $expected_result != "" } {
157                 regsub "^\[^\r\n\]+\[\r\n\]+" "$expect_out(1,string)" "" out
158                 if ![regexp $expected_result $out] {
159                     set passfail "fail"
160                 }
161                 set expected_result ""
162             }
163             if { $state < [llength $args] } {
164                 send_gdb "[lindex $args $state]\n"
165                 incr state
166                 set expected_result [lindex $args $state]
167                 incr state
168             } else {
169                 send_gdb "end\n"
170                 set expected_result ""
171             }
172             exp_continue
173         }
174         -re "\(.*\)$gdb_prompt $" {
175             if { $expected_result != "" } {
176                 if ![regexp $expected_result $expect_out(1,string)] {
177                     set passfail "fail"
178                 }
179                 set expected_result ""
180             }
181             if { [llength $args] < $state } {
182                 set passfail "fail"
183             }
184         }
185         default {
186             set passfail "fail"
187         }
188     }
189     if { $testname != "" } {
190         $passfail $testname
191     }
192     if { $passfail == "pass" } then { 
193         return 0
194     } else {
195         return 1
196     }
197 }
198
199 # Define actions for a tracepoint, using the "actions" command.  See
200 # gdb_trace_setactions_command.
201 #
202 proc gdb_trace_setactions { testname tracepoint args } {
203     eval gdb_trace_setactions_command "actions" {$testname} {$tracepoint} $args
204 }
205
206 # Define actions for a tracepoint, using the "commands" command.  See
207 # gdb_trace_setactions_command.
208 #
209 proc gdb_trace_setcommands { testname tracepoint args } {
210     eval gdb_trace_setactions_command "commands" {$testname} {$tracepoint} $args
211 }
212
213 #
214 # Procedure: gdb_tfind_test
215 #   Find a specified trace frame.
216 #   Arguments: 
217 #       testname   -- identifying string for pass/fail output
218 #       tfind_arg  -- frame (line, PC, etc.) identifier
219 #       exp_res    -- Expected result of frame test
220 #       args       -- Test expression
221 #   Returns:
222 #       zero       -- success
223 #       non-zero   -- failure
224 #
225
226 proc gdb_tfind_test { testname tfind_arg exp_res args } {
227     global gdb_prompt
228
229     if { "$args" != "" } {
230         set expr "$exp_res"
231         set exp_res "$args"
232     } else {
233         set expr "(int) \$trace_frame"
234     }
235     set passfail "fail"
236
237     gdb_test "tfind $tfind_arg" "" ""
238     send_gdb "printf \"x \%d x\\n\", $expr\n"
239     gdb_expect 10 {
240         -re "x (-*\[0-9\]+) x" {
241             if { $expect_out(1,string) == $exp_res } {
242                 set passfail "pass"
243             }
244             exp_continue
245         }
246         -re "$gdb_prompt $" { }
247     }
248     $passfail "$testname"
249     if { $passfail == "pass" } then { 
250         return 0
251     } else {
252         return 1
253     }
254 }
255
256 #
257 # Procedure: gdb_readexpr
258 #   Arguments:
259 #       gdb_expr    -- the expression whose value is desired
260 #   Returns:
261 #       the value of gdb_expr, as evaluated by gdb.
262 #       [FIXME: returns -1 on error, which is sometimes a legit value]
263 #
264
265 proc gdb_readexpr { gdb_expr } {
266     global gdb_prompt
267
268     set result -1
269     send_gdb "print $gdb_expr\n"
270     gdb_expect 5 {
271         -re "\[$\].*= (\[0-9\]+).*$gdb_prompt $" {
272             set result $expect_out(1,string)
273         }
274         -re "$gdb_prompt $" { }
275         default { }
276     }
277     return $result
278 }
279
280 #
281 # Procedure: gdb_gettpnum
282 #   Arguments:
283 #       tracepoint (optional): if supplied, set a tracepoint here.
284 #   Returns:
285 #       the tracepoint ID of the most recently set tracepoint.
286 #
287
288 proc gdb_gettpnum { tracepoint } {
289     global gdb_prompt
290
291     if { $tracepoint != "" } {
292         gdb_test "trace $tracepoint" "" ""
293     }
294     return [gdb_readexpr "\$tpnum"]
295 }
296
297
298 #
299 # Procedure: gdb_find_function_baseline
300 #   Arguments:
301 #       func_name -- name of source function
302 #   Returns:
303 #       Sourcefile line of function definition (open curly brace),
304 #       or -1 on failure.  Caller must check return value.
305 #   Note:
306 #       Works only for open curly brace at beginning of source line!
307 #
308
309 proc gdb_find_function_baseline { func_name } {
310     global gdb_prompt
311
312     set baseline -1
313
314     send_gdb "list $func_name\n"
315 #    gdb_expect {
316 #       -re "\[\r\n\]\[\{\].*$gdb_prompt $" {
317 #           set baseline 1
318 #        }
319 #    }
320 }
321
322 #
323 # Procedure: gdb_find_function_baseline
324 #   Arguments:
325 #       filename: name of source file of desired function.
326 #   Returns:
327 #       Sourcefile line of function definition (open curly brace),
328 #       or -1 on failure.  Caller must check return value.
329 #   Note:
330 #       Works only for open curly brace at beginning of source line!
331 #
332
333 proc gdb_find_recursion_test_baseline { filename } {
334     global gdb_prompt
335
336     set baseline -1
337
338     gdb_test "list $filename:1" "" ""
339     send_gdb "search gdb_recursion_test line 0\n"
340     gdb_expect {
341         -re "(\[0-9\]+)\[\t \]+\{.*line 0.*$gdb_prompt $" {
342             set baseline $expect_out(1,string)
343         }
344         -re "$gdb_prompt $" { }
345         default { }
346     }
347     return $baseline
348 }
349
350 # Return the location of the IPA library.
351
352 proc get_in_proc_agent {} {
353     global objdir
354
355     if [target_info exists in_proc_agent] {
356         return [target_info in_proc_agent]
357     } else {
358         return $objdir/../gdbserver/libinproctrace.so
359     }
360 }
361
362 # Execute BINFILE on target to generate tracefile.  Return 1 if
363 # tracefile is generated successfully, return 0 otherwise.
364
365 proc generate_tracefile { binfile } {
366     set status [remote_exec target "$binfile"]
367
368     if { [lindex $status 0] != 0 } {
369         # Failed to execute $binfile, for example on bare metal targets.
370         # Alternatively, load the binary and run it.  If target doesn't
371         # have fileio capabilities, tracefile can't be generated.  Skip
372         # the test.
373         if [target_info exists gdb,nofileio] {
374             return 0
375         }
376
377         clean_restart $binfile
378
379         if ![runto_main] then {
380             return 0
381         }
382         gdb_continue_to_end "" continue 1
383         gdb_exit
384     }
385
386     return 1
387 }