This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH 2/4] Add Jeff Mahoney's py-crash patches.
- From: Kieran Bingham <kieran dot bingham at linaro dot org>
- To: Ales Novak <alnovak at suse dot cz>, gdb-patches at sourceware dot org
- Date: Mon, 1 Feb 2016 12:34:41 +0000
- Subject: Re: [PATCH 2/4] Add Jeff Mahoney's py-crash patches.
- Authentication-results: sourceware.org; auth=none
- References: <1454276692-7119-1-git-send-email-alnovak at suse dot cz> <1454276692-7119-3-git-send-email-alnovak at suse dot cz>
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, §ion_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, §ion_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, §ion_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 (§ion_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 *) §ion_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\