diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/NEWS | 2 | ||||
-rw-r--r-- | gdb/arm-linux-tdep.c | 58 | ||||
-rw-r--r-- | gdb/data-directory/Makefile.in | 1 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/catch-syscall.exp | 9 |
6 files changed, 82 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 55e2337..8d939d9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2013-08-22 Samuel Bronson <naesten@gmail.com> + + ARM Linux support for `catch syscall'. + * syscalls/arm-linux.py: New file. + * syscalls/arm-linux.xml: Likewise. + * arm-linux-tdep.c (arm_linux_get_syscall_number): New function. + (arm_linux_init_abi): Register the new function and syscall xml file. + * data-directory/Makefile.in: Install the new syscall xml file. + * NEWS: Brag about this. + 2013-08-22 Pedro Alves <palves@redhat.com> PR gdb/15871 @@ -3,6 +3,8 @@ *** Changes since GDB 7.6 +* The "catch syscall" command now works on arm*-linux* targets. + * Python scripting ** Frame filters and frame decorators have been added. diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 1502bdc..6ac61cc 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -33,6 +33,7 @@ #include "tramp-frame.h" #include "breakpoint.h" #include "auxv.h" +#include "xml-syscall.h" #include "arm-tdep.h" #include "arm-linux-tdep.h" @@ -794,6 +795,59 @@ arm_linux_sigreturn_return_addr (struct frame_info *frame, return 0; } +/* At a ptrace syscall-stop, return the syscall number. This either + comes from the SWI instruction (OABI) or from r7 (EABI). + + When the function fails, it should return -1. */ + +static LONGEST +arm_linux_get_syscall_number (struct gdbarch *gdbarch, + ptid_t ptid) +{ + struct regcache *regs = get_thread_regcache (ptid); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + ULONGEST pc; + ULONGEST cpsr; + ULONGEST t_bit = arm_psr_thumb_bit (gdbarch); + int is_thumb; + ULONGEST svc_number = -1; + + regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &pc); + regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &cpsr); + is_thumb = (cpsr & t_bit) != 0; + + if (is_thumb) + { + regcache_cooked_read_unsigned (regs, 7, &svc_number); + } + else + { + enum bfd_endian byte_order_for_code = + gdbarch_byte_order_for_code (gdbarch); + + /* PC gets incremented before the syscall-stop, so read the + previous instruction. */ + unsigned long this_instr = + read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code); + + unsigned long svc_operand = (0x00ffffff & this_instr); + + if (svc_operand) + { + /* OABI */ + svc_number = svc_operand - 0x900000; + } + else + { + /* EABI */ + regcache_cooked_read_unsigned (regs, 7, &svc_number); + } + } + + return svc_number; +} + /* When FRAME is at a syscall instruction, return the PC of the next instruction to be executed. */ @@ -1294,6 +1348,10 @@ arm_linux_init_abi (struct gdbarch_info info, tdep->syscall_next_pc = arm_linux_syscall_next_pc; + /* `catch syscall' */ + set_xml_syscall_file_name ("syscalls/arm-linux.xml"); + set_gdbarch_get_syscall_number (gdbarch, arm_linux_get_syscall_number); + /* Syscall record. */ tdep->arm_swi_record = NULL; } diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index dec6207..3d05213 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -45,6 +45,7 @@ SYSCALLS_DIR = syscalls SYSCALLS_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(SYSCALLS_DIR) SYSCALLS_FILES = \ gdb-syscalls.dtd \ + arm-linux.xml \ ppc-linux.xml ppc64-linux.xml \ i386-linux.xml amd64-linux.xml \ sparc-linux.xml sparc64-linux.xml \ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 8d2605f..1c8b947 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-08-22 Samuel Bronson <naesten@gmail.com> + + ARM Linux support for `catch syscall'. + * gdb.base/catch-syscall.exp: Test this on ARM now. + (fill_all_syscalls_numbers): ARM has close/chroot on 6/61, too. + 2013-08-22 Tom Tromey <tromey@redhat.com> * lib/dwarf.exp (cu, tu): Handle addr_size of "default". Change diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp index 395fcd4..1066caf 100644 --- a/gdb/testsuite/gdb.base/catch-syscall.exp +++ b/gdb/testsuite/gdb.base/catch-syscall.exp @@ -34,7 +34,7 @@ if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"] && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"] && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"] - && ![istarget "mips*-linux*"] } { + && ![istarget "mips*-linux*"] && ![istarget "arm*-linux*"] } { continue } @@ -407,11 +407,12 @@ proc do_syscall_tests_without_xml {} { proc fill_all_syscalls_numbers {} { global all_syscalls_numbers - # For Linux on x86, PPC, PPC64, SPARC and SPARC64, the numbers for the syscalls - # "close" and "chroot" are the same. + # For Linux on x86, PPC, PPC64, SPARC, SPARC64 and ARM, + # the numbers for the syscalls "close" and "chroot" are the same. if { [istarget "i\[34567\]86-*-linux*"] || [istarget "powerpc-*-linux*"] || [istarget "powerpc64-*-linux*"] - || [istarget "sparc-*-linux*"] || [istarget "sparc64-*-linux*"] } { + || [istarget "sparc-*-linux*"] || [istarget "sparc64-*-linux*"] + || [istarget "arm*-linux*"] } { set all_syscalls_numbers { "6" "61" } } } |