fix latent bugs in ui-out.c
[binutils-gdb.git] / gdb / i386-tdep.c
index 4a5f652b168d79facacf9dbec413620a38f612a5..be40b2070a7d8cee4d77f3431f88121b550d272c 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.  */
 
@@ -1753,8 +1808,8 @@ i386_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
          call_dest = call_dest & 0xffffffffU;
          s = lookup_minimal_symbol_by_pc (call_dest);
          if (s.minsym != NULL
-             && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
-             && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0)
+             && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL
+             && strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0)
            pc += 5;
        }
     }
@@ -3507,7 +3562,7 @@ i386_pe_skip_trampoline_code (struct frame_info *frame,
        read_memory_unsigned_integer (pc + 2, 4, byte_order);
       struct minimal_symbol *indsym =
        indirect ? lookup_minimal_symbol_by_pc (indirect).minsym : 0;
-      const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0;
+      const char *symname = indsym ? MSYMBOL_LINKAGE_NAME (indsym) : 0;
 
       if (symname)
        {
@@ -3639,6 +3694,9 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
          got_minus[0] = 1;
        }
 
+      if (!isdigit ((unsigned char) *s))
+       return 0;
+
       displacements[0] = strtol (s, &endp, 10);
       s = endp;
 
@@ -3657,6 +3715,9 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
          got_minus[1] = 1;
        }
 
+      if (!isdigit ((unsigned char) *s))
+       return 0;
+
       displacements[1] = strtol (s, &endp, 10);
       s = endp;
 
@@ -3675,6 +3736,9 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
          got_minus[2] = 1;
        }
 
+      if (!isdigit ((unsigned char) *s))
+       return 0;
+
       displacements[2] = strtol (s, &endp, 10);
       s = endp;
 
@@ -3690,7 +3754,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       if (*s++ != ')')
        return 0;
 
-      len = s - start;
+      len = s - start - 1;
       regname = alloca (len + 1);
 
       strncpy (regname, start, len);
@@ -8017,6 +8081,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);