Update mn10300 dwarf register map
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index ce44ffd7226baa06d014bf89bfb1d3e31f642aa6..57f18cbab8d43505c8f3078ec5bbc1d284f55ed2 100644 (file)
@@ -530,6 +530,22 @@ i386_absolute_jmp_p (const gdb_byte *insn)
   return 0;
 }
 
+/* Return non-zero if INSN is a jump, zero otherwise.  */
+
+static int
+i386_jmp_p (const gdb_byte *insn)
+{
+  /* jump short, relative.  */
+  if (insn[0] == 0xeb)
+    return 1;
+
+  /* jump near, relative.  */
+  if (insn[0] == 0xe9)
+    return 1;
+
+  return i386_absolute_jmp_p (insn);
+}
+
 static int
 i386_absolute_call_p (const gdb_byte *insn)
 {
@@ -601,6 +617,45 @@ i386_syscall_p (const gdb_byte *insn, int *lengthp)
   return 0;
 }
 
+/* The gdbarch insn_is_call method.  */
+
+static int
+i386_insn_is_call (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  gdb_byte buf[I386_MAX_INSN_LEN], *insn;
+
+  read_code (addr, buf, I386_MAX_INSN_LEN);
+  insn = i386_skip_prefixes (buf, I386_MAX_INSN_LEN);
+
+  return i386_call_p (insn);
+}
+
+/* The gdbarch insn_is_ret method.  */
+
+static int
+i386_insn_is_ret (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  gdb_byte buf[I386_MAX_INSN_LEN], *insn;
+
+  read_code (addr, buf, I386_MAX_INSN_LEN);
+  insn = i386_skip_prefixes (buf, I386_MAX_INSN_LEN);
+
+  return i386_ret_p (insn);
+}
+
+/* The gdbarch insn_is_jump method.  */
+
+static int
+i386_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  gdb_byte buf[I386_MAX_INSN_LEN], *insn;
+
+  read_code (addr, buf, I386_MAX_INSN_LEN);
+  insn = i386_skip_prefixes (buf, I386_MAX_INSN_LEN);
+
+  return i386_jmp_p (insn);
+}
+
 /* Some kernels may run one past a syscall insn, so we have to cope.
    Otherwise this is just simple_displaced_step_copy_insn.  */
 
@@ -3605,311 +3660,338 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
          || (*s == '%' && isalpha (s[1]))); /* Register access.  */
 }
 
-/* Implementation of `gdbarch_stap_parse_special_token', as defined in
-   gdbarch.h.  */
+/* Helper function for i386_stap_parse_special_token.
 
-int
-i386_stap_parse_special_token (struct gdbarch *gdbarch,
-                              struct stap_parse_info *p)
+   This function parses operands of the form `-8+3+1(%rbp)', which
+   must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
+
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
+
+static int
+i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
+                                      struct stap_parse_info *p)
 {
-  /* In order to parse special tokens, we use a state-machine that go
-     through every known token and try to get a match.  */
-  enum
+  const char *s = p->arg;
+
+  if (isdigit (*s) || *s == '-' || *s == '+')
     {
-      TRIPLET,
-      THREE_ARG_DISPLACEMENT,
-      DONE
-    } current_state;
+      int got_minus[3];
+      int i;
+      long displacements[3];
+      const char *start;
+      char *regname;
+      int len;
+      struct stoken str;
+      char *endp;
+
+      got_minus[0] = 0;
+      if (*s == '+')
+       ++s;
+      else if (*s == '-')
+       {
+         ++s;
+         got_minus[0] = 1;
+       }
 
-  current_state = TRIPLET;
+      displacements[0] = strtol (s, &endp, 10);
+      s = endp;
 
-  /* The special tokens to be parsed here are:
+      if (*s != '+' && *s != '-')
+       {
+         /* We are not dealing with a triplet.  */
+         return 0;
+       }
 
-     - `register base + (register index * size) + offset', as represented
-     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+      got_minus[1] = 0;
+      if (*s == '+')
+       ++s;
+      else
+       {
+         ++s;
+         got_minus[1] = 1;
+       }
 
-     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
-     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+      displacements[1] = strtol (s, &endp, 10);
+      s = endp;
 
-  while (current_state != DONE)
-    {
-      const char *s = p->arg;
+      if (*s != '+' && *s != '-')
+       {
+         /* We are not dealing with a triplet.  */
+         return 0;
+       }
 
-      switch (current_state)
+      got_minus[2] = 0;
+      if (*s == '+')
+       ++s;
+      else
        {
-       case TRIPLET:
-           {
-             if (isdigit (*s) || *s == '-' || *s == '+')
-               {
-                 int got_minus[3];
-                 int i;
-                 long displacements[3];
-                 const char *start;
-                 char *regname;
-                 int len;
-                 struct stoken str;
-                 char *endp;
-
-                 got_minus[0] = 0;
-                 if (*s == '+')
-                   ++s;
-                 else if (*s == '-')
-                   {
-                     ++s;
-                     got_minus[0] = 1;
-                   }
+         ++s;
+         got_minus[2] = 1;
+       }
 
-                 displacements[0] = strtol (s, &endp, 10);
-                 s = endp;
+      displacements[2] = strtol (s, &endp, 10);
+      s = endp;
 
-                 if (*s != '+' && *s != '-')
-                   {
-                     /* We are not dealing with a triplet.  */
-                     break;
-                   }
+      if (*s != '(' || s[1] != '%')
+       return 0;
 
-                 got_minus[1] = 0;
-                 if (*s == '+')
-                   ++s;
-                 else
-                   {
-                     ++s;
-                     got_minus[1] = 1;
-                   }
+      s += 2;
+      start = s;
 
-                 displacements[1] = strtol (s, &endp, 10);
-                 s = endp;
+      while (isalnum (*s))
+       ++s;
 
-                 if (*s != '+' && *s != '-')
-                   {
-                     /* We are not dealing with a triplet.  */
-                     break;
-                   }
+      if (*s++ != ')')
+       return 0;
 
-                 got_minus[2] = 0;
-                 if (*s == '+')
-                   ++s;
-                 else
-                   {
-                     ++s;
-                     got_minus[2] = 1;
-                   }
+      len = s - start;
+      regname = alloca (len + 1);
 
-                 displacements[2] = strtol (s, &endp, 10);
-                 s = endp;
+      strncpy (regname, start, len);
+      regname[len] = '\0';
 
-                 if (*s != '(' || s[1] != '%')
-                   break;
+      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
+       error (_("Invalid register name `%s' on expression `%s'."),
+              regname, p->saved_arg);
 
-                 s += 2;
-                 start = s;
+      for (i = 0; i < 3; i++)
+       {
+         write_exp_elt_opcode (OP_LONG);
+         write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+         write_exp_elt_longcst (displacements[i]);
+         write_exp_elt_opcode (OP_LONG);
+         if (got_minus[i])
+           write_exp_elt_opcode (UNOP_NEG);
+       }
 
-                 while (isalnum (*s))
-                   ++s;
+      write_exp_elt_opcode (OP_REGISTER);
+      str.ptr = regname;
+      str.length = len;
+      write_exp_string (str);
+      write_exp_elt_opcode (OP_REGISTER);
 
-                 if (*s++ != ')')
-                   break;
+      write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
+      write_exp_elt_opcode (UNOP_CAST);
 
-                 len = s - start;
-                 regname = alloca (len + 1);
+      write_exp_elt_opcode (BINOP_ADD);
+      write_exp_elt_opcode (BINOP_ADD);
+      write_exp_elt_opcode (BINOP_ADD);
 
-                 strncpy (regname, start, len);
-                 regname[len] = '\0';
+      write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_type (lookup_pointer_type (p->arg_type));
+      write_exp_elt_opcode (UNOP_CAST);
 
-                 if (user_reg_map_name_to_regnum (gdbarch,
-                                                  regname, len) == -1)
-                   error (_("Invalid register name `%s' "
-                            "on expression `%s'."),
-                          regname, p->saved_arg);
+      write_exp_elt_opcode (UNOP_IND);
 
-                 for (i = 0; i < 3; i++)
-                   {
-                     write_exp_elt_opcode (OP_LONG);
-                     write_exp_elt_type
-                       (builtin_type (gdbarch)->builtin_long);
-                     write_exp_elt_longcst (displacements[i]);
-                     write_exp_elt_opcode (OP_LONG);
-                     if (got_minus[i])
-                       write_exp_elt_opcode (UNOP_NEG);
-                   }
+      p->arg = s;
 
-                 write_exp_elt_opcode (OP_REGISTER);
-                 str.ptr = regname;
-                 str.length = len;
-                 write_exp_string (str);
-                 write_exp_elt_opcode (OP_REGISTER);
+      return 1;
+    }
 
-                 write_exp_elt_opcode (UNOP_CAST);
-                 write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
-                 write_exp_elt_opcode (UNOP_CAST);
+  return 0;
+}
 
-                 write_exp_elt_opcode (BINOP_ADD);
-                 write_exp_elt_opcode (BINOP_ADD);
-                 write_exp_elt_opcode (BINOP_ADD);
+/* Helper function for i386_stap_parse_special_token.
 
-                 write_exp_elt_opcode (UNOP_CAST);
-                 write_exp_elt_type (lookup_pointer_type (p->arg_type));
-                 write_exp_elt_opcode (UNOP_CAST);
+   This function parses operands of the form `register base +
+   (register index * size) + offset', as represented in
+   `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
 
-                 write_exp_elt_opcode (UNOP_IND);
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
 
-                 p->arg = s;
+static int
+i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
+                                             struct stap_parse_info *p)
+{
+  const char *s = p->arg;
 
-                 return 1;
-               }
-             break;
-           }
-       case THREE_ARG_DISPLACEMENT:
-           {
-             if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
-               {
-                 int offset_minus = 0;
-                 long offset = 0;
-                 int size_minus = 0;
-                 long size = 0;
-                 const char *start;
-                 char *base;
-                 int len_base;
-                 char *index;
-                 int len_index;
-                 struct stoken base_token, index_token;
-
-                 if (*s == '+')
-                   ++s;
-                 else if (*s == '-')
-                   {
-                     ++s;
-                     offset_minus = 1;
-                   }
+  if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
+    {
+      int offset_minus = 0;
+      long offset = 0;
+      int size_minus = 0;
+      long size = 0;
+      const char *start;
+      char *base;
+      int len_base;
+      char *index;
+      int len_index;
+      struct stoken base_token, index_token;
+
+      if (*s == '+')
+       ++s;
+      else if (*s == '-')
+       {
+         ++s;
+         offset_minus = 1;
+       }
 
-                 if (offset_minus && !isdigit (*s))
-                   break;
+      if (offset_minus && !isdigit (*s))
+       return 0;
 
-                 if (isdigit (*s))
-                   {
-                     char *endp;
+      if (isdigit (*s))
+       {
+         char *endp;
 
-                     offset = strtol (s, &endp, 10);
-                     s = endp;
-                   }
+         offset = strtol (s, &endp, 10);
+         s = endp;
+       }
 
-                 if (*s != '(' || s[1] != '%')
-                   break;
+      if (*s != '(' || s[1] != '%')
+       return 0;
 
-                 s += 2;
-                 start = s;
+      s += 2;
+      start = s;
 
-                 while (isalnum (*s))
-                   ++s;
+      while (isalnum (*s))
+       ++s;
 
-                 if (*s != ',' || s[1] != '%')
-                   break;
+      if (*s != ',' || s[1] != '%')
+       return 0;
 
-                 len_base = s - start;
-                 base = alloca (len_base + 1);
-                 strncpy (base, start, len_base);
-                 base[len_base] = '\0';
+      len_base = s - start;
+      base = alloca (len_base + 1);
+      strncpy (base, start, len_base);
+      base[len_base] = '\0';
 
-                 if (user_reg_map_name_to_regnum (gdbarch,
-                                                  base, len_base) == -1)
-                   error (_("Invalid register name `%s' "
-                            "on expression `%s'."),
-                          base, p->saved_arg);
+      if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
+       error (_("Invalid register name `%s' on expression `%s'."),
+              base, p->saved_arg);
 
-                 s += 2;
-                 start = s;
+      s += 2;
+      start = s;
 
-                 while (isalnum (*s))
-                   ++s;
+      while (isalnum (*s))
+       ++s;
 
-                 len_index = s - start;
-                 index = alloca (len_index + 1);
-                 strncpy (index, start, len_index);
-                 index[len_index] = '\0';
+      len_index = s - start;
+      index = alloca (len_index + 1);
+      strncpy (index, start, len_index);
+      index[len_index] = '\0';
 
-                 if (user_reg_map_name_to_regnum (gdbarch,
-                                                  index, len_index) == -1)
-                   error (_("Invalid register name `%s' "
-                            "on expression `%s'."),
-                          index, p->saved_arg);
+      if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
+       error (_("Invalid register name `%s' on expression `%s'."),
+              index, p->saved_arg);
 
-                 if (*s != ',' && *s != ')')
-                   break;
+      if (*s != ',' && *s != ')')
+       return 0;
 
-                 if (*s == ',')
-                   {
-                     char *endp;
+      if (*s == ',')
+       {
+         char *endp;
 
-                     ++s;
-                     if (*s == '+')
-                       ++s;
-                     else if (*s == '-')
-                       {
-                         ++s;
-                         size_minus = 1;
-                       }
+         ++s;
+         if (*s == '+')
+           ++s;
+         else if (*s == '-')
+           {
+             ++s;
+             size_minus = 1;
+           }
 
-                     size = strtol (s, &endp, 10);
-                     s = endp;
+         size = strtol (s, &endp, 10);
+         s = endp;
 
-                     if (*s != ')')
-                       break;
-                   }
+         if (*s != ')')
+           return 0;
+       }
 
-                 ++s;
+      ++s;
 
-                 if (offset)
-                   {
-                     write_exp_elt_opcode (OP_LONG);
-                     write_exp_elt_type
-                       (builtin_type (gdbarch)->builtin_long);
-                     write_exp_elt_longcst (offset);
-                     write_exp_elt_opcode (OP_LONG);
-                     if (offset_minus)
-                       write_exp_elt_opcode (UNOP_NEG);
-                   }
+      if (offset)
+       {
+         write_exp_elt_opcode (OP_LONG);
+         write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+         write_exp_elt_longcst (offset);
+         write_exp_elt_opcode (OP_LONG);
+         if (offset_minus)
+           write_exp_elt_opcode (UNOP_NEG);
+       }
 
-                 write_exp_elt_opcode (OP_REGISTER);
-                 base_token.ptr = base;
-                 base_token.length = len_base;
-                 write_exp_string (base_token);
-                 write_exp_elt_opcode (OP_REGISTER);
+      write_exp_elt_opcode (OP_REGISTER);
+      base_token.ptr = base;
+      base_token.length = len_base;
+      write_exp_string (base_token);
+      write_exp_elt_opcode (OP_REGISTER);
 
-                 if (offset)
-                   write_exp_elt_opcode (BINOP_ADD);
+      if (offset)
+       write_exp_elt_opcode (BINOP_ADD);
 
-                 write_exp_elt_opcode (OP_REGISTER);
-                 index_token.ptr = index;
-                 index_token.length = len_index;
-                 write_exp_string (index_token);
-                 write_exp_elt_opcode (OP_REGISTER);
+      write_exp_elt_opcode (OP_REGISTER);
+      index_token.ptr = index;
+      index_token.length = len_index;
+      write_exp_string (index_token);
+      write_exp_elt_opcode (OP_REGISTER);
 
-                 if (size)
-                   {
-                     write_exp_elt_opcode (OP_LONG);
-                     write_exp_elt_type
-                       (builtin_type (gdbarch)->builtin_long);
-                     write_exp_elt_longcst (size);
-                     write_exp_elt_opcode (OP_LONG);
-                     if (size_minus)
-                       write_exp_elt_opcode (UNOP_NEG);
-                     write_exp_elt_opcode (BINOP_MUL);
-                   }
+      if (size)
+       {
+         write_exp_elt_opcode (OP_LONG);
+         write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+         write_exp_elt_longcst (size);
+         write_exp_elt_opcode (OP_LONG);
+         if (size_minus)
+           write_exp_elt_opcode (UNOP_NEG);
+         write_exp_elt_opcode (BINOP_MUL);
+       }
 
-                 write_exp_elt_opcode (BINOP_ADD);
+      write_exp_elt_opcode (BINOP_ADD);
 
-                 write_exp_elt_opcode (UNOP_CAST);
-                 write_exp_elt_type (lookup_pointer_type (p->arg_type));
-                 write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_type (lookup_pointer_type (p->arg_type));
+      write_exp_elt_opcode (UNOP_CAST);
 
-                 write_exp_elt_opcode (UNOP_IND);
+      write_exp_elt_opcode (UNOP_IND);
 
-                 p->arg = s;
+      p->arg = s;
 
-                 return 1;
-               }
-             break;
-           }
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Implementation of `gdbarch_stap_parse_special_token', as defined in
+   gdbarch.h.  */
+
+int
+i386_stap_parse_special_token (struct gdbarch *gdbarch,
+                              struct stap_parse_info *p)
+{
+  /* In order to parse special tokens, we use a state-machine that go
+     through every known token and try to get a match.  */
+  enum
+    {
+      TRIPLET,
+      THREE_ARG_DISPLACEMENT,
+      DONE
+    } current_state;
+
+  current_state = TRIPLET;
+
+  /* The special tokens to be parsed here are:
+
+     - `register base + (register index * size) + offset', as represented
+     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+
+     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
+     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+
+  while (current_state != DONE)
+    {
+      switch (current_state)
+       {
+       case TRIPLET:
+         if (i386_stap_parse_special_token_triplet (gdbarch, p))
+           return 1;
+         break;
+
+       case THREE_ARG_DISPLACEMENT:
+         if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
+           return 1;
+         break;
        }
 
       /* Advancing to the next state.  */
@@ -7792,7 +7874,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  tdep = XCALLOC (1, struct gdbarch_tdep);
+  tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* General-purpose registers.  */
@@ -7990,6 +8072,10 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_gen_return_address (gdbarch, i386_gen_return_address);
 
+  set_gdbarch_insn_is_call (gdbarch, i386_insn_is_call);
+  set_gdbarch_insn_is_ret (gdbarch, i386_insn_is_ret);
+  set_gdbarch_insn_is_jump (gdbarch, i386_insn_is_jump);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.tdep_info = (void *) tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
This page took 0.036458 seconds and 4 git commands to generate.