aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.arch
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2009-01-29 00:29:57 +0000
committerDoug Evans <dje@google.com>2009-01-29 00:29:57 +0000
commit35669430c88d5bcf7a346d47818c3eef0bf57d96 (patch)
tree12edeb51967522ebb031fe5b5a7506e8ed021217 /gdb/testsuite/gdb.arch
parent2211be76e9b95052a9c9403eaf032bd71d52c04c (diff)
downloadgdb-35669430c88d5bcf7a346d47818c3eef0bf57d96.zip
gdb-35669430c88d5bcf7a346d47818c3eef0bf57d96.tar.gz
gdb-35669430c88d5bcf7a346d47818c3eef0bf57d96.tar.bz2
* opcode/i386.h: Add multiple inclusion protection.
(EAX_REG_NUM,ECX_REG_NUM,EDX_REGNUM,EBX_REG_NUM,ESI_REG_NUM) (EDI_REG_NUM): New macros. (MODRM_MOD_FIELD,MODRM_REG_FIELD,MODRM_RM_FIELD): New macros. (SIB_SCALE_FIELD,SIB_INDEX_FIELD,SIB_BASE_FIELD): New macros. (REG_PREFIX_P): New macro. * amd64-tdep.h (amd64_displaced_step_copy_insn): Declare. (amd64_displaced_step_fixup): Declare. * amd64-tdep.c: #include opcode/i386.h, dis-asm.h. (amd64_arch_regmap): Move out of amd64_analyze_stack_align and make static global. (amd64_arch_regmap_len): New static global. (amd64_arch_reg_to_regnum): New function. (struct amd64_insn): New struct. (struct displaced_step_closure): New struct. (onebyte_has_modrm,twobyte_has_modrm): New static globals. (rex_prefix_p,skip_prefixes) (amd64_insn_length_fprintf,amd64_insn_length_init_dis) (amd64_insn_length,amd64_get_unused_input_int_reg) (amd64_get_insn_details,fixup_riprel,fixup_displaced_copy) (amd64_displaced_step_copy_insn) (amd64_absolute_jmp_p,amd64_absolute_call_p,amd64_ret_p) (amd64_call_p,amd64_breakpoint_p,amd64_syscall_p) (amd64_displaced_step_fixup): New functions. * amd64-linux-tdep.c: #include arch-utils.h. (amd64_linux_init_abi): Install displaced stepping support. * gdb.arch/amd64-disp-step.S: New file. * gdb.arch/amd64-disp-step.exp: New file. * gdb.arch/i386-disp-step.S: New file. * gdb.arch/i386-disp-step.exp: New file.
Diffstat (limited to 'gdb/testsuite/gdb.arch')
-rw-r--r--gdb/testsuite/gdb.arch/amd64-disp-step.S153
-rw-r--r--gdb/testsuite/gdb.arch/amd64-disp-step.exp219
-rw-r--r--gdb/testsuite/gdb.arch/i386-disp-step.S64
-rw-r--r--gdb/testsuite/gdb.arch/i386-disp-step.exp112
4 files changed, 548 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step.S b/gdb/testsuite/gdb.arch/amd64-disp-step.S
new file mode 100644
index 0000000..45eeb9b
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step.S
@@ -0,0 +1,153 @@
+/* Copyright 2009 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 file is part of the gdb testsuite.
+ It tests displaced stepping over various insns that require special
+ handling. */
+
+ .text
+
+ .global main
+main:
+ nop
+
+/* test call/ret */
+
+ .global test_call
+test_call:
+ call test_call_subr
+ nop
+ .global test_ret_end
+test_ret_end:
+ nop
+
+/* test abs-jmp/rep-ret */
+
+test_abs_jmp_setup:
+ mov $test_abs_jmp_return,%rdx
+ push %rdx
+ mov $test_abs_jmp_subr,%rdx
+ .global test_abs_jmp
+test_abs_jmp:
+ jmp *%rdx
+test_abs_jmp_return:
+ nop
+ .global test_rep_ret_end
+test_rep_ret_end:
+ nop
+
+/* test syscall */
+
+ .global test_syscall
+ mov $0x27,%eax /* getpid */
+test_syscall:
+ syscall
+ nop
+test_syscall_end:
+ nop
+
+/* test rip-relative
+ GDB picks a spare register to hold the rip-relative address.
+ Exercise all the possibilities (rax-rdi, sans rsp). */
+
+ .global test_rip_rax
+test_rip_rax:
+ add answer(%rip),%rax
+ .global test_rip_rax_end
+test_rip_rax_end:
+ nop
+
+ .global test_rip_rbx
+test_rip_rbx:
+ add answer(%rip),%rbx
+ .global test_rip_rbx_end
+test_rip_rbx_end:
+ nop
+
+ .global test_rip_rcx
+test_rip_rcx:
+ add answer(%rip),%rcx
+ .global test_rip_rcx_end
+test_rip_rcx_end:
+ nop
+
+ .global test_rip_rdx
+test_rip_rdx:
+ add answer(%rip),%rdx
+ .global test_rip_rdx_end
+test_rip_rdx_end:
+ nop
+
+ .global test_rip_rbp
+test_rip_rbp:
+ add answer(%rip),%rbp
+ .global test_rip_rbp_end
+test_rip_rbp_end:
+ nop
+
+ .global test_rip_rsi
+test_rip_rsi:
+ add answer(%rip),%rsi
+ .global test_rip_rsi_end
+test_rip_rsi_end:
+ nop
+
+ .global test_rip_rdi
+test_rip_rdi:
+ add answer(%rip),%rdi
+ .global test_rip_rdi_end
+test_rip_rdi_end:
+ nop
+
+ /* skip over test data */
+ jmp done
+
+/* test rip-relative data */
+
+answer: .8byte 42
+
+/* all done */
+
+done:
+ mov $0,%rdi
+ call exit
+ hlt
+
+/***********************************************/
+
+/* subroutine to help test call/ret */
+
+test_call_subr:
+ nop
+ .global test_call_end
+test_call_end:
+ nop
+
+ .global test_ret
+test_ret:
+ ret
+
+/* subroutine to help test abs-jmp/rep-ret */
+
+test_abs_jmp_subr:
+ nop
+ .global test_abs_jmp_end
+test_abs_jmp_end:
+ nop
+
+ .global test_rep_ret
+test_rep_ret:
+ repz
+ ret
diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step.exp b/gdb/testsuite/gdb.arch/amd64-disp-step.exp
new file mode 100644
index 0000000..26ebe59
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step.exp
@@ -0,0 +1,219 @@
+# Copyright 2009 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 file is part of the gdb testsuite.
+
+# Test amd64 displaced stepping.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "x86_64-*-linux*"] then {
+ verbose "Skipping x86_64 displaced stepping tests."
+ return
+}
+
+set newline "\[\r\n\]*"
+
+set testfile "amd64-disp-step"
+set srcfile ${testfile}.S
+set binfile ${objdir}/${subdir}/${testfile}
+
+set additional_flags "-Wa,-g"
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } {
+ untested amd64-disp-step.exp
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set displaced-stepping on" ""
+gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+##########################################
+
+# Test call/ret.
+
+gdb_test "break test_call" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_call"
+gdb_test "break test_call_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_call_end"
+
+gdb_test "break test_ret" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_ret"
+gdb_test "break test_ret_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_ret_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_call ().*" \
+ "continue to test_call"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_call_end ().*" \
+ "continue to test_call_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_ret ().*" \
+ "continue to test_ret"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_ret_end ().*" \
+ "continue to test_ret_end"
+
+##########################################
+
+# Test abs-jmp/rep-ret.
+
+gdb_test "break test_abs_jmp" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_abs_jmp"
+gdb_test "break test_abs_jmp_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_abs_jmp_end"
+
+gdb_test "break test_rep_ret" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_rep_ret"
+gdb_test "break test_rep_ret_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_rep_ret_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_abs_jmp ().*" \
+ "continue to test_abs_jmp"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_abs_jmp_end ().*" \
+ "continue to test_abs_jmp_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_rep_ret ().*" \
+ "continue to test_rep_ret"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_rep_ret_end ().*" \
+ "continue to test_rep_ret_end"
+
+##########################################
+
+# Test syscall.
+
+gdb_test "break test_syscall" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_syscall"
+gdb_test "break test_syscall_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_syscall_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_syscall ().*" \
+ "continue to test_syscall"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_syscall_end ().*" \
+ "continue to test_syscall_end"
+
+##########################################
+
+# Test rip-relative.
+# GDB picks a spare register to hold the rip-relative address.
+# Exercise all the possibilities (rax-rdi, sans rsp).
+
+# The order must much the order in srcfile.
+set rip_regs { "rax" "rbx" "rcx" "rdx" "rbp" "rsi" "rdi" }
+
+# Assign val to all specified regs.
+
+proc set_regs { regs val } {
+ global gdb_prompt
+
+ foreach reg ${regs} {
+ # Use send_gdb/gdb_expect so that these aren't logged as pass/fail.
+ send_gdb "set \$${reg} = ${val}\n"
+ gdb_expect 10 {
+ -re "$gdb_prompt $" {
+ verbose "Setting ${reg} to ${val}." 2
+ }
+ timeout {
+ warning "Couldn't set ${reg} to ${val}."
+ }
+ }
+ }
+}
+
+# Verify all REGS equal VAL, except REG which equals REG_VAL.
+
+proc verify_regs { test_name regs val except_reg except_reg_val } {
+ global newline
+
+ foreach reg ${regs} {
+ set expected ${val}
+ if { "${reg}" == "${except_reg}" } {
+ set expected ${except_reg_val}
+ }
+ # The cast to (int) is because RBP is printed as a pointer.
+ gdb_test "p (int) \$${reg}" " = ${expected}${newline}" "${test_name} ${reg} expected value"
+ }
+}
+
+proc rip_test { reg } {
+ global srcfile rip_regs
+
+ set test_start_label "test_rip_${reg}"
+ set test_end_label "test_rip_${reg}_end"
+
+ gdb_test "break ${test_start_label}" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break ${test_start_label}"
+ gdb_test "break ${test_end_label}" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break ${test_end_label}"
+
+ gdb_test "continue" \
+ "Continuing.*Breakpoint.*, ${test_start_label} ().*" \
+ "continue to ${test_start_label}"
+
+ set_regs ${rip_regs} 0
+
+ gdb_test "continue" \
+ "Continuing.*Breakpoint.*, ${test_end_label} ().*" \
+ "continue to ${test_end_label}"
+
+ verify_regs "test rip w/${reg}" ${rip_regs} 0 ${reg} 42
+}
+
+foreach reg ${rip_regs} {
+ rip_test $reg
+}
+
+##########################################
+
+# Done, run program to exit.
+
+gdb_continue_to_end "amd64-disp-step"
diff --git a/gdb/testsuite/gdb.arch/i386-disp-step.S b/gdb/testsuite/gdb.arch/i386-disp-step.S
new file mode 100644
index 0000000..a56ff1c
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-disp-step.S
@@ -0,0 +1,64 @@
+/* Copyright 2009 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 file is part of the gdb testsuite.
+ It tests displaced stepping over various insns that require special
+ handling. */
+
+ .text
+
+ .global main
+main:
+ nop
+
+/* test call/ret */
+
+ .global test_call
+test_call:
+ call test_call_subr
+ nop
+ .global test_ret_end
+test_ret_end:
+ nop
+
+/* test syscall */
+
+ .global test_syscall
+ mov $0x14,%eax /* getpid */
+test_syscall:
+ int $0x80
+ nop
+test_syscall_end:
+ nop
+
+/* all done */
+
+ pushl $0
+ call exit
+ hlt
+
+/***********************************************/
+
+/* subroutine to help test call/ret */
+
+test_call_subr:
+ nop
+ .global test_call_end
+test_call_end:
+ nop
+
+ .global test_ret
+test_ret:
+ ret
diff --git a/gdb/testsuite/gdb.arch/i386-disp-step.exp b/gdb/testsuite/gdb.arch/i386-disp-step.exp
new file mode 100644
index 0000000..06c5fb2
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-disp-step.exp
@@ -0,0 +1,112 @@
+# Copyright 2009 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 file is part of the gdb testsuite.
+
+# Test i386 displaced stepping.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "i?86-*-linux*"] then {
+ verbose "Skipping x86 displaced stepping tests."
+ return
+}
+
+set testfile "i386-disp-step"
+set srcfile ${testfile}.S
+set binfile ${objdir}/${subdir}/${testfile}
+
+set additional_flags "-Wa,-g"
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } {
+ untested i386-disp-step.exp
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set displaced-stepping on" ""
+gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+##########################################
+
+# Test call/ret.
+
+gdb_test "break test_call" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_call"
+gdb_test "break test_call_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_call_end"
+
+gdb_test "break test_ret" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_ret"
+gdb_test "break test_ret_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_ret_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_call ().*" \
+ "continue to test_call"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_call_end ().*" \
+ "continue to test_call_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_ret ().*" \
+ "continue to test_ret"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_ret_end ().*" \
+ "continue to test_ret_end"
+
+##########################################
+
+# Test syscall.
+
+gdb_test "break test_syscall" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_syscall"
+gdb_test "break test_syscall_end" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break test_syscall_end"
+
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_syscall ().*" \
+ "continue to test_syscall"
+gdb_test "continue" \
+ "Continuing.*Breakpoint.*, test_syscall_end ().*" \
+ "continue to test_syscall_end"
+
+##########################################
+
+# Done, run program to exit.
+
+gdb_continue_to_end "i386-disp-step"