testsuite: Fix for gcc-4.8: gdb.base/jit.exp gdb.base/jit-so.exp
[deliverable/binutils-gdb.git] / gdb / s390-linux-tdep.c
index 57e25b43177be564729ea0b1a2ee72b78fe3c8d4..fc5759250ef6ca6fd6ce482c0d9287c78c182404 100644 (file)
@@ -559,6 +559,100 @@ s390_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   return default_register_reggroup_p (gdbarch, regnum, group);
 }
 
+/* The "ax_pseudo_register_collect" gdbarch method.  */
+
+static int
+s390_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                                struct agent_expr *ax, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (regnum == tdep->pc_regnum)
+    {
+      ax_reg_mask (ax, S390_PSWA_REGNUM);
+    }
+  else if (regnum == tdep->cc_regnum)
+    {
+      ax_reg_mask (ax, S390_PSWM_REGNUM);
+    }
+  else if (regnum_is_gpr_full (tdep, regnum))
+    {
+      regnum -= tdep->gpr_full_regnum;
+      ax_reg_mask (ax, S390_R0_REGNUM + regnum);
+      ax_reg_mask (ax, S390_R0_UPPER_REGNUM + regnum);
+    }
+  else if (regnum_is_vxr_full (tdep, regnum))
+    {
+      regnum -= tdep->v0_full_regnum;
+      ax_reg_mask (ax, S390_F0_REGNUM + regnum);
+      ax_reg_mask (ax, S390_V0_LOWER_REGNUM + regnum);
+    }
+  else
+    {
+      internal_error (__FILE__, __LINE__, _("invalid regnum"));
+    }
+  return 0;
+}
+
+/* The "ax_pseudo_register_push_stack" gdbarch method.  */
+
+static int
+s390_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
+                                   struct agent_expr *ax, int regnum)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (regnum == tdep->pc_regnum)
+    {
+      ax_reg (ax, S390_PSWA_REGNUM);
+      if (register_size (gdbarch, S390_PSWA_REGNUM) == 4)
+       {
+         ax_zero_ext (ax, 31);
+       }
+    }
+  else if (regnum == tdep->cc_regnum)
+    {
+      ax_reg (ax, S390_PSWM_REGNUM);
+      if (register_size (gdbarch, S390_PSWA_REGNUM) == 4)
+       ax_const_l (ax, 12);
+      else
+       ax_const_l (ax, 44);
+      ax_simple (ax, aop_rsh_unsigned);
+      ax_zero_ext (ax, 2);
+    }
+  else if (regnum_is_gpr_full (tdep, regnum))
+    {
+      regnum -= tdep->gpr_full_regnum;
+      ax_reg (ax, S390_R0_REGNUM + regnum);
+      ax_reg (ax, S390_R0_UPPER_REGNUM + regnum);
+      ax_const_l (ax, 32);
+      ax_simple (ax, aop_lsh);
+      ax_simple (ax, aop_bit_or);
+    }
+  else if (regnum_is_vxr_full (tdep, regnum))
+    {
+      /* Too large to stuff on the stack.  */
+      return 1;
+    }
+  else
+    {
+      internal_error (__FILE__, __LINE__, _("invalid regnum"));
+    }
+  return 0;
+}
+
+/* The "gen_return_address" gdbarch method.  Since this is supposed to be
+   just a best-effort method, and we don't really have the means to run
+   the full unwinder here, just collect the link register.  */
+
+static void
+s390_gen_return_address (struct gdbarch *gdbarch,
+                        struct agent_expr *ax, struct axs_value *value,
+                        CORE_ADDR scope)
+{
+  value->type = register_type (gdbarch, S390_R14_REGNUM);
+  value->kind = axs_lvalue_register;
+  value->u.reg = S390_R14_REGNUM;
+}
+
 
 /* A helper for s390_software_single_step, decides if an instruction
    is a partial-execution instruction that needs to be executed until
@@ -1567,13 +1661,25 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
            break;
        }
 
+      /* BRC/BRCL -- branch relative on condition.  Ignore "branch
+        never", branch to following instruction, and "conditional
+        trap" (BRC +2).  Otherwise terminate search.  */
+      else if (is_ri (insn, op1_brc, op2_brc, &r1, &i2))
+       {
+         if (r1 != 0 && i2 != 1 && i2 != 2)
+           break;
+       }
+      else if (is_ril (insn, op1_brcl, op2_brcl, &r1, &i2))
+       {
+         if (r1 != 0 && i2 != 3)
+           break;
+       }
+
       /* Terminate search when hitting any other branch instruction.  */
       else if (is_rr (insn, op_basr, &r1, &r2)
               || is_rx (insn, op_bas, &r1, &d2, &x2, &b2)
               || is_rr (insn, op_bcr, &r1, &r2)
               || is_rx (insn, op_bc, &r1, &d2, &x2, &b2)
-              || is_ri (insn, op1_brc, op2_brc, &r1, &i2)
-              || is_ril (insn, op1_brcl, op2_brcl, &r1, &i2)
               || is_ril (insn, op1_brasl, op2_brasl, &r2, &i2))
        break;
 
@@ -2011,9 +2117,12 @@ s390_prologue_frame_unwind_cache (struct frame_info *this_frame,
      bother searching for it -- with modern compilers this would be mostly
      pointless anyway.  Trust that we'll either have valid DWARF-2 CFI data
      or else a valid backchain ...  */
-  func = get_frame_func (this_frame);
-  if (!func)
-    return 0;
+  if (!get_frame_func_if_available (this_frame, &info->func))
+    {
+      info->func = -1;
+      return 0;
+    }
+  func = info->func;
 
   /* Try to analyze the prologue.  */
   result = s390_analyze_prologue (gdbarch, func,
@@ -2167,7 +2276,6 @@ s390_prologue_frame_unwind_cache (struct frame_info *this_frame,
       info->local_base = prev_sp - size;
     }
 
-  info->func = func;
   return 1;
 }
 
@@ -2180,7 +2288,7 @@ s390_backchain_frame_unwind_cache (struct frame_info *this_frame,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR backchain;
   ULONGEST reg;
-  LONGEST sp;
+  LONGEST sp, tmp;
   int i;
 
   /* Set up ABI call-saved/call-clobbered registers.  */
@@ -2193,7 +2301,9 @@ s390_backchain_frame_unwind_cache (struct frame_info *this_frame,
 
   /* Get the backchain.  */
   reg = get_frame_register_unsigned (this_frame, S390_SP_REGNUM);
-  backchain = read_memory_unsigned_integer (reg, word_size, byte_order);
+  if (!safe_read_memory_integer (reg, word_size, byte_order, &tmp))
+    tmp = 0;
+  backchain = (CORE_ADDR) tmp;
 
   /* A zero backchain terminates the frame chain.  As additional
      sanity check, let's verify that the spill slot for SP in the
@@ -2265,7 +2375,11 @@ s390_frame_this_id (struct frame_info *this_frame,
     = s390_frame_unwind_cache (this_frame, this_prologue_cache);
 
   if (info->frame_base == -1)
-    return;
+    {
+      if (info->func != -1)
+       *this_id = frame_id_build_unavailable_stack (info->func);
+      return;
+    }
 
   *this_id = frame_id_build (info->frame_base, info->func);
 }
@@ -7898,6 +8012,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_tdesc_pseudo_register_type (gdbarch, s390_pseudo_register_type);
   set_tdesc_pseudo_register_reggroup_p (gdbarch,
                                        s390_pseudo_register_reggroup_p);
+  set_gdbarch_ax_pseudo_register_collect (gdbarch,
+                                         s390_ax_pseudo_register_collect);
+  set_gdbarch_ax_pseudo_register_push_stack
+      (gdbarch, s390_ax_pseudo_register_push_stack);
+  set_gdbarch_gen_return_address (gdbarch, s390_gen_return_address);
   tdesc_use_registers (gdbarch, tdesc, tdesc_data);
   set_gdbarch_register_name (gdbarch, s390_register_name);
 
This page took 0.025763 seconds and 4 git commands to generate.