This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/4] Add Jeff Mahoney's py-crash patches.


---
 gdb/Makefile.in              |  12 ++
 gdb/python/py-minsymbol.c    | 353 +++++++++++++++++++++++++++++++++++++
 gdb/python/py-objfile.c      |  29 +++-
 gdb/python/py-section.c      | 401 +++++++++++++++++++++++++++++++++++++++++++
 gdb/python/py-symbol.c       |  52 ++++--
 gdb/python/python-internal.h |  14 ++
 gdb/python/python.c          |   7 +-
 7 files changed, 853 insertions(+), 15 deletions(-)
 create mode 100644 gdb/python/py-minsymbol.c
 create mode 100644 gdb/python/py-section.c

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3c7518a..751de4d 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -398,11 +398,13 @@ 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 \
 	py-prettyprint.o \
 	py-progspace.o \
+	py-section.o \
 	py-signalevent.o \
 	py-stopevent.o \
 	py-symbol.o \
@@ -438,11 +440,13 @@ 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 \
 	python/py-prettyprint.c \
 	python/py-progspace.c \
+	python/py-section.c \
 	python/py-signalevent.c \
 	python/py-stopevent.c \
 	python/py-symbol.c \
@@ -2607,6 +2611,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)
@@ -2627,6 +2635,10 @@ py-progspace.o: $(srcdir)/python/py-progspace.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-progspace.c
 	$(POSTCOMPILE)
 
+py-section.o: $(srcdir)/python/py-section.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-section.c
+	$(POSTCOMPILE)
+
 py-signalevent.o: $(srcdir)/python/py-signalevent.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-signalevent.c
 	$(POSTCOMPILE)
diff --git a/gdb/python/py-minsymbol.c b/gdb/python/py-minsymbol.c
new file mode 100644
index 0000000..efff59da
--- /dev/null
+++ b/gdb/python/py-minsymbol.c
@@ -0,0 +1,353 @@
+/* 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"
+
+extern PyTypeObject minsym_object_type;
+
+typedef struct msympy_symbol_object {
+  PyObject_HEAD
+  /* The GDB minimal_symbol structure this object is wrapping.  */
+  struct minimal_symbol *minsym;
+
+  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;
+
+PyObject *minsym_to_minsym_object (struct minimal_symbol *minsym);
+struct minimal_symbol *minsym_object_to_minsym (PyObject *obj);
+/* 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,		\
+			 _("MiniSymbol 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_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.MiniSymbol.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;
+  volatile struct gdb_exception except;
+
+  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 minimal_symbol *minsym)
+{
+  obj->minsym = minsym;
+  switch (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_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;
+}
+
+/* Create a new symbol object (gdb.MiniSymbol) that encapsulates the struct
+   symbol object from GDB.  */
+PyObject *
+minsym_to_minsym_object (struct minimal_symbol *minsym)
+{
+  minsym_object *msym_obj;
+
+  msym_obj = PyObject_New (minsym_object, &minsym_object_type);
+  if (msym_obj)
+    set_symbol (msym_obj, minsym);
+
+  return (PyObject *) msym_obj;
+}
+
+/* Return the symbol that is wrapped by this symbol object.  */
+struct minimal_symbol *
+minsym_object_to_minsym (PyObject *obj)
+{
+  if (! PyObject_TypeCheck (obj, &minsym_object_type))
+    return NULL;
+  return ((minsym_object *) obj)->minsym;
+}
+
+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;
+}
+
+/* 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;
+  volatile struct gdb_exception except;
+
+  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 (minsym)
+    {
+      msym_obj = minsym_to_minsym_object (bound_minsym.minsym);
+      if (!msym_obj)
+	return NULL;
+    }
+  else
+    {
+      msym_obj = Py_None;
+      Py_INCREF (Py_None);
+    }
+
+  return msym_obj;
+}
+
+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, "MiniSymbol",
+				 (PyObject *) &minsym_object_type);
+}
+
+
+
+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 the symbol is in. 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 },
+  { 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.MiniSymbol",			  /*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/py-objfile.c b/gdb/python/py-objfile.c
index 5dc9ae6..498819b 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -25,7 +25,7 @@
 #include "build-id.h"
 #include "symtab.h"
 
-typedef struct
+typedef struct objfile_object
 {
   PyObject_HEAD
 
@@ -653,6 +653,31 @@ objfile_to_objfile_object (struct objfile *objfile)
   return (PyObject *) object;
 }
 
+static PyObject *
+objfpy_get_sections (PyObject *self, void *closure)
+{
+  objfile_object *obj = (objfile_object *) self;
+  PyObject *dict;
+  asection *section = obj->objfile->sections->the_bfd_section;
+
+  dict = PyDict_New();
+  if (!dict)
+    return NULL;
+
+  while (section) {
+    PyObject *sec = section_to_section_object(section, obj->objfile);
+    if (!sec) {
+      PyObject_Del(dict);
+      return NULL;
+    }
+
+    PyDict_SetItemString(dict, section->name, sec);
+    section = section->next;
+  }
+
+  return PyDictProxy_New(dict);
+}
+
 int
 gdbpy_initialize_objfile (void)
 {
@@ -707,6 +732,8 @@ static PyGetSetDef objfile_getset[] =
     "Type printers.", NULL },
   { "xmethods", objfpy_get_xmethods, NULL,
     "Debug methods.", NULL },
+  { "sections", objfpy_get_sections, NULL,
+    "The sections that make up the objfile.", NULL },
   { NULL }
 };
 
diff --git a/gdb/python/py-section.c b/gdb/python/py-section.c
new file mode 100644
index 0000000..985c69c
--- /dev/null
+++ b/gdb/python/py-section.c
@@ -0,0 +1,401 @@
+/* Python interface to sections.
+
+   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"
+
+typedef struct secpy_section_object {
+  PyObject_HEAD
+  asection *section;
+  struct objfile *objfile;
+  /* The GDB section structure this object is wrapping.  */
+  /* A section object is associated with an objfile, so keep track with
+     doubly-linked list, rooted in the objfile.  This lets us
+     invalidate the underlying section when the objfile is
+     deleted.  */
+  struct secpy_section_object *prev;
+  struct secpy_section_object *next;
+} section_object;
+
+/* Require a valid section.  All access to section_object->section should be
+   gated by this call.  */
+#define SYMPY_REQUIRE_VALID(section_obj, section)		\
+  do {							\
+    section = section_object_to_section (section_obj);	\
+    if (section == NULL)					\
+      {							\
+	PyErr_SetString (PyExc_RuntimeError,		\
+			 _("Section is invalid."));	\
+	return NULL;					\
+      }							\
+  } while (0)
+
+static const struct objfile_data *secpy_objfile_data_key;
+
+static PyObject *
+secpy_str (PyObject *self)
+{
+  PyObject *result;
+  asection *section = NULL;
+
+  SYMPY_REQUIRE_VALID (self, section);
+
+  result = PyString_FromString (section->name);
+
+  return result;
+}
+
+static PyObject *
+secpy_get_flags (PyObject *self, void *closure)
+{
+  asection *section = NULL;
+
+  SYMPY_REQUIRE_VALID (self, section);
+
+  return PyInt_FromLong (section->flags);
+}
+
+static PyObject *
+secpy_get_objfile (PyObject *self, void *closure)
+{
+  section_object *obj = (section_object *)self;
+
+  if (! PyObject_TypeCheck (self, &section_object_type))
+    return NULL;
+
+  return objfile_to_objfile_object (obj->objfile);
+}
+
+static PyObject *
+secpy_get_name (PyObject *self, void *closure)
+{
+  asection *section = NULL;
+
+  SYMPY_REQUIRE_VALID (self, section);
+
+  return PyString_FromString (section->name);
+}
+
+static PyObject *
+secpy_get_id (PyObject *self, void *closure)
+{
+  asection *section = NULL;
+
+  SYMPY_REQUIRE_VALID (self, section);
+
+  return PyInt_FromLong (section->id);
+}
+
+#define secpy_return_string(self, val)		\
+({						\
+  asection *section = NULL;			\
+  SYMPY_REQUIRE_VALID (self, section);		\
+  PyString_FromString (val);		\
+})
+
+#define secpy_return_longlong(self, val)	\
+({						\
+  asection *section = NULL;			\
+  SYMPY_REQUIRE_VALID (self, section);		\
+  PyLong_FromUnsignedLongLong (val);	\
+})
+
+static PyObject *
+secpy_get_vma (PyObject *self, void *closure)
+{
+  return secpy_return_longlong(self, section->vma);
+}
+
+static PyObject *
+secpy_get_lma (PyObject *self, void *closure)
+{
+  return secpy_return_longlong(self, section->lma);
+}
+
+static PyObject *
+secpy_get_size (PyObject *self, void *closure)
+{
+  return secpy_return_longlong(self, section->size);
+}
+
+static PyObject *
+secpy_get_rawsize (PyObject *self, void *closure)
+{
+  return secpy_return_longlong(self, section->rawsize);
+}
+
+static PyObject *
+secpy_get_compressed_size (PyObject *self, void *closure)
+{
+  return secpy_return_longlong(self, section->compressed_size);
+}
+
+static PyObject *
+secpy_get_print_name (PyObject *self, void *closure)
+{
+  return secpy_str (self);
+}
+
+static PyObject *
+secpy_is_compressed (PyObject *self, void *closure)
+{
+  asection *section = NULL;
+
+  SYMPY_REQUIRE_VALID (self, section);
+
+  return PyBool_FromLong (section->compress_status == 1);
+}
+
+/* Given a section, and a section_object that has previously been
+   allocated and initialized, populate the section_object with the
+   asection data.  Also, register the section_object life-cycle
+   with the life-cycle of the object file associated with this
+   section, if needed.  */
+static void
+set_section (section_object *obj, asection *section, struct objfile *objfile)
+{
+  obj->section = section;
+  obj->prev = NULL;
+  obj->objfile = objfile;
+  obj->next = objfile_data (obj->objfile, secpy_objfile_data_key);
+
+  if (obj->next)
+    obj->next->prev = obj;
+
+  set_objfile_data (obj->objfile, secpy_objfile_data_key, obj);
+}
+
+/* Create a new section object (gdb.Section) that encapsulates the struct
+   section object from GDB.  */
+PyObject *
+section_to_section_object (asection *section, struct objfile *objfile)
+{
+  section_object *sec_obj;
+
+  sec_obj = PyObject_New (section_object, &section_object_type);
+  if (sec_obj) {
+    set_section (sec_obj, section, objfile);
+  }
+
+  return (PyObject *) sec_obj;
+}
+
+/* Return the section that is wrapped by this section object.  */
+asection *
+section_object_to_section (PyObject *obj)
+{
+  if (! PyObject_TypeCheck (obj, &section_object_type))
+    return NULL;
+  return ((section_object *) obj)->section;
+}
+
+static void
+secpy_dealloc (PyObject *obj)
+{
+  section_object *section_obj = (section_object *) obj;
+
+  if (section_obj->prev)
+    section_obj->prev->next = section_obj->next;
+  else if (section_obj->objfile)
+    {
+      set_objfile_data (section_obj->objfile,
+			secpy_objfile_data_key, section_obj->next);
+    }
+  if (section_obj->next)
+    section_obj->next->prev = section_obj->prev;
+  section_obj->section = NULL;
+}
+
+static PyObject *
+secpy_is_valid (PyObject *self, PyObject *args)
+{
+  asection *section = NULL;
+
+  section = section_object_to_section (self);
+  if (section == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
+/* This function is called when an objfile is about to be freed.
+   Invalidate the section as further actions on the section would result
+   in bad data.  All access to obj->section should be gated by
+   SYMPY_REQUIRE_VALID which will raise an exception on invalid
+   sections.  */
+static void
+del_objfile_sections (struct objfile *objfile, void *datum)
+{
+  section_object *obj = datum;
+  while (obj)
+    {
+      section_object *next = obj->next;
+
+      obj->section = NULL;
+      obj->next = NULL;
+      obj->prev = NULL;
+
+      obj = next;
+    }
+}
+
+int
+gdbpy_initialize_sections (void)
+{
+  if (PyType_Ready (&section_object_type) < 0)
+    return -1;
+
+  /* Register an objfile "free" callback so we can properly
+     invalidate section when an object file that is about to be
+     deleted.  */
+  secpy_objfile_data_key
+    = register_objfile_data_with_cleanup (NULL, del_objfile_sections);
+
+  if (PyModule_AddIntConstant (gdb_module, "SEC_NO_FLAGS", SEC_NO_FLAGS) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_ALLOC", SEC_ALLOC) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LOAD", SEC_LOAD) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_RELOC", SEC_RELOC) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_READONLY", SEC_READONLY) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_CODE", SEC_CODE) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_DATA", SEC_DATA) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_ROM", SEC_ROM) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_CONSTRUCTOR",
+				  SEC_CONSTRUCTOR) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_HAS_CONTENTS",
+				  SEC_HAS_CONTENTS) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_NEVER_LOAD",
+				  SEC_NEVER_LOAD) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_THREAD_LOCAL",
+				  SEC_THREAD_LOCAL) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_HAS_GOT_REF",
+				  SEC_HAS_GOT_REF) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_IS_COMMON",
+				  SEC_IS_COMMON) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_DEBUGGING",
+				  SEC_DEBUGGING) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_IN_MEMORY",
+				  SEC_IN_MEMORY) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_EXCLUDE", SEC_EXCLUDE) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_SORT_ENTRIES",
+				  SEC_SORT_ENTRIES) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LINK_ONCE",
+				  SEC_LINK_ONCE) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LINK_DUPLICATES",
+				  SEC_LINK_DUPLICATES) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LINK_DUPLICATES_DISCARD",
+				  SEC_LINK_DUPLICATES_DISCARD) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LINK_DUPLICATES_ONE_ONLY",
+				  SEC_LINK_DUPLICATES_ONE_ONLY) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LINK_DUPLICATES_SAME_SIZE",
+				  SEC_LINK_DUPLICATES_SAME_SIZE) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_LINKER_CREATED",
+				  SEC_LINKER_CREATED) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_KEEP", SEC_KEEP) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_SMALL_DATA",
+				  SEC_SMALL_DATA) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_MERGE", SEC_MERGE) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_STRNGS", SEC_STRINGS) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_GROUP", SEC_GROUP) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_COFF_SHARED_LIBRARY",
+				  SEC_COFF_SHARED_LIBRARY) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_ELF_REVERSE_COPY",
+				  SEC_ELF_REVERSE_COPY) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_COFF_SHARED",
+				  SEC_COFF_SHARED) < 0
+      || PyModule_AddIntConstant (gdb_module, "SEC_COFF_NOREAD",
+				  SEC_COFF_NOREAD) < 0)
+    return -1;
+
+  return gdb_pymodule_addobject (gdb_module, "Section",
+				 (PyObject *) &section_object_type);
+}
+
+
+
+static PyGetSetDef section_object_getset[] = {
+  { "flags", secpy_get_flags, NULL,
+    "Flags of the section.", NULL },
+  { "objfile", secpy_get_objfile, NULL,
+    "Object file in which the section appears.", NULL },
+  { "name", secpy_get_name, NULL,
+    "Name of the section, as it appears in the source code.", NULL },
+  { "size", secpy_get_size, NULL, "Size of the section.", NULL },
+  { "compressed_size", secpy_get_compressed_size, NULL,
+    "Compressed size of the section.", NULL },
+  { "rawsize", secpy_get_rawsize, NULL,
+    "Size of the section on disk.", NULL },
+  { "id", secpy_get_id, NULL,
+    "Sequence number of the section.", NULL },
+  { "print_name", secpy_get_print_name, NULL,
+    "Name of the section 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 },
+  { "vma", secpy_get_vma, NULL,
+    "Virtual memory address of the section at runtime." },
+  { "lma", secpy_get_lma, NULL,
+    "Load memory address of the section." },
+  { "is_compressed", secpy_is_compressed, NULL,
+    "True if the section is compressed." },
+  { NULL }  /* Sentinel */
+};
+
+static PyMethodDef section_object_methods[] = {
+  { "is_valid", secpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this section is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
+PyTypeObject section_object_type = {
+  PyVarObject_HEAD_INIT (NULL, 0)
+  "gdb.Section",		  /*tp_name*/
+  sizeof (section_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  secpy_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*/
+  secpy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB section object",		  /*tp_doc */
+  0,				  /*tp_traverse */
+  0,				  /*tp_clear */
+  0,				  /*tp_richcompare */
+  0,				  /*tp_weaklistoffset */
+  0,				  /*tp_iter */
+  0,				  /*tp_iternext */
+  section_object_methods,	  /*tp_methods */
+  0,				  /*tp_members */
+  section_object_getset		  /*tp_getset */
+};
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 4306f61..1aa5477 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -239,6 +239,28 @@ sympy_is_valid (PyObject *self, PyObject *args)
   Py_RETURN_TRUE;
 }
 
+static PyObject *
+sympy_section (PyObject *self, void *closure)
+{
+  struct symbol *symbol = NULL;
+  PyObject *section_obj;
+  struct obj_section *section;
+
+  SYMPY_REQUIRE_VALID (self, symbol);
+
+  section = SYMBOL_OBJ_SECTION(symbol_objfile(symbol), symbol);
+
+  if (section) {
+    section_obj = section_to_section_object(section->the_bfd_section,
+                                            symbol_objfile(symbol));
+    if (section_obj)
+      return section_obj;
+  }
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
 /* Implementation of gdb.Symbol.value (self[, frame]) -> gdb.Value.  Returns
    the value of the symbol, or an error in various circumstances.  */
 
@@ -378,14 +400,26 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
 
   if (block_obj)
     block = block_object_to_block (block_obj);
-  else
+  TRY
+    {
+      symbol = lookup_symbol (name, block, domain, &is_a_field_of_this);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  if (!block)
     {
       struct frame_info *selected_frame;
 
       TRY
 	{
-	  selected_frame = get_selected_frame (_("No frame selected."));
-	  block = get_frame_block (selected_frame, NULL);
+	  if (symbol && symbol_read_needs_frame(symbol)) {
+	    selected_frame = get_selected_frame (_("No frame selected."));
+	    block = get_frame_block (selected_frame, NULL);
+	  }
 	}
       CATCH (except, RETURN_MASK_ALL)
 	{
@@ -394,16 +428,6 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
       END_CATCH
     }
 
-  TRY
-    {
-      symbol = lookup_symbol (name, block, domain, &is_a_field_of_this);
-    }
-  CATCH (except, RETURN_MASK_ALL)
-    {
-      GDB_PY_HANDLE_EXCEPTION (except);
-    }
-  END_CATCH
-
   ret_tuple = PyTuple_New (2);
   if (!ret_tuple)
     return NULL;
@@ -583,6 +607,8 @@ to display demangled or mangled names.", NULL },
     "True if the symbol requires a frame for evaluation." },
   { "line", sympy_line, NULL,
     "The source line number at which the symbol was defined." },
+  { "section", sympy_section, NULL,
+    "Section of executable where symbol resides." },
   { NULL }  /* Sentinel */
 };
 
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index ee949b7..e8776f1 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -143,6 +143,8 @@ typedef int Py_ssize_t;
 #define PyEval_ReleaseLock()
 #endif
 
+#define gdb_py_long_from_pointer PyLong_FromLong
+
 /* Python supplies HAVE_LONG_LONG and some `long long' support when it
    is available.  These defines let us handle the differences more
    cleanly.  */
@@ -241,6 +243,10 @@ 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 section_object_type;
+     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("section_object");
+extern PyTypeObject objfile_object_type;
+     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
 extern PyTypeObject event_object_type
     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
 extern PyTypeObject stop_event_object_type
@@ -362,6 +368,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);
@@ -381,6 +389,7 @@ char *gdbpy_parse_command_name (const char *name,
 				struct cmd_list_element ***base_list,
 				struct cmd_list_element **start_list);
 
+PyObject *section_to_section_object (asection *sym, struct objfile *objf);
 PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal);
 PyObject *symtab_to_symtab_object (struct symtab *symtab);
 PyObject *symbol_to_symbol_object (struct symbol *sym);
@@ -414,6 +423,7 @@ PyObject *find_inferior_object (int pid);
 PyObject *inferior_to_inferior_object (struct inferior *inferior);
 
 const struct block *block_object_to_block (PyObject *obj);
+asection *section_object_to_section (PyObject *obj);
 struct symbol *symbol_object_to_symbol (PyObject *obj);
 struct value *value_object_to_value (PyObject *self);
 struct value *convert_value_from_python (PyObject *obj);
@@ -436,6 +446,10 @@ 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_sections (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 4f88b0e..817ec25 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1800,7 +1800,9 @@ 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_sections () < 0
       || gdbpy_initialize_blocks () < 0
       || gdbpy_initialize_functions () < 0
       || gdbpy_initialize_parameters () < 0
@@ -2025,7 +2027,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,
     "lookup_objfile (name, [by_build_id]) -> objfile\n\
-- 
2.7.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]