Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Siva Chandra <sivachandra@google.com>
To: gdb-patches <gdb-patches@sourceware.org>
Cc: Tom Tromey <tromey@redhat.com>, Eli Zaretskii <eliz@gnu.org>
Subject: Re: [RFC - Python Scripting] New method gdb.Architecture.disassemble
Date: Wed, 13 Feb 2013 19:50:00 -0000	[thread overview]
Message-ID: <CAGyQ6gwSnFH3OKHSpNxVmVxRRRM61c=T=euhJg6hyFL7+88ecg@mail.gmail.com> (raw)
In-Reply-To: <87r4kkks5g.fsf@fleche.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 783 bytes --]

Addressed all off Eli's and Tom's comments in the attached patch.

Thanks a lot Tom, for your detailed explanations.

2013-02-13  Siva Chandra Reddy  <sivachandra@google.com>

        Add a new method 'disassemble' to gdb.Architecture class.
        * python/py-arch.c (archpy_disassmble): Implementation of the
        new method gdb.Architecture.disassemble.
        (arch_object_methods): Add entry for the new method.

doc/

        * gdb.texinfo (Architectures In Python): Add description about
        the new method gdb.Architecture.disassemble.

testsuite/

        * gdb.python/py-arch.c: New test case
        * gdb.python/py-arch.exp: New tests to test
        gdb.Architecture.disassemble
        * gdb.python/Makefile.in: Add py-arch to the list of
        EXECUTABLES.

[-- Attachment #2: arch_disassemble_patch_v5.txt --]
[-- Type: text/plain, Size: 8991 bytes --]

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e3f336e..8436781 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -26040,6 +26040,37 @@ A @code{gdb.Architecture} class has the following methods:
 Return the name (string value) of the architecture.
 @end defun
 
+@defun Architecture.disassemble (@var{low}, @var{high})
+Return a list of disassembled instructions whose start address falls in
+the closed memory address interval from @var{low} to @var{high}.  Each
+element of the list is a Python @code{dict} with the following string
+keys:
+
+@table @code
+
+@item addr
+The value corresponding to this key is a Python long integer capturing
+the memory address of the instruction.
+
+@item asm
+The value corresponding to this key is a string value which represents
+the instruction with assembly language mnemonics.
+
+@item func
+The value corresponding to this key is the name of the function (string
+value) the instruction belongs to.
+
+@item length
+The value correspoding to this key is the length (integer value) of the
+instruction in bytes.
+
+@item offset
+The value corresponding to this key is the byte offset (integer value)
+of the instruction within the function it belongs to.
+
+@end table
+@end defun
+
 @node Python Auto-loading
 @subsection Python Auto-loading
 @cindex Python auto-loading
diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
index edd508f..1da7b67 100644
--- a/gdb/python/py-arch.c
+++ b/gdb/python/py-arch.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "gdbarch.h"
 #include "arch-utils.h"
+#include "disasm.h"
 #include "python-internal.h"
 
 typedef struct arch_object_type_object {
@@ -86,6 +87,102 @@ archpy_name (PyObject *self, PyObject *args)
   return py_name;
 }
 
+/* Implementation of gdb.Architecture.disassemble (self, low, high) -> List.
+   Returns a list of instructions in a memory address range.  Each instruction
+   in the list is a Python dict object.
+*/
+
+static PyObject *
+archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
+{
+  static char *keywords[] = { "low", "high", NULL };
+  CORE_ADDR low, high;
+  CORE_ADDR pc;
+  PyObject *result_list;
+  struct gdbarch *gdbarch = arch_object_to_gdbarch (self);
+
+  if (!PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG GDB_PY_LLU_ARG,
+                                    keywords, &low, &high))
+    return NULL;
+
+  result_list = PyList_New (0);
+  if (result_list == NULL)
+    return NULL;
+
+  for (pc = low; pc <= high;)
+    {
+      int line = -1, unmapped, offset = -1, insn_len = 0;
+      char *filename = NULL, *fn = NULL, *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);
+          /* Even though filename, line and unmapped are passed as arguments,
+             they do not give us any meaningful values currently.  */
+          build_address_symbolic (gdbarch, pc, 0, &fn, &offset, &filename,
+                                  &line, &unmapped);
+        }
+      if (except.reason < 0)
+        {
+          Py_DECREF (result_list);
+          ui_file_delete (memfile);
+          xfree (fn);
+          xfree (filename);
+
+          return gdbpy_convert_exception (except);
+        }
+
+      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, "func",
+                                   PyString_FromString (fn ? fn : "<unknown>"))
+          || PyDict_SetItemString (insn_dict, "length",
+                                   PyInt_FromLong (insn_len))
+          || PyDict_SetItemString (insn_dict, "offset",
+                                   PyInt_FromLong (offset)))
+        {
+          Py_DECREF (result_list);
+
+          ui_file_delete (memfile);
+          xfree (as);
+          xfree (fn);
+          xfree (filename);
+
+          return NULL;
+        }
+
+      pc += insn_len;
+      ui_file_delete (memfile);
+      xfree (as);
+      xfree (fn);
+      xfree (filename);
+    }
+
+  return result_list;
+}
+
 /* Initializes the Architecture class in the gdb module.  */
 
 void
@@ -105,6 +202,10 @@ static PyMethodDef arch_object_methods [] = {
   { "name", archpy_name, METH_NOARGS,
     "name () -> String.\n\
 Return the name of the architecture as a string value." },
+  { "disassemble", (PyCFunction) archpy_disassemble,
+    METH_VARARGS | METH_KEYWORDS,
+    "disassemble (low, high) -> List.\n\
+Return the list of disassembled instructions from LOW to HIGH." },
   {NULL}  /* Sentinel */
 };
 
diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in
index 4e286b5..0b81507 100644
--- a/gdb/testsuite/gdb.python/Makefile.in
+++ b/gdb/testsuite/gdb.python/Makefile.in
@@ -6,7 +6,7 @@ EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
 	py-shared python lib-types py-events py-evthreads py-frame \
 	py-mi py-pp-maint py-progspace py-section-script py-objfile \
 	py-finish-breakpoint py-finish-breakpoint2 py-value-cc py-explore \
-	py-explore-cc
+	py-explore-cc py-arch
 
 MISCELLANEOUS = py-shared-sl.sl py-events-shlib.so py-events-shlib-nodebug.so 
 
diff --git a/gdb/testsuite/gdb.python/py-arch.c b/gdb/testsuite/gdb.python/py-arch.c
new file mode 100644
index 0000000..e2fe55c
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-arch.c
@@ -0,0 +1,23 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see  <http://www.gnu.org/licenses/>.
+*/
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.python/py-arch.exp b/gdb/testsuite/gdb.python/py-arch.exp
new file mode 100644
index 0000000..25b8b11
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-arch.exp
@@ -0,0 +1,47 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if ![runto_main] {
+   return -1
+}
+
+gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "get frame" 0
+gdb_py_test_silent_cmd "python arch = frame.architecture()" "get arch" 0
+gdb_py_test_silent_cmd "python pc = frame.pc()" "get pc" 0
+gdb_py_test_silent_cmd "python insn_list = arch.disassemble(pc, pc)" \
+  "disassemble" 0
+
+gdb_test "python print len(insn_list)" "1" "test number of instructions"
+
+gdb_py_test_silent_cmd "python insn = insn_list\[0\]" "get instruction" 0
+
+gdb_test "python print \"addr\" in insn" "True" "test key addr"
+gdb_test "python print \"asm\" in insn" "True" "test key asm"
+gdb_test "python print \"func\" in insn" "True" "test key func"
+gdb_test "python print \"length\" in insn" "True" "test key length"
+gdb_test "python print \"offset\" in insn" "True" "test key offset"
+
+# Negative test
+gdb_test "python arch.disassemble(0, 0)" ".*gdb\.MemoryError.*" \
+  "test exception"

  reply	other threads:[~2013-02-13 19:50 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-04 14:09 Siva Chandra
2013-02-05 23:28 ` Doug Evans
2013-02-06  1:53   ` Siva Chandra
2013-02-06 20:00     ` Tom Tromey
2013-02-08 18:05     ` Doug Evans
2013-02-09 17:55       ` Matt Rice
2013-02-12 14:56       ` Siva Chandra
2013-02-12 21:18         ` Tom Tromey
2013-02-13 14:37           ` Siva Chandra
2013-02-13 17:52             ` Eli Zaretskii
2013-02-13 18:03             ` Tom Tromey
2013-02-13 19:50               ` Siva Chandra [this message]
2013-02-13 20:42                 ` Doug Evans
2013-02-14 22:46                   ` Siva Chandra
2013-02-15  6:43                     ` Doug Evans
2013-02-15 17:32                       ` Doug Evans
2013-02-15 17:40                         ` Siva Chandra
2013-02-15 17:41                           ` Siva Chandra
2013-02-15 18:57                           ` Doug Evans
2013-02-15 20:36                       ` Siva Chandra
2013-02-15 21:01                         ` Siva Chandra
2013-02-16  5:30                           ` Doug Evans
2013-02-16  8:47                           ` Eli Zaretskii
2013-02-19  5:36                             ` Siva Chandra
2013-02-19 15:51                               ` Paul_Koning
2013-02-19 16:35                                 ` Eli Zaretskii
2013-02-19 16:38                               ` Eli Zaretskii
2013-02-20 12:34                                 ` Siva Chandra
2013-02-20 18:44                                   ` Eli Zaretskii
2013-02-21  1:49                                     ` Siva Chandra
2013-02-06 19:58 ` Tom Tromey
2013-02-06 20:31   ` Phil Muldoon
2013-02-06 22:31   ` Matt Rice
2013-02-06 23:19     ` Siva Chandra
2013-02-07  1:11       ` Siva Chandra
2013-02-07 23:03         ` Matt Rice
     [not found]       ` <20130206235707.GA2353@klara.mpi.htwm.de>
2013-02-07  1:18         ` Siva Chandra
2013-02-07 14:14   ` Siva Chandra
2013-02-07 16:42     ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAGyQ6gwSnFH3OKHSpNxVmVxRRRM61c=T=euhJg6hyFL7+88ecg@mail.gmail.com' \
    --to=sivachandra@google.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox