From: Tom de Vries <tdevries@suse.de>
To: Simon Marchi <simon.marchi@ericsson.com>,
gdb-patches@sourceware.org, Phil Muldoon <pmuldoon@redhat.com>,
Tom Tromey <tom@tromey.com>
Subject: Re: [PATCH][gdb/python] Add interface to access minimal_symbols
Date: Wed, 31 Oct 2018 16:59:00 -0000 [thread overview]
Message-ID: <211c4746-389a-93b7-faf9-c8f9b6245541@suse.de> (raw)
In-Reply-To: <39c4336d-c749-6f79-5a29-0b764fc4935e@ericsson.com>
[-- Attachment #1: Type: text/plain, Size: 14622 bytes --]
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 <jeffm@suse.com>
>> Tom de Vries <tdevries@suse.de>
>>
>> * 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);
>> +}
>> +
>> +\f
>> +
>> +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
>
> <gdb.MinSymbol name=%s>
>
> 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:
...
<gdb.MinSymbol name=%s filename=%s objfile=%s>
...
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.
Thanks,
- Tom
[-- Attachment #2: 0001-gdb-python-Add-interface-to-access-minimal_symbols.patch --]
[-- Type: text/x-patch, Size: 34958 bytes --]
[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 <jeffm@suse.com>
Tom de Vries <tdevries@suse.de>
* 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 <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "block.h"
+#include "exceptions.h"
+#include "frame.h"
+#include "symtab.h"
+#include "python-internal.h"
+#include "objfiles.h"
+#include "value.h"
+#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 ("<gdb.MinSymbol name=%s filename=%s"
+ " objfile=%s>",
+ MSYMBOL_LINKAGE_NAME (minsym),
+ minsym->filename,
+ objfile_filename (objfile));
+
+ return PyString_FromFormat ("<gdb.MinSymbol name=%s objfile=%s>",
+ 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<char> 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);
+}
+
+\f
+
+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 <http://www.gnu.org/licenses/>. */
+
+/* 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 <http://www.gnu.org/licenses/>.
+
+# 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" " = \{<text variable, no debug info>\} 0x\[0-9a-f\]* <text_msym>" "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"
next prev parent reply other threads:[~2018-10-31 16:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-04 21:11 Tom de Vries
2018-10-05 4:43 ` Simon Marchi
2018-10-31 16:59 ` Tom de Vries [this message]
2018-11-26 11:17 ` [PING][PATCH][gdb/python] " Tom de Vries
2018-11-26 21:31 ` [PATCH][gdb/python] " Simon Marchi
2018-11-27 18:10 ` Matt Rice
2018-11-29 22:32 ` Tom Tromey
2018-11-29 22:12 ` Tom Tromey
2018-10-05 6:46 ` Eli Zaretskii
2018-10-31 17:02 ` Tom de Vries
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=211c4746-389a-93b7-faf9-c8f9b6245541@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
--cc=pmuldoon@redhat.com \
--cc=simon.marchi@ericsson.com \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).