From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22570 invoked by alias); 26 Nov 2018 11:17:02 -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 22558 invoked by uid 89); 26 Nov 2018 11:17:01 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,KAM_STOCKGEN,SPF_PASS autolearn=ham version=3.3.2 spammy=tendency, som, reality, typical X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 26 Nov 2018 11:16:52 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 76E1CAEC1; Mon, 26 Nov 2018 11:16:49 +0000 (UTC) Subject: [PING][PATCH][gdb/python] Add interface to access minimal_symbols From: Tom de Vries To: Simon Marchi , gdb-patches@sourceware.org, Phil Muldoon , Tom Tromey References: <20181004211115.GA31056@delia> <39c4336d-c749-6f79-5a29-0b764fc4935e@ericsson.com> <211c4746-389a-93b7-faf9-c8f9b6245541@suse.de> Message-ID: <98824cdf-deaa-3d3c-eaae-f2abdb36d57a@suse.de> Date: Mon, 26 Nov 2018 11:17:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0 MIME-Version: 1.0 In-Reply-To: <211c4746-389a-93b7-faf9-c8f9b6245541@suse.de> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2018-11/txt/msg00436.txt.bz2 On 31-10-18 17:59, Tom de Vries wrote: > On 10/5/18 6:43 AM, Simon Marchi wrote: >> On 2018-10-04 05:11 PM, Tom de Vries wrote: >>> Hi, >>> >>> [ Submitted earlier here ( >>> https://sourceware.org/ml/gdb-patches/2016-02/msg00124.html ). ] >>> >>> This patch adds a new gdb.MinSymbol object to export the minimal_symbol >>> interface. >>> >>> Build and reg-tested on x86_64-linux. >>> >>> OK for trunk? >>> >>> Thanks, >>> - Tom >> Hi Tom, >> >> I think I have read (probably from Phil or Tom Tromey) that the intention was to >> expose minsyms and full symbols using the same Symbol class, to avoid exposing >> the fact that GDB represents symbols in different ways internally. I don't know >> if there was some concrete plans for that or if it was just at the idea stage. >> >> Otherwise, I'd be fine with exposing gdb.MinSyms and documenting that they map to >> the binary file format symbols (ELF, PE, mach-O, etc) while gdb.Symbols map to >> debug info symbols. I think it's a reality that will not change any time soon, >> and it could be useful for users of the Python API to make the distinction >> between the two. >> >> Maybe I'm missing something that has already been discussed that makes exposing >> minsyms a bad idea, in that case Phil and Tom are probably going to be able to >> shed som light on that. In the mean time here are a bunch of random >> comments/suggestions. >> >> * A general GDB-specific code style comment, every time you compare a pointer >> to know if it's NULL or not, it should be explicitly "ptr == NULL" or "ptr != NULL". > Done. > >> * Please make sure that all functions are documented (with an introductory comment). >> > Done. > >>> [gdb/python] Add interface to access minimal_symbols >>> >>> 2018-09-27 Jeff Mahoney >>> Tom de Vries >>> >>> * Makefile.in (SUBDIR_PYTHON_SRCS): Add python/py-minsymbol.c. >>> * python/py-minsymbol.c: New file. >>> * python/py-objfile.c (objfpy_object_to_objfile): New function. >>> * python/python-internal.h (minsym_object_type) >>> (gdbpy_lookup_minimal_symbol, objfpy_object_to_objfile): >>> (gdbpy_initialize_minsymbols): Declare. >>> * python/python.c (do_start_initialization): Call >>> gdbpy_initialize_minsymbols. >>> (python_GdbMethods): Add lookup_minimal_symbol entry. >>> >>> * python.texi (@node Python API): Add "Minimal Symbols In Python" menu >>> entry. >>> (@node Minimal Symbols In Python): New node. >>> >>> * gdb.python/py-minsymbol.c: New test. >>> * gdb.python/py-minsymbol.exp: New file. >>> >>> --- >>> gdb/Makefile.in | 1 + >>> gdb/doc/python.texi | 140 +++++++++ >>> gdb/python/py-minsymbol.c | 492 ++++++++++++++++++++++++++++++ >>> gdb/python/py-objfile.c | 9 + >>> gdb/python/python-internal.h | 7 + >>> gdb/python/python.c | 5 + >>> gdb/testsuite/gdb.python/py-minsymbol.c | 38 +++ >>> gdb/testsuite/gdb.python/py-minsymbol.exp | 67 ++++ >>> 8 files changed, 759 insertions(+) >>> >>> diff --git a/gdb/Makefile.in b/gdb/Makefile.in >>> index 8d780ac758..489dab5ca1 100644 >>> --- a/gdb/Makefile.in >>> +++ b/gdb/Makefile.in >>> @@ -377,6 +377,7 @@ SUBDIR_PYTHON_SRCS = \ >>> python/py-instruction.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 \ >>> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi >>> index 1035be33f0..d91f6e35c5 100644 >>> --- a/gdb/doc/python.texi >>> +++ b/gdb/doc/python.texi >>> @@ -158,6 +158,7 @@ optional arguments while skipping others. Example: >>> * Frames In Python:: Accessing inferior stack frames from Python. >>> * Blocks In Python:: Accessing blocks from Python. >>> * Symbols In Python:: Python representation of symbols. >>> +* Minimal Symbols In Python:: Python representation of minimal symbols. >>> * Symbol Tables In Python:: Python representation of symbol tables. >>> * Line Tables In Python:: Python representation of line tables. >>> * Breakpoints In Python:: Manipulating breakpoints using Python. >>> @@ -4878,6 +4879,145 @@ The value does not actually exist in the program. >>> The value's address is a computed location. >>> @end vtable >>> >>> +@node Minimal Symbols In Python >>> +@subsubsection Python representation of Minimal Symbols. >>> + >>> +@cindex minsymbols in python >>> +@tindex gdb.MinSymbol >>> + >>> +@value{GDBN} represents every variable, function and type as an >>> +entry in a symbol table. @xref{Symbols, ,Examining the Symbol Table}. >>> +Typical symbols like functions, variables, etc are represented by >>> +gdb.Symbol objects in Python. Some symbols are defined with less >>> +information associated with them, like linker script variables >>> +or assembly labels. Python represents these minimal symbols in @value{GDBN} >>> +with the @code{gdb.MinSymbol} object. >> Here for example, I would make it clear that a MinSym == a symbol provided by the >> binary file format, and would cite ELF, PE and mach-O as examples. I think that >> would make it more obvious to the reader. >> > Done. > >>> + >>> +The following minimal symbol-related functions are available in the @code{gdb} >>> +module: >>> + >>> +@findex gdb.lookup_minimal_symbol >>> +@defun gdb.lookup_minimal_symbol (name @r{[}, sfile@r{]}, objfile@r{[}) >> The square bracket look wrong. Since sfile and objfile are keyword arguments, >> I guess you want them to look like this? >> >> gdb.lookup_minimal_symbol (name [, sfile][, objfile]) >> >> ? >> > Done. > >> Not in this patch, but I think we should document the default value for keyword >> arguments, like the official Python doc does, which would mean something like: >> >> gdb.lookup_minimal_symbol (name, sfile=None, objfile=None) >> >> >>> +This function searches for a minimal symbol by name. >>> +The search scope can be restricted by the sfile and objfile arguments. >>> + >>> +@var{name} is the name of the minimal symbol. It must be a string. >>> +The optional @var{sfile} argument restricts the search to the source file >>> +in which the minimal symbol was defined. >>> +The @var{sfile} argument must be a string. The optional @var{objfile} >>> +restricts the search to the objfile that contains the minimal symbol. >>> +The @var{objfile} argument must be a @code{gdb.Objfile} object. >> Can you try to split these in some kind of bullet, or at least one parameter >> per paragraph? I think we have a tendency to document parameters in a big >> paragraph, which does not make it easy to look up an individual parameter. >> >> I think a format like this makes it really easy to read: >> >> https://nodejs.org/dist/latest-v10.x/docs/api/buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length >> > Done. > >> Also, would it be possible to precise how the search is made, especially >> when multiple symbols match a search? If I have a C++ program with this: >> >> void allo(int x) >> { >> } >> >> void allo(float f) >> { >> } >> >> then doing gdb.lookup_minimal_symbol('allo') will only return one of them. >> > Done. > >> It would also be good to mention how the sfile argument is used, does it have >> to be an exact match, just the base name, any substring? >> > Done. > >>> +The result is a @code{gdb.MinSymbol} object or @code{None} if the symbol >>> +is not found. >>> +@end defun >>> + >>> +A @code{gdb.MinSymbol} object has the following attributes: >>> + >>> +@defvar MinSymbol.name >>> +The name of the symbol as a string. This attribute is not writable. >>> +@end defvar >>> + >>> +@defvar MinSymbol.linkage_name >>> +The name of the symbol, as used by the linker (i.e., may be mangled). >>> +This attribute is not writable. >>> +@end defvar >>> + >>> +@defvar MinSymbol.print_name >>> +The name of the symbol in a form suitable for output. This is either >>> +@code{name} or @code{linkage_name}, depending on whether the user >>> +asked @value{GDBN} to display demangled or mangled names. >>> +@end defvar >>> + >>> +@defvar MinSymbol.filename >>> +The file name of the source file where the minimal symbol is defined. This >>> +value may represent filenames used internally by the compiler rather >>> +than a viewable/editable source file. >>> +@end defvar >>> + >>> +@defvar MinSymbol.section >>> +The name of the binary section containing this minimal symbol. >>> +@end defvar >>> + >>> +@defvar MinSymbol.is_code >>> +@code{True} if the minimal symbol is a function or a method. >>> +@end defvar >>> + >>> +@defvar MinSymbol.is_data >>> +@code{True} if the symbol is a variable or other data. >>> +@end defvar >>> + >>> +A @code{gdb.MinSymbol} object has the following methods: >>> + >>> +@defun MinSymbol.is_valid () >>> +Returns @code{True} if the @code{gdb.MinSymbol} object is valid, >>> +@code{False} if not. A @code{gdb.MinSymbol} object can become invalid if >>> +the symbol it refers to does not exist in @value{GDBN} any longer. >>> +All other @code{gdb.MinSymbol} methods will throw an exception if it is >>> +invalid at the time the method is called. >>> +@end defun >>> + >>> +@defun MinSymbol.value () >>> +Compute the value of the minimal symbol, as a @code{gdb.Value}. The value >>> +returned represents the address of the minimal symbol. Since minimal symbols >>> +represent objects without rich type information, the @code{gdb.Type} >>> +associated with the @code{gdb.Value} objects will be limited to whether >>> +the minimal symbol describes executable code or data. >>> +@end defun >>> + >>> +The available types for @code{gdb.MinSymbol} are represented >>> +as constants in the @code{gdb} module. They are distinctly separate from the >>> +types represented by the @code{gdb.Type} object. >> I think the "type" method, that returns one of these, is not documented. >> > Done. > >>> +int >>> +gdbpy_initialize_minsymbols (void) >>> +{ >>> + if (PyType_Ready (&minsym_object_type) < 0) >>> + return -1; >>> + >>> + msympy_objfile_data_key >>> + = register_objfile_data_with_cleanup (NULL, del_objfile_msymbols); >>> + >>> + 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) >> I was a bit worried about exposing the internal enum values, but it seems like >> we do this in other places (like gdb.COMMAND_* constants). If scripts use the >> labels, they don't really care what the numerical value is. >> >>> + return -1; >>> + >>> + return gdb_pymodule_addobject (gdb_module, "MinSymbol", >>> + (PyObject *) &minsym_object_type); >>> +} >>> + >>> + >>> + >>> +static gdb_PyGetSetDef minsym_object_getset[] = { >>> + { "name", msympy_get_name, NULL, >>> + "Name of the minimal symbol, as it appears in the source code.", NULL }, >>> + { "linkage_name", msympy_get_linkage_name, NULL, >>> + "Name of the minimal symbol, as used by the linker (i.e., may be mangled).", >>> + NULL }, >>> + { "filename", msympy_get_file_name, NULL, >>> + "Name of source file that contains this minimal symbol. Only applies for" >>> + " mst_file_*.", >>> + NULL }, >>> + { "print_name", msympy_get_print_name, NULL, >>> + "Name of the minimal 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 }, >>> + { "section", msympy_get_section, NULL, >>> + "Section that contains this minimal symbol, if any", NULL, }, >> I would suggest naming this "section_name". It would leave the "section" property >> available so that ff we ever have a Python type to represent binary file sections, >> we can use it to return that. >> > Done. > >>> + { "type", msympy_get_type, NULL, >>> + "Type that this minimal symbol represents." }, >>> + { NULL } /* Sentinel */ >>> +}; >>> + >>> +static PyMethodDef minsym_object_methods[] = { >>> + { "is_valid", msympy_is_valid, METH_NOARGS, >>> + "is_valid () -> Boolean.\n\ >>> +Return true if this minimal symbol is valid, false if not." }, >>> + { "is_code", msympy_is_code, METH_NOARGS, >>> + "is_code () -> Boolean.\n\ >>> +Return true if this minimal symbol represents code." }, >>> + { "is_data", msympy_is_data, METH_NOARGS, >>> + "is_data () -> Boolean.\n\ >>> +Return true if this minimal symbol represents data." }, >>> + { "value", msympy_value, METH_VARARGS, >>> + "value ([frame]) -> gdb.Value\n\ >>> +Return the value of the minimal symbol." }, >>> + {NULL} /* Sentinel */ >>> +}; >>> + >>> +PyTypeObject minsym_object_type = { >>> + PyVarObject_HEAD_INIT (NULL, 0) >>> + "gdb.MinSymbol", /*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*/ >> I would suggest implementing repr instead, as we have done for >> gdb.Objfile and others. Also, I would suggest using the output >> style >> >> >> >> to be somewhat consistent. > Done. > > AFAIU, the purpose of repr is to print a unique representation, and > distinct symbols can have the same name, so I went for: > ... > > ... > for local symbols, dropping the filename=%s part for local symbols. > >> I think it helps when developing to >> have the type of the object printed. Plus, we make sure people >> don't rely on the output of repr/str to format the output the >> way they want :). >> > Retested as attached. > Ping. OK for trunk? Thanks, - Tom > 0001-gdb-python-Add-interface-to-access-minimal_symbols.patch > > [gdb/python] Add interface to access minimal_symbols > > [ Submitted earlier here ( > https://sourceware.org/ml/gdb-patches/2016-02/msg00124.html ). ] > > This patch adds a new gdb.MinSymbol object to export the minimal_symbol > interface. > > Build and reg-tested on x86_64-linux. > > 2018-09-27 Jeff Mahoney > Tom de Vries > > * NEWS: Mention new function gdb.lookup_minimal_symbol and new class > gdb.MinSymbol. > * Makefile.in (SUBDIR_PYTHON_SRCS): Add python/py-minsymbol.c. > * python/py-minsymbol.c: New file. > * python/py-objfile.c (objectfile_object_to_objfile): New function. > * python/python-internal.h (minsym_object_type) > (gdbpy_lookup_minimal_symbol, objectfile_object_to_objfile): > (gdbpy_initialize_minsymbols): Declare. > * python/python.c (do_start_initialization): Call > gdbpy_initialize_minsymbols. > (python_GdbMethods): Add lookup_minimal_symbol entry. > > * python.texi (@node Python API): Add "Minimal Symbols In Python" menu > entry. > (@node Minimal Symbols In Python): New node. > * gdb.texinfo (@anchor{set print demangle}): New anchor. > > * gdb.python/py-minsymbol.c: New test. > * gdb.python/py-minsymbol.exp: New file. > > --- > gdb/Makefile.in | 1 + > gdb/doc/python.texi | 139 ++++++++ > gdb/python/py-minsymbol.c | 511 ++++++++++++++++++++++++++++++ > gdb/python/py-objfile.c | 9 + > gdb/python/python-internal.h | 7 + > gdb/python/python.c | 5 + > gdb/testsuite/gdb.python/Makefile.in | 22 ++ > gdb/testsuite/gdb.python/py-minsymbol.exp | 59 ++++ > 8 files changed, 753 insertions(+) > > diff --git a/gdb/Makefile.in b/gdb/Makefile.in > index 73e15fcf12..75de424a36 100644 > --- a/gdb/Makefile.in > +++ b/gdb/Makefile.in > @@ -377,6 +377,7 @@ SUBDIR_PYTHON_SRCS = \ > python/py-instruction.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 \ > diff --git a/gdb/NEWS b/gdb/NEWS > index 4331769f21..b9b08a0daa 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -139,6 +139,9 @@ FreeBSD/riscv riscv*-*-freebsd* > gdb.SYMBOL_TYPES_DOMAIN are now deprecated. These were never > correct and did not work properly. > > + ** The new function gdb.lookup_minimal_symbol can be used to find minimal > + symbols. It return the new class gdb.MinSymbol. > + > * Configure changes > > --enable-ubsan > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 0226b6d88d..c1bdaa357f 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -10672,6 +10672,7 @@ These settings are of interest when debugging C@t{++} programs: > > @table @code > @cindex demangling C@t{++} names > +@anchor{set print demangle} > @item set print demangle > @itemx set print demangle on > Print C@t{++} names in their source form rather than in the encoded > diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi > index ff5fecea1b..f22fdfe8d6 100644 > --- a/gdb/doc/python.texi > +++ b/gdb/doc/python.texi > @@ -158,6 +158,7 @@ optional arguments while skipping others. Example: > * Frames In Python:: Accessing inferior stack frames from Python. > * Blocks In Python:: Accessing blocks from Python. > * Symbols In Python:: Python representation of symbols. > +* Minimal Symbols In Python:: Python representation of minimal symbols. > * Symbol Tables In Python:: Python representation of symbol tables. > * Line Tables In Python:: Python representation of line tables. > * Breakpoints In Python:: Manipulating breakpoints using Python. > @@ -4886,6 +4887,152 @@ The value's address is a symbol. This is only used for Fortran common > blocks. > @end vtable > > +@node Minimal Symbols In Python > +@subsubsection Python representation of Minimal Symbols. > + > +@cindex minsymbols in python > +@tindex gdb.MinSymbol > + > +@value{GDBN} represents every variable, function and type provided by > +the binary file format (f.i. ELF, PE or mach-O) as an entry in a > +symbol table. @xref{Symbols, ,Examining the Symbol Table}. > +Typical symbols like functions, variables, etc are represented by > +@code{gdb.Symbol} objects in Python. Some symbols are defined with less > +information associated with them, like linker script variables > +or assembly labels. Python represents these minimal symbols in @value{GDBN} > +with the @code{gdb.MinSymbol} object. > + > +The following minimal symbol-related functions are available in the @code{gdb} > +module: > + > +@defun gdb.lookup_minimal_symbol (name @r{[}, sfile@r{][}, objfile@r{]}) > +This function searches for a minimal symbol by name. The search scope > +can be restricted by the @var{sfile} and @var{objfile} arguments. > + > +@itemize @bullet > +@item > +The @var{name} argument is the name of the minimal symbol. It must be > +a string. Both mangled and demangled names can be used. > +@item > +The optional @var{sfile} argument restricts the search to the basename > +of source file @var{sfile} for local symbols. For global symbols, > +this argument has no effect. The @var{sfile} argument must be a string. > +@item > +The optional @var{objfile} > +restricts the search to the objfile that contains the minimal symbol. > +The @var{objfile} argument must be a @code{gdb.Objfile} object. > +@item > +The result is a @code{gdb.MinSymbol} object or @code{None} if the symbol > +is not found. In case there's more than one match, the first one > +found is returned. > +@end itemize > +@end defun > + > +A @code{gdb.MinSymbol} object has the following attributes: > + > +@defvar MinSymbol.name > +The name of the symbol as a string. This attribute is not writable. > +@end defvar > + > +@defvar MinSymbol.linkage_name > +The name of the symbol, as used by the linker (i.e., may be mangled). > +This attribute is not writable. > +@end defvar > + > +@defvar MinSymbol.print_name > +The name of the symbol in a form suitable for output. This is either > +@code{name} or @code{linkage_name}, depending on whether the user > +asked @value{GDBN} to display demangled or mangled names > +(@pxref{set print demangle}). > +@end defvar > + > +@defvar MinSymbol.filename > +The file name of the source file where the minimal symbol is defined. > +@end defvar > + > +@defvar MinSymbol.section_name > +The name of the section in the object file containing this minimal symbol. > +@end defvar > + > +@defvar MinSymbol.is_code > +@code{True} if the minimal symbol is a function or a method. > +@end defvar > + > +@defvar MinSymbol.is_data > +@code{True} if the symbol is a variable or other data. > +@end defvar > + > +@defun MinSymbol.type > +The type of the symbol. The value can be one of: > + > +@vtable @code > +@vindex MINSYMBOL_TYPE_UNKNOWN > +@item gdb.MINSYMBOL_TYPE_UNKNOWN > +This is used when the type has not been discovered or none of the > +following types apply. This usually indicates an error either > +in the symbol information or in @value{GDBN}'s handling of symbols. > + > +@vindex MINSYMBOL_TYPE_TEXT > +@item gdb.MINSYMBOL_TYPE_TEXT > +This type represents executable code. > + > +@vindex MINSYMBOL_TYPE_TEXT_GNU_IFUNC > +@item gdb.MINSYMBOL_TYPE_TEXT_GNU_IFUNC > +This type represents executable code that returns the address > +of executable code. > + > +@vindex MINSYMBOL_TYPE_SLOT_GOT_PLT > +@item gdb.MINSYMBOL_TYPE_SLOT_GOT_PLT > +This type represents GOT for .plt sections. > + > +@vindex MINSYMBOL_TYPE_DATA > +@item gdb.MINSYMBOL_TYPE_DATA > +This type represents generally initialized (nonzero) data. > + > +@vindex MINSYMBOL_TYPE_BSS > +@item gdb.MINSYMBOL_TYPE_BSS > +This type represents generally uninitialized (zeroed) data. > + > +@vindex MINSYMBOL_TYPE_ABS > +@item gdb.MINSYMBOL_TYPE_ABS > +This type represents generally absolute (non-relocatable) data. > + > +@vindex MINSYMBOL_TYPE_SOLIB_TRAMPOLINE > +@item gdb.MINSYMBOL_TYPE_SOLIB_TRAMPOLINE > +This type represents the start address of a shared library trampoline entry. > + > +@vindex MINSYMBOL_TYPE_FILE_TEXT > +@item gdb.MINSYMBOL_TYPE_FILE_TEXT > +This type represents the static version of @code{gdb.MINSYMBOL_TYPE_TEXT}. > + > +@vindex MINSYMBOL_TYPE_FILE_DATA > +@item gdb.MINSYMBOL_TYPE_FILE_DATA > +This type represents the static version of @code{gdb.MINSYMBOL_TYPE_DATA}. > + > +@vindex MINSYMBOL_TYPE_FILE_BSS > +@item gdb.MINSYMBOL_TYPE_FILE_BSS > +This type represents the static version of @code{gdb.MINSYMBOL_TYPE_BSS}. > +@end vtable > +@end defun > + > +A @code{gdb.MinSymbol} object has the following methods: > + > +@defun MinSymbol.is_valid () > +Returns @code{True} if the @code{gdb.MinSymbol} object is valid, > +@code{False} if not. A @code{gdb.MinSymbol} object can become invalid if > +the symbol it refers to does not exist in @value{GDBN} any longer. > +All other @code{gdb.MinSymbol} methods will throw an exception if it is > +invalid at the time the method is called. > +@end defun > + > +@defun MinSymbol.value () > +Compute the value of the minimal symbol, as a @code{gdb.Value}. The value > +returned represents the address of the minimal symbol. Since minimal symbols > +represent objects without rich type information, the @code{gdb.Type} > +associated with the @code{gdb.Value} objects will be limited to whether > +the minimal symbol describes executable code or data. > +@end defun > + > @node Symbol Tables In Python > @subsubsection Symbol table representation in Python > > diff --git a/gdb/python/py-minsymbol.c b/gdb/python/py-minsymbol.c > new file mode 100644 > index 0000000000..93df3f9da5 > --- /dev/null > +++ b/gdb/python/py-minsymbol.c > @@ -0,0 +1,560 @@ > +/* Python interface to minsymbols. > + > + Copyright (C) 2018 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" > +#include "py-ref.h" > + > +typedef struct msympy_symbol_object { > + PyObject_HEAD > + > + /* The GDB bound_minimal_symbol structure this object is wrapping. */ > + struct bound_minimal_symbol bound; > + > + /* A minsym 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; > + > +/* Return the symbol that is wrapped by this symbol object. */ > +static struct minimal_symbol * > +minsym_object_to_minsym (PyObject *obj) > +{ > + if (! PyObject_TypeCheck (obj, &minsym_object_type)) > + return NULL; > + return ((minsym_object *) obj)->bound.minsym; > +} > + > +/* Return the objectfile containing the symbol that is wrapped by this symbol > + object. */ > +static struct objfile * > +minsym_object_to_objfile (PyObject *obj) > +{ > + if (! PyObject_TypeCheck (obj, &minsym_object_type)) > + return NULL; > + return ((minsym_object *) obj)->bound.objfile; > +} > + > +/* Require a valid symbol. All access to minsym_object->bound.minsym 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, \ > + _("MinSymbol is invalid.")); \ > + return NULL; \ > + } \ > + } while (0) > + > +/* Require a valid bound. All access to minsym_object->bound should be > + gated by this call. */ > +#define MSYMPY_REQUIRE_VALID_BOUND(minsym_obj, minsym, objfile) \ > + do { \ > + minsym = minsym_object_to_minsym (minsym_obj); \ > + objfile = minsym_object_to_objfile (minsym_obj); \ > + if (minsym == NULL || objfile == NULL) \ > + { \ > + PyErr_SetString (PyExc_RuntimeError, \ > + _("MinSymbol is invalid.")); \ > + return NULL; \ > + } \ > + } while (0) > + > +static const struct objfile_data *msympy_objfile_data_key; > + > +/* Return string object containing MSYMBOL_PRINT_NAME for minsym object > + SELF. */ > + > +static PyObject * > +msympy_str (PyObject *self) > +{ > + struct minimal_symbol *minsym = NULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym); > + > + return PyString_FromString (MSYMBOL_PRINT_NAME (minsym)); > +} > + > +/* Implement repr() for gdb.MinSymbol. */ > + > +static PyObject * > +msympy_repr (PyObject *self) > +{ > + struct minimal_symbol *minsym = minsym_object_to_minsym (self); > + struct objfile *objfile = minsym_object_to_objfile (self); > + > + if (minsym->filename != NULL) > + return PyString_FromFormat (" + " objfile=%s>", > + MSYMBOL_LINKAGE_NAME (minsym), > + minsym->filename, > + objfile_filename (objfile)); > + > + return PyString_FromFormat ("", > + MSYMBOL_LINKAGE_NAME (minsym), > + objfile_filename (objfile)); > +} > + > +/* Implement gdb.MinSymbol.name -> String. */ > + > +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)); > +} > + > +/* Implement gdb.MinSymbol.filename -> String. */ > + > +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); > +} > + > +/* Implement gdb.MinSymbol.linkage_name -> String. */ > + > +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)); > +} > + > +/* Implement gdb.MinSymbol.print_name -> String. */ > + > +static PyObject * > +msympy_get_print_name (PyObject *self, void *closure) > +{ > + struct minimal_symbol *minsym = NULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym); > + > + return msympy_str (self); > +} > + > +/* Implement gdb.MinSymbol.section_name -> String. */ > + > +static PyObject * > +msympy_get_section (PyObject *self, void *closure) > +{ > + struct minimal_symbol *minsym = NULL; > + struct objfile *objfile = NULL; > + struct obj_section *section; > + const char *name; > + > + MSYMPY_REQUIRE_VALID_BOUND (self, minsym, objfile); > + > + section = MSYMBOL_OBJ_SECTION (objfile, minsym); > + if (section != NULL) > + { > + name = bfd_section_name (objfile->obfd, section->the_bfd_section); > + if (name != NULL) > + return PyString_FromString (name); > + } > + > + Py_RETURN_NONE; > +} > + > +/* Implement gdb.MinSymbol.type -> Int. */ > + > +static PyObject * > +msympy_get_type (PyObject *self, void *closure) > +{ > + struct minimal_symbol *minsym = NULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym); > + return PyInt_FromLong (MSYMBOL_TYPE (minsym)); > +} > + > +/* Implement gdb.MinSymbol.is_valid (self) -> Boolean. */ > + > +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; > +} > + > +/* Return gdbarch corresponding to minsym object MINSYM_OBJ. */ > + > +static struct gdbarch * > +minsym_gdbarch (PyObject *minsym_obj) > +{ > + return get_objfile_arch (minsym_object_to_objfile (minsym_obj)); > +} > + > +/* Return type corresponding to minsym object MINSYM_OBJ. */ > + > +static struct type * > +minsym_type (PyObject *minsym_obj) > +{ > + struct type *type; > + > + switch (minsym_object_to_minsym (minsym_obj)->type) > + { > + case mst_text: > + case mst_solib_trampoline: > + case mst_file_text: > + case mst_text_gnu_ifunc: > + case mst_slot_got_plt: > + type = builtin_type (minsym_gdbarch (minsym_obj))->builtin_func_ptr; > + break; > + > + case mst_data: > + case mst_abs: > + case mst_bss: > + case mst_file_data: > + case mst_file_bss: > + type = builtin_type (minsym_gdbarch (minsym_obj))->builtin_data_ptr; > + break; > + > + case mst_unknown: > + default: > + type = builtin_type (minsym_gdbarch (minsym_obj))->builtin_void; > + break; > + } > + > + return type; > +} > + > +/* Implement gdb.MinSymbol.is_code (self) -> Boolean. */ > + > +static PyObject * > +msympy_is_code (PyObject *self, PyObject *args) > +{ > + struct minimal_symbol *minsym = NULL; > + struct type *type; > + MSYMPY_REQUIRE_VALID (self, minsym); > + > + type = builtin_type (minsym_gdbarch (self))->builtin_func_ptr; > + > + if (minsym_type (self) == type) > + Py_RETURN_TRUE; > + > + Py_RETURN_FALSE; > +} > + > +/* Implement gdb.MinSymbol.is_data (self) -> Boolean. */ > + > +static PyObject * > +msympy_is_data (PyObject *self, PyObject *args) > +{ > + struct minimal_symbol *minsym = NULL; > + struct type *type; > + MSYMPY_REQUIRE_VALID (self, minsym); > + > + type = builtin_type (minsym_gdbarch (self))->builtin_data_ptr; > + > + if (minsym_type (self) == type) > + Py_RETURN_TRUE; > + > + Py_RETURN_FALSE; > +} > + > +/* 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 = (minsym_object *)self; > + struct minimal_symbol *minsym = NULL; > + struct value *value = NULL; > + > + if (!PyArg_ParseTuple (args, "")) > + return NULL; > + > + MSYMPY_REQUIRE_VALID (self, minsym); > + TRY > + { > + value = value_at_lazy (minsym_type (self), > + BMSYMBOL_VALUE_ADDRESS (minsym_obj->bound)); > + } > + CATCH (except, RETURN_MASK_ALL) > + { > + GDB_PY_HANDLE_EXCEPTION (except); > + } > + END_CATCH > + > + return value_to_value_object (value); > +} > + > +/* Given a bound minimal symbol, and a minsym_object that has previously been > + allocated and initialized, populate the minsym_object with the struct > + bound_minimal_symbol data. Also, register the minsym_objectlife-cycle with > + the life-cycle of the object file associated with this minimal symbol, if > + needed. */ > + > +static void > +set_symbol (minsym_object *obj, struct bound_minimal_symbol *bound) > +{ > + obj->bound = *bound; > + obj->prev = NULL; > + if (bound->objfile != NULL) > + { > + obj->next = (minsym_object *) objfile_data (bound->objfile, > + msympy_objfile_data_key); > + if (obj->next != NULL) > + obj->next->prev = obj; > + set_objfile_data (bound->objfile, msympy_objfile_data_key, obj); > + } > + else > + obj->next = NULL; > +} > + > +/* Create a new minsym object (gdb.MinSymbol) that encapsulates the struct > + bound_minimal_symbol object from GDB. */ > + > +static PyObject * > +bound_minsym_to_minsym_object (struct bound_minimal_symbol *bound) > +{ > + minsym_object *msym_obj; > + > + msym_obj = PyObject_New (minsym_object, &minsym_object_type); > + if (msym_obj != NULL) > + set_symbol (msym_obj, bound); > + > + return (PyObject *) msym_obj; > +} > + > +/* Deallocate minsym object. */ > + > +static void > +msympy_dealloc (PyObject *obj) > +{ > + minsym_object *msym_obj = (minsym_object *) obj; > + > + if (msym_obj->prev != NULL) > + msym_obj->prev->next = msym_obj->next; > + else if (msym_obj->bound.objfile != NULL) > + set_objfile_data (msym_obj->bound.objfile, > + msympy_objfile_data_key, msym_obj->next); > + if (msym_obj->next != NULL) > + msym_obj->next->prev = msym_obj->prev; > + msym_obj->bound.minsym = NULL; > + msym_obj->bound.objfile = NULL; > +} > + > +/* Implementation of > + gdb.lookup_minimal_symbol (name, [sfile, [objfile]]) -> symbol or None. */ > + > +PyObject * > +gdbpy_lookup_minimal_symbol (PyObject *self, PyObject *args, PyObject *kw) > +{ > + const char *name, *sfile = NULL; > + struct objfile *objfile = NULL; > + static const char *keywords[] = { "name", "sfile", "objfile", NULL }; > + struct bound_minimal_symbol bound_minsym = {}; > + PyObject *msym_obj = NULL, *sfile_obj = NULL, *objfile_obj = NULL; > + gdb::unique_xmalloc_ptr sfile_tmp; > + > + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|OO", keywords, &name, > + &sfile_obj, &objfile_obj)) > + return NULL; > + > + if (sfile_obj != NULL && sfile_obj != Py_None) > + { > + sfile_tmp = gdbpy_obj_to_string (sfile_obj); > + sfile = sfile_tmp.get (); > + } > + > + if (objfile_obj != NULL && objfile_obj != Py_None) > + { > + objfile = objectfile_object_to_objfile (objfile_obj); > + if (objfile == NULL) > + return NULL; > + } > + > + TRY > + { > + bound_minsym = lookup_minimal_symbol (name, sfile, objfile); > + } > + CATCH (except, RETURN_MASK_ALL) > + { > + GDB_PY_HANDLE_EXCEPTION (except); > + } > + END_CATCH > + > + if (bound_minsym.minsym != NULL) > + msym_obj = bound_minsym_to_minsym_object (&bound_minsym); > + > + if (msym_obj != NULL) > + return msym_obj; > + > + Py_RETURN_NONE; > +} > + > +/* This function is called when an objfile is about to be freed. > + Invalidate the minsym as further actions on the minsym would result > + in bad data. All access to obj->bound.minsym should be gated by > + MSYMPY_REQUIRE_VALID which will raise an exception on invalid > + minimal symbols. */ > + > +static void > +del_objfile_msymbols (struct objfile *objfile, void *datum) > +{ > + minsym_object *obj = (minsym_object *) datum; > + while (obj != NULL) > + { > + minsym_object *next = obj->next; > + > + obj->bound.minsym = NULL; > + obj->bound.objfile = NULL; > + obj->next = NULL; > + obj->prev = NULL; > + > + obj = next; > + } > +} > + > +/* Initialize gdb.MinSymbol. Return -1 on error, 0 on success. */ > + > +int > +gdbpy_initialize_minsymbols (void) > +{ > + if (PyType_Ready (&minsym_object_type) < 0) > + return -1; > + > + msympy_objfile_data_key > + = register_objfile_data_with_cleanup (NULL, del_objfile_msymbols); > + > + 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, "MinSymbol", > + (PyObject *) &minsym_object_type); > +} > + > + > + > +static gdb_PyGetSetDef minsym_object_getset[] = { > + { "name", msympy_get_name, NULL, > + "Name of the minimal symbol, as it appears in the source code.", NULL }, > + { "linkage_name", msympy_get_linkage_name, NULL, > + "Name of the minimal symbol, as used by the linker (i.e., may be mangled).", > + NULL }, > + { "filename", msympy_get_file_name, NULL, > + "Name of source file that contains this minimal symbol. Only applies for" > + " mst_file_*.", > + NULL }, > + { "print_name", msympy_get_print_name, NULL, > + "Name of the minimal 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 }, > + { "section_name", msympy_get_section, NULL, > + "Name of section that contains this minimal symbol, if any", NULL, }, > + { "type", msympy_get_type, NULL, > + "Type that this minimal symbol represents." }, > + { NULL } /* Sentinel */ > +}; > + > +static PyMethodDef minsym_object_methods[] = { > + { "is_valid", msympy_is_valid, METH_NOARGS, > + "is_valid () -> Boolean.\n\ > +Return true if this minimal symbol is valid, false if not." }, > + { "is_code", msympy_is_code, METH_NOARGS, > + "is_code () -> Boolean.\n\ > +Return true if this minimal symbol represents code." }, > + { "is_data", msympy_is_data, METH_NOARGS, > + "is_data () -> Boolean.\n\ > +Return true if this minimal symbol represents data." }, > + { "value", msympy_value, METH_VARARGS, > + "value ([frame]) -> gdb.Value\n\ > +Return the value of the minimal symbol." }, > + {NULL} /* Sentinel */ > +}; > + > +PyTypeObject minsym_object_type = { > + PyVarObject_HEAD_INIT (NULL, 0) > + "gdb.MinSymbol", /*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*/ > + msympy_repr, /*tp_repr*/ > + 0, /*tp_as_number*/ > + 0, /*tp_as_sequence*/ > + 0, /*tp_as_mapping*/ > + 0, /*tp_hash */ > + 0, /*tp_call*/ > + 0, /*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 2e24d0f3ff..89d8d6d815 100644 > --- a/gdb/python/py-objfile.c > +++ b/gdb/python/py-objfile.c > @@ -417,6 +417,17 @@ objfpy_is_valid (PyObject *self, PyObject *args) > Py_RETURN_TRUE; > } > > +/* Return struct objfile reference that is wrapped by the SELF object. */ > + > +struct objfile * > +objectfile_object_to_objfile (PyObject *self) > +{ > + objfile_object *obj = (objfile_object *) self; > + OBJFPY_REQUIRE_VALID (obj); > + > + return obj->objfile; > +} > + > /* Implementation of gdb.Objfile.add_separate_debug_file (self) -> Boolean. */ > > static PyObject * > diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h > index 1812abb5b7..28f89919ff 100644 > --- a/gdb/python/python-internal.h > +++ b/gdb/python/python-internal.h > @@ -366,6 +366,8 @@ 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 minsym_object_type > + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("minsym_object"); > extern PyTypeObject event_object_type > CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); > extern PyTypeObject breakpoint_object_type > @@ -475,6 +477,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_start_recording (PyObject *self, PyObject *args); > PyObject *gdbpy_current_recording (PyObject *self, PyObject *args); > PyObject *gdbpy_stop_recording (PyObject *self, PyObject *args); > @@ -516,6 +520,7 @@ PyObject *objfpy_get_frame_filters (PyObject *, void *); > PyObject *objfpy_get_frame_unwinders (PyObject *, void *); > PyObject *objfpy_get_xmethods (PyObject *, void *); > PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw); > +struct objfile *objectfile_object_to_objfile (PyObject *self); > > PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch); > > @@ -552,6 +557,8 @@ 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_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 348405e205..8d5ab0f649 100644 > --- a/gdb/python/python.c > +++ b/gdb/python/python.c > @@ -1684,6 +1684,7 @@ do_start_initialization () > || gdbpy_initialize_record () < 0 > || gdbpy_initialize_btrace () < 0 > || gdbpy_initialize_symbols () < 0 > + || gdbpy_initialize_minsymbols () < 0 > || gdbpy_initialize_symtabs () < 0 > || gdbpy_initialize_blocks () < 0 > || gdbpy_initialize_functions () < 0 > @@ -1984,6 +1985,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, [sfile, [objfile]]) -> minsym\n\ > +Return the symbol corresponding to the given name (or None)." }, > > { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile, > METH_VARARGS | METH_KEYWORDS, > diff --git a/gdb/testsuite/gdb.python/py-minsymbol.c b/gdb/testsuite/gdb.python/py-minsymbol.c > new file mode 100644 > index 0000000000..e33ee2041f > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-minsymbol.c > @@ -0,0 +1,38 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2018 Free Software Foundation, Inc. > + > + 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 . */ > + > +/* So we have a data section */ > +const char foo[] = "somestring"; > + > +asm("\ > +.section .text\n\ > +.global text_msym\n\ > +text_msym:\n\ > + .byte 0\n\ > +.section .data\n\ > +.globl data_msym\n\ > +data_msym:\n\ > + .asciz \"minsym text\"\n\ > +data_msym2:\n\ > + .asciz \"minsym2 text\"\n\ > +"); > + > +int > +main (void) > +{ > + return 0; > +} > diff --git a/gdb/testsuite/gdb.python/py-minsymbol.exp b/gdb/testsuite/gdb.python/py-minsymbol.exp > new file mode 100644 > index 0000000000..f765358719 > --- /dev/null > +++ b/gdb/testsuite/gdb.python/py-minsymbol.exp > @@ -0,0 +1,69 @@ > +# Copyright (C) 2018 Free Software Foundation, Inc. > + > +# 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 . > + > +# This file is part of the GDB testsuite. It tests the mechanism > +# exposing values to Python. > + > +load_lib gdb-python.exp > + > +standard_testfile > + > +if {[prepare_for_testing $testfile.exp $testfile $srcfile nodebug]} { > + return -1 > +} > + > +# Skip all tests if Python scripting is not enabled. > +if { [skip_python_tests] } { continue } > + > +# Test looking up missing value > +gdb_test "python print (gdb.lookup_minimal_symbol('xyz'))" "None" "lookup missing symbol" > + > +# Test handling of invalid arguments > +gdb_test "python print (gdb.lookup_minimal_symbol(None))" ".*TypeError: argument 1 must be str(ing)?, not None.*" "lookup_minimal_symbol name arg None" > +gdb_test "python print (gdb.lookup_minimal_symbol('text_msym', None).name)" "text_msym" "lookup_minimal_symbol sfile arg None" > +gdb_test "python print (gdb.lookup_minimal_symbol('text_msym', objfile=None).name)" "text_msym" "lookup_minimal_symbol objfile arg None" > + > +# Test looking up a minimal symbol of text type > +gdb_test "print text_msym" " = \{\} 0x\[0-9a-f\]* " "locate text_msym with print" > +gdb_py_test_silent_cmd "python x = gdb.lookup_minimal_symbol('text_msym')" "Lookup text_msym" 1 > +gdb_test "python print (x.name)" "text_msym" "get text minsym name" > +gdb_test "python print (x.linkage_name)" "text_msym" "get text minsym linkage_name" > +# Using asm() ends up inventing a compiler-dependent filename > +gdb_test "python print (x.filename)" ".*" "get text minsym filename" > +gdb_test "python print (x.print_name)" "text_msym" "get text minsym print_name" > +gdb_test "python print (x.section_name)" ".text" "get text minsym section" > +gdb_test "python print (x.value())" "0x\[0-9a-f\]*.*" "get text minsym value" > +gdb_test "python print (x.value().type)" "void \\(\\*\\)\\(\\)" "get text minsym value type" > + > +# Test looking up a minimal symbol of data type > +gdb_test "print (void *)data_msym" "0x\[0-9a-f\]*.*" "locate data_msym with print" > +gdb_py_test_silent_cmd "python x = gdb.lookup_minimal_symbol('data_msym')" "Lookup data_msym" 1 > +gdb_test "python print (x.name)" "data_msym" "get data minsym name" > +gdb_test "python print (x.linkage_name)" "data_msym" "get data minsym linkage_name" > +# Using asm() ends up inventing a compiler-dependent filename > +gdb_test "python print (x.filename)" ".*" "get data minsym filename" > +gdb_test "python print (x.print_name)" "data_msym" "get data minsym print_name" > +gdb_test "python print (x.section_name)" ".data" "get data minsym section" > +gdb_test "python print (x.value())" "0x\[0-9a-f\]*.*" "get data minsym value" > + > +gdb_test "python print(gdb.lookup_minimal_symbol('data_msym2', 'foobar.c'))" "None" "Lookup local data_msym2 in foobar.c src" > +gdb_test "python print(gdb.lookup_minimal_symbol('data_msym2', 'py-minsymbol.c').name)" "data_msym2" "Lookup local data_msym2 in py-minsymbol.c src" > +gdb_test "python print(gdb.lookup_minimal_symbol('data_msym2', 'foobar/py-minsymbol.c').name)" "data_msym2" "Lookup local data_msym2 in py-minsymbol.c src" > +gdb_test "python print(gdb.lookup_minimal_symbol('data_msym2', 'py-minsymbol'))" "None" "Lookup local data_msym2 in py-minsymbol.c src using substring" > +gdb_test "python print(gdb.lookup_minimal_symbol('data_msym', 'foobar.c').name)" "data_msym" "Lookup global data_msym in foobar.c src" > + > +gdb_unload > +gdb_test "python print (x.is_valid())" "False" "Test symbol non-validity" > +gdb_test_no_output "python a = None" "Test symbol destructor" >