* emultempl/pe.em: Add --disable-large-address-aware option.
[deliverable/binutils-gdb.git] / gdb / s390-tdep.c
index d5bc1b1f4289ef2542969f5605b2d0d8ffda4ad0..72d55450225e89da4394079efac1fa33b36cb68c 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
 
    Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
    for IBM Deutschland Entwicklung GmbH, IBM Corporation.
 #include "linux-tdep.h"
 #include "s390-tdep.h"
 
+#include "stap-probe.h"
+#include "ax.h"
+#include "ax-gdb.h"
+#include "user-regs.h"
+#include "cli/cli-utils.h"
+#include <ctype.h>
+
 #include "features/s390-linux32.c"
 #include "features/s390-linux32v1.c"
 #include "features/s390-linux32v2.c"
@@ -56,7 +62,6 @@
 #include "features/s390x-linux64v1.c"
 #include "features/s390x-linux64v2.c"
 
-
 /* The tdep structure.  */
 
 struct gdbarch_tdep
@@ -170,7 +175,7 @@ static int s390_dwarf_regmap[] =
   S390_R8_REGNUM, S390_R9_REGNUM, S390_R10_REGNUM, S390_R11_REGNUM,
   S390_R12_REGNUM, S390_R13_REGNUM, S390_R14_REGNUM, S390_R15_REGNUM,
 
-  /* Linux-specific registers (not mapped).  */
+  /* GNU/Linux-specific registers (not mapped).  */
   -1, -1, -1,
 };
 
@@ -371,9 +376,11 @@ s390_value_from_register (struct type *type, int regnum,
                          struct frame_info *frame)
 {
   struct value *value = default_value_from_register (type, regnum, frame);
-  int len = TYPE_LENGTH (check_typedef (type));
 
-  if (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM && len < 8)
+  check_typedef (type);
+
+  if (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM
+      && TYPE_LENGTH (type) < 8)
     set_value_offset (value, 0);
 
   return value;
@@ -426,7 +433,7 @@ int s390_regmap_gregset[S390_NUM_REGS] =
   /* GPR Uppper Halves.  */
   -1, -1, -1, -1, -1, -1, -1, -1,
   -1, -1, -1, -1, -1, -1, -1, -1,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   0x88, -1, -1,
 };
 
@@ -454,7 +461,7 @@ int s390x_regmap_gregset[S390_NUM_REGS] =
   0x30, 0x38, 0x40, 0x48,
   0x50, 0x58, 0x60, 0x68,
   0x70, 0x78, 0x80, 0x88,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   0xd0, -1, -1,
 };
 
@@ -478,7 +485,7 @@ int s390_regmap_fpregset[S390_NUM_REGS] =
   /* GPR Uppper Halves.  */
   -1, -1, -1, -1, -1, -1, -1, -1,
   -1, -1, -1, -1, -1, -1, -1, -1,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   -1, -1, -1,
 };
 
@@ -502,7 +509,7 @@ int s390_regmap_upper[S390_NUM_REGS] =
   0x10, 0x14, 0x18, 0x1c,
   0x20, 0x24, 0x28, 0x2c,
   0x30, 0x34, 0x38, 0x3c,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   -1, -1, -1,
 };
 
@@ -524,7 +531,7 @@ int s390_regmap_last_break[S390_NUM_REGS] =
   /* GPR Uppper Halves.  */
   -1, -1, -1, -1, -1, -1, -1, -1,
   -1, -1, -1, -1, -1, -1, -1, -1,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   -1, 4, -1,
 };
 
@@ -546,7 +553,7 @@ int s390x_regmap_last_break[S390_NUM_REGS] =
   /* GPR Uppper Halves.  */
   -1, -1, -1, -1, -1, -1, -1, -1,
   -1, -1, -1, -1, -1, -1, -1, -1,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   -1, 0, -1,
 };
 
@@ -568,7 +575,7 @@ int s390_regmap_system_call[S390_NUM_REGS] =
   /* GPR Uppper Halves.  */
   -1, -1, -1, -1, -1, -1, -1, -1,
   -1, -1, -1, -1, -1, -1, -1, -1,
-  /* Linux-specific optional "registers".  */
+  /* GNU/Linux-specific optional "registers".  */
   -1, -1, 0,
 };
 
@@ -957,7 +964,7 @@ is_rre (bfd_byte *insn, int op, unsigned int *r1, unsigned int *r2)
 
 static int
 is_rs (bfd_byte *insn, int op,
-       unsigned int *r1, unsigned int *r3, unsigned int *d2, unsigned int *b2)
+       unsigned int *r1, unsigned int *r3, int *d2, unsigned int *b2)
 {
   if (insn[0] == op)
     {
@@ -974,7 +981,7 @@ is_rs (bfd_byte *insn, int op,
 
 static int
 is_rsy (bfd_byte *insn, int op1, int op2,
-        unsigned int *r1, unsigned int *r3, unsigned int *d2, unsigned int *b2)
+        unsigned int *r1, unsigned int *r3, int *d2, unsigned int *b2)
 {
   if (insn[0] == op1
       && insn[5] == op2)
@@ -1029,7 +1036,7 @@ is_rie (bfd_byte *insn, int op1, int op2,
 
 static int
 is_rx (bfd_byte *insn, int op,
-       unsigned int *r1, unsigned int *d2, unsigned int *x2, unsigned int *b2)
+       unsigned int *r1, int *d2, unsigned int *x2, unsigned int *b2)
 {
   if (insn[0] == op)
     {
@@ -1046,7 +1053,7 @@ is_rx (bfd_byte *insn, int op,
 
 static int
 is_rxy (bfd_byte *insn, int op1, int op2,
-        unsigned int *r1, unsigned int *d2, unsigned int *x2, unsigned int *b2)
+        unsigned int *r1, int *d2, unsigned int *x2, unsigned int *b2)
 {
   if (insn[0] == op1
       && insn[5] == op2)
@@ -1161,7 +1168,6 @@ s390_load (struct s390_prologue_data *data,
           
 {
   pv_t addr = s390_addr (data, d2, x2, b2);
-  pv_t offset;
 
   /* If it's a load from an in-line constant pool, then we can
      simulate that, under the assumption that the code isn't
@@ -1173,7 +1179,8 @@ s390_load (struct s390_prologue_data *data,
       struct target_section *secp;
       secp = target_section_by_addr (&current_target, addr.k);
       if (secp != NULL
-          && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+          && (bfd_get_section_flags (secp->the_bfd_section->owner,
+                                    secp->the_bfd_section)
               & SEC_READONLY))
         return pv_constant (read_memory_integer (addr.k, size,
                                                 data->byte_order));
@@ -1455,13 +1462,14 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
        break;
 
       else
-        /* An instruction we don't know how to simulate.  The only
-           safe thing to do would be to set every value we're tracking
-           to 'unknown'.  Instead, we'll be optimistic: we assume that
-          we *can* interpret every instruction that the compiler uses
-          to manipulate any of the data we're interested in here --
-          then we can just ignore anything else.  */
-        ;
+       {
+         /* An instruction we don't know how to simulate.  The only
+            safe thing to do would be to set every value we're tracking
+            to 'unknown'.  Instead, we'll be optimistic: we assume that
+            we *can* interpret every instruction that the compiler uses
+            to manipulate any of the data we're interested in here --
+            then we can just ignore anything else.  */
+       }
 
       /* Record the address after the last instruction that changed
          the FP, SP, or backlink.  Ignore instructions that changed
@@ -2109,7 +2117,7 @@ s390_stub_frame_sniffer (const struct frame_unwind *self,
      have trapped due to an invalid function pointer call.  We handle
      the non-existing current function like a PLT stub.  */
   addr_in_block = get_frame_address_in_block (this_frame);
-  if (in_plt_section (addr_in_block, NULL)
+  if (in_plt_section (addr_in_block)
       || s390_readinstruction (insn, get_frame_pc (this_frame)) < 0)
     return 1;
   return 0;
@@ -2485,8 +2493,7 @@ is_power_of_two (unsigned int n)
 static int
 s390_function_arg_pass_by_reference (struct type *type)
 {
-  unsigned length = TYPE_LENGTH (type);
-  if (length > 8)
+  if (TYPE_LENGTH (type) > 8)
     return 1;
 
   return (is_struct_like (type) && !is_power_of_two (TYPE_LENGTH (type)))
@@ -2499,8 +2506,7 @@ s390_function_arg_pass_by_reference (struct type *type)
 static int
 s390_function_arg_float (struct type *type)
 {
-  unsigned length = TYPE_LENGTH (type);
-  if (length > 8)
+  if (TYPE_LENGTH (type) > 8)
     return 0;
 
   return is_float_like (type);
@@ -2511,13 +2517,12 @@ s390_function_arg_float (struct type *type)
 static int
 s390_function_arg_integer (struct type *type)
 {
-  unsigned length = TYPE_LENGTH (type);
-  if (length > 8)
+  if (TYPE_LENGTH (type) > 8)
     return 0;
 
    return is_integer_like (type)
          || is_pointer_like (type)
-         || (is_struct_like (type) && is_power_of_two (length));
+         || (is_struct_like (type) && is_power_of_two (TYPE_LENGTH (type)));
 }
 
 /* Return ARG, a `SIMPLE_ARG', sign-extended or zero-extended to a full
@@ -2612,11 +2617,10 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
     {
       struct value *arg = args[i];
       struct type *type = check_typedef (value_type (arg));
-      unsigned length = TYPE_LENGTH (type);
 
       if (s390_function_arg_pass_by_reference (type))
         {
-          sp -= length;
+          sp -= TYPE_LENGTH (type);
           sp = align_down (sp, alignment_of (type));
           copy_addr[i] = sp;
         }
@@ -2749,9 +2753,15 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       }
   }
 
-  /* Store return address.  */
+  /* Store return PSWA.  In 31-bit mode, keep addressing mode bit.  */
+  if (word_size == 4)
+    {
+      ULONGEST pswa;
+      regcache_cooked_read_unsigned (regcache, S390_PSWA_REGNUM, &pswa);
+      bp_addr = (bp_addr & 0x7fffffff) | (pswa & 0x80000000);
+    }
   regcache_cooked_write_unsigned (regcache, S390_RETADDR_REGNUM, bp_addr);
-  
+
   /* Store updated stack pointer.  */
   regcache_cooked_write_unsigned (regcache, S390_SP_REGNUM, sp);
 
@@ -2789,8 +2799,7 @@ s390_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
 static enum return_value_convention
 s390_return_value_convention (struct gdbarch *gdbarch, struct type *type)
 {
-  int length = TYPE_LENGTH (type);
-  if (length > 8)
+  if (TYPE_LENGTH (type) > 8)
     return RETURN_VALUE_STRUCT_CONVENTION;
 
   switch (TYPE_CODE (type))
@@ -2807,7 +2816,7 @@ s390_return_value_convention (struct gdbarch *gdbarch, struct type *type)
 }
 
 static enum return_value_convention
-s390_return_value (struct gdbarch *gdbarch, struct type *func_type,
+s390_return_value (struct gdbarch *gdbarch, struct value *function,
                   struct type *type, struct regcache *regcache,
                   gdb_byte *out, const gdb_byte *in)
 {
@@ -2948,6 +2957,18 @@ s390_address_class_name_to_type_flags (struct gdbarch *gdbarch,
     return 0;
 }
 
+/* Implementation of `gdbarch_stap_is_single_operand', as defined in
+   gdbarch.h.  */
+
+static int
+s390_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
+{
+  return ((isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement
+                                                         or indirection.  */
+         || *s == '%' /* Register access.  */
+         || isdigit (*s)); /* Literal number.  */
+}
+
 /* Set up gdbarch struct.  */
 
 static struct gdbarch *
@@ -3068,7 +3089,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        valid_p &= tdesc_numbered_register (feature, tdesc_data,
                                            S390_A0_REGNUM + i, acrs[i]);
 
-      /* Optional Linux-specific "registers".  */
+      /* Optional GNU/Linux-specific "registers".  */
       feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.linux");
       if (feature)
        {
@@ -3278,6 +3299,12 @@ 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_is_single_operand (gdbarch, s390_stap_is_single_operand);
+
   return gdbarch;
 }
 
@@ -3290,7 +3317,7 @@ _initialize_s390_tdep (void)
   /* Hook us into the gdbarch mechanism.  */
   register_gdbarch_init (bfd_arch_s390, s390_gdbarch_init);
 
-  /* Initialize the Linux target descriptions.  */
+  /* Initialize the GNU/Linux target descriptions.  */
   initialize_tdesc_s390_linux32 ();
   initialize_tdesc_s390_linux32v1 ();
   initialize_tdesc_s390_linux32v2 ();
This page took 0.028626 seconds and 4 git commands to generate.