示例#1
0
void
gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
		 char *file_string, int flags, int how_many,
		 CORE_ADDR low, CORE_ADDR high)
{
  struct ui_file *stb = mem_fileopen ();
  struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
  struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
  struct symtab *symtab;
  struct linetable_entry *le = NULL;
  int nlines = -1;

  /* Assume symtab is valid for whole PC range.  */
  symtab = find_pc_line_symtab (low);

  if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
    {
      /* Convert the linetable to a bunch of my_line_entry's.  */
      le = SYMTAB_LINETABLE (symtab)->item;
      nlines = SYMTAB_LINETABLE (symtab)->nitems;
    }

  if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0
      || symtab == NULL || SYMTAB_LINETABLE (symtab) == NULL)
    do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);

  else if (flags & DISASSEMBLY_SOURCE)
    do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
				  high, symtab, how_many, flags, stb);

  do_cleanups (cleanups);
  gdb_flush (gdb_stdout);
}
示例#2
0
static char *
explicit_to_string_internal (int as_linespec,
			     const struct explicit_location *explicit_loc)
{
  struct ui_file *buf;
  char space, *result;
  int need_space = 0;
  struct cleanup *cleanup;

  space = as_linespec ? ':' : ' ';
  buf = mem_fileopen ();
  cleanup = make_cleanup_ui_file_delete (buf);

  if (explicit_loc->source_filename != NULL)
    {
      if (!as_linespec)
	fputs_unfiltered ("-source ", buf);
      fputs_unfiltered (explicit_loc->source_filename, buf);
      need_space = 1;
    }

  if (explicit_loc->function_name != NULL)
    {
      if (need_space)
	fputc_unfiltered (space, buf);
      if (!as_linespec)
	fputs_unfiltered ("-function ", buf);
      fputs_unfiltered (explicit_loc->function_name, buf);
      need_space = 1;
    }

  if (explicit_loc->label_name != NULL)
    {
      if (need_space)
	fputc_unfiltered (space, buf);
      if (!as_linespec)
	fputs_unfiltered ("-label ", buf);
      fputs_unfiltered (explicit_loc->label_name, buf);
      need_space = 1;
    }

  if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
    {
      if (need_space)
	fputc_unfiltered (space, buf);
      if (!as_linespec)
	fputs_unfiltered ("-line ", buf);
      fprintf_filtered (buf, "%s%d",
			(explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? ""
			 : (explicit_loc->line_offset.sign
			    == LINE_OFFSET_PLUS ? "+" : "-")),
			explicit_loc->line_offset.offset);
    }

  result = ui_file_xstrdup (buf, NULL);
  do_cleanups (cleanup);
  return result;
}
/* Print a floating-point value of type TYPE, pointed to in GDB by
   VALADDR, on STREAM.  Use Ada formatting conventions: there must be
   a decimal point, and at least one digit before and after the
   point.  We use GNAT format for NaNs and infinities.  */
static void
ada_print_floating (const gdb_byte *valaddr, struct type *type,
		    struct ui_file *stream)
{
  char buffer[64];
  char *s, *result;
  int len;
  struct ui_file *tmp_stream = mem_fileopen ();
  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream);

  print_floating (valaddr, type, tmp_stream);
  ui_file_put (tmp_stream, ui_memcpy, buffer);
  do_cleanups (cleanups);

  result = buffer;
  len = strlen (result);

  /* Modify for Ada rules.  */
  
  s = strstr (result, "inf");
  if (s == NULL)
    s = strstr (result, "Inf");
  if (s == NULL)
    s = strstr (result, "INF");
  if (s != NULL)
    strcpy (s, "Inf");

  if (s == NULL)
    {
      s = strstr (result, "nan");
      if (s == NULL)
	s = strstr (result, "NaN");
      if (s == NULL)
	s = strstr (result, "Nan");
      if (s != NULL)
	{
	  s[0] = s[2] = 'N';
	  if (result[0] == '-')
	    result += 1;
	}
    }

  if (s == NULL && strchr (result, '.') == NULL)
    {
      s = strchr (result, 'e');
      if (s == NULL)
	fprintf_filtered (stream, "%s.0", result);
      else
	fprintf_filtered (stream, "%.*s.0%s", (int) (s-result), result, s);
      return;
    }
  fprintf_filtered (stream, "%s", result);
}
示例#4
0
struct ui_out *
mi_out_new (int mi_version)
{
  int flags = 0;
  struct ui_out_data *data = XMALLOC (struct ui_out_data);
  data->suppress_field_separator = 0;
  data->suppress_output = 0;
  data->mi_version = mi_version;
  /* FIXME: This code should be using a ``string_file'' and not the
     TUI buffer hack. */
  data->buffer = mem_fileopen ();
  return ui_out_new (&mi_ui_out_impl, data, flags);
}
示例#5
0
文件: ada-varobj.c 项目: CromFr/gdb
static char *
ada_varobj_scalar_image (struct type *type, LONGEST val)
{
  struct ui_file *buf = mem_fileopen ();
  struct cleanup *cleanups = make_cleanup_ui_file_delete (buf);
  char *result;

  ada_print_scalar (type, val, buf);
  result = ui_file_xstrdup (buf, NULL);
  do_cleanups (cleanups);

  return result;
}
示例#6
0
static void
ada_print_floating (const gdb_byte *valaddr, struct type *type,
		    struct ui_file *stream)
{
  struct ui_file *tmp_stream = mem_fileopen ();
  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream);

  print_floating (valaddr, type, tmp_stream);

  std::string s = ui_file_as_string (tmp_stream);
  size_t skip_count = 0;

  /* Modify for Ada rules.  */

  size_t pos = s.find ("inf");
  if (pos == std::string::npos)
    pos = s.find ("Inf");
  if (pos == std::string::npos)
    pos = s.find ("INF");
  if (pos != std::string::npos)
    s.replace (pos, 3, "Inf");

  if (pos == std::string::npos)
    {
      pos = s.find ("nan");
      if (pos == std::string::npos)
	pos = s.find ("NaN");
      if (pos == std::string::npos)
	pos = s.find ("Nan");
      if (pos != std::string::npos)
	{
	  s[pos] = s[pos + 2] = 'N';
	  if (s[0] == '-')
	    skip_count = 1;
	}
    }

  if (pos == std::string::npos
      && s.find ('.') == std::string::npos)
    {
      pos = s.find ('e');
      if (pos == std::string::npos)
	fprintf_filtered (stream, "%s.0", s.c_str ());
      else
	fprintf_filtered (stream, "%.*s.0%s", (int) pos, s.c_str (), &s[pos]);
    }
  else
    fprintf_filtered (stream, "%s", &s[skip_count]);

  do_cleanups (cleanups);
}
示例#7
0
文件: py-frame.c 项目: abidh/gdb
static PyObject *
frapy_str (PyObject *self)
{
  char *s;
  PyObject *result;
  struct ui_file *strfile;

  strfile = mem_fileopen ();
  fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
  s = ui_file_xstrdup (strfile, NULL);
  result = PyString_FromString (s);
  xfree (s);

  return result;
}
示例#8
0
char *
type_sprint(struct type *type, const char *varstring, int show)
{
  struct ui_file *stb;
  struct cleanup *wipe;
  long length;
  char *type_name;

  stb = mem_fileopen();
  wipe = make_cleanup_ui_file_delete(stb);

  type_print(type, varstring, stb, show);
  type_name = ui_file_xstrdup(stb, &length);
  do_cleanups(wipe);

  return type_name;
}
示例#9
0
文件: ada-varobj.c 项目: CromFr/gdb
static char *
ada_varobj_get_value_image (struct value *value,
			    struct value_print_options *opts)
{
  char *result;
  struct ui_file *buffer;
  struct cleanup *old_chain;

  buffer = mem_fileopen ();
  old_chain = make_cleanup_ui_file_delete (buffer);

  common_val_print (value, buffer, 0, opts, current_language);
  result = ui_file_xstrdup (buffer, NULL);

  do_cleanups (old_chain);
  return result;
}
示例#10
0
static int
frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
{
    frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
    struct ui_file *strfile;
    char *s;

    gdbscm_printf (port, "#<%s ", frame_smob_name);

    strfile = mem_fileopen ();
    fprint_frame_id (strfile, f_smob->frame_id);
    s = ui_file_xstrdup (strfile, NULL);
    gdbscm_printf (port, "%s", s);
    ui_file_delete (strfile);
    xfree (s);

    scm_puts (">", port);

    scm_remember_upto_here_1 (self);

    /* Non-zero means success.  */
    return 1;
}
示例#11
0
文件: scm-type.c 项目: ChrisG0x20/gdb
static char *
tyscm_type_name (struct type *type, SCM *excp)
{
  char *name = NULL;

  TRY
    {
      struct cleanup *old_chain;
      struct ui_file *stb;

      stb = mem_fileopen ();
      old_chain = make_cleanup_ui_file_delete (stb);

      LA_PRINT_TYPE (type, "", stb, -1, 0, &type_print_raw_options);

      name = ui_file_xstrdup (stb, NULL);
      do_cleanups (old_chain);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      *excp = gdbscm_scm_from_gdb_exception (except);
      return NULL;
    }
示例#12
0
/* Report a memory error with error(): */
void ATTR_NORETURN
memory_error (int status, CORE_ADDR memaddr)
{
  struct ui_file *tmp_stream = mem_fileopen();
  make_cleanup_ui_file_delete(tmp_stream);

  if (status == EIO)
    {
      /* Actually, address between memaddr and memaddr + len
         was out of bounds. */
      fprintf_unfiltered (tmp_stream, "Cannot access memory at address 0x%s",
                          phex_nz (memaddr, sizeof (CORE_ADDR)));
    }
  else
    {
      fprintf_filtered (tmp_stream, "Error accessing memory address 0x%s",
                          phex_nz (memaddr, sizeof (CORE_ADDR)));
      fprintf_filtered (tmp_stream, ": %s.",
		       safe_strerror (status));
    }

  error_stream (tmp_stream);
}
示例#13
0
文件: mi-cmd-stack.c 项目: 5kg/gdb
static void
list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
		   enum print_values values)
{
  struct cleanup *old_chain;
  struct ui_out *uiout = current_uiout;
  struct ui_file *stb;

  stb = mem_fileopen ();
  old_chain = make_cleanup_ui_file_delete (stb);

  gdb_assert (!arg->val || !arg->error);
  gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL
	       && arg->error == NULL)
	      || values == PRINT_SIMPLE_VALUES
	      || (values == PRINT_ALL_VALUES
		  && (arg->val != NULL || arg->error != NULL)));
  gdb_assert (arg->entry_kind == print_entry_values_no
	      || (arg->entry_kind == print_entry_values_only
	          && (arg->val || arg->error)));

  if (values != PRINT_NO_VALUES || what == all)
    make_cleanup_ui_out_tuple_begin_end (uiout, NULL);

  fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb);
  if (arg->entry_kind == print_entry_values_only)
    fputs_filtered ("@entry", stb);
  ui_out_field_stream (uiout, "name", stb);

  if (what == all && SYMBOL_IS_ARGUMENT (arg->sym))
    ui_out_field_int (uiout, "arg", 1);

  if (values == PRINT_SIMPLE_VALUES)
    {
      check_typedef (arg->sym->type);
      type_print (arg->sym->type, "", stb, -1);
      ui_out_field_stream (uiout, "type", stb);
    }

  if (arg->val || arg->error)
    {
      volatile struct gdb_exception except;

      if (arg->error)
	except.message = arg->error;
      else
	{
	  /* TRY_CATCH has two statements, wrap it in a block.  */

	  TRY_CATCH (except, RETURN_MASK_ERROR)
	    {
	      struct value_print_options opts;

	      get_raw_print_options (&opts);
	      opts.deref_ref = 1;
	      common_val_print (arg->val, stb, 0, &opts,
				language_def (SYMBOL_LANGUAGE (arg->sym)));
	    }
	}
      if (except.message)
	fprintf_filtered (stb, _("<error reading variable: %s>"),
			  except.message);
      ui_out_field_stream (uiout, "value", stb);
    }

  do_cleanups (old_chain);
}
示例#14
0
void
do_setshow_command(char *arg, int from_tty, struct cmd_list_element *c)
{
  if (c->type == set_cmd)
    {
      switch (c->var_type)
	{
	case var_string:
	  {
	    char *newstr;
	    char *p;
	    char *q;
	    int ch;

	    if (arg == NULL)
	      arg = "";
	    newstr = (char *)xmalloc(strlen(arg) + 2);
	    p = arg;
	    q = newstr;
	    while ((ch = *p++) != '\000')
	      {
		if (ch == '\\')
		  {
		    /* \ at end of argument is used after spaces
		       so they won't be lost.  */
		    /* This is obsolete now that we no longer strip
		       trailing whitespace and actually, the backslash
		       didn't get here in my test, readline or
		       something did something funky with a backslash
		       right before a newline.  */
		    if (*p == 0)
		      break;
		    ch = parse_escape(&p);
		    if (ch == 0)
		      break;	/* C loses */
		    else if (ch > 0)
		      *q++ = ch;
		  }
		else
		  *q++ = ch;
	      }
#if 0
	    if (*(p - 1) != '\\')
	      *q++ = ' ';
#endif /* 0 */
	    *q++ = '\0';
	    newstr = (char *)xrealloc(newstr, (q - newstr));
	    if (*(char **)c->var != NULL)
	      xfree(*(char **)c->var);
	    *(char **)c->var = newstr;
	  }
	  break;
	case var_string_noescape:
	  if (arg == NULL)
	    arg = "";
	  if (*(char **)c->var != NULL)
	    xfree(*(char **)c->var);
	  *(char **)c->var = savestring(arg, strlen(arg));
	  break;
	case var_optional_filename:
	  if (arg == NULL)
	    arg = "";
	  if (*(char **)c->var != NULL)
	    xfree(*(char **)c->var);
	  *(char **)c->var = savestring(arg, strlen(arg));
	  break;
	case var_filename:
	  if (arg == NULL)
	    error_no_arg(_("filename to set it to."));
	  if (*(char **)c->var != NULL)
	    xfree (*(char **)c->var);
	  *(char **)c->var = tilde_expand(arg);
	  break;
	case var_boolean:
	  *(int *)c->var = parse_binary_operation(arg);
	  break;
	case var_auto_boolean:
	  *(enum auto_boolean *)c->var = parse_auto_binary_operation(arg);
	  break;
	case var_uinteger:
	  if (arg == NULL)
	    error_no_arg(_("integer to set it to."));
	  *(unsigned int *)c->var = (unsigned int)parse_and_eval_long(arg);
	  if (*(unsigned int *)c->var == 0)
	    *(unsigned int *)c->var = UINT_MAX;
	  break;
	case var_integer:
	  {
	    unsigned int val;
	    if (arg == NULL)
	      error_no_arg(_("integer to set it to."));
	    val = (unsigned int)parse_and_eval_long(arg);
	    if (val == 0)
	      *(int *)c->var = INT_MAX;
	    else if (val >= INT_MAX)
	      error(_("integer %u out of range"), val);
	    else
	      *(int *)c->var = val;
	    break;
	  }
	case var_zinteger:
	  if (arg == NULL)
	    error_no_arg(_("integer to set it to."));
	  *(int *)c->var = (int)parse_and_eval_long(arg);
	  break;
	case var_enum:
	  {
	    int i;
	    int len;
	    int nmatches = 0;
	    const char *match = NULL;
	    char *p;

	    /* APPLE LOCAL: Give the valid options for all error
	       messages for enum type commands. */

	    /* If an argument was supplied, parse it. */
	    if (arg != NULL)
	      {
		p = strchr(arg, ' ');

		if (p)
		  len = (p - arg);
		else
		  len = strlen(arg);

		nmatches = 0;
		for (i = 0; c->enums[i]; i++)
		  if (strncmp(arg, c->enums[i], len) == 0)
		    {
		      if (c->enums[i][len] == '\0')
			{
			  match = c->enums[i];
			  nmatches = 1;
			  break; /* exact match. */
			}
		      else
			{
			  match = c->enums[i];
			  nmatches++;
			}
		    }
	      }

	    if (nmatches == 1)
	      *(const char **)c->var = match;
	    else
	      {
                /* If there was an error, print an informative
                   error message.  */
                struct ui_file *tmp_error_stream = mem_fileopen();
                make_cleanup_ui_file_delete (tmp_error_stream);

                if (arg == NULL)
                  fprintf_unfiltered(tmp_error_stream, "Requires an argument.");
                else if (nmatches <= 0)
                  fprintf_unfiltered(tmp_error_stream, "Undefined item: \"%s\".", arg);
		else if (nmatches > 1)
                  fprintf_unfiltered(tmp_error_stream, "Ambiguous item \"%s\".", arg);

                fprintf_unfiltered(tmp_error_stream, " Valid arguments are ");
                for (i = 0; c->enums[i]; i++)
                  {
                    if (i != 0)
                      fprintf_unfiltered(tmp_error_stream, ", ");
                    fputs_unfiltered(c->enums[i], tmp_error_stream);
                  }
                fprintf_unfiltered(tmp_error_stream, ".");
                error_stream(tmp_error_stream);
	      }

	    /* END APPLE LOCAL */
	  }
	  break;
	default:
	  error(_("gdb internal error: bad var_type in do_setshow_command"));
	}
    }
  else if (c->type == show_cmd)
    {
      struct cleanup *old_chain;
      struct ui_stream *stb;

      stb = ui_out_stream_new(uiout);
      old_chain = make_cleanup_ui_out_stream_delete(stb);

      /* Possibly call the pre hook: */
      if (c->pre_show_hook)
	(c->pre_show_hook)(c);

      switch (c->var_type)
	{
	case var_string:
	  {
	    if (*(unsigned char **)c->var)
	      fputstr_filtered(*(char **)c->var, '"', stb->stream);
	  }
	  break;
	case var_string_noescape:
	case var_optional_filename:
	case var_filename:
	case var_enum:
	  if (*(char **)c->var)
	    fputs_filtered(*(char **)c->var, stb->stream);
	  break;
	case var_boolean:
	  fputs_filtered(*(int *)c->var ? "on" : "off", stb->stream);
	  break;
	case var_auto_boolean:
	  switch (*(enum auto_boolean*)c->var)
	    {
	    case AUTO_BOOLEAN_TRUE:
	      fputs_filtered("on", stb->stream);
	      break;
	    case AUTO_BOOLEAN_FALSE:
	      fputs_filtered("off", stb->stream);
	      break;
	    case AUTO_BOOLEAN_AUTO:
	      fputs_filtered("auto", stb->stream);
	      break;
	    default:
	      internal_error(__FILE__, __LINE__,
			     _("do_setshow_command: invalid var_auto_boolean"));
	      break;
	    }
	  break;
	case var_uinteger:
	  if (*(unsigned int *)c->var == UINT_MAX)
	    {
	      fputs_filtered("unlimited", stb->stream);
	      break;
	    }
	  /* else fall through */
	case var_zinteger:
	  fprintf_filtered(stb->stream, "%u", *(unsigned int *)c->var);
	  break;
	case var_integer:
	  if (*(int *)c->var == INT_MAX)
	    {
	      fputs_filtered("unlimited", stb->stream);
	    }
	  else
	    fprintf_filtered(stb->stream, "%d", *(int *)c->var);
	  break;

	default:
	  error(_("gdb internal error: bad var_type in do_setshow_command"));
	}


      /* FIXME: cagney/2005-02-10: Need to split this in half: code to
	 convert the value into a string (esentially the above); and
	 code to print the value out.  For the latter there should be
	 MI and CLI specific versions.  */

      if (ui_out_is_mi_like_p(uiout))
	ui_out_field_stream(uiout, "value", stb);
      else
	{
	  long length;
	  char *value = ui_file_xstrdup(stb->stream, &length);
	  make_cleanup(xfree, value);
	  if (c->show_value_func != NULL)
	    c->show_value_func(gdb_stdout, from_tty, c, value);
	  else
	    deprecated_show_value_hack(gdb_stdout, from_tty, c, value);
	}
      do_cleanups(old_chain);
    }
  else
    error(_("gdb internal error: bad cmd_type in do_setshow_command"));
  c->func(c, NULL, from_tty);
  if ((c->type == set_cmd) && deprecated_set_hook)
    deprecated_set_hook(c);
}
示例#15
0
static void
get_register (int regnum, map_arg arg)
{
  int realnum;
  CORE_ADDR addr;
  enum lval_type lval;
  struct type *reg_vtype;
  gdb_byte buffer[MAX_REGISTER_SIZE];
  int optim, format;
  struct cleanup *old_chain = NULL;
  struct ui_file *stb;
  long dummy;
  char *res;
 
  format = regformat[regnum];
  if (format == 0)
    format = 'x';
  
  reg_vtype = regtype[regnum];
  if (reg_vtype == NULL)
    reg_vtype = register_type (get_current_arch (), regnum);

  if (!target_has_registers)
    {
      if (result_ptr->flags & GDBTK_MAKES_LIST)
	Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj ("", -1));
      else
	Tcl_SetStringObj (result_ptr->obj_ptr, "", -1);
      return;
    }

  frame_register (get_selected_frame (NULL), regnum, &optim, &lval, 
		  &addr, &realnum, buffer);

  if (optim)
    {
      Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
				Tcl_NewStringObj ("Optimized out", -1));
      return;
    }

  stb = mem_fileopen ();
  old_chain = make_cleanup_ui_file_delete (stb);

  if (format == 'r')
    {
      /* shouldn't happen. raw format is deprecated */
      int j;
      char *ptr, buf[1024];

      strcpy (buf, "0x");
      ptr = buf + 2;
      for (j = 0; j < register_size (get_current_arch (), regnum); j++)
	{
	  int idx = ((gdbarch_byte_order (get_current_arch ()) == BFD_ENDIAN_BIG)
		     ? j : register_size (get_current_arch (), regnum) - 1 - j);
	  sprintf (ptr, "%02x", (unsigned char) buffer[idx]);
	  ptr += 2;
	}
      fputs_unfiltered (buf, stb);
    }
  else
    {
      struct value_print_options opts;

      get_formatted_print_options (&opts, format);
      opts.deref_ref = 1;
      opts.pretty = Val_pretty_default;

      if ((TYPE_CODE (reg_vtype) == TYPE_CODE_UNION)
	  && (strcmp (FIELD_NAME (TYPE_FIELD (reg_vtype, 0)), 
		      gdbarch_register_name (get_current_arch (), regnum)) == 0))
	{
	  val_print (FIELD_TYPE (TYPE_FIELD (reg_vtype, 0)), buffer, 0, 0,
		     stb, 0, NULL, &opts, current_language);
	}
      else
	val_print (reg_vtype, buffer, 0, 0,
		   stb, 0, NULL, &opts, current_language);
    }
  
  res = ui_file_xstrdup (stb, &dummy);

  if (result_ptr->flags & GDBTK_MAKES_LIST)
    Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj (res, -1));
  else
    Tcl_SetStringObj (result_ptr->obj_ptr, res, -1);

  xfree (res);
  do_cleanups (old_chain);
}
示例#16
0
void
add_language (const struct language_defn *lang)
{
  /* For the "set language" command.  */
  static const char **language_names = NULL;
  /* For the "help set language" command.  */
  char *language_set_doc = NULL;

  int i;
  struct ui_file *tmp_stream;

  if (lang->la_magic != LANG_MAGIC)
    {
      fprintf_unfiltered (gdb_stderr,
			  "Magic number of %s language struct wrong\n",
			  lang->la_name);
      internal_error (__FILE__, __LINE__,
		      _("failed internal consistency check"));
    }

  if (!languages)
    {
      languages_allocsize = DEFAULT_ALLOCSIZE;
      languages = (const struct language_defn **) xmalloc
	(languages_allocsize * sizeof (*languages));
    }
  if (languages_size >= languages_allocsize)
    {
      languages_allocsize *= 2;
      languages = (const struct language_defn **) xrealloc ((char *) languages,
				 languages_allocsize * sizeof (*languages));
    }
  languages[languages_size++] = lang;

  /* Build the language names array, to be used as enumeration in the
     set language" enum command.  */
  language_names = xrealloc (language_names,
			     (languages_size + 1) * sizeof (const char *));
  for (i = 0; i < languages_size; ++i)
    language_names[i] = languages[i]->la_name;
  language_names[i] = NULL;

  /* Build the "help set language" docs.  */
  tmp_stream = mem_fileopen ();

  fprintf_unfiltered (tmp_stream,
		      _("Set the current source language.\n"
			"The currently understood settings are:\n\nlocal or "
			"auto    Automatic setting based on source file\n"));

  for (i = 0; i < languages_size; ++i)
    {
      /* Already dealt with these above.  */
      if (languages[i]->la_language == language_unknown
	  || languages[i]->la_language == language_auto)
	continue;

      /* FIXME: i18n: for now assume that the human-readable name
	 is just a capitalization of the internal name.  */
      fprintf_unfiltered (tmp_stream, "%-16s Use the %c%s language\n",
			  languages[i]->la_name,
			  /* Capitalize first letter of language
			     name.  */
			  toupper (languages[i]->la_name[0]),
			  languages[i]->la_name + 1);
    }

  language_set_doc = ui_file_xstrdup (tmp_stream, NULL);
  ui_file_delete (tmp_stream);

  add_setshow_enum_cmd ("language", class_support,
			(const char **) language_names,
			&language,
			language_set_doc,
			_("Show the current source language."),
			NULL, set_language_command,
			show_language_command,
			&setlist, &showlist);

  xfree (language_set_doc);
}
示例#17
0
static void
list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
		   enum print_values values, int skip_unavailable)
{
  struct cleanup *old_chain;
  struct ui_out *uiout = current_uiout;
  struct ui_file *stb;

  gdb_assert (!arg->val || !arg->error);
  gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL
	       && arg->error == NULL)
	      || values == PRINT_SIMPLE_VALUES
	      || (values == PRINT_ALL_VALUES
		  && (arg->val != NULL || arg->error != NULL)));
  gdb_assert (arg->entry_kind == print_entry_values_no
	      || (arg->entry_kind == print_entry_values_only
	          && (arg->val || arg->error)));

  if (skip_unavailable && arg->val != NULL
      && (value_entirely_unavailable (arg->val)
	  /* A scalar object that does not have all bits available is
	     also considered unavailable, because all bits contribute
	     to its representation.  */
	  || (val_print_scalar_type_p (value_type (arg->val))
	      && !value_bytes_available (arg->val,
					 value_embedded_offset (arg->val),
					 TYPE_LENGTH (value_type (arg->val))))))
    return;

  stb = mem_fileopen ();
  old_chain = make_cleanup_ui_file_delete (stb);

  if (values != PRINT_NO_VALUES || what == all)
    make_cleanup_ui_out_tuple_begin_end (uiout, NULL);

  fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb);
  if (arg->entry_kind == print_entry_values_only)
    fputs_filtered ("@entry", stb);
  ui_out_field_stream (uiout, "name", stb);

  if (what == all && SYMBOL_IS_ARGUMENT (arg->sym))
    ui_out_field_int (uiout, "arg", 1);

  if (values == PRINT_SIMPLE_VALUES)
    {
      check_typedef (arg->sym->type);
      type_print (arg->sym->type, "", stb, -1);
      ui_out_field_stream (uiout, "type", stb);
    }

  if (arg->val || arg->error)
    {
      const char *error_message = NULL;

      if (arg->error)
	error_message = arg->error;
      else
	{
	  TRY
	    {
	      struct value_print_options opts;

	      get_no_prettyformat_print_options (&opts);
	      opts.deref_ref = 1;
	      common_val_print (arg->val, stb, 0, &opts,
				language_def (SYMBOL_LANGUAGE (arg->sym)));
	    }
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      error_message = except.message;
	    }
	  END_CATCH
	}
      if (error_message != NULL)
	fprintf_filtered (stb, _("<error reading variable: %s>"),
			  error_message);
      ui_out_field_stream (uiout, "value", stb);
    }

  do_cleanups (old_chain);
}
示例#18
0
static SCM
gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest)
{
  arch_smob *a_smob
    = arscm_get_arch_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct gdbarch *gdbarch = arscm_get_gdbarch (a_smob);
  const SCM keywords[] = {
    port_keyword, offset_keyword, size_keyword, count_keyword, SCM_BOOL_F
  };
  int port_arg_pos = -1, offset_arg_pos = -1;
  int size_arg_pos = -1, count_arg_pos = -1;
  SCM port = SCM_BOOL_F;
  ULONGEST offset = 0;
  unsigned int count = 1;
  unsigned int size;
  ULONGEST start_arg;
  CORE_ADDR start, end;
  CORE_ADDR pc;
  unsigned int i;
  int using_port;
  SCM result;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "U#OUuu",
			      start_scm, &start_arg, rest,
			      &port_arg_pos, &port,
			      &offset_arg_pos, &offset,
			      &size_arg_pos, &size,
			      &count_arg_pos, &count);
  /* START is first stored in a ULONGEST because we don't have a format char
     for CORE_ADDR, and it's not really worth it to have one yet.  */
  start = start_arg;

  if (port_arg_pos > 0)
    {
      SCM_ASSERT_TYPE (gdbscm_is_false (port)
		       || gdbscm_is_true (scm_input_port_p (port)),
		       port, port_arg_pos, FUNC_NAME, _("input port"));
    }
  using_port = gdbscm_is_true (port);

  if (offset_arg_pos > 0
      && (port_arg_pos < 0
	  || gdbscm_is_false (port)))
    {
      gdbscm_out_of_range_error (FUNC_NAME, offset_arg_pos,
				 gdbscm_scm_from_ulongest (offset),
				 _("offset provided but port is missing"));
    }

  if (size_arg_pos > 0)
    {
      if (size == 0)
	return SCM_EOL;
      /* For now be strict about start+size overflowing.  If it becomes
	 a nuisance we can relax things later.  */
      if (start + size < start)
	{
	  gdbscm_out_of_range_error (FUNC_NAME, 0,
				scm_list_2 (gdbscm_scm_from_ulongest (start),
					    gdbscm_scm_from_ulongest (size)),
				     _("start+size overflows"));
	}
      end = start + size - 1;
    }
  else
    end = ~(CORE_ADDR) 0;

  if (count == 0)
    return SCM_EOL;

  result = SCM_EOL;

  for (pc = start, i = 0; pc <= end && i < count; )
    {
      int insn_len = 0;
      struct ui_file *memfile = mem_fileopen ();
      struct cleanup *cleanups = make_cleanup_ui_file_delete (memfile);

      TRY
	{
	  if (using_port)
	    {
	      insn_len = gdbscm_print_insn_from_port (gdbarch, port, offset,
						      pc, memfile, NULL);
	    }
	  else
	    insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS (except, cleanups);
	}
      END_CATCH

      std::string as = ui_file_as_string (memfile);

      result = scm_cons (dascm_make_insn (pc, as.c_str (), insn_len),
			 result);

      pc += insn_len;
      i++;
      do_cleanups (cleanups);
    }
示例#19
0
void
do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
{
  struct ui_out *uiout = current_uiout;
  struct cleanup *old_chain;
  struct ui_file *stb;

  gdb_assert (c->type == show_cmd);

  stb = mem_fileopen ();
  old_chain = make_cleanup_ui_file_delete (stb);

  /* Possibly call the pre hook.  */
  if (c->pre_show_hook)
    (c->pre_show_hook) (c);

  switch (c->var_type)
    {
    case var_string:
      if (*(char **) c->var)
	fputstr_filtered (*(char **) c->var, '"', stb);
      break;
    case var_string_noescape:
    case var_optional_filename:
    case var_filename:
    case var_enum:
      if (*(char **) c->var)
	fputs_filtered (*(char **) c->var, stb);
      break;
    case var_boolean:
      fputs_filtered (*(int *) c->var ? "on" : "off", stb);
      break;
    case var_auto_boolean:
      switch (*(enum auto_boolean*) c->var)
	{
	case AUTO_BOOLEAN_TRUE:
	  fputs_filtered ("on", stb);
	  break;
	case AUTO_BOOLEAN_FALSE:
	  fputs_filtered ("off", stb);
	  break;
	case AUTO_BOOLEAN_AUTO:
	  fputs_filtered ("auto", stb);
	  break;
	default:
	  internal_error (__FILE__, __LINE__,
			  _("do_show_command: "
			    "invalid var_auto_boolean"));
	  break;
	}
      break;
    case var_uinteger:
    case var_zuinteger:
      if (c->var_type == var_uinteger
	  && *(unsigned int *) c->var == UINT_MAX)
	fputs_filtered ("unlimited", stb);
      else
	fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
      break;
    case var_integer:
    case var_zinteger:
      if (c->var_type == var_integer
	  && *(int *) c->var == INT_MAX)
	fputs_filtered ("unlimited", stb);
      else
	fprintf_filtered (stb, "%d", *(int *) c->var);
      break;
    case var_zuinteger_unlimited:
      {
	if (*(int *) c->var == -1)
	  fputs_filtered ("unlimited", stb);
	else
	  fprintf_filtered (stb, "%d", *(int *) c->var);
      }
      break;
    default:
      error (_("gdb internal error: bad var_type in do_show_command"));
    }


  /* FIXME: cagney/2005-02-10: Need to split this in half: code to
     convert the value into a string (esentially the above); and
     code to print the value out.  For the latter there should be
     MI and CLI specific versions.  */

  if (ui_out_is_mi_like_p (uiout))
    ui_out_field_stream (uiout, "value", stb);
  else
    {
      char *value = ui_file_xstrdup (stb, NULL);

      make_cleanup (xfree, value);
      if (c->show_value_func != NULL)
	c->show_value_func (gdb_stdout, from_tty, c, value);
      else
	deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
    }
  do_cleanups (old_chain);

  c->func (c, NULL, from_tty);
}
示例#20
0
文件: main.c 项目: 2asoft/freebsd
		read_memory(bufp + rseq, &c, 1);
		putchar(c);
		rseq++;
		if (rseq == size)
			rseq = 0;
	}
	if (c != '\n')
		putchar('\n');
	putchar('\n');
}

static void
kgdb_init(char *argv0 __unused)
{

	parse_gdberr = mem_fileopen();
	set_prompt("(kgdb) ");
	initialize_kgdb_target();
	initialize_kld_target();
	kgdb_new_objfile_chain = target_new_objfile_hook;
	target_new_objfile_hook = kgdb_new_objfile;
}

/*
 * Remote targets can support any number of syntaxes and we want to
 * support them all with one addition: we support specifying a device
 * node for a serial device without the "/dev/" prefix.
 *
 * What we do is to stat(2) the existing remote target first.  If that
 * fails, we try it with "/dev/" prepended.  If that succeeds we use
 * the resulting path, otherwise we use the original target.  If
char *
c_compute_program (struct compile_instance *inst,
		   const char *input,
		   struct gdbarch *gdbarch,
		   const struct block *expr_block,
		   CORE_ADDR expr_pc)
{
  struct ui_file *buf, *var_stream = NULL;
  char *code;
  struct cleanup *cleanup;
  struct compile_c_instance *context = (struct compile_c_instance *) inst;

  buf = mem_fileopen ();
  cleanup = make_cleanup_ui_file_delete (buf);

  write_macro_definitions (expr_block, expr_pc, buf);

  /* Do not generate local variable information for "raw"
     compilations.  In this case we aren't emitting our own function
     and the user's code may only refer to globals.  */
  if (inst->scope != COMPILE_I_RAW_SCOPE)
    {
      unsigned char *registers_used;
      int i;

      /* Generate the code to compute variable locations, but do it
	 before generating the function header, so we can define the
	 register struct before the function body.  This requires a
	 temporary stream.  */
      var_stream = mem_fileopen ();
      make_cleanup_ui_file_delete (var_stream);
      registers_used = generate_c_for_variable_locations (context,
							  var_stream, gdbarch,
							  expr_block, expr_pc);
      make_cleanup (xfree, registers_used);

      fputs_unfiltered ("typedef unsigned int"
			" __attribute__ ((__mode__(__pointer__)))"
			" __gdb_uintptr;\n",
			buf);
      fputs_unfiltered ("typedef int"
			" __attribute__ ((__mode__(__pointer__)))"
			" __gdb_intptr;\n",
			buf);

      /* Iterate all log2 sizes in bytes supported by c_get_mode_for_size.  */
      for (i = 0; i < 4; ++i)
	{
	  const char *mode = c_get_mode_for_size (1 << i);

	  gdb_assert (mode != NULL);
	  fprintf_unfiltered (buf,
			      "typedef int"
			      " __attribute__ ((__mode__(__%s__)))"
			      " __gdb_int_%s;\n",
			      mode, mode);
	}

      generate_register_struct (buf, gdbarch, registers_used);
    }

  add_code_header (inst->scope, buf);

  if (inst->scope == COMPILE_I_SIMPLE_SCOPE
      || inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
      || inst->scope == COMPILE_I_PRINT_VALUE_SCOPE)
    {
      ui_file_put (var_stream, ui_file_write_for_put, buf);
      fputs_unfiltered ("#pragma GCC user_expression\n", buf);
    }

  /* The user expression has to be in its own scope, so that "extern"
     works properly.  Otherwise gcc thinks that the "extern"
     declaration is in the same scope as the declaration provided by
     gdb.  */
  if (inst->scope != COMPILE_I_RAW_SCOPE)
    fputs_unfiltered ("{\n", buf);

  fputs_unfiltered ("#line 1 \"gdb command line\"\n", buf);

  switch (inst->scope)
    {
    case COMPILE_I_PRINT_ADDRESS_SCOPE:
    case COMPILE_I_PRINT_VALUE_SCOPE:
      fprintf_unfiltered (buf,
"__auto_type " COMPILE_I_EXPR_VAL " = %s;\n"
"typeof (%s) *" COMPILE_I_EXPR_PTR_TYPE ";\n"
"memcpy (" COMPILE_I_PRINT_OUT_ARG ", %s" COMPILE_I_EXPR_VAL ",\n"
	 "sizeof (*" COMPILE_I_EXPR_PTR_TYPE "));\n"
			  , input, input,
			  (inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
			   ? "&" : ""));
      break;
    default:
      fputs_unfiltered (input, buf);
      break;
    }

  fputs_unfiltered ("\n", buf);

  /* For larger user expressions the automatic semicolons may be
     confusing.  */
  if (strchr (input, '\n') == NULL)
    fputs_unfiltered (";\n", buf);

  if (inst->scope != COMPILE_I_RAW_SCOPE)
    fputs_unfiltered ("}\n", buf);

  add_code_footer (inst->scope, buf);
  code = ui_file_xstrdup (buf, NULL);
  do_cleanups (cleanup);
  return code;
}
示例#22
0
static int
dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
	    struct disassemble_info * di,
	    CORE_ADDR low, CORE_ADDR high,
	    int how_many, int flags, struct ui_file *stb)
{
  int num_displayed = 0;
  CORE_ADDR pc;

  /* parts of the symbolic representation of the address */
  int unmapped;
  int offset;
  int line;
  struct cleanup *ui_out_chain;

  for (pc = low; pc < high;)
    {
      char *filename = NULL;
      char *name = NULL;

      QUIT;
      if (how_many >= 0)
	{
	  if (num_displayed >= how_many)
	    break;
	  else
	    num_displayed++;
	}
      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);

      if ((flags & DISASSEMBLY_OMIT_PC) == 0)
	ui_out_text (uiout, pc_prefix (pc));
      ui_out_field_core_addr (uiout, "address", gdbarch, pc);

      if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
				   &line, &unmapped))
	{
	  /* We don't care now about line, filename and
	     unmapped. But we might in the future.  */
	  ui_out_text (uiout, " <");
	  if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
	    ui_out_field_string (uiout, "func-name", name);
	  ui_out_text (uiout, "+");
	  ui_out_field_int (uiout, "offset", offset);
	  ui_out_text (uiout, ">:\t");
	}
      else
	ui_out_text (uiout, ":\t");

      if (filename != NULL)
	xfree (filename);
      if (name != NULL)
	xfree (name);

      ui_file_rewind (stb);
      if (flags & DISASSEMBLY_RAW_INSN)
        {
          CORE_ADDR old_pc = pc;
          bfd_byte data;
          int status;
          const char *spacer = "";

          /* Build the opcodes using a temporary stream so we can
             write them out in a single go for the MI.  */
          struct ui_file *opcode_stream = mem_fileopen ();
          struct cleanup *cleanups =
            make_cleanup_ui_file_delete (opcode_stream);

          pc += gdbarch_print_insn (gdbarch, pc, di);
          for (;old_pc < pc; old_pc++)
            {
              status = (*di->read_memory_func) (old_pc, &data, 1, di);
              if (status != 0)
                (*di->memory_error_func) (status, old_pc, di);
              fprintf_filtered (opcode_stream, "%s%02x",
                                spacer, (unsigned) data);
              spacer = " ";
            }
          ui_out_field_stream (uiout, "opcodes", opcode_stream);
          ui_out_text (uiout, "\t");

          do_cleanups (cleanups);
        }
      else
        pc += gdbarch_print_insn (gdbarch, pc, di);
      ui_out_field_stream (uiout, "inst", stb);
      ui_file_rewind (stb);
      do_cleanups (ui_out_chain);
      ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
示例#23
0
static int
inspect_type (struct demangle_parse_info *info,
	      struct demangle_component *ret_comp,
	      canonicalization_ftype *finder,
	      void *data)
{
  int i;
  char *name;
  struct symbol *sym;

  /* Copy the symbol's name from RET_COMP and look it up
     in the symbol table.  */
  name = (char *) alloca (ret_comp->u.s_name.len + 1);
  memcpy (name, ret_comp->u.s_name.s, ret_comp->u.s_name.len);
  name[ret_comp->u.s_name.len] = '\0';

  /* Ignore any typedefs that should not be substituted.  */
  for (i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i)
    {
      if (strcmp (name, ignore_typedefs[i]) == 0)
	return 0;
    }

  sym = NULL;

  TRY
    {
      sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      return 0;
    }
  END_CATCH

  if (sym != NULL)
    {
      struct type *otype = SYMBOL_TYPE (sym);

      if (finder != NULL)
	{
	  const char *new_name = (*finder) (otype, data);

	  if (new_name != NULL)
	    {
	      ret_comp->u.s_name.s = new_name;
	      ret_comp->u.s_name.len = strlen (new_name);
	      return 1;
	    }

	  return 0;
	}

      /* If the type is a typedef or namespace alias, replace it.  */
      if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF
	  || TYPE_CODE (otype) == TYPE_CODE_NAMESPACE)
	{
	  long len;
	  int is_anon;
	  struct type *type;
	  struct demangle_parse_info *i;
	  struct ui_file *buf;

	  /* Get the real type of the typedef.  */
	  type = check_typedef (otype);

	  /* If the symbol is a namespace and its type name is no different
	     than the name we looked up, this symbol is not a namespace
	     alias and does not need to be substituted.  */
	  if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE
	      && strcmp (TYPE_NAME (type), name) == 0)
	    return 0;

	  is_anon = (TYPE_TAG_NAME (type) == NULL
		     && (TYPE_CODE (type) == TYPE_CODE_ENUM
			 || TYPE_CODE (type) == TYPE_CODE_STRUCT
			 || TYPE_CODE (type) == TYPE_CODE_UNION));
	  if (is_anon)
	    {
	      struct type *last = otype;

	      /* Find the last typedef for the type.  */
	      while (TYPE_TARGET_TYPE (last) != NULL
		     && (TYPE_CODE (TYPE_TARGET_TYPE (last))
			 == TYPE_CODE_TYPEDEF))
		last = TYPE_TARGET_TYPE (last);

	      /* If there is only one typedef for this anonymous type,
		 do not substitute it.  */
	      if (type == otype)
		return 0;
	      else
		/* Use the last typedef seen as the type for this
		   anonymous type.  */
		type = last;
	    }

	  buf = mem_fileopen ();
	  TRY
	  {
	    type_print (type, "", buf, -1);
	  }

	  /* If type_print threw an exception, there is little point
	     in continuing, so just bow out gracefully.  */
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      ui_file_delete (buf);
	      return 0;
	    }
	  END_CATCH

	  name = ui_file_obsavestring (buf, &info->obstack, &len);
	  ui_file_delete (buf);

	  /* Turn the result into a new tree.  Note that this
	     tree will contain pointers into NAME, so NAME cannot
	     be free'd until all typedef conversion is done and
	     the final result is converted into a string.  */
	  i = cp_demangled_name_to_comp (name, NULL);
	  if (i != NULL)
	    {
	      /* Merge the two trees.  */
	      cp_merge_demangle_parse_infos (info, ret_comp, i);

	      /* Replace any newly introduced typedefs -- but not
		 if the type is anonymous (that would lead to infinite
		 looping).  */
	      if (!is_anon)
		replace_typedefs (info, ret_comp, finder, data);
	    }
	  else
	    {
	      /* This shouldn't happen unless the type printer has
		 output something that the name parser cannot grok.
		 Nonetheless, an ounce of prevention...

		 Canonicalize the name again, and store it in the
		 current node (RET_COMP).  */
	      char *canon = cp_canonicalize_string_no_typedefs (name);

	      if (canon != NULL)
		{
		  /* Copy the canonicalization into the obstack and
		     free CANON.  */
		  name = copy_string_to_obstack (&info->obstack, canon, &len);
		  xfree (canon);
		}

	      ret_comp->u.s_name.s = name;
	      ret_comp->u.s_name.len = len;
	    }

	  return 1;
	}
示例#24
0
文件: py-arch.c 项目: nds32/gdb
static PyObject *
archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
{
    static char *keywords[] = { "start_pc", "end_pc", "count", NULL };
    CORE_ADDR start, end = 0;
    CORE_ADDR pc;
    gdb_py_ulongest start_temp;
    long count = 0, i;
    PyObject *result_list, *end_obj = NULL, *count_obj = NULL;
    struct gdbarch *gdbarch = NULL;

    ARCHPY_REQUIRE_VALID (self, gdbarch);

    if (!PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO", keywords,
                                      &start_temp, &end_obj, &count_obj))
        return NULL;

    start = start_temp;
    if (end_obj)
    {
        if (PyLong_Check (end_obj))
            end = PyLong_AsUnsignedLongLong (end_obj);
        else if (PyInt_Check (end_obj))
            /* If the end_pc value is specified without a trailing 'L', end_obj will
               be an integer and not a long integer.  */
            end = PyInt_AsLong (end_obj);
        else
        {
            Py_DECREF (end_obj);
            Py_XDECREF (count_obj);
            PyErr_SetString (PyExc_TypeError,
                             _("Argument 'end_pc' should be a (long) integer."));

            return NULL;
        }

        if (end < start)
        {
            Py_DECREF (end_obj);
            Py_XDECREF (count_obj);
            PyErr_SetString (PyExc_ValueError,
                             _("Argument 'end_pc' should be greater than or "
                               "equal to the argument 'start_pc'."));

            return NULL;
        }
    }
    if (count_obj)
    {
        count = PyInt_AsLong (count_obj);
        if (PyErr_Occurred () || count < 0)
        {
            Py_DECREF (count_obj);
            Py_XDECREF (end_obj);
            PyErr_SetString (PyExc_TypeError,
                             _("Argument 'count' should be an non-negative "
                               "integer."));

            return NULL;
        }
    }

    result_list = PyList_New (0);
    if (result_list == NULL)
        return NULL;

    for (pc = start, i = 0;
            /* All args are specified.  */
            (end_obj && count_obj && pc <= end && i < count)
            /* end_pc is specified, but no count.  */
            || (end_obj && count_obj == NULL && pc <= end)
            /* end_pc is not specified, but a count is.  */
            || (end_obj == NULL && count_obj && i < count)
            /* Both end_pc and count are not specified.  */
            || (end_obj == NULL && count_obj == NULL && pc == start);)
    {
        int insn_len = 0;
        char *as = NULL;
        struct ui_file *memfile = mem_fileopen ();
        PyObject *insn_dict = PyDict_New ();
        volatile struct gdb_exception except;

        if (insn_dict == NULL)
        {
            Py_DECREF (result_list);
            ui_file_delete (memfile);

            return NULL;
        }
        if (PyList_Append (result_list, insn_dict))
        {
            Py_DECREF (result_list);
            Py_DECREF (insn_dict);
            ui_file_delete (memfile);

            return NULL;  /* PyList_Append Sets the exception.  */
        }

        TRY_CATCH (except, RETURN_MASK_ALL)
        {
            insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
        }
        if (except.reason < 0)
        {
            Py_DECREF (result_list);
            ui_file_delete (memfile);

            gdbpy_convert_exception (except);
            return NULL;
        }

        as = ui_file_xstrdup (memfile, NULL);
        if (PyDict_SetItemString (insn_dict, "addr",
                                  gdb_py_long_from_ulongest (pc))
                || PyDict_SetItemString (insn_dict, "asm",
                                         PyString_FromString (*as ? as : "<unknown>"))
                || PyDict_SetItemString (insn_dict, "length",
                                         PyInt_FromLong (insn_len)))
        {
            Py_DECREF (result_list);

            ui_file_delete (memfile);
            xfree (as);

            return NULL;
        }

        pc += insn_len;
        i++;
        ui_file_delete (memfile);
        xfree (as);
    }