Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: jeffm@suse.com
To: gdb-patches@sourceware.org
Cc: Jeff Mahoney <jeffm@suse.com>
Subject: [PATCH 6/7] py-minsymbol: Add interface to access minimal_symbols
Date: Thu, 04 Feb 2016 17:29:00 -0000	[thread overview]
Message-ID: <1454606973-31017-7-git-send-email-jeffm@suse.com> (raw)
In-Reply-To: <1454606973-31017-1-git-send-email-jeffm@suse.com>

From: Jeff Mahoney <jeffm@suse.com>

This patch adds a new gdb.MinSymbol object to export the minimal_symbol
interface.  These objects can be resolved using a new
gdb.lookup_minimal_symbol call.
---
 gdb/Makefile.in              |   6 +
 gdb/python/py-minsymbol.c    | 390 +++++++++++++++++++++++++++++++++++++++++++
 gdb/python/python-internal.h |   6 +
 gdb/python/python.c          |   5 +
 4 files changed, 407 insertions(+)
 create mode 100644 gdb/python/py-minsymbol.c

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3eadbbc..c2f7eef 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -400,6 +400,7 @@ SUBDIR_PYTHON_OBS = \
 	py-infthread.o \
 	py-lazy-string.o \
 	py-linetable.o \
+	py-minsymbol.o \
 	py-newobjfileevent.o \
 	py-objfile.o \
 	py-param.o \
@@ -440,6 +441,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-infthread.c \
 	python/py-lazy-string.c \
 	python/py-linetable.c \
+	python/py-minsymbol.c \
 	python/py-newobjfileevent.c \
 	python/py-objfile.c \
 	python/py-param.c \
@@ -2635,6 +2637,10 @@ py-linetable.o: $(srcdir)/python/py-linetable.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-linetable.c
 	$(POSTCOMPILE)
 
+py-minsymbol.o: $(srcdir)/python/py-minsymbol.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-minsymbol.c
+	$(POSTCOMPILE)
+
 py-newobjfileevent.o: $(srcdir)/python/py-newobjfileevent.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-newobjfileevent.c
 	$(POSTCOMPILE)
diff --git a/gdb/python/py-minsymbol.c b/gdb/python/py-minsymbol.c
new file mode 100644
index 0000000..d8b56bc
--- /dev/null
+++ b/gdb/python/py-minsymbol.c
@@ -0,0 +1,390 @@
+/* Python interface to minsymbols.
+
+   Copyright (C) 2008-2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "defs.h"
+#include "block.h"
+#include "exceptions.h"
+#include "frame.h"
+#include "symtab.h"
+#include "python-internal.h"
+#include "objfiles.h"
+#include "value.h"
+
+typedef struct msympy_symbol_object {
+  PyObject_HEAD
+  /* The GDB minimal_symbol structure this object is wrapping.  */
+  struct minimal_symbol *minsym;
+  struct objfile *objfile;
+
+  struct type *type;
+  /* A symbol object is associated with an objfile, so keep track with
+     doubly-linked list, rooted in the objfile.  This lets us
+     invalidate the underlying struct minimal_symbol when the objfile is
+     deleted.  */
+  struct msympy_symbol_object *prev;
+  struct msympy_symbol_object *next;
+} minsym_object;
+
+/* Return the symbol that is wrapped by this symbol object.  */
+static struct minimal_symbol *
+minsym_object_to_minsym (PyObject *obj)
+{
+  if (! PyObject_TypeCheck (obj, &minsym_object_type))
+    return NULL;
+  return ((minsym_object *) obj)->minsym;
+}
+
+static struct objfile *
+minsym_object_to_objfile (PyObject *obj)
+{
+  if (! PyObject_TypeCheck (obj, &minsym_object_type))
+    return NULL;
+  return ((minsym_object *) obj)->objfile;
+}
+
+/* Require a valid symbol.  All access to minsym_object->symbol should be
+   gated by this call.  */
+#define MSYMPY_REQUIRE_VALID(minsym_obj, minsym)	\
+  do {							\
+    minsym = minsym_object_to_minsym (minsym_obj);	\
+    if (minsym == NULL)				\
+      {							\
+	PyErr_SetString (PyExc_RuntimeError,		\
+			 _("MinSymbol is invalid."));	\
+	return NULL;					\
+      }							\
+  } while (0)
+
+#define MSYMPY_REQUIRE_VALID_BOUND(minsym_obj, minsym, objfile)	\
+  do {								\
+    minsym = minsym_object_to_minsym (minsym_obj);		\
+    objfile = minsym_object_to_objfile (minsym_obj);		\
+    if (minsym == NULL || objfile == NULL)			\
+      {								\
+	PyErr_SetString (PyExc_RuntimeError,			\
+			 _("MinSymbol is invalid."));		\
+	return NULL;						\
+      }								\
+  } while (0)
+
+static PyObject *
+msympy_str (PyObject *self)
+{
+  PyObject *result;
+  struct minimal_symbol *minsym = NULL;
+
+  MSYMPY_REQUIRE_VALID (self, minsym);
+
+  result = PyString_FromString (MSYMBOL_PRINT_NAME (minsym));
+
+  return result;
+}
+
+static PyObject *
+msympy_get_name (PyObject *self, void *closure)
+{
+  struct minimal_symbol *minsym = NULL;
+
+  MSYMPY_REQUIRE_VALID (self, minsym);
+
+  return PyString_FromString (MSYMBOL_NATURAL_NAME (minsym));
+}
+
+static PyObject *
+msympy_get_file_name (PyObject *self, void *closure)
+{
+  struct minimal_symbol *minsym = NULL;
+
+  MSYMPY_REQUIRE_VALID (self, minsym);
+
+  return PyString_FromString (minsym->filename);
+}
+
+static PyObject *
+msympy_get_linkage_name (PyObject *self, void *closure)
+{
+  struct minimal_symbol *minsym = NULL;
+
+  MSYMPY_REQUIRE_VALID (self, minsym);
+
+  return PyString_FromString (MSYMBOL_LINKAGE_NAME (minsym));
+}
+
+static PyObject *
+msympy_get_print_name (PyObject *self, void *closure)
+{
+  struct minimal_symbol *minsym = NULL;
+
+  MSYMPY_REQUIRE_VALID (self, minsym);
+
+  return msympy_str (self);
+}
+
+static PyObject *
+msympy_get_section (PyObject *self, void *closure)
+{
+  struct minimal_symbol *minsym = NULL;
+  struct objfile *objfile = NULL;
+  struct obj_section *section;
+  const char *name;
+
+  MSYMPY_REQUIRE_VALID_BOUND (self, minsym, objfile);
+
+  section = MSYMBOL_OBJ_SECTION (objfile, minsym);
+  if (section) {
+    name = bfd_section_name (objfile->obfd, section->the_bfd_section);
+    if (name)
+      return PyString_FromString (name);
+  }
+
+  Py_RETURN_NONE;
+
+}
+
+static PyObject *
+msympy_is_valid (PyObject *self, PyObject *args)
+{
+  struct minimal_symbol *minsym = NULL;
+
+  minsym = minsym_object_to_minsym (self);
+  if (minsym == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.MinSymbol.value (self) -> gdb.Value.  Returns
+   the value of the symbol, or an error in various circumstances.  */
+
+static PyObject *
+msympy_value (PyObject *self, PyObject *args)
+{
+  minsym_object *minsym_obj = (minsym_object *)self;
+  struct minimal_symbol *minsym = NULL;
+  struct value *value = NULL;
+
+  if (!PyArg_ParseTuple (args, ""))
+    return NULL;
+
+  MSYMPY_REQUIRE_VALID (self, minsym);
+  TRY
+    {
+      value = value_from_ulongest(minsym_obj->type,
+				  MSYMBOL_VALUE_RAW_ADDRESS(minsym));
+      if (value)
+	set_value_address(value, MSYMBOL_VALUE_RAW_ADDRESS(minsym));
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  return value_to_value_object (value);
+}
+
+/* Given a symbol, and a minsym_object that has previously been
+   allocated and initialized, populate the minsym_object with the
+   struct minimal_symbol data.  Also, register the minsym_object life-cycle
+   with the life-cycle of the object file associated with this
+   symbol, if needed.  */
+static void
+set_symbol (minsym_object *obj, struct bound_minimal_symbol *bound)
+{
+  obj->minsym = bound->minsym;
+  obj->objfile = bound->objfile;
+  switch (obj->minsym->type) {
+  case mst_text:
+  case mst_solib_trampoline:
+  case mst_file_text:
+  case mst_text_gnu_ifunc:
+  case mst_slot_got_plt:
+    obj->type = builtin_type(python_gdbarch)->builtin_func_ptr;
+    break;
+
+  case mst_data:
+  case mst_abs:
+  case mst_bss:
+  case mst_file_data:
+  case mst_file_bss:
+    obj->type = builtin_type(python_gdbarch)->builtin_data_ptr;
+    break;
+
+  case mst_unknown:
+  default:
+    obj->type = builtin_type(python_gdbarch)->builtin_void;
+    break;
+  }
+
+  obj->prev = NULL;
+  obj->next = NULL;
+}
+
+static PyObject *
+bound_minsym_to_minsym_object (struct bound_minimal_symbol *bound)
+{
+  minsym_object *msym_obj;
+
+  msym_obj = PyObject_New (minsym_object, &minsym_object_type);
+  if (msym_obj)
+    set_symbol (msym_obj, bound);
+
+  return (PyObject *) msym_obj;
+}
+
+static void
+msympy_dealloc (PyObject *obj)
+{
+  minsym_object *msym_obj = (minsym_object *) obj;
+
+  if (msym_obj->prev)
+    msym_obj->prev->next = msym_obj->next;
+  if (msym_obj->next)
+    msym_obj->next->prev = msym_obj->prev;
+  msym_obj->minsym = NULL;
+  msym_obj->objfile = NULL;
+}
+
+/* Implementation of
+   gdb.lookup_minimal_symbol (name) -> symbol or None.  */
+
+PyObject *
+gdbpy_lookup_minimal_symbol (PyObject *self, PyObject *args, PyObject *kw)
+{
+  int domain = VAR_DOMAIN;
+  const char *name;
+  static char *keywords[] = { "name", NULL };
+  struct bound_minimal_symbol bound_minsym = {};
+  struct minimal_symbol *minsym = NULL;
+  PyObject *msym_obj = NULL;
+
+  if (!PyArg_ParseTupleAndKeywords (args, kw, "s|", keywords, &name))
+    return NULL;
+
+  TRY
+    {
+      bound_minsym = lookup_minimal_symbol (name, NULL, NULL);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  if (bound_minsym.minsym)
+      msym_obj = bound_minsym_to_minsym_object (&bound_minsym);
+
+  if (msym_obj)
+    return msym_obj;
+
+  Py_RETURN_NONE;
+}
+
+int
+gdbpy_initialize_minsymbols (void)
+{
+  if (PyType_Ready (&minsym_object_type) < 0)
+    return -1;
+
+  if (PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_UNKNOWN",
+			       mst_unknown) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_TEXT", mst_text) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_TEXT_GNU_IFUNC",
+			      mst_text_gnu_ifunc) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_SLOT_GOT_PLT",
+			      mst_slot_got_plt) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_DATA", mst_data) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_BSS", mst_bss) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_ABS", mst_abs) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_SOLIB_TRAMPOLINE",
+			      mst_solib_trampoline) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_FILE_TEXT",
+			      mst_file_text) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_FILE_DATA",
+			      mst_file_data) < 0
+  || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_FILE_BSS",
+			      mst_file_bss) < 0)
+    return -1;
+
+  return gdb_pymodule_addobject (gdb_module, "MinSymbol",
+				 (PyObject *) &minsym_object_type);
+}
+
+\f
+
+static PyGetSetDef minsym_object_getset[] = {
+  { "name", msympy_get_name, NULL,
+    "Name of the symbol, as it appears in the source code.", NULL },
+  { "linkage_name", msympy_get_linkage_name, NULL,
+    "Name of the symbol, as used by the linker (i.e., may be mangled).",
+    NULL },
+  { "filename", msympy_get_file_name, NULL,
+    "Name of source file that contains this symbol. Only applies for mst_file_*.",
+    NULL },
+  { "print_name", msympy_get_print_name, NULL,
+    "Name of the symbol in a form suitable for output.\n\
+This is either name or linkage_name, depending on whether the user asked GDB\n\
+to display demangled or mangled names.", NULL },
+  { "section", msympy_get_section, NULL,
+    "Section that contains this symbol, if any", NULL, },
+  { NULL }  /* Sentinel */
+};
+
+static PyMethodDef minsym_object_methods[] = {
+  { "is_valid", msympy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this symbol is valid, false if not." },
+  { "value", msympy_value, METH_VARARGS,
+    "value ([frame]) -> gdb.Value\n\
+Return the value of the symbol." },
+  {NULL}  /* Sentinel */
+};
+
+PyTypeObject minsym_object_type = {
+  PyVarObject_HEAD_INIT (NULL, 0)
+  "gdb.MinSymbol",		  /*tp_name*/
+  sizeof (minsym_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  msympy_dealloc,		  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  msympy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB minimal symbol object",	  /*tp_doc */
+  0,				  /*tp_traverse */
+  0,				  /*tp_clear */
+  0,				  /*tp_richcompare */
+  0,				  /*tp_weaklistoffset */
+  0,				  /*tp_iter */
+  0,				  /*tp_iternext */
+  minsym_object_methods,	  /*tp_methods */
+  0,				  /*tp_members */
+  minsym_object_getset		  /*tp_getset */
+};
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index ee949b7..2fae31d 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -241,6 +241,8 @@ extern PyTypeObject block_object_type
     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF("block_object");
 extern PyTypeObject symbol_object_type
     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symbol_object");
+extern PyTypeObject minsym_object_type;
+     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("minsym_object");
 extern PyTypeObject event_object_type
     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
 extern PyTypeObject stop_event_object_type
@@ -362,6 +364,8 @@ PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
 PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw);
 PyObject *gdbpy_lookup_global_symbol (PyObject *self, PyObject *args,
 				      PyObject *kw);
+PyObject *gdbpy_lookup_minimal_symbol (PyObject *self, PyObject *args,
+				       PyObject *kw);
 PyObject *gdbpy_newest_frame (PyObject *self, PyObject *args);
 PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
 PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args);
@@ -436,6 +440,8 @@ int gdbpy_initialize_commands (void)
   CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
 int gdbpy_initialize_symbols (void)
   CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
+int gdbpy_initialize_minsymbols (void)
+  CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
 int gdbpy_initialize_symtabs (void)
   CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
 int gdbpy_initialize_blocks (void)
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 6cbe5f0..30a86e1 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1800,6 +1800,7 @@ message == an error message without a stack will be printed."),
       || gdbpy_initialize_frames () < 0
       || gdbpy_initialize_commands () < 0
       || gdbpy_initialize_symbols () < 0
+      || gdbpy_initialize_minsymbols () < 0
       || gdbpy_initialize_symtabs () < 0
       || gdbpy_initialize_blocks () < 0
       || gdbpy_initialize_functions () < 0
@@ -2025,6 +2026,10 @@ a boolean indicating if name is a field of the current implied argument\n\
     METH_VARARGS | METH_KEYWORDS,
     "lookup_global_symbol (name [, domain]) -> symbol\n\
 Return the symbol corresponding to the given name (or None)." },
+{ "lookup_minimal_symbol", (PyCFunction) gdbpy_lookup_minimal_symbol,
+    METH_VARARGS | METH_KEYWORDS,
+    "lookup_minimal_symbol (name) -> minsym\n\
+Return the symbol corresponding to the given name (or None)." },
 
   { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile,
     METH_VARARGS | METH_KEYWORDS,
-- 
2.1.4


  parent reply	other threads:[~2016-02-04 17:29 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-04 17:29 [PATCH 0/7] Python extension patchset jeffm
2016-02-04 17:29 ` [PATCH 7/7] py-regcache: Add interface to regcache jeffm
2016-02-04 17:29 ` jeffm [this message]
2016-02-05 12:25   ` [PATCH 6/7] py-minsymbol: Add interface to access minimal_symbols Phil Muldoon
2016-02-05 16:43   ` Phil Muldoon
2016-02-08 15:51     ` Jeff Mahoney
2016-02-04 17:29 ` [PATCH 3/7] py-symbol: use Py_RETURN_NONE instead of open coding it jeffm
2016-02-04 17:29 ` [PATCH 1/7] check_types_equal: short circuit check if identical pointers are used jeffm
2016-02-04 17:29 ` [PATCH 4/7] py-symbol: Require a frame for lookup_symbol only when necessary jeffm
2016-02-05 12:17   ` Phil Muldoon
2016-02-05 16:08     ` Jeff Mahoney
2016-02-05 16:35   ` Phil Muldoon
2016-02-04 17:43 ` [PATCH 5/7] py-symbol: export section name jeffm
2016-02-05 12:18   ` Phil Muldoon
2016-02-04 17:43 ` [PATCH 2/7] py-value: properly handle unsigned and pointer types jeffm
2016-02-05 12:12   ` Phil Muldoon
2016-02-05 12:29     ` Phil Muldoon

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=1454606973-31017-7-git-send-email-jeffm@suse.com \
    --to=jeffm@suse.com \
    --cc=gdb-patches@sourceware.org \
    /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