aboutsummaryrefslogtreecommitdiff
path: root/gdb/s390-linux-tdep.c
diff options
context:
space:
mode:
authorAndreas Arnez <arnez@vnet.linux.ibm.com>2014-01-22 18:54:43 +0100
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2014-01-22 18:54:43 +0100
commit237b092b9f52d90716e537d624e9a8c60a4cd4b5 (patch)
treebfe2e78b5ca16b2d49af5b82ac99e789e4890b60 /gdb/s390-linux-tdep.c
parentd674a7090f3ae01552e9df5044acc2df1127a7c0 (diff)
downloadgdb-237b092b9f52d90716e537d624e9a8c60a4cd4b5.zip
gdb-237b092b9f52d90716e537d624e9a8c60a4cd4b5.tar.gz
gdb-237b092b9f52d90716e537d624e9a8c60a4cd4b5.tar.bz2
gdb/ChangeLog:
* syscalls/s390x-linux.xml: New file. * syscalls/s390-linux.xml: New file. * s390-linux-tdep.c (XML_SYSCALL_FILENAME_S390): New macro. (XML_SYSCALL_FILENAME_S390X): Likewise. (op_svc): New enum value for SVC opcode. (s390_sigtramp_frame_sniffer): Replace literal by 'op_svc'. (s390_linux_get_syscall_number): New function. (s390_gdbarch_init): Register '*get_syscall_number' and the syscall xml file name. * data-directory/Makefile.in (SYSCALLS_FILES): Add "s390-linux.xml" and "s390x-linux.xml". * NEWS: Announce new feature. gdb/testsuite/ChangeLog: * gdb.base/catch-syscall.exp: Activate test on s390*-linux.
Diffstat (limited to 'gdb/s390-linux-tdep.c')
-rw-r--r--gdb/s390-linux-tdep.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 8b71e78..3084b32 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -45,6 +45,7 @@
#include "linux-tdep.h"
#include "s390-linux-tdep.h"
#include "auxv.h"
+#include "xml-syscall.h"
#include "stap-probe.h"
#include "ax.h"
@@ -66,6 +67,9 @@
#include "features/s390x-linux64v2.c"
#include "features/s390x-te-linux64.c"
+#define XML_SYSCALL_FILENAME_S390 "syscalls/s390-linux.xml"
+#define XML_SYSCALL_FILENAME_S390X "syscalls/s390x-linux.xml"
+
/* The tdep structure. */
struct gdbarch_tdep
@@ -905,6 +909,7 @@ enum
op1_brxhg= 0xec, op2_brxhg= 0x44,
op_brxle = 0x85,
op1_brxlg= 0xec, op2_brxlg= 0x45,
+ op_svc = 0x0a,
};
@@ -2328,7 +2333,7 @@ s390_sigtramp_frame_sniffer (const struct frame_unwind *self,
if (target_read_memory (pc, sigreturn, 2))
return 0;
- if (sigreturn[0] != 0x0a /* svc */)
+ if (sigreturn[0] != op_svc)
return 0;
if (sigreturn[1] != 119 /* sigreturn */
@@ -2347,6 +2352,36 @@ static const struct frame_unwind s390_sigtramp_frame_unwind = {
s390_sigtramp_frame_sniffer
};
+/* Retrieve the syscall number at a ptrace syscall-stop. Return -1
+ upon error. */
+
+static LONGEST
+s390_linux_get_syscall_number (struct gdbarch *gdbarch,
+ ptid_t ptid)
+{
+ struct regcache *regs = get_thread_regcache (ptid);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ ULONGEST pc;
+ ULONGEST svc_number = -1;
+ unsigned opcode;
+
+ /* Assume that the PC points after the 2-byte SVC instruction. We
+ don't currently support SVC via EXECUTE. */
+ regcache_cooked_read_unsigned (regs, tdep->pc_regnum, &pc);
+ pc -= 2;
+ opcode = read_memory_unsigned_integer ((CORE_ADDR) pc, 1, byte_order);
+ if (opcode != op_svc)
+ return -1;
+
+ svc_number = read_memory_unsigned_integer ((CORE_ADDR) pc + 1, 1,
+ byte_order);
+ if (svc_number == 0)
+ regcache_cooked_read_unsigned (regs, S390_R1_REGNUM, &svc_number);
+
+ return svc_number;
+}
+
/* Frame base handling. */
@@ -3265,6 +3300,9 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_frame_align (gdbarch, s390_frame_align);
set_gdbarch_return_value (gdbarch, s390_return_value);
+ /* Syscall handling. */
+ set_gdbarch_get_syscall_number (gdbarch, s390_linux_get_syscall_number);
+
/* Frame handling. */
dwarf2_frame_set_init_reg (gdbarch, s390_dwarf2_frame_init_reg);
dwarf2_frame_set_adjust_regnum (gdbarch, s390_adjust_frame_regnum);
@@ -3303,6 +3341,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_xml_syscall_file_name (XML_SYSCALL_FILENAME_S390);
+
if (have_upper)
{
if (have_linux_v2)
@@ -3347,6 +3387,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_address_class_name_to_type_flags (gdbarch,
s390_address_class_name_to_type_flags);
+ set_xml_syscall_file_name (XML_SYSCALL_FILENAME_S390);
+
if (have_linux_v2)
set_gdbarch_core_regset_sections (gdbarch,
s390x_linux64v2_regset_sections);