From b39a8faf7cc4901252a59b531074a092a80d2354 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Sat, 24 Aug 2013 01:53:06 +0000 Subject: gdb/testsuite/ * lib/dwarf.exp (_location): Handle DW_OP_deref_size. * gdb.trace/entry-values.c: New. * gdb.trace/entry-values.exp: New. --- gdb/testsuite/ChangeLog | 6 + gdb/testsuite/gdb.trace/entry-values.c | 45 ++++++ gdb/testsuite/gdb.trace/entry-values.exp | 232 +++++++++++++++++++++++++++++++ gdb/testsuite/lib/dwarf.exp | 8 ++ 4 files changed, 291 insertions(+) create mode 100644 gdb/testsuite/gdb.trace/entry-values.c create mode 100644 gdb/testsuite/gdb.trace/entry-values.exp (limited to 'gdb/testsuite') diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3e347a1..49d4b38 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-08-24 Yao Qi + + * lib/dwarf.exp (_location): Handle DW_OP_deref_size. + * gdb.trace/entry-values.c: New. + * gdb.trace/entry-values.exp: New. + 2013-07-12 Muhammad Waqas PR gdb/15501 diff --git a/gdb/testsuite/gdb.trace/entry-values.c b/gdb/testsuite/gdb.trace/entry-values.c new file mode 100644 index 0000000..3f98615 --- /dev/null +++ b/gdb/testsuite/gdb.trace/entry-values.c @@ -0,0 +1,45 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012-2013 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 . */ + +int +foo (int i, int j) +{ + return 0; +} + +int +bar (int i) +{ + int j = 2; + + return foo (i, j); +} + +int global1 = 1; +int global2 = 2; + +int +main (void) +{ + int ret = 0; + + global1++; + global2++; + ret = bar (0); + + return ret; +} diff --git a/gdb/testsuite/gdb.trace/entry-values.exp b/gdb/testsuite/gdb.trace/entry-values.exp new file mode 100644 index 0000000..0fb060a --- /dev/null +++ b/gdb/testsuite/gdb.trace/entry-values.exp @@ -0,0 +1,232 @@ +# Copyright 2013 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 . +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile .c entry-values-dw.S + +if {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \ + object {nodebug}] != ""} { + return -1 +} + +# Start GDB and load object file, compute the function length and +# the offset of branch instruction in function. They are needed +# in the Dwarf Assembler below. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile}1.o + +set foo_length "" + +# Calculate the offset of the last instruction from the beginning. +set test "disassemble foo" +gdb_test_multiple $test $test { + -re ".*$hex <\\+($decimal)>:\[^\r\n\]+\r\nEnd of assembler dump\.\r\n$gdb_prompt $" { + set foo_length $expect_out(1,string) + pass $test + } + -re ".*$gdb_prompt $" { + fail $test + # Bail out here, because we can't do the following tests if + # $foo_length is unknown. + return -1 + } +} + +# Calculate the size of the last instruction. Single instruction +# shouldn't be longer than 10 bytes. + +set test "disassemble foo+$foo_length,+10" +gdb_test_multiple $test $test { + -re ".*($hex) :\[^\r\n\]+\r\n\[ \]+($hex) .*\.\r\n$gdb_prompt $" { + set start $expect_out(1,string) + set end $expect_out(2,string) + + set foo_length [expr $foo_length + $end - $start] + pass $test + } + -re ".*$gdb_prompt $" { + fail $test + # Bail out here, because we can't do the following tests if + # $foo_length is unknown. + return -1 + } +} + +set bar_length "" +set bar_call_foo "" + +# Calculate the offset of the last instruction from the beginning. +set test "disassemble bar" +gdb_test_multiple $test $test { + -re ".*$hex <\\+$decimal>:\[ \t\]+call\[^\r\n\]+\r\n\[ \]+$hex <\\+($decimal)>:" { + set bar_call_foo $expect_out(1,string) + exp_continue + } + -re ".*$hex <\\+($decimal)>:\[^\r\n\]+\r\nEnd of assembler dump\.\r\n$gdb_prompt $" { + set bar_length $expect_out(1,string) + pass $test + } + -re ".*$gdb_prompt $" { + fail $test + } +} + +if { [string equal $bar_call_foo ""] || [string equal $bar_length ""] } { + fail "Find the call or branch instruction offset in bar" + # The following test makes no sense if the offset is unknown. We need + # to update the pattern above to match call or branch instruction for + # the target architecture. + return -1 +} + +# Calculate the size of the last instruction. + +set test "disassemble bar+$bar_length,+10" +gdb_test_multiple $test $test { + -re ".*($hex) :\[^\r\n\]+\r\n\[ \]+($hex) .*\.\r\n$gdb_prompt $" { + set start $expect_out(1,string) + set end $expect_out(2,string) + + set bar_length [expr $bar_length + $end - $start] + pass $test + } + -re ".*$gdb_prompt $" { + fail $test + # Bail out here, because we can't do the following tests if + # $bar_length is unknown. + return -1 + } +} + +gdb_exit + +# Make some DWARF for the test. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + declare_labels int_label foo_label + global foo_length bar_length bar_call_foo + + cu {} { + compile_unit {{language @DW_LANG_C}} { + int_label: base_type { + {name int} + {encoding @DW_ATE_signed} + {byte_size 4 DW_FORM_sdata} + } + + foo_label: subprogram { + {name foo} + {decl_file 1} + {low_pc foo addr} + {high_pc "foo + $foo_length" addr} + } { + formal_parameter { + {type :$int_label} + {name i} + {location {DW_OP_reg0} SPECIAL_expr} + } + formal_parameter { + {type :$int_label} + {name j} + {location {DW_OP_reg1} SPECIAL_expr} + } + } + + subprogram { + {name bar} + {decl_file 1} + {low_pc bar addr} + {high_pc "bar + $bar_length" addr} + {GNU_all_call_sites 1} + } { + formal_parameter { + {type :$int_label} + {name i} + } + + GNU_call_site { + {low_pc "bar + $bar_call_foo" addr} + {abstract_origin :$foo_label} + } { + # Faked entry values are reference to variables 'global1' + # and 'global2' and faked locations are register 0 and + # register 1. + GNU_call_site_parameter { + {location {DW_OP_reg0} SPECIAL_expr} + {GNU_call_site_value { + addr global1 + deref_size 4 + } SPECIAL_expr} + } + GNU_call_site_parameter { + {location {DW_OP_reg1} SPECIAL_expr} + {GNU_call_site_value { + addr global2 + deref_size 4 + } SPECIAL_expr} + } + } + } + } + } +} + +if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} { + return -1 +} + +if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \ + "${binfile}" executable {}] != ""} { + return -1 +} + +clean_restart ${testfile} + +if ![runto_main] { + fail "Can't run to main" + return -1 +} + +gdb_breakpoint "foo" + +gdb_continue_to_breakpoint "foo" + +gdb_test_no_output "set print entry-values both" + +gdb_test_sequence "bt" "bt (1)" { + "\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=2, j=[-]?[0-9]+, j@entry=3\\)" + "\[\r\n\]#1 .* bar \\(i=, i@entry=\\)" + "\[\r\n\]#2 .* main \\(\\)" +} + +# Update global variables 'global1' and 'global2' and test that the +# entry values are updated too. + +gdb_test_no_output "set var global1=10" +gdb_test_no_output "set var global2=11" + +gdb_test_sequence "bt" "bt (2)" { + "\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=10, j=[-]?[0-9]+, j@entry=11\\)" + "\[\r\n\]#1 .* bar \\(i=, i@entry=\\)" + "\[\r\n\]#2 .* main \\(\\)" +} diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 1d3eb03..3977384 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -667,6 +667,14 @@ namespace eval Dwarf { _op .sleb128 [lindex $line 2] } + DW_OP_deref_size { + if {[llength $line] != 2} { + error "usage: DW_OP_deref_size SIZE" + } + + _op .byte [lindex $line 1] + } + default { if {[llength $line] > 1} { error "Unimplemented: operands in location for $opcode" -- cgit v1.1