From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 97077 invoked by alias); 31 Jan 2016 21:45:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 96854 invoked by uid 89); 31 Jan 2016 21:45:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=no version=3.3.2 spammy=supplies, sk:symbol_, 353, vma X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Sun, 31 Jan 2016 21:45:16 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 3A91CAC04 for ; Sun, 31 Jan 2016 21:45:02 +0000 (UTC) Received: by linux-2znx.site (Postfix, from userid 1001) id B9F8D783E8B; Sun, 31 Jan 2016 22:45:01 +0100 (CET) From: Ales Novak To: gdb-patches@sourceware.org Cc: Ales Novak Subject: [PATCH 2/4] Add Jeff Mahoney's py-crash patches. Date: Sun, 31 Jan 2016 21:45:00 -0000 Message-Id: <1454276692-7119-3-git-send-email-alnovak@suse.cz> In-Reply-To: <1454276692-7119-1-git-send-email-alnovak@suse.cz> References: <1454276692-7119-1-git-send-email-alnovak@suse.cz> X-IsSubscribed: yes X-SW-Source: 2016-01/txt/msg00734.txt.bz2 --- 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 . */ + +#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 . */ + +#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