From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 86241 invoked by alias); 1 Feb 2016 12:35:06 -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 86133 invoked by uid 89); 1 Feb 2016 12:35:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=no version=3.3.2 spammy=supplies, sk:symbol_, 353, rooted X-HELO: mail-wm0-f47.google.com Received: from mail-wm0-f47.google.com (HELO mail-wm0-f47.google.com) (74.125.82.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 01 Feb 2016 12:34:46 +0000 Received: by mail-wm0-f47.google.com with SMTP id l66so68009559wml.0 for ; Mon, 01 Feb 2016 04:34:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=gdFNirWv2898Lf8qakY6CsoMMObkh95yqafT9IHcErI=; b=dKlgzeVD7WCazuh2uQmRJonJ9zWmZ7euD4/0OgOE6KF5go87msQXU9t21YJ5jB7VWG CmrFqHrdkJWZPRgdMAmLWgQSo+vMQxq/V0h3iqVq6UHVJIYXZ49474iAZjNTNWV1WnTL 1vc2IvJh8NjDMJmesb80q5Q41K4Qjxu/rK6rPo9IAzQHEDIE7mGxv3hRii3FSwJQvXnc gIusN5rnOzcR8slWdA/tTslgMqeH2WuXGCTJcMFTNXN3SqqfoTVsjqpWK4oa/C8rCqIO 2TtlXwgQ1QIKzso8P1bDee3W0HF1ZNtbp/DT/6U9mza7sqFg4ZkChodqzfRhKdwit0FI 66lg== X-Gm-Message-State: AG10YOTC6BbpnzYVTI4Cku7RUiNPgCSFk6LFujZPQ0IKYsczRhHpjWjI/QBmoBuL4MQSJJ6k X-Received: by 10.28.126.65 with SMTP id z62mr12205588wmc.3.1454330082692; Mon, 01 Feb 2016 04:34:42 -0800 (PST) Received: from [192.168.0.31] (cpc87017-aztw30-2-0-cust65.18-1.cable.virginm.net. [92.232.232.66]) by smtp.gmail.com with ESMTPSA id kb5sm29024784wjc.22.2016.02.01.04.34.41 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 01 Feb 2016 04:34:42 -0800 (PST) Subject: Re: [PATCH 2/4] Add Jeff Mahoney's py-crash patches. To: Ales Novak , gdb-patches@sourceware.org References: <1454276692-7119-1-git-send-email-alnovak@suse.cz> <1454276692-7119-3-git-send-email-alnovak@suse.cz> From: Kieran Bingham X-Enigmail-Draft-Status: N1110 Message-ID: <56AF50E1.3000301@linaro.org> Date: Mon, 01 Feb 2016 12:35:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 In-Reply-To: <1454276692-7119-3-git-send-email-alnovak@suse.cz> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-02/txt/msg00008.txt.bz2 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 . */ > + > +#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\