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

Kieran Bingham kieran.bingham@linaro.org
Mon Feb 1 12:35:00 GMT 2016


Are these identical to the ones available at:
https://github.com/jeffmahoney/py-crash? or have you made any modifications

Wouldn't it be better to keep Jeff's patches separate, and maintain his
authorship?

I can see these potentially being useful to my work, so I believe they 
would be good additions.
I'll likely pick the patches from his repository for now and set my work
on top.

--
Regards

Kieran

On 31/01/16 21:44, Ales Novak wrote:
> ---
>  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\



More information about the Gdb-patches mailing list