From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 99477 invoked by alias); 5 Feb 2016 12:25:42 -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 99466 invoked by uid 89); 5 Feb 2016 12:25:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.7 required=5.0 tests=BAYES_00,KAM_STOCKGEN,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=no version=3.3.2 spammy=rooted, 407, 2418, 4006 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 05 Feb 2016 12:25:39 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id BA4FF77356; Fri, 5 Feb 2016 12:25:38 +0000 (UTC) Received: from [10.36.112.51] (ovpn-112-51.ams2.redhat.com [10.36.112.51]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u15CPaf5012486; Fri, 5 Feb 2016 07:25:37 -0500 Subject: Re: [PATCH 6/7] py-minsymbol: Add interface to access minimal_symbols To: jeffm@suse.com, gdb-patches@sourceware.org References: <1454606973-31017-1-git-send-email-jeffm@suse.com> <1454606973-31017-7-git-send-email-jeffm@suse.com> From: Phil Muldoon Message-ID: <56B494C0.2040205@redhat.com> Date: Fri, 05 Feb 2016 12:25:00 -0000 MIME-Version: 1.0 In-Reply-To: <1454606973-31017-7-git-send-email-jeffm@suse.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2016-02/txt/msg00141.txt.bz2 On 04/02/16 17:29, jeffm@suse.com wrote: > From: Jeff Mahoney > > This patch adds a new gdb.MinSymb= ol object to export the minimal_symbol > interface. These objects can be r= esolved using a new > gdb.lookup_minimal_symbol call. > --- > gdb/Makefile= .in | 6 + > gdb/python/py-minsymbol.c | 390 ++++++++++++= +++++++++++++++++++++++++++++++ > gdb/python/python-internal.h | 6 + > = gdb/python/python.c | 5 + > 4 files changed, 407 insertions(+) = > create mode 100644 gdb/python/py-minsymbol.c > > diff --git a/gdb/Makefi= le.in b/gdb/Makefile.in > index 3eadbbc..c2f7eef 100644 > --- a/gdb/Makefil= e.in > +++ b/gdb/Makefile.in > @@ -400,6 +400,7 @@ SUBDIR_PYTHON_OBS =3D \ = > py-infthread.o \ > py-lazy-string.o \ > py-linetable.o \ >= + py-minsymbol.o \ > py-newobjfileevent.o \ > py-objfile.o \ = > py-param.o \ > @@ -440,6 +441,7 @@ SUBDIR_PYTHON_SRCS =3D \ > p= ython/py-infthread.c \ > python/py-lazy-string.c \ > python/py-li= netable.c \ > + python/py-minsymbol.c \ >=20=20=20=20=20 python/py-newobjfileevent.c \ > python/py-objfile.c \ > python/py= -param.c \ > @@ -2635,6 +2637,10 @@ py-linetable.o: $(srcdir)/python/py-lin= etable.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-newobjfile= event.c > $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-newobjfileev= ent.c > $(POSTCOMPILE) > diff --git a/gdb/python/py-minsymbol.c b/gdb/= python/py-minsymbol.c > new file mode 100644 > index 0000000..d8b56bc > ---= /dev/null > +++ b/gdb/python/py-minsymbol.c > @@ -0,0 +1,390 @@ > +/* Pyth= on interface to minsymbols. > + > + Copyright (C) 2008-2013 Free Software= Foundation, Inc. Wrong copyright date. > + > + 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 versi= on. > + > + This program is distributed in the hope that it will be usefu= l, > + 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. I= f not, see . */ > + > +#include "defs.h" > += #include "block.h" > +#include "exceptions.h" > +#include "frame.h" > +#inc= lude "symtab.h" > +#include "python-internal.h" > +#include "objfiles.h" > = +#include "value.h" > + > +typedef struct msympy_symbol_object { > + PyObj= ect_HEAD > + /* The GDB minimal_symbol structure this object is wrapping. */ > + struct m= inimal_symbol *minsym; > + struct objfile *objfile; > + > + 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; Can you please document all elements in the struct. > +/* Return the symbol that is wrapped by this symbol object. */ > +stati= c struct minimal_symbol * > +minsym_object_to_minsym (PyObject *obj) > +{ >= + if (! PyObject_TypeCheck (obj, &minsym_object_type)) > + return NULL= ; > + return ((minsym_object *) obj)->minsym; > +} > + > +static struct ob= jfile * > +minsym_object_to_objfile (PyObject *obj) > +{ > + if (! PyObjec= t_TypeCheck (obj, &minsym_object_type)) > + return NULL; > + return ((m= insym_object *) obj)->objfile; > +} > + > +/* 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 =3D minsym_object_to_minsym (minsym_obj); = \ > + if (minsym =3D=3D NULL) \ > + { = \ > + PyErr_SetString (PyExc_RuntimeError, \ > + = _("MinSymbol is invalid.")); \ > + return NULL; = \ > + } \ > + } while (0) > + > += #define MSYMPY_REQUIRE_VALID_BOUND(minsym_obj, minsym, objfile) \ > + do { = \ > + minsym =3D minsym_object_to_minsym (min= sym_obj); \ > + objfile =3D minsym_object_to_objfile (minsym_obj)= ; \ > + if (minsym =3D=3D NULL || objfile =3D=3D NULL) = \ > + { \ > + PyErr_SetString (PyEx= c_RuntimeError, \ > + _("MinSymbol is invalid.")); = \ > + return NULL; \ > + } = \ > + } while (0) > + > +static PyObject * > +msympy_s= tr (PyObject *self) > +{ > + PyObject *result; > + struct minimal_symbol = *minsym =3D NULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym); > + > + re= sult =3D PyString_FromString (MSYMBOL_PRINT_NAME (minsym)); > + > + return= result; > +} > + > +static PyObject * > +msympy_get_name (PyObject *self, = void *closure) > +{ > + struct minimal_symbol *minsym =3D NULL; > + > + M= SYMPY_REQUIRE_VALID (self, minsym); > + > + return PyString_FromString (MSYMBOL_NATURAL_NAME (minsym)= ); > +} > + > +static PyObject * > +msympy_get_file_name (PyObject *self, v= oid *closure) > +{ > + struct minimal_symbol *minsym =3D NULL; > + > + MS= YMPY_REQUIRE_VALID (self, minsym); > + > + return PyString_FromString (min= sym->filename); > +} > + > +static PyObject * > +msympy_get_linkage_name (P= yObject *self, void *closure) > +{ > + struct minimal_symbol *minsym =3D N= ULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym); > + > + return PyString= _FromString (MSYMBOL_LINKAGE_NAME (minsym)); > +} > + > +static PyObject * = > +msympy_get_print_name (PyObject *self, void *closure) > +{ > + struct m= inimal_symbol *minsym =3D NULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym= ); > + > + return msympy_str (self); > +} > + > +static PyObject * > +msym= py_get_section (PyObject *self, void *closure) > +{ > + struct minimal_sym= bol *minsym =3D NULL; > + struct objfile *objfile =3D NULL; > + struct ob= j_section *section; > +=20 const char *name; > + > + MSYMPY_REQUIRE_VALID_BOUND (self, minsym, objfil= e); > + > + section =3D MSYMBOL_OBJ_SECTION (objfile, minsym); > + if (se= ction) { Newline before {. > + name =3D bfd_section_name (objfile->obfd, section->the_bfd_section);= > + if (name) > + return PyString_FromString (name); > + } > + > = + Py_RETURN_NONE; > + > +} > + > +static PyObject * > +msympy_is_valid (Py= Object *self, PyObject *args) > +{ > + struct minimal_symbol *minsym =3D N= ULL; > + > + minsym =3D minsym_object_to_minsym (self); > + if (minsym = =3D=3D NULL) > + Py_RETURN_FALSE; > + > + Py_RETURN_TRUE; > +} > + > +/= * Implementation of gdb.MinSymbol.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 =3D (minsym_object *)self; > + struct minimal_= symbol *minsym =3D NULL; > + struct value *value =3D NULL; > + > + if (!P= yArg_ParseTuple (args, "")) > + return NULL; > + > + MSYMPY_REQUIRE_VAL= ID (self, minsym); > + TRY > + { > + value =3D value_from_ulongest= (minsym_obj->type, > + MSYMBOL_VALUE_RAW_ADDRESS(minsym)); Spaces in function name and (. This an others. > + if (value) > + set_value_address(value, MSYMBOL_VALUE_RAW_ADDRE= SS(minsym)); > + } Ditto x 2. > + CATCH (except, RETURN_MASK_ALL) > + { > + GDB_PY_HANDLE_EXCEPT= ION (except); > + } > + END_CATCH > + > + return value_to_value_object= (value); > +} > + > +/* Given a symbol, and a minsym_object that has previ= ously been > + allocated and initialized, populate the minsym_object with= the > + struct minimal_symbol data. Also, register the minsym_object li= fe-cycle > + with the life-cycle of the object file associated with this = > + symbol, if needed. */ > +static void > +set_symbol (minsym_object *o= bj, struct bound_minimal_symbol *bound) > +{ > + obj->minsym =3D bound->mi= nsym; > + obj->objfile =3D bound->objfile; > + switch (obj->minsym->type)= { > + case mst_text: > + case mst_solib_trampoline: > + case mst_file_t= ext: > + case mst_text_gnu_ifunc: > + case mst_slot_got_plt: > + obj->= type =3D builtin_type(python_gdbarch)->builtin_func_ptr; > + break; > + Ditto. > + case mst_data: > + case mst_abs: > + case mst_bss: > + case mst_fil= e_data: > + case mst_file_bss: > + obj->type =3D builtin_type(python_gd= barch)->builtin_data_ptr; > + break; > + Ditto. > + case mst_unknown: > + default: > + obj->type =3D builtin_type(pyth= on_gdbarch)->builtin_void; > + break; > + } > + Ditto. > + obj->prev =3D NULL; > + obj->next =3D NULL; > +} > + > +static PyObje= ct * > +bound_minsym_to_minsym_object (struct bound_minimal_symbol *bound) = > +{ > + minsym_object *msym_obj; > + > + msym_obj =3D PyObject_New (mins= ym_object, &minsym_object_type); > + if (msym_obj) > + set_symbol (msym= _obj, bound); > + > + return (PyObject *) msym_obj; > +} > + > +static voi= d > +msympy_dealloc (PyObject *obj) > +{ > + minsym_object *msym_obj =3D (= minsym_object *) obj; > + > + if (msym_obj->prev) > + msym_obj->prev->n= ext =3D msym_obj->next; > + if (msym_obj->next) > + msym_obj->next->pre= v =3D msym_obj->prev; > + msym_obj->minsym =3D NULL; > + msym_obj->objfil= e =3D NULL; > +} > + > +/* Implementation of > + gdb.lookup_minimal_symbo= l (name) -> symbol or None. */ > + > +PyObject * > +gdbpy_lookup_minimal_s= ymbol (PyObject *self, PyObject *args, PyObject *kw) > +{ > + int domain = =3D VAR_DOMAIN; > + const char *name; > + static char *keywords[] =3D { "= name", NULL }; > + struct bound_minimal_symbol bound_minsym =3D {}; > + struct minimal_symbol *minsym =3D NULL; > + PyOb= ject *msym_obj =3D NULL; > + > + if (!PyArg_ParseTupleAndKeywords (args, k= w, "s|", keywords, &name)) > + return NULL; > + > + TRY > + { > + = bound_minsym =3D lookup_minimal_symbol (name, NULL, NULL); > + } > + = CATCH (except, RETURN_MASK_ALL) > + { > + GDB_PY_HANDLE_EXCEPTION = (except); > + } > + END_CATCH > + > + if (bound_minsym.minsym) > + = msym_obj =3D bound_minsym_to_minsym_object (&bound_minsym); > + > + if (= msym_obj) > + return msym_obj; > + > + Py_RETURN_NONE; > +} > + > +int = > +gdbpy_initialize_minsymbols (void) > +{ > + if (PyType_Ready (&minsym_o= bject_type) < 0) > + return -1; > + > + if (PyModule_AddIntConstant (gd= b_module, "MINSYMBOL_TYPE_UNKNOWN", > + mst_unknown) < 0 = > + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_TEXT", mst_tex= t) < 0 > + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_TEXT_GN= U_IFUNC", > +=20=20=20=20=20=20=20=20=20=20=20 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", ms= t_bss) < 0 > + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_ABS= ", mst_abs) < 0 > + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYP= E_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_pymodu= le_addobject (gdb_module, "MinSymbol", > + (PyObject *) &minsym_object_type); > +} > + > +=0C > + > +static PyGetSetDef minsym_obje= ct_getset[] =3D { > + { "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_g= et_file_name, NULL, > + "Name of source file that contains this symbol. = Only applies for mst_file_*.", > + NULL }, > + { "print_name", msympy_g= et_print_name, NULL, > + "Name of the symbol in a form suitable for outp= ut.\n\ > +This is either name or linkage_name, depending on whether the use= r asked GDB\n\ > +to display demangled or mangled names.", NULL }, > + { "= section", msympy_get_section, NULL, > + "Section that contains this symb= ol, if any", NULL, }, > + { NULL } /* Sentinel */ > +}; > + > +static PyM= ethodDef minsym_object_methods[] =3D { > + { "is_valid", msympy_is_valid, = METH_NOARGS, > +=20=20=20 "is_valid () -> Boolean.\n\ > +Return true if this symbol is valid, false i= f not." }, > + { "value", msympy_value, METH_VARARGS, > + "value ([fram= e]) -> gdb.Value\n\ > +Return the value of the symbol." }, > + {NULL} /* = Sentinel */ > +}; > + > +PyTypeObject minsym_object_type =3D { > + PyVarOb= ject_HEAD_INIT (NULL, 0) > + "gdb.MinSymbol", /*tp_name*/ > + si= zeof (minsym_object), /*tp_basicsize*/ > + 0, /*tp_i= temsize*/ > + 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_mappin= g*/ > + 0, /*tp_hash */ > + 0, /*tp_cal= l*/ > + msympy_str, /*tp_str*/ > + 0, /*tp_= getattro*/ > +=20 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_m= ethods, /*tp_methods */ > + 0, /*tp_members */ > + = minsym_object_getset /*tp_getset */ > +}; > diff --git a/gdb/pytho= n/python-internal.h b/gdb/python/python-internal.h > index ee949b7..2fae31d= 100644 > --- a/gdb/python/python-internal.h > +++ b/gdb/python/python-inte= rnal.h > @@ -241,6 +241,8 @@ extern PyTypeObject block_object_type > C= PYCHECKER_TYPE_OBJECT_FOR_TYPEDEF("block_object"); > extern PyTypeObject s= ymbol_object_type > CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symbol_object= "); > +extern PyTypeObject minsym_object_type; > + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF= ("minsym_object"); > extern PyTypeObject event_object_type > CPYCHEC= KER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); > extern PyTypeObject stop_e= vent_object_type > @@ -362,6 +364,8 @@ PyObject *gdbpy_frame_stop_reason_st= ring (PyObject *, PyObject *); > PyObject *gdbpy_lookup_symbol (PyObject *= self, PyObject *args, PyObject *kw); > PyObject *gdbpy_lookup_global_symbo= l (PyObject *self, PyObject *args, > PyObject *kw); = > +PyObject *gdbpy_lookup_minimal_symbol (PyObject *self, PyObject *args, >= + PyObject *kw); > PyObject *gdbpy_newest_frame (Py= Object *self, PyObject *args); > PyObject *gdbpy_selected_frame (PyObject = *self, PyObject *args); > PyObject *gdbpy_block_for_pc (PyObject *self, Py= Object *args); > @@ -436,6 +440,8 @@ int gdbpy_initialize_commands (void) >= CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; > int gdbpy_initialize_symb= ols (void) >=20=20=20 CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; > +int gdbpy_initialize_minsymbo= ls (void) > + CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; > int gdbpy_init= ialize_symtabs (void) > CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; > in= t gdbpy_initialize_blocks (void) > diff --git a/gdb/python/python.c b/gdb/p= ython/python.c > index 6cbe5f0..30a86e1 100644 > --- a/gdb/python/python.c = > +++ b/gdb/python/python.c > @@ -1800,6 +1800,7 @@ message =3D=3D an error= message without a stack will be printed."), > || gdbpy_initialize_f= rames () < 0 > || gdbpy_initialize_commands () < 0 > || gdbpy= _initialize_symbols () < 0 > + || gdbpy_initialize_minsymbols () < 0 >= || gdbpy_initialize_symtabs () < 0 > || gdbpy_initialize_blo= cks () < 0 > || gdbpy_initialize_functions () < 0 > @@ -2025,6 +2026= ,10 @@ a boolean indicating if name is a field of the current implied argum= ent\n\ > METH_VARARGS | METH_KEYWORDS, > "lookup_global_symbol (n= ame [, 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, This needs a set of tests and documentation. Cheers Phil