Rename 'descr' field in regset structure to 'regmap'.
[deliverable/binutils-gdb.git] / gdb / s390-linux-tdep.c
index b75c86a5789e97808d223e402ed08dac699912cd..d1f474962c8a20312807a6cbec4d4b113934afde 100644 (file)
@@ -24,6 +24,7 @@
 #include "arch-utils.h"
 #include "frame.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "symtab.h"
 #include "target.h"
 #include "gdbcore.h"
 #include "reggroups.h"
 #include "regset.h"
 #include "value.h"
-#include "gdb_assert.h"
 #include "dis-asm.h"
 #include "solib-svr4.h"
 #include "prologue-value.h"
 #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
@@ -376,11 +380,11 @@ s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
    registers, even though we are otherwise a big-endian platform.  */
 
 static struct value *
-s390_value_from_register (struct type *type, int regnum,
-                         struct frame_info *frame)
+s390_value_from_register (struct gdbarch *gdbarch, struct type *type,
+                         int regnum, struct frame_id frame_id)
 {
-  struct value *value = default_value_from_register (type, regnum, frame);
-
+  struct value *value = default_value_from_register (gdbarch, type,
+                                                    regnum, frame_id);
   check_typedef (type);
 
   if (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM
@@ -605,7 +609,7 @@ s390_supply_regset (const struct regset *regset, struct regcache *regcache,
                    int regnum, const void *regs, size_t len)
 {
   const short *map;
-  for (map = regset->descr; map[0] >= 0; map += 2)
+  for (map = regset->regmap; map[0] >= 0; map += 2)
     if (regnum == -1 || regnum == map[1])
       regcache_raw_supply (regcache, map[1],
                           regs ? (const char *)regs + map[0] : NULL);
@@ -638,7 +642,7 @@ s390_collect_regset (const struct regset *regset,
                     int regnum, void *regs, size_t len)
 {
   const short *map;
-  for (map = regset->descr; map[0] >= 0; map += 2)
+  for (map = regset->regmap; map[0] >= 0; map += 2)
     if (regnum == -1 || regnum == map[1])
       regcache_raw_collect (regcache, map[1], (char *)regs + map[0]);
 }
@@ -905,6 +909,7 @@ enum
     op1_brxhg= 0xec,   op2_brxhg= 0x44,
     op_brxle = 0x85,
     op1_brxlg= 0xec,   op2_brxlg= 0x45,
+    op_svc   = 0x0a,
   };
 
 
@@ -2039,7 +2044,9 @@ static struct s390_unwind_cache *
 s390_frame_unwind_cache (struct frame_info *this_frame,
                         void **this_prologue_cache)
 {
+  volatile struct gdb_exception ex;
   struct s390_unwind_cache *info;
+
   if (*this_prologue_cache)
     return *this_prologue_cache;
 
@@ -2050,10 +2057,15 @@ s390_frame_unwind_cache (struct frame_info *this_frame,
   info->frame_base = -1;
   info->local_base = -1;
 
-  /* Try to use prologue analysis to fill the unwind cache.
-     If this fails, fall back to reading the stack backchain.  */
-  if (!s390_prologue_frame_unwind_cache (this_frame, info))
-    s390_backchain_frame_unwind_cache (this_frame, info);
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      /* Try to use prologue analysis to fill the unwind cache.
+        If this fails, fall back to reading the stack backchain.  */
+      if (!s390_prologue_frame_unwind_cache (this_frame, info))
+       s390_backchain_frame_unwind_cache (this_frame, info);
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
 
   return info;
 }
@@ -2321,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 */
@@ -2340,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.  */
 
@@ -3258,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);
@@ -3296,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)
@@ -3340,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);
This page took 0.027274 seconds and 4 git commands to generate.