Ejemplo n.º 1
0
/* Evaluate the value of the argument. The argument is an
   expression. If the expression contains spaces it needs to be
   included in double quotes. */
enum mi_cmd_result
mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
{
  struct expression *expr;
  struct cleanup *old_chain = NULL;
  struct value *val;
  struct ui_stream *stb = NULL;

  stb = ui_out_stream_new (uiout);

  if (argc != 1)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression");
      return MI_CMD_ERROR;
    }

  expr = parse_expression (argv[0]);

  old_chain = make_cleanup (free_current_contents, &expr);

  val = evaluate_expression (expr);

  /* Print the result of the expression evaluation. */
  val_print (value_type (val), value_contents (val),
	     value_embedded_offset (val), VALUE_ADDRESS (val),
	     stb->stream, 0, 0, 0, 0);

  ui_out_field_stream (uiout, "value", stb);
  ui_out_stream_delete (stb);

  do_cleanups (old_chain);

  return MI_CMD_DONE;
}
Ejemplo n.º 2
0
static int
dump_insns(struct ui_out *uiout, struct disassemble_info * di,
	   CORE_ADDR low, CORE_ADDR high,
	   int how_many, struct ui_stream *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);
      ui_out_field_core_addr (uiout, "address", pc);

      if (!build_address_symbolic (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, " <");
	  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->stream);
      pc += TARGET_PRINT_INSN (pc, di);
      ui_out_field_stream (uiout, "inst", stb);
      ui_file_rewind (stb->stream);
      do_cleanups (ui_out_chain);
      ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
Ejemplo n.º 3
0
/* Output one register's contents in the desired format. */
static int
get_register (int regnum, int format)
{
  gdb_byte buffer[MAX_REGISTER_SIZE];
  int optim;
  int realnum;
  CORE_ADDR addr;
  enum lval_type lval;
  static struct ui_stream *stb = NULL;

  stb = ui_out_stream_new (uiout);

  if (format == 'N')
    format = 0;

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

  if (optim)
    {
      mi_error_message = xstrprintf ("Optimized out");
      return -1;
    }

  if (format == 'r')
    {
      int j;
      char *ptr, buf[1024];

      strcpy (buf, "0x");
      ptr = buf + 2;
      for (j = 0; j < register_size (current_gdbarch, regnum); j++)
	{
	  int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
	  : register_size (current_gdbarch, regnum) - 1 - j;
	  sprintf (ptr, "%02x", (unsigned char) buffer[idx]);
	  ptr += 2;
	}
      ui_out_field_string (uiout, "value", buf);
      /*fputs_filtered (buf, gdb_stdout); */
    }
  else
    {
      val_print (register_type (current_gdbarch, regnum), buffer, 0, 0,
		 stb->stream, format, 1, 0, Val_pretty_default);
      ui_out_field_stream (uiout, "value", stb);
      ui_out_stream_delete (stb);
    }
  return 1;
}
Ejemplo n.º 4
0
int
gdb_print_insn (CORE_ADDR memaddr, struct ui_file *stream)
{
	struct ui_stream *stb = ui_out_stream_new (uiout);
	struct cleanup *cleanups = make_cleanup_ui_out_stream_delete (stb);
	struct disassemble_info di = gdb_disassemble_info (current_gdbarch, stb->stream);
	//  struct disassemble_info di = gdb_disassemble_info (current_gdbarch, stream);
	struct disassemble_info * di2 = &di;
	struct cleanup *ui_out_chain;
	
	ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	int i;
	CORE_ADDR old_pc = memaddr;
	CORE_ADDR oldmemaddr = memaddr;
	bfd_byte data;
	int status;
	ui_file_rewind (stb->stream);
	memaddr = TARGET_PRINT_INSN (memaddr, &di);
	oldmemaddr += memaddr;
	for (; old_pc < oldmemaddr; old_pc ++)
	{
		status = (*di2->read_memory_func) (old_pc, &data, 1, di2);
		if (status != 0)
			(*di2->memory_error_func) (status, old_pc, di2);
		ui_out_message (uiout, 0, " %02x", (unsigned)data);
	}
	i = memaddr;
	for (; i<10; i++) ui_out_text(uiout, "   ");
	ui_out_text (uiout, " ");
	ui_out_field_stream(uiout, "inst", stb);
	ui_file_rewind (stb->stream);
	do_cleanups (ui_out_chain);
	
	return memaddr;
	//  return TARGET_PRINT_INSN (memaddr, &di);
}
Ejemplo n.º 5
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_stream *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);
      ui_out_field_core_addr (uiout, "address", gdbarch, pc);

      if (!build_address_symbolic (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, " <");
	  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->stream);
      if (flags & DISASSEMBLY_RAW_INSN)
        {
          CORE_ADDR old_pc = pc;
          bfd_byte data;
          int status;
          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);
              ui_out_message (uiout, 0, " %02x", (unsigned)data);
            }
          ui_out_text (uiout, "\t");
        }
      else
        pc += gdbarch_print_insn (gdbarch, pc, di);
      ui_out_field_stream (uiout, "inst", stb);
      ui_file_rewind (stb->stream);
      do_cleanups (ui_out_chain);
      ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
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_stream *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);
      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->stream);
      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_stream *opcode_stream = ui_out_stream_new (uiout);
          struct cleanup *cleanups =
            make_cleanup_ui_out_stream_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->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->stream);
      do_cleanups (ui_out_chain);
      ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
enum mi_cmd_result
mi_cmd_data_read_memory (char *command, char **argv, int argc)
{
  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
  CORE_ADDR addr;
  long total_bytes;
  long nr_cols;
  long nr_rows;
  char word_format;
  struct type *word_type;
  long word_size;
  char word_asize;
  char aschar;
  gdb_byte *mbuf;
  int nr_bytes;
  long offset = 0;
  int optind = 0;
  char *optarg;
  enum opt
    {
      OFFSET_OPT
    };
  static struct mi_opt opts[] =
  {
    {"o", OFFSET_OPT, 1},
    0
  };

  while (1)
    {
      int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts,
			   &optind, &optarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case OFFSET_OPT:
	  offset = atol (optarg);
	  break;
	}
    }
  argv += optind;
  argc -= optind;

  if (argc < 5 || argc > 6)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
      return MI_CMD_ERROR;
    }

  /* Extract all the arguments. */

  /* Start address of the memory dump. */
  addr = parse_and_eval_address (argv[0]) + offset;
  /* The format character to use when displaying a memory word. See
     the ``x'' command. */
  word_format = argv[1][0];
  /* The size of the memory word. */
  word_size = atol (argv[2]);
  switch (word_size)
    {
    case 1:
      word_type = builtin_type_int8;
      word_asize = 'b';
      break;
    case 2:
      word_type = builtin_type_int16;
      word_asize = 'h';
      break;
    case 4:
      word_type = builtin_type_int32;
      word_asize = 'w';
      break;
    case 8:
      word_type = builtin_type_int64;
      word_asize = 'g';
      break;
    default:
      word_type = builtin_type_int8;
      word_asize = 'b';
    }
  /* The number of rows */
  nr_rows = atol (argv[3]);
  if (nr_rows <= 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of rows.");
      return MI_CMD_ERROR;
    }
  /* number of bytes per row. */
  nr_cols = atol (argv[4]);
  if (nr_cols <= 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of columns.");
      return MI_CMD_ERROR;
    }
  /* The un-printable character when printing ascii. */
  if (argc == 6)
    aschar = *argv[5];
  else
    aschar = 0;

  /* create a buffer and read it in. */
  total_bytes = word_size * nr_rows * nr_cols;
  mbuf = xcalloc (total_bytes, 1);
  make_cleanup (xfree, mbuf);

  nr_bytes = target_read (&current_target, TARGET_OBJECT_MEMORY, NULL,
			  mbuf, addr, total_bytes);
  if (nr_bytes <= 0)
    {
      do_cleanups (cleanups);
      mi_error_message = xstrdup ("Unable to read memory.");
      return MI_CMD_ERROR;
    }

  /* output the header information. */
  ui_out_field_core_addr (uiout, "addr", addr);
  ui_out_field_int (uiout, "nr-bytes", nr_bytes);
  ui_out_field_int (uiout, "total-bytes", total_bytes);
  ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols);
  ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols);
  ui_out_field_core_addr (uiout, "next-page", addr + total_bytes);
  ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes);

  /* Build the result as a two dimentional table. */
  {
    struct ui_stream *stream = ui_out_stream_new (uiout);
    struct cleanup *cleanup_list_memory;
    int row;
    int row_byte;
    cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory");
    for (row = 0, row_byte = 0;
	 row < nr_rows;
	 row++, row_byte += nr_cols * word_size)
      {
	int col;
	int col_byte;
	struct cleanup *cleanup_tuple;
	struct cleanup *cleanup_list_data;
	cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	ui_out_field_core_addr (uiout, "addr", addr + row_byte);
	/* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */
	cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
	for (col = 0, col_byte = row_byte;
	     col < nr_cols;
	     col++, col_byte += word_size)
	  {
	    if (col_byte + word_size > nr_bytes)
	      {
		ui_out_field_string (uiout, NULL, "N/A");
	      }
	    else
	      {
		ui_file_rewind (stream->stream);
		print_scalar_formatted (mbuf + col_byte, word_type, word_format,
					word_asize, stream->stream);
		ui_out_field_stream (uiout, NULL, stream);
	      }
	  }
	do_cleanups (cleanup_list_data);
	if (aschar)
	  {
	    int byte;
	    ui_file_rewind (stream->stream);
	    for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++)
	      {
		if (byte >= nr_bytes)
		  {
		    fputc_unfiltered ('X', stream->stream);
		  }
		else if (mbuf[byte] < 32 || mbuf[byte] > 126)
		  {
		    fputc_unfiltered (aschar, stream->stream);
		  }
		else
		  fputc_unfiltered (mbuf[byte], stream->stream);
	      }
	    ui_out_field_stream (uiout, "ascii", stream);
	  }
	do_cleanups (cleanup_tuple);
      }
    ui_out_stream_delete (stream);
    do_cleanups (cleanup_list_memory);
  }
  do_cleanups (cleanups);
  return MI_CMD_DONE;
}
Ejemplo n.º 11
0
/* Output one register's contents in the desired format. */
static int
get_register (int regnum, int format)
{
  char raw_buffer[MAX_REGISTER_SIZE];
  char virtual_buffer[MAX_REGISTER_SIZE];
  int optim;
  int realnum;
  CORE_ADDR addr;
  enum lval_type lval;
  static struct ui_stream *stb = NULL;

  stb = ui_out_stream_new (uiout);

  if (format == 'N')
    format = 0;

  frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr,
		  &realnum, raw_buffer);

  if (optim)
    {
      xasprintf (&mi_error_message, "Optimized out");
      return -1;
    }

  /* Convert raw data to virtual format if necessary.  */

  if (DEPRECATED_REGISTER_CONVERTIBLE_P ()
      && DEPRECATED_REGISTER_CONVERTIBLE (regnum))
    {
      DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum,
				   register_type (current_gdbarch, regnum),
				   raw_buffer, virtual_buffer);
    }
  else
    memcpy (virtual_buffer, raw_buffer, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum));

  if (format == 'r')
    {
      int j;
      char *ptr, buf[1024];

      strcpy (buf, "0x");
      ptr = buf + 2;
      for (j = 0; j < DEPRECATED_REGISTER_RAW_SIZE (regnum); j++)
	{
	  int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
	  : DEPRECATED_REGISTER_RAW_SIZE (regnum) - 1 - j;
	  sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]);
	  ptr += 2;
	}
      ui_out_field_string (uiout, "value", buf);
      /*fputs_filtered (buf, gdb_stdout); */
    }
  else
    {
      val_print (register_type (current_gdbarch, regnum), virtual_buffer, 0, 0,
		 stb->stream, format, 1, 0, Val_pretty_default);
      ui_out_field_stream (uiout, "value", stb);
      ui_out_stream_delete (stb);
    }
  return 1;
}
Ejemplo n.º 12
0
/* Print a list of the locals or the arguments for the currently
   selected frame.  If the argument passed is 0, printonly the names
   of the variables, if an argument of 1 is passed, print the values
   as well. */
static void
list_args_or_locals (int locals, int values, struct frame_info *fi)
{
  struct block *block;
  struct symbol *sym;
  struct dict_iterator iter;
  int nsyms;
  struct cleanup *cleanup_list;
  static struct ui_stream *stb = NULL;
  struct type *type;

  stb = ui_out_stream_new (uiout);

  block = get_frame_block (fi, 0);

  cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");

  while (block != 0)
    {
      ALL_BLOCK_SYMBOLS (block, iter, sym)
	{
          int print_me = 0;

	  switch (SYMBOL_CLASS (sym))
	    {
	    default:
	    case LOC_UNDEF:	/* catches errors        */
	    case LOC_CONST:	/* constant              */
	    case LOC_TYPEDEF:	/* local typedef         */
	    case LOC_LABEL:	/* local label           */
	    case LOC_BLOCK:	/* local function        */
	    case LOC_CONST_BYTES:	/* loc. byte seq.        */
	    case LOC_UNRESOLVED:	/* unresolved static     */
	    case LOC_OPTIMIZED_OUT:	/* optimized out         */
	      print_me = 0;
	      break;

	    case LOC_ARG:	/* argument              */
	    case LOC_REF_ARG:	/* reference arg         */
	    case LOC_REGPARM:	/* register arg          */
	    case LOC_REGPARM_ADDR:	/* indirect register arg */
	    case LOC_LOCAL_ARG:	/* stack arg             */
	    case LOC_BASEREG_ARG:	/* basereg arg           */
	    case LOC_COMPUTED_ARG:	/* arg with computed location */
	      if (!locals)
		print_me = 1;
	      break;

	    case LOC_LOCAL:	/* stack local           */
	    case LOC_BASEREG:	/* basereg local         */
	    case LOC_STATIC:	/* static                */
	    case LOC_REGISTER:	/* register              */
	    case LOC_COMPUTED:	/* computed location     */
	      if (locals)
		print_me = 1;
	      break;
	    }
	  if (print_me)
	    {
	      struct cleanup *cleanup_tuple = NULL;
	      struct symbol *sym2;
	      if (values != PRINT_NO_VALUES)
		cleanup_tuple =
		  make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	      ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));

	      if (!locals)
		sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
				      block, VAR_DOMAIN,
				      (int *) NULL,
				      (struct symtab **) NULL);
	      else
		    sym2 = sym;
	      switch (values)
		{
		case PRINT_SIMPLE_VALUES:
		  type = check_typedef (sym2->type);
		  type_print (sym2->type, "", stb->stream, -1);
		  ui_out_field_stream (uiout, "type", stb);
		  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
		      && TYPE_CODE (type) != TYPE_CODE_STRUCT
		      && TYPE_CODE (type) != TYPE_CODE_UNION)
		    {
		      print_variable_value (sym2, fi, stb->stream);
		      ui_out_field_stream (uiout, "value", stb);
		    }
		  do_cleanups (cleanup_tuple);
		  break;
		case PRINT_ALL_VALUES:
		  print_variable_value (sym2, fi, stb->stream);
		  ui_out_field_stream (uiout, "value", stb);
		  do_cleanups (cleanup_tuple);
		  break;
		}
	    }
	}
      if (BLOCK_FUNCTION (block))
	break;
      else
	block = BLOCK_SUPERBLOCK (block);
    }
Ejemplo n.º 13
0
static int
dump_insns (struct ui_out *uiout, struct disassemble_info * di,
	    CORE_ADDR low, CORE_ADDR high,
	    int how_many, struct ui_stream *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;

  struct cleanup *table_chain;
  struct cleanup *tuple_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);
      ui_out_field_core_addr (uiout, "address", pc);

      if (!build_address_symbolic (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, " <");
	  ui_out_field_string (uiout, "func-name", name);
	  ui_out_text (uiout, "+");
	  ui_out_field_int (uiout, "offset", offset);
	  ui_out_text (uiout, ">: ");
	}
      else
		  ui_out_text (uiout, ": ");
		
      if (filename != NULL)
	xfree (filename);
      if (name != NULL)
	xfree (name);
		
      ui_file_rewind (stb->stream);
	  // dump the disassembly raw bytes - ripped from gnu gdb latest cvs version
	  // fG! - 12/08/2009
	  // save the initial disassembly address
      CORE_ADDR old_pc = pc;
      bfd_byte data;
      int status;
      int i;
		
	  // this will return the disassembled instructions, but it will be buffered into the stream
	  // pc will hold the final address after the disassembly, so we can compute the length of the instruction
	  // the macro returns the number of bytes disassembled
      pc += TARGET_PRINT_INSN (pc, di);
      i = pc - old_pc;
	  // read the bytes from the initial address to the final address
      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);
		// print the raw bytes
        ui_out_message (uiout, 0, " %02x", (unsigned)data);
       }
      // to align the output... gdb tables don't work correctly :(
      for (; i < 10 ; i++) ui_out_text(uiout, "   ");
      ui_out_text(uiout, " ");
	  // now we can finally print the buffered stream
      ui_out_field_stream (uiout, "inst", stb);		
      ui_file_rewind (stb->stream);

	  do_cleanups (ui_out_chain);
	  ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
Ejemplo n.º 14
0
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);
}