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

Message ID 1454276692-7119-3-git-send-email-alnovak@suse.cz
State New, archived
Headers

Commit Message

Ales Novak Jan. 31, 2016, 9:44 p.m. UTC
  ---
 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
  

Comments

Kieran Bingham Feb. 1, 2016, 12:34 p.m. UTC | #1
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\
  
Doug Evans Feb. 1, 2016, 10:22 p.m. UTC | #2
On Sun, Jan 31, 2016 at 1:44 PM, Ales Novak <alnovak@suse.cz> 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


Hi.

Part of what this patch is doing is exporting bfd to python.
E.g., all the SEC_* constants.

As a rule we absolutely discourage people from using bfd outside of
the the binutils+gdb source tree.
Either this rule needs to change, or I don't think we can allow this patch.
I'd be interested to hear what others in the community think.

For myself, I would much rather export ELF separately (e.g., a separate
python API one can use independent of any particular tool, including gdb),
and then have gdb provide the necessary glue to use this API.
[I can imagine some compromises being needed, at least for now;
e.g., it'd be cumbersome to read in all ELF symbols twice.
But fixing that is just an optimization.]


> ...
> +  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;
> ...
  
Jeff Mahoney Feb. 2, 2016, 2:55 a.m. UTC | #3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2/1/16 5:22 PM, Doug Evans wrote:
> On Sun, Jan 31, 2016 at 1:44 PM, Ales Novak <alnovak@suse.cz>
> 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
> 
> 
> Hi.

Hi Doug -

> Part of what this patch is doing is exporting bfd to python. E.g.,
> all the SEC_* constants.
> 
> As a rule we absolutely discourage people from using bfd outside
> of the the binutils+gdb source tree. Either this rule needs to
> change, or I don't think we can allow this patch. I'd be interested
> to hear what others in the community think.

That's unfortunate.  The Linux kernel uses ELF sections for a number
of purposes.  Most notably is the definition of per-cpu variables.
Without the ELF section, we can't resolve the addresses for the
variables.  So, from our perspective, it's a requirement.

> For myself, I would much rather export ELF separately (e.g., a
> separate python API one can use independent of any particular tool,
> including gdb), and then have gdb provide the necessary glue to use
> this API. [I can imagine some compromises being needed, at least
> for now; e.g., it'd be cumbersome to read in all ELF symbols
> twice. But fixing that is just an optimization.]

Ok, that's doable.  As it is, the section code mixes GDB and BFD
pretty heavily.  It shouldn't be too difficult to separate the two out
and push the section stuff into a new BFD python interface and
associate the objfiles with it.

- -Jeff

> 
>> ... +  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; ...
> 


- -- 
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQIcBAEBAgAGBQJWsBq4AAoJEB57S2MheeWyiNkP/ihEmdfSciKJ1oZjW8bFM3pb
IopJO86jZWhLMdG5CcDvoc/Mhf/xbGGeCvPgJOVvgdhLOqBR+8H3xT4ot0TzPfba
yCas29vKis2+wLEFBGoFVWXzxhYF6SZ4YjZSlUleD7kGvja2kWAj173Oj8q9xuy5
A88hWy/+bTTxVuaBE4NW9RNy+2kt+XwneP2ccBRdaVK2FUUHk62znEAcs/SmAoeN
20Nq8a24pYl+6T/GM1E2lnA2OdBtadcY3G3zXKGtw3JExaNpytlndvdRaDUUJLFV
0TbAE1WsaK5LzOxZzfgn43MLr5y1APdihvGJN1voSnz6mmnmQ6q008z4M7eKVhf6
GuQAMNW8lI4Ki+WwEIOJHiORDNjummRHrzvI8PY5ci9xbD0JEpf3cQVOwGW9Wlqz
M7tLdREWll4fm85V8W8wdq7ETsMmoL5SUaAGVn2ZucJLoNDif0jNoLsOeee0YPEa
2EjgB7hleE3GkFgpwPa/75FRANO2AnxzDQPCELoJJ1bMRFONMT46A7T3zbfzijwf
+MZWY9h40QUewtLJlqCpVcXWWhNPpNCuzRhwrpKLYAXnT2dBT0zhRRNxKaFzeQo6
YfmFEDWapK97biwKen6/snNSfWpZJAEGprSsU5uqv2iLVzITtlr9euaL9bR9p1fq
geG2m6SRtR9JUzIvUn71
=7HLd
-----END PGP SIGNATURE-----
  
Kieran Bingham Feb. 2, 2016, 8:25 a.m. UTC | #4
On 02/02/16 02:55, Jeff Mahoney wrote:
> On 2/1/16 5:22 PM, Doug Evans wrote:
>> On Sun, Jan 31, 2016 at 1:44 PM, Ales Novak <alnovak@suse.cz>
>> 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
> 
> 
>> Hi.
> 
> Hi Doug -
> 
>> Part of what this patch is doing is exporting bfd to python. E.g.,
>> all the SEC_* constants.
> 
>> As a rule we absolutely discourage people from using bfd outside
>> of the the binutils+gdb source tree. Either this rule needs to
>> change, or I don't think we can allow this patch. I'd be interested
>> to hear what others in the community think.
> 
> That's unfortunate.  The Linux kernel uses ELF sections for a number
> of purposes.  Most notably is the definition of per-cpu variables.
> Without the ELF section, we can't resolve the addresses for the
> variables.  So, from our perspective, it's a requirement.

Jeff,

I haven't yet looked into your code specifically to check your per-cpu
implementation detail yet, so I'll just speculate for a moment:

Have you seen that we can obtain per_cpu variable from
linux.git/scripts/gdb/linux/cpus.py ?


def per_cpu(var_ptr, cpu):
    if cpu == -1:
        cpu = get_current_cpu()
    if utils.is_target_arch("sparc:v9"):
        offset = gdb.parse_and_eval(
            "trap_block[{0}].__per_cpu_base".format(str(cpu)))
    else:
        try:
            offset = gdb.parse_and_eval(
                "__per_cpu_offset[{0}]".format(str(cpu)))
        except gdb.error:
            # !CONFIG_SMP case
            offset = 0
    pointer = var_ptr.cast(utils.get_long_type()) + offset
    return pointer.cast(var_ptr.type).dereference()



>> For myself, I would much rather export ELF separately (e.g., a
>> separate python API one can use independent of any particular tool,
>> including gdb), and then have gdb provide the necessary glue to use
>> this API. [I can imagine some compromises being needed, at least
>> for now; e.g., it'd be cumbersome to read in all ELF symbols
>> twice. But fixing that is just an optimization.]
> 
> Ok, that's doable.  As it is, the section code mixes GDB and BFD
> pretty heavily.  It shouldn't be too difficult to separate the two out
> and push the section stuff into a new BFD python interface and
> associate the objfiles with it.

Some of our further work (/stretch goals) on Linux Kernel Awareness,
will also utilise this so I will be interested to see how it goes.

> -Jeff
> 
> 
>>> ... +  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; ...
> 
> 
> 
>
  
Jeff Mahoney Feb. 3, 2016, 5:55 p.m. UTC | #5
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2/1/16 9:55 PM, Jeff Mahoney wrote:
> On 2/1/16 5:22 PM, Doug Evans wrote:
>> On Sun, Jan 31, 2016 at 1:44 PM, Ales Novak <alnovak@suse.cz> 
>> 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
> 
> 
>> Hi.
> 
> Hi Doug -
> 
>> Part of what this patch is doing is exporting bfd to python.
>> E.g., all the SEC_* constants.
> 
>> As a rule we absolutely discourage people from using bfd outside 
>> of the the binutils+gdb source tree. Either this rule needs to 
>> change, or I don't think we can allow this patch. I'd be
>> interested to hear what others in the community think.
> 
> That's unfortunate.  The Linux kernel uses ELF sections for a
> number of purposes.  Most notably is the definition of per-cpu
> variables. Without the ELF section, we can't resolve the addresses
> for the variables.  So, from our perspective, it's a requirement.
> 
>> For myself, I would much rather export ELF separately (e.g., a 
>> separate python API one can use independent of any particular
>> tool, including gdb), and then have gdb provide the necessary
>> glue to use this API. [I can imagine some compromises being
>> needed, at least for now; e.g., it'd be cumbersome to read in all
>> ELF symbols twice. But fixing that is just an optimization.]
> 
> Ok, that's doable.  As it is, the section code mixes GDB and BFD 
> pretty heavily.  It shouldn't be too difficult to separate the two
> out and push the section stuff into a new BFD python interface and 
> associate the objfiles with it.

And here's what I've come up with.  Does this constitute enough of a
separation?  It /should/ cross over into the BFD code in the same way
that the GDB code does: As soon as we hit a bfd object or a
bfd_section object, we call into bfd's new python API to generate the
objects.

https://jeffm.io/git/cgit.cgi/gnu/binutils-gdb/log/?h=gdb/python-bfd

For the fully-integrated kdump work, use the python-bfd-kdump branch
(or SUSE folks, python-bfd-kdump-buildid will pick up the separate
debuginfos as we usually expect).

- -Jeff

>>> ... +  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; ...
> 
> 
> 
> 

- -- 
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQIcBAEBAgAGBQJWsj8aAAoJEB57S2MheeWyhQAP/jVlYhIHlLr/h1j1F64PR5mP
i2+CRVorxMcRwVRMz8ymFJBzAoZoxzlEtjnX9b9rdfVnPd/wT8qmT0BBbj1FY1a6
kIPF5a6Wea6kJcbLeZ/yeyml9hhz2SULr9Lc0IqIQ20BGcPwPQkMqqEPgHZbalxZ
HmboZWz4o9QObOUOdXyyBxgmU148Pi7WsnD3dmD+qi/cLc5hppDy7/xpv0H6cDRw
mBlKVpvf8+Yv+yNTSx39k51XW7TKko13GxJ5Sdm1/zC+PGIHbRgKHvN4gYc5Fr4d
kd8oR9w/S8DQRNypU4lUPwPVXLz7Njy6S2Kmz8rPobh6RvEpRv8koLZUjUzimcC8
BTKcwHwlI8eQCZ/t+OB7uMJLKte0oqItg+ynPuD1FWsWSGI2cqWmOHL3NBc4fU5/
RO/7u52Fr21gKwQ0EbaSZeEC0knAGMxw8gWmTaZaArkbSAIlPR2wsfEgVekFBZLb
7gyFY8ut6k641oivGumpTMVS6LhQxTxOMD41oTrCO7VWintuOhNmSjh0rkjy8Ax8
PdG16Pc6EI3th6LPKE28nsMKxLCXr2N5wOLLETWcAKDcgXgIa4aHTLTVMdy5MIuu
4C6AOoKnjNwlypqa36uuWAy9dzzUuY7zJrIgRiGesSDpmtlCxsDyxsqJicZZu5tF
JKA7TkwqGAJsmyw7tNNe
=DH0z
-----END PGP SIGNATURE-----
  
Doug Evans Feb. 3, 2016, 6:30 p.m. UTC | #6
On Wed, Feb 3, 2016 at 9:55 AM, Jeff Mahoney <jeffm@suse.com> wrote:
>...
>>> Hi.
>>
>> Hi Doug -
>>
>>> Part of what this patch is doing is exporting bfd to python.
>>> E.g., all the SEC_* constants.
>>
>>> As a rule we absolutely discourage people from using bfd outside
>>> of the the binutils+gdb source tree. Either this rule needs to
>>> change, or I don't think we can allow this patch. I'd be
>>> interested to hear what others in the community think.
>>
>> That's unfortunate.  The Linux kernel uses ELF sections for a
>> number of purposes.  Most notably is the definition of per-cpu
>> variables. Without the ELF section, we can't resolve the addresses
>> for the variables.  So, from our perspective, it's a requirement.
>>
>>> For myself, I would much rather export ELF separately (e.g., a
>>> separate python API one can use independent of any particular
>>> tool, including gdb), and then have gdb provide the necessary
>>> glue to use this API. [I can imagine some compromises being
>>> needed, at least for now; e.g., it'd be cumbersome to read in all
>>> ELF symbols twice. But fixing that is just an optimization.]
>>
>> Ok, that's doable.  As it is, the section code mixes GDB and BFD
>> pretty heavily.  It shouldn't be too difficult to separate the two
>> out and push the section stuff into a new BFD python interface and
>> associate the objfiles with it.
>
> And here's what I've come up with.  Does this constitute enough of a
> separation?  It /should/ cross over into the BFD code in the same way
> that the GDB code does: As soon as we hit a bfd object or a
> bfd_section object, we call into bfd's new python API to generate the
> objects.
>
> https://jeffm.io/git/cgit.cgi/gnu/binutils-gdb/log/?h=gdb/python-bfd
>
> For the fully-integrated kdump work, use the python-bfd-kdump branch
> (or SUSE folks, python-bfd-kdump-buildid will pick up the separate
> debuginfos as we usually expect).

Separation isn't the issue, unfortunately.
The issue is that we cannot export bfd to python, period.

I'm certainly open to others convincing me I'm wrong.
But that is my understanding.
What we can do is export ELF, and that is what I'd like to see.
  
Jeff Mahoney Feb. 3, 2016, 7:29 p.m. UTC | #7
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2/3/16 1:30 PM, Doug Evans wrote:
> On Wed, Feb 3, 2016 at 9:55 AM, Jeff Mahoney <jeffm@suse.com>
> wrote:
>> ...
>>>> Hi.
>>> 
>>> Hi Doug -
>>> 
>>>> Part of what this patch is doing is exporting bfd to python. 
>>>> E.g., all the SEC_* constants.
>>> 
>>>> As a rule we absolutely discourage people from using bfd
>>>> outside of the the binutils+gdb source tree. Either this rule
>>>> needs to change, or I don't think we can allow this patch.
>>>> I'd be interested to hear what others in the community
>>>> think.
>>> 
>>> That's unfortunate.  The Linux kernel uses ELF sections for a 
>>> number of purposes.  Most notably is the definition of per-cpu 
>>> variables. Without the ELF section, we can't resolve the
>>> addresses for the variables.  So, from our perspective, it's a
>>> requirement.
>>> 
>>>> For myself, I would much rather export ELF separately (e.g.,
>>>> a separate python API one can use independent of any
>>>> particular tool, including gdb), and then have gdb provide
>>>> the necessary glue to use this API. [I can imagine some
>>>> compromises being needed, at least for now; e.g., it'd be
>>>> cumbersome to read in all ELF symbols twice. But fixing that
>>>> is just an optimization.]
>>> 
>>> Ok, that's doable.  As it is, the section code mixes GDB and
>>> BFD pretty heavily.  It shouldn't be too difficult to separate
>>> the two out and push the section stuff into a new BFD python
>>> interface and associate the objfiles with it.
>> 
>> And here's what I've come up with.  Does this constitute enough
>> of a separation?  It /should/ cross over into the BFD code in the
>> same way that the GDB code does: As soon as we hit a bfd object
>> or a bfd_section object, we call into bfd's new python API to
>> generate the objects.
>> 
>> https://jeffm.io/git/cgit.cgi/gnu/binutils-gdb/log/?h=gdb/python-bfd
>>
>>
>> 
For the fully-integrated kdump work, use the python-bfd-kdump branch
>> (or SUSE folks, python-bfd-kdump-buildid will pick up the
>> separate debuginfos as we usually expect).
> 
> Separation isn't the issue, unfortunately. The issue is that we
> cannot export bfd to python, period.
> 
> I'm certainly open to others convincing me I'm wrong. But that is
> my understanding. What we can do is export ELF, and that is what
> I'd like to see.

Ok, so looking at this again, I don't need full section information.
I just need a name.   Would it be acceptable to just export the name
of the section via gdb.Symbol and my new gdb.MinSymbol instead?

- -Jeff

- -- 
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQIcBAEBAgAGBQJWslUlAAoJEB57S2MheeWy2KYP/0t+pzbrp9blhgMF2JBKkqhD
ZM+RbVZFaQysJdINqeTZcF9lYkg7f0eJ0Xi6+3/6+zniTDAKtvxIHlgq15cO1itM
XrUAArhedT684Klm80BL8PUp10pamTyFO34p4EdKVeWajWXIt8UWxo+wQv9nvldA
J163npwniBYk7ZsoNz13RvtRLyL1BOQEhh/xoODAs8SJGm8MRpydLw4QNRN+KTb5
NkSCXuh0cORz0/KN6yugsR4SZ/JnBovm0iIQu47IiZbVG0SbQk5thtF002ejojL4
O5KOSQxW5wfcWNbBo79bw45+S+MPBpEZItPXaXeiFZBBL7agYEmCO50+iKv93xLw
0f1MPA6GuJjM3yLld+ONPFnrC3Mw/CVPBkuxUgVwQedzGUkRJ7zzGVvGbnSmzvyI
YIVXea4u4YG4Lk/d0+XTozfNfrm5kRfvtVckX3ThVMDyKIacJyVLGGKDHV5UvRlh
oUOPUeiwaOyPqY46gyNepuY7tebg10ykeso5TpMqrJVwUfL0Ri4jIKKVSYvvvG7U
9M748VB/an1idysIZ9z1D7gIbs11L+jeq44Hy2AJe0nfVdsJKXy6NjCKrW1vXlKA
X5gP85oPe89iACtRE3TlBbl916dsW67GHP6oUvCpKseliqsevRuUsC8/gukpFOpe
e6V1i8k5z+2doLxHv7by
=b8yC
-----END PGP SIGNATURE-----
  
Petr Tesarik Feb. 4, 2016, 5:25 p.m. UTC | #8
Hi Doug,

On Wed, 3 Feb 2016 10:30:20 -0800
Doug Evans <dje@google.com> wrote:

> On Wed, Feb 3, 2016 at 9:55 AM, Jeff Mahoney <jeffm@suse.com> wrote:
> >...
> >>> Hi.
> >>
> >> Hi Doug -
> >>
> >>> Part of what this patch is doing is exporting bfd to python.
> >>> E.g., all the SEC_* constants.
> >>
> >>> As a rule we absolutely discourage people from using bfd outside
> >>> of the the binutils+gdb source tree. Either this rule needs to
> >>> change, or I don't think we can allow this patch. I'd be
> >>> interested to hear what others in the community think.
> >>
> >> That's unfortunate.  The Linux kernel uses ELF sections for a
> >> number of purposes.  Most notably is the definition of per-cpu
> >> variables. Without the ELF section, we can't resolve the addresses
> >> for the variables.  So, from our perspective, it's a requirement.
> >>
> >>> For myself, I would much rather export ELF separately (e.g., a
> >>> separate python API one can use independent of any particular
> >>> tool, including gdb), and then have gdb provide the necessary
> >>> glue to use this API. [I can imagine some compromises being
> >>> needed, at least for now; e.g., it'd be cumbersome to read in all
> >>> ELF symbols twice. But fixing that is just an optimization.]
> >>
> >> Ok, that's doable.  As it is, the section code mixes GDB and BFD
> >> pretty heavily.  It shouldn't be too difficult to separate the two
> >> out and push the section stuff into a new BFD python interface and
> >> associate the objfiles with it.
> >
> > And here's what I've come up with.  Does this constitute enough of a
> > separation?  It /should/ cross over into the BFD code in the same way
> > that the GDB code does: As soon as we hit a bfd object or a
> > bfd_section object, we call into bfd's new python API to generate the
> > objects.
> >
> > https://jeffm.io/git/cgit.cgi/gnu/binutils-gdb/log/?h=gdb/python-bfd
> >
> > For the fully-integrated kdump work, use the python-bfd-kdump branch
> > (or SUSE folks, python-bfd-kdump-buildid will pick up the separate
> > debuginfos as we usually expect).
> 
> Separation isn't the issue, unfortunately.
> The issue is that we cannot export bfd to python, period.

Excuse my ignorance, but can you explain a bit more why BFD should not
be used? I'm sure there has been some discussion on that topic; a
pointer in the right direction would be welcome.

TIA,
Petr Tesarik
  
Matt Rice Feb. 4, 2016, 6:32 p.m. UTC | #9
On Thu, Feb 4, 2016 at 9:25 AM, Petr Tesarik <ptesarik@suse.cz> wrote:
> Hi Doug,
>
> On Wed, 3 Feb 2016 10:30:20 -0800
> Doug Evans <dje@google.com> wrote:
>
>> On Wed, Feb 3, 2016 at 9:55 AM, Jeff Mahoney <jeffm@suse.com> wrote:
>> >...
>> >>> Hi.
>> >>
>> >> Hi Doug -
>> >>
>> >>> Part of what this patch is doing is exporting bfd to python.
>> >>> E.g., all the SEC_* constants.
>> >>
>> >>> As a rule we absolutely discourage people from using bfd outside
>> >>> of the the binutils+gdb source tree. Either this rule needs to
>> >>> change, or I don't think we can allow this patch. I'd be
>> >>> interested to hear what others in the community think.
>> >>
>> >> That's unfortunate.  The Linux kernel uses ELF sections for a
>> >> number of purposes.  Most notably is the definition of per-cpu
>> >> variables. Without the ELF section, we can't resolve the addresses
>> >> for the variables.  So, from our perspective, it's a requirement.
>> >>
>> >>> For myself, I would much rather export ELF separately (e.g., a
>> >>> separate python API one can use independent of any particular
>> >>> tool, including gdb), and then have gdb provide the necessary
>> >>> glue to use this API. [I can imagine some compromises being
>> >>> needed, at least for now; e.g., it'd be cumbersome to read in all
>> >>> ELF symbols twice. But fixing that is just an optimization.]
>> >>
>> >> Ok, that's doable.  As it is, the section code mixes GDB and BFD
>> >> pretty heavily.  It shouldn't be too difficult to separate the two
>> >> out and push the section stuff into a new BFD python interface and
>> >> associate the objfiles with it.
>> >
>> > And here's what I've come up with.  Does this constitute enough of a
>> > separation?  It /should/ cross over into the BFD code in the same way
>> > that the GDB code does: As soon as we hit a bfd object or a
>> > bfd_section object, we call into bfd's new python API to generate the
>> > objects.
>> >
>> > https://jeffm.io/git/cgit.cgi/gnu/binutils-gdb/log/?h=gdb/python-bfd
>> >
>> > For the fully-integrated kdump work, use the python-bfd-kdump branch
>> > (or SUSE folks, python-bfd-kdump-buildid will pick up the separate
>> > debuginfos as we usually expect).
>>
>> Separation isn't the issue, unfortunately.
>> The issue is that we cannot export bfd to python, period.
>
> Excuse my ignorance, but can you explain a bit more why BFD should not
> be used? I'm sure there has been some discussion on that topic; a
> pointer in the right direction would be welcome.

BFD has never provided releases which admit conformance to a stable API/ABI
or the BFD library has always been an unstable API which you include
directly and use locally in your program.

Currently when a change to BFD would break some BFD using program,
that program would be fixed to use the new API.

Exporting BFD from gdb entails a level of certainty about how BFD may
change in the future so we can keep this exported API the same in gdb
as BFD changes underneath it.

the closest thing I could find to this effect is from the BFD:
"BFD is normally built as part of another package.  See the build
instructions for that package"
  
Doug Evans Feb. 4, 2016, 10:26 p.m. UTC | #10
On Thu, Feb 4, 2016 at 9:25 AM, Petr Tesarik <ptesarik@suse.cz> wrote:
>
> Hi Doug,
>
> On Wed, 3 Feb 2016 10:30:20 -0800
> Doug Evans <dje@google.com> wrote:
>
> > On Wed, Feb 3, 2016 at 9:55 AM, Jeff Mahoney <jeffm@suse.com> wrote:
> > >...
> > >>> Hi.
> > >>
> > >> Hi Doug -
> > >>
> > >>> Part of what this patch is doing is exporting bfd to python.
> > >>> E.g., all the SEC_* constants.
> > >>
> > >>> As a rule we absolutely discourage people from using bfd outside
> > >>> of the the binutils+gdb source tree. Either this rule needs to
> > >>> change, or I don't think we can allow this patch. I'd be
> > >>> interested to hear what others in the community think.
> > >>
> > >> That's unfortunate.  The Linux kernel uses ELF sections for a
> > >> number of purposes.  Most notably is the definition of per-cpu
> > >> variables. Without the ELF section, we can't resolve the addresses
> > >> for the variables.  So, from our perspective, it's a requirement.
> > >>
> > >>> For myself, I would much rather export ELF separately (e.g., a
> > >>> separate python API one can use independent of any particular
> > >>> tool, including gdb), and then have gdb provide the necessary
> > >>> glue to use this API. [I can imagine some compromises being
> > >>> needed, at least for now; e.g., it'd be cumbersome to read in all
> > >>> ELF symbols twice. But fixing that is just an optimization.]
> > >>
> > >> Ok, that's doable.  As it is, the section code mixes GDB and BFD
> > >> pretty heavily.  It shouldn't be too difficult to separate the two
> > >> out and push the section stuff into a new BFD python interface and
> > >> associate the objfiles with it.
> > >
> > > And here's what I've come up with.  Does this constitute enough of a
> > > separation?  It /should/ cross over into the BFD code in the same way
> > > that the GDB code does: As soon as we hit a bfd object or a
> > > bfd_section object, we call into bfd's new python API to generate the
> > > objects.
> > >
> > > https://jeffm.io/git/cgit.cgi/gnu/binutils-gdb/log/?h=gdb/python-bfd
> > >
> > > For the fully-integrated kdump work, use the python-bfd-kdump branch
> > > (or SUSE folks, python-bfd-kdump-buildid will pick up the separate
> > > debuginfos as we usually expect).
> >
> > Separation isn't the issue, unfortunately.
> > The issue is that we cannot export bfd to python, period.
>
> Excuse my ignorance, but can you explain a bit more why BFD should not
> be used? I'm sure there has been some discussion on that topic; a
> pointer in the right direction would be welcome.



Hi.
I'm not sure this is written down anywhere, but
the basic answer is that bfd is explicitly not a published API.
The developers reserve the right to rewrite it at will.
[Not that any kind of "rewrite" will ever happen,
but things do get changed.]
Exporting it to python means such changes are
harder, if not impossible, to make.

Which isn't to say that the gnu tools shouldn't
be providing published APIs for such things.
I think they should.
But bfd has a lot of, ummm, history,
and publishing it as a stable API is unlikely to
get buy-in
from anyone. I could be wrong of course.
Maybe someone could start carving off
bits of it to publish, but I would go slow
and get consensus before proceeding too far -
I wouldn't want anyone to end up wasting time on
this.
  

Patch

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\