This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 2/4] Add Jeff Mahoney's py-crash patches.
- From: Ales Novak <alnovak at suse dot cz>
- To: gdb-patches at sourceware dot org
- Cc: Ales Novak <alnovak at suse dot cz>
- Date: Sun, 31 Jan 2016 22:44:50 +0100
- Subject: [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>
---
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\
--
2.7.0