aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/NEWS2
-rw-r--r--gdb/arm-linux-tdep.c58
-rw-r--r--gdb/data-directory/Makefile.in1
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.base/catch-syscall.exp9
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
diff --git a/gdb/NEWS b/gdb/NEWS
index 6ee82f7..f246ee1 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -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" }
}
}