/* Function to set the disassembly window's content.
   Disassemble count lines starting at pc.
   Return address of the count'th instruction after pc.  */
static CORE_ADDR
tui_disassemble (struct tui_asm_line* asm_lines, CORE_ADDR pc, int count)
{
  struct ui_file *gdb_dis_out;

  /* now init the ui_file structure */
  gdb_dis_out = tui_sfileopen (256);

  /* Now construct each line */
  for (; count > 0; count--, asm_lines++)
    {
      if (asm_lines->addr_string)
        xfree (asm_lines->addr_string);
      if (asm_lines->insn)
        xfree (asm_lines->insn);
      
      print_address (pc, gdb_dis_out);
      asm_lines->addr = pc;
      asm_lines->addr_string = xstrdup (tui_file_get_strbuf (gdb_dis_out));

      ui_file_rewind (gdb_dis_out);

      pc = pc + gdb_print_insn (pc, gdb_dis_out);

      asm_lines->insn = xstrdup (tui_file_get_strbuf (gdb_dis_out));

      /* reset the buffer to empty */
      ui_file_rewind (gdb_dis_out);
    }
  ui_file_delete (gdb_dis_out);
  return pc;
}
示例#2
0
/* Function to set the disassembly window's content.
   Disassemble count lines starting at pc.
   Return address of the count'th instruction after pc.  */
static CORE_ADDR
tui_disassemble (struct gdbarch *gdbarch, struct tui_asm_line *asm_lines,
		 CORE_ADDR pc, int count)
{
  string_file gdb_dis_out;

  /* Now construct each line.  */
  for (; count > 0; count--, asm_lines++)
    {
      if (asm_lines->addr_string)
        xfree (asm_lines->addr_string);
      if (asm_lines->insn)
        xfree (asm_lines->insn);
      
      print_address (gdbarch, pc, &gdb_dis_out);
      asm_lines->addr = pc;
      asm_lines->addr_string = xstrdup (gdb_dis_out.c_str ());

      gdb_dis_out.clear ();

      pc = pc + gdb_print_insn (gdbarch, pc, &gdb_dis_out, NULL);

      asm_lines->insn = xstrdup (gdb_dis_out.c_str ());

      /* Reset the buffer to empty.  */
      gdb_dis_out.clear ();
    }
  return pc;
}
示例#3
0
int
gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  static struct ui_file *null_stream = NULL;

  /* Dummy file descriptor for the disassembler.  */
  if (!null_stream)
    {
      null_stream = ui_file_new ();
      make_final_cleanup (do_ui_file_delete, null_stream);
    }

  return gdb_print_insn (gdbarch, addr, null_stream, NULL);
}
示例#4
0
文件: py-arch.c 项目: ibuclaw/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 *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)
    {
      /* Make a long logic check first.  In Python 3.x, internally,
	 all integers are represented as longs.  In Python 2.x, there
	 is still a differentiation internally between a PyInt and a
	 PyLong.  Explicitly do this long check conversion first. In
	 GDB, for Python 3.x, we #ifdef PyInt = PyLong.  This check has
	 to be done first to ensure we do not lose information in the
	 conversion process.  */
      if (PyLong_Check (end_obj))
        end = PyLong_AsUnsignedLongLong (end_obj);
#if PY_MAJOR_VERSION == 2
      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);
#endif
      else
        {
          PyErr_SetString (PyExc_TypeError,
                           _("Argument 'end_pc' should be a (long) integer."));

          return NULL;
        }

      if (end < start)
        {
          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)
        {
          PyErr_SetString (PyExc_TypeError,
                           _("Argument 'count' should be an non-negative "
                             "integer."));

          return NULL;
        }
    }

  gdbpy_ref<> 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;
      gdbpy_ref<> insn_dict (PyDict_New ());

      if (insn_dict == NULL)
	return NULL;
      if (PyList_Append (result_list.get (), insn_dict.get ()))
	return NULL;  /* PyList_Append Sets the exception.  */

      string_file stb;

      TRY
        {
          insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL);
        }
      CATCH (except, RETURN_MASK_ALL)
        {
	  gdbpy_convert_exception (except);
	  return NULL;
        }
      END_CATCH

      if (PyDict_SetItemString (insn_dict.get (), "addr",
                                gdb_py_long_from_ulongest (pc))
          || PyDict_SetItemString (insn_dict.get (), "asm",
                                   PyString_FromString (!stb.empty ()
							? stb.c_str ()
							: "<unknown>"))
          || PyDict_SetItemString (insn_dict.get (), "length",
                                   PyInt_FromLong (insn_len)))
	return NULL;

      pc += insn_len;
      i++;
    }
示例#5
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);
    }
示例#6
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);
    }