diff options
author | Andreas Arnez <arnez@vnet.linux.ibm.com> | 2014-01-22 18:54:43 +0100 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2014-01-22 18:54:43 +0100 |
commit | 237b092b9f52d90716e537d624e9a8c60a4cd4b5 (patch) | |
tree | bfe2e78b5ca16b2d49af5b82ac99e789e4890b60 /gdb/s390-linux-tdep.c | |
parent | d674a7090f3ae01552e9df5044acc2df1127a7c0 (diff) | |
download | gdb-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.c | 44 |
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); |