Пример #1
0
static int
gdb_regformat (ClientData clientData, Tcl_Interp *interp,
	       int objc, Tcl_Obj **objv)
{
  int fm, regno, numregs;
  struct type *type;

  if (objc != 3)
    {
      Tcl_WrongNumArgs (interp, 0, objv, "gdb_reginfo regno type format");
      return TCL_ERROR;
    }

  if (Tcl_GetIntFromObj (interp, objv[0], &regno) != TCL_OK)
    return TCL_ERROR;

  type = (struct type *)strtol (Tcl_GetStringFromObj (objv[1], NULL), NULL, 16);  
  fm = (int)*(Tcl_GetStringFromObj (objv[2], NULL));

  numregs = (gdbarch_num_regs (get_current_arch ())
	     + gdbarch_num_pseudo_regs (get_current_arch ()));
  if (regno >= numregs)
    {
      gdbtk_set_result (interp, "Register number %d too large", regno);
      return TCL_ERROR;
    }
  
  regformat[regno] = fm;
  regtype[regno] = type;

  return TCL_OK;
}
Пример #2
0
static int
map_arg_registers (Tcl_Interp *interp, int objc, Tcl_Obj **objv,
		   map_func func, map_arg arg)
{
  int regnum, numregs;

  /* Note that the test for a valid register must include checking the
     gdbarch_register_name because gdbarch_num_regs may be allocated for
     the union of the register sets within a family of related processors.
     In this case, some entries of gdbarch_register_name will change
     depending upon the particular processor being debugged.  */

  numregs = (gdbarch_num_regs (get_current_arch ())
	     + gdbarch_num_pseudo_regs (get_current_arch ()));

  if (objc == 0)		/* No args, just do all the regs */
    {
      result_ptr->flags |= GDBTK_MAKES_LIST;
      for (regnum = 0; regnum < numregs; regnum++)
	{
	  if (gdbarch_register_name (get_current_arch (), regnum) == NULL
	      || *(gdbarch_register_name (get_current_arch (), regnum)) == '\0')
	    continue;
	  func (regnum, arg);
	}      
      return TCL_OK;
    }

  if (objc == 1)
    if (Tcl_ListObjGetElements (interp, *objv, &objc, &objv ) != TCL_OK)
      return TCL_ERROR;

  if (objc > 1)
    result_ptr->flags |= GDBTK_MAKES_LIST;

  /* Else, list of register #s, just do listed regs */
  for (; objc > 0; objc--, objv++)
    {
      if (Tcl_GetIntFromObj (NULL, *objv, &regnum) != TCL_OK)
	{
	  result_ptr->flags |= GDBTK_IN_TCL_RESULT;
	  return TCL_ERROR;
	}

      if (regnum >= 0  && regnum < numregs)
	func (regnum, arg);
      else
	{
	  Tcl_SetStringObj (result_ptr->obj_ptr, "bad register number", -1);
	  return TCL_ERROR;
	}
    }
  return TCL_OK;
}
Пример #3
0
enum mi_cmd_result
mi_cmd_data_list_register_names (char *command, char **argv, int argc)
{
  int regnum, numregs;
  int i;
  struct cleanup *cleanup;

  /* Note that the test for a valid register must include checking the
     gdbarch_register_name because gdbarch_num_regs may be allocated for
     the union of the register sets within a family of related processors.
     In this case, some entries of gdbarch_register_name will change depending
     upon the particular processor being debugged.  */

  numregs = gdbarch_num_regs (current_gdbarch)
	    + gdbarch_num_pseudo_regs (current_gdbarch);

  cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names");

  if (argc == 0)		/* No args, just do all the regs.  */
    {
      for (regnum = 0;
	   regnum < numregs;
	   regnum++)
	{
	  if (gdbarch_register_name (current_gdbarch, regnum) == NULL
	      || *(gdbarch_register_name (current_gdbarch, regnum)) == '\0')
	    ui_out_field_string (uiout, NULL, "");
	  else
	    ui_out_field_string (uiout, NULL,
				 gdbarch_register_name
				   (current_gdbarch, regnum));
	}
    }

  /* Else, list of register #s, just do listed regs.  */
  for (i = 0; i < argc; i++)
    {
      regnum = atoi (argv[i]);
      if (regnum < 0 || regnum >= numregs)
	{
	  do_cleanups (cleanup);
	  mi_error_message = xstrprintf ("bad register number");
	  return MI_CMD_ERROR;
	}
      if (gdbarch_register_name (current_gdbarch, regnum) == NULL
	  || *(gdbarch_register_name (current_gdbarch, regnum)) == '\0')
	ui_out_field_string (uiout, NULL, "");
      else
	ui_out_field_string (uiout, NULL,
			     gdbarch_register_name (current_gdbarch, regnum));
    }
  do_cleanups (cleanup);
  return MI_CMD_DONE;
}
Пример #4
0
static void
setup_architecture_data ()
{
  int numregs;

  xfree (old_regs);
  xfree (regformat);
  xfree (regtype);

  numregs = (gdbarch_num_regs (get_current_arch ())
	     + gdbarch_num_pseudo_regs (get_current_arch ()));
  old_regs = xcalloc (1, numregs * MAX_REGISTER_SIZE + 1);
  regformat = (int *)xcalloc (numregs, sizeof(int));
  regtype = (struct type **)xcalloc (numregs, sizeof(struct type **));
}
Пример #5
0
static int
m68k_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
  if (num < 8)
    /* d0..7 */
    return (num - 0) + M68K_D0_REGNUM;
  else if (num < 16)
    /* a0..7 */
    return (num - 8) + M68K_A0_REGNUM;
  else if (num < 24 && gdbarch_tdep (gdbarch)->fpregs_present)
    /* fp0..7 */
    return (num - 16) + M68K_FP0_REGNUM;
  else if (num == 25)
    /* pc */
    return M68K_PC_REGNUM;
  else
    return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
}
Пример #6
0
static int
gdb_reggroup (ClientData clientData, Tcl_Interp *interp,
	      int objc, Tcl_Obj **objv)
{
  struct reggroup *group;
  char *groupname;
  int regnum, num;

  if (objc != 1)
    {
      Tcl_WrongNumArgs (interp, 0, objv, "gdb_reginfo group groupname");
      return TCL_ERROR;
    }
  
  groupname = Tcl_GetStringFromObj (objv[0], NULL);
  if (groupname == NULL)
    {
      gdbtk_set_result (interp, "could not read groupname");
      return TCL_ERROR;
    }

  for (group = reggroup_next (get_current_arch (), NULL);
       group != NULL;
       group = reggroup_next (get_current_arch (), group))
    {
      if (strcmp (groupname, reggroup_name (group)) == 0)
	break;
    }

  if (group == NULL)
    return TCL_ERROR;

  num = (gdbarch_num_regs (get_current_arch ())
	 + gdbarch_num_pseudo_regs (get_current_arch ()));
  for (regnum = 0; regnum < num; regnum++)
    {
      if (gdbarch_register_reggroup_p (get_current_arch (), regnum, group))
	Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (regnum));
    }
  return TCL_OK;
}
Пример #7
0
static enum tui_status
tui_show_register_group (struct reggroup *group,
                         struct frame_info *frame,
                         int refresh_values_only)
{
    struct gdbarch *gdbarch = get_frame_arch (frame);
    enum tui_status ret = TUI_FAILURE;
    int nr_regs;
    int allocated_here = FALSE;
    int regnum, pos;
    char title[80];
    struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;

    /* Make a new title showing which group we display.  */
    snprintf (title, sizeof (title) - 1, "Register group: %s",
    reggroup_name (group));
    xfree (TUI_DATA_WIN->generic.title);
    TUI_DATA_WIN->generic.title = xstrdup (title);

    /* See how many registers must be displayed.  */
    nr_regs = 0;
    for (regnum = 0;
    regnum < gdbarch_num_regs (gdbarch)
    + gdbarch_num_pseudo_regs (gdbarch);
    regnum++)
    {
        const char *name;

        /* Must be in the group.  */
        if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
            continue;

        /* If the register name is empty, it is undefined for this
        processor, so don't display anything.  */
        name = gdbarch_register_name (gdbarch, regnum);
        if (name == 0 || *name == '\0')
            continue;

        nr_regs++;
    }

    if (display_info->regs_content_count > 0 && !refresh_values_only)
    {
        tui_free_data_content (display_info->regs_content,
        display_info->regs_content_count);
        display_info->regs_content_count = 0;
    }

    if (display_info->regs_content_count <= 0)
    {
        display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
        allocated_here = TRUE;
        refresh_values_only = FALSE;
    }

    if (display_info->regs_content != (tui_win_content) NULL)
    {
        if (!refresh_values_only || allocated_here)
        {
            TUI_DATA_WIN->generic.content = (void*) NULL;
            TUI_DATA_WIN->generic.content_size = 0;
            tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
            display_info->regs_content
            = (tui_win_content) TUI_DATA_WIN->generic.content;
            display_info->regs_content_count = nr_regs;
        }

        /* Now set the register names and values.  */
        pos = 0;
        for (regnum = 0;
                regnum < gdbarch_num_regs (gdbarch)
                + gdbarch_num_pseudo_regs (gdbarch);
                regnum++)
        {
            struct tui_gen_win_info *data_item_win;
            struct tui_data_element *data;
            const char *name;

            /* Must be in the group.  */
            if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
                continue;

            /* If the register name is empty, it is undefined for this
               processor, so don't display anything.  */
            name = gdbarch_register_name (gdbarch, regnum);
            if (name == 0 || *name == '\0')
                continue;

            data_item_win =
                &display_info->regs_content[pos]->which_element.data_window;
            data = &((struct tui_win_element *)
                     data_item_win->content[0])->which_element.data;
            if (data)
            {
                if (!refresh_values_only)
                {
                    data->item_no = regnum;
                    data->name = name;
                    data->highlight = FALSE;
                }
                tui_get_register (frame, data, regnum, 0);
            }
            pos++;
        }

        TUI_DATA_WIN->generic.content_size =
            display_info->regs_content_count + display_info->data_content_count;
        ret = TUI_SUCCESS;
    }

    return ret;
}
Пример #8
0
/* Write given values into registers. The registers and values are
   given as pairs.  The corresponding MI command is 
   -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/
enum mi_cmd_result
mi_cmd_data_write_register_values (char *command, char **argv, int argc)
{
  int numregs, i;
  char format;

  /* Note that the test for a valid register must include checking the
     gdbarch_register_name because gdbarch_num_regs may be allocated for
     the union of the register sets within a family of related processors.
     In this case, some entries of gdbarch_register_name will change depending
     upon the particular processor being debugged.  */

  numregs = gdbarch_num_regs (current_gdbarch)
	    + gdbarch_num_pseudo_regs (current_gdbarch);

  if (argc == 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]");
      return MI_CMD_ERROR;
    }

  format = (int) argv[0][0];

  if (!target_has_registers)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No registers.");
      return MI_CMD_ERROR;
    }

  if (!(argc - 1))
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No regs and values specified.");
      return MI_CMD_ERROR;
    }

  if ((argc - 1) % 2)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Regs and vals are not in pairs.");
      return MI_CMD_ERROR;
    }

  for (i = 1; i < argc; i = i + 2)
    {
      int regnum = atoi (argv[i]);

      if (regnum >= 0 && regnum < numregs
	  && gdbarch_register_name (current_gdbarch, regnum)
	  && *gdbarch_register_name (current_gdbarch, regnum))
	{
	  LONGEST value;

	  /* Get the value as a number.  */
	  value = parse_and_eval_address (argv[i + 1]);

	  /* Write it down.  */
	  regcache_cooked_write_signed (get_current_regcache (), regnum, value);
	}
      else
	{
	  mi_error_message = xstrprintf ("bad register number");
	  return MI_CMD_ERROR;
	}
    }
  return MI_CMD_DONE;
}
Пример #9
0
/* Return a list of register number and value pairs.  The valid
   arguments expected are: a letter indicating the format in which to
   display the registers contents.  This can be one of: x (hexadecimal), d
   (decimal), N (natural), t (binary), o (octal), r (raw).  After the
   format argumetn there can be a sequence of numbers, indicating which
   registers to fetch the content of.  If the format is the only argument,
   a list of all the registers with their values is returned.  */
enum mi_cmd_result
mi_cmd_data_list_register_values (char *command, char **argv, int argc)
{
  int regnum, numregs, format, result;
  int i;
  struct cleanup *list_cleanup, *tuple_cleanup;

  /* Note that the test for a valid register must include checking the
     gdbarch_register_name because gdbarch_num_regs may be allocated for
     the union of the register sets within a family of related processors.
     In this case, some entries of gdbarch_register_name will change depending
     upon the particular processor being debugged.  */

  numregs = gdbarch_num_regs (current_gdbarch)
	    + gdbarch_num_pseudo_regs (current_gdbarch);

  if (argc == 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]");
      return MI_CMD_ERROR;
    }

  format = (int) argv[0][0];

  list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");

  if (argc == 1)	    /* No args, beside the format: do all the regs.  */
    {
      for (regnum = 0;
	   regnum < numregs;
	   regnum++)
	{
	  if (gdbarch_register_name (current_gdbarch, regnum) == NULL
	      || *(gdbarch_register_name (current_gdbarch, regnum)) == '\0')
	    continue;
	  tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	  ui_out_field_int (uiout, "number", regnum);
	  result = get_register (regnum, format);
	  if (result == -1)
	    {
	      do_cleanups (list_cleanup);
	      return MI_CMD_ERROR;
	    }
	  do_cleanups (tuple_cleanup);
	}
    }

  /* Else, list of register #s, just do listed regs.  */
  for (i = 1; i < argc; i++)
    {
      regnum = atoi (argv[i]);

      if (regnum >= 0
	  && regnum < numregs
	  && gdbarch_register_name (current_gdbarch, regnum) != NULL
	  && *gdbarch_register_name (current_gdbarch, regnum) != '\000')
	{
	  tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	  ui_out_field_int (uiout, "number", regnum);
	  result = get_register (regnum, format);
	  if (result == -1)
	    {
	      do_cleanups (list_cleanup);
	      return MI_CMD_ERROR;
	    }
	  do_cleanups (tuple_cleanup);
	}
      else
	{
	  do_cleanups (list_cleanup);
	  mi_error_message = xstrprintf ("bad register number");
	  return MI_CMD_ERROR;
	}
    }
  do_cleanups (list_cleanup);
  return MI_CMD_DONE;
}
Пример #10
0
enum mi_cmd_result
mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
{
  static struct regcache *this_regs = NULL;
  struct regcache *prev_regs;
  int regnum, numregs, changed;
  int i;
  struct cleanup *cleanup;

  /* The last time we visited this function, the current frame's register
     contents were saved in THIS_REGS.  Move THIS_REGS over to PREV_REGS,
     and refresh THIS_REGS with the now-current register contents.  */

  prev_regs = this_regs;
  this_regs = frame_save_as_regcache (get_selected_frame (NULL));
  cleanup = make_cleanup_regcache_xfree (prev_regs);

  /* Note that the test for a valid register must include checking the
     gdbarch_register_name because gdbarch_num_regs may be allocated for
     the union of the register sets within a family of related processors.
     In this  case, some entries of gdbarch_register_name will change depending
     upon the particular processor being debugged.  */

  numregs = gdbarch_num_regs (current_gdbarch)
	    + gdbarch_num_pseudo_regs (current_gdbarch);

  make_cleanup_ui_out_list_begin_end (uiout, "changed-registers");

  if (argc == 0)		/* No args, just do all the regs.  */
    {
      for (regnum = 0;
	   regnum < numregs;
	   regnum++)
	{
	  if (gdbarch_register_name (current_gdbarch, regnum) == NULL
	      || *(gdbarch_register_name (current_gdbarch, regnum)) == '\0')
	    continue;
	  changed = register_changed_p (regnum, prev_regs, this_regs);
	  if (changed < 0)
	    {
	      do_cleanups (cleanup);
	      mi_error_message = xstrprintf ("mi_cmd_data_list_changed_registers: Unable to read register contents.");
	      return MI_CMD_ERROR;
	    }
	  else if (changed)
	    ui_out_field_int (uiout, NULL, regnum);
	}
    }

  /* Else, list of register #s, just do listed regs.  */
  for (i = 0; i < argc; i++)
    {
      regnum = atoi (argv[i]);

      if (regnum >= 0
	  && regnum < numregs
	  && gdbarch_register_name (current_gdbarch, regnum) != NULL
	  && *gdbarch_register_name (current_gdbarch, regnum) != '\000')
	{
	  changed = register_changed_p (regnum, prev_regs, this_regs);
	  if (changed < 0)
	    {
	      do_cleanups (cleanup);
	      mi_error_message = xstrprintf ("mi_cmd_data_list_register_change: Unable to read register contents.");
	      return MI_CMD_ERROR;
	    }
	  else if (changed)
	    ui_out_field_int (uiout, NULL, regnum);
	}
      else
	{
	  do_cleanups (cleanup);
	  mi_error_message = xstrprintf ("bad register number");
	  return MI_CMD_ERROR;
	}
    }
  do_cleanups (cleanup);
  return MI_CMD_DONE;
}