Use address_from_register in dwarf2-frame.c:read_addr_from_reg
[deliverable/binutils-gdb.git] / gdb / s390-linux-tdep.c
index cd41de5acd9a7ffb8ea10683e12d68334d4a2ddc..9ab5c703f61a04dbc79e2614dc1c53157f1991a9 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+   Copyright (C) 2001-2014 Free Software Foundation, Inc.
 
    Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
    for IBM Deutschland Entwicklung GmbH, IBM Corporation.
@@ -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
@@ -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
@@ -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.  */
 
@@ -3026,6 +3068,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   int have_linux_v1 = 0;
   int have_linux_v2 = 0;
   int first_pseudo_reg, last_pseudo_reg;
+  static const char *const stap_register_prefixes[] = { "%", NULL };
+  static const char *const stap_register_indirection_prefixes[] = { "(",
+                                                                   NULL };
+  static const char *const stap_register_indirection_suffixes[] = { ")",
+                                                                   NULL };
 
   /* Default ABI and register size.  */
   switch (info.bfd_arch_info->mach)
@@ -3191,7 +3238,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* Otherwise create a new gdbarch for the specified machine type.  */
-  tdep = XCALLOC (1, struct gdbarch_tdep);
+  tdep = XCNEW (struct gdbarch_tdep);
   tdep->abi = tdep_abi;
   gdbarch = gdbarch_alloc (&info, tdep);
 
@@ -3253,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);
@@ -3291,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)
@@ -3335,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);
@@ -3358,9 +3412,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
 
   /* SystemTap functions.  */
-  set_gdbarch_stap_register_prefix (gdbarch, "%");
-  set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
-  set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
+  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
+  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
+                                         stap_register_indirection_prefixes);
+  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
+                                         stap_register_indirection_suffixes);
   set_gdbarch_stap_is_single_operand (gdbarch, s390_stap_is_single_operand);
 
   return gdbarch;
This page took 0.029295 seconds and 4 git commands to generate.