New python function gdb.lookup_objfile.
gdb/ChangeLog: * NEWS: Mention gdb.lookup_objfile. * python/python.c (GdbMethods): Add lookup_objfile. * python/python-internal.h (gdbpy_lookup_objfile): Declare. * python/py-objfile.c: #include "symtab.h". (objfpy_build_id_ok, objfpy_build_id_matches): New functions. (objfpy_lookup_objfile_by_name): New function. (objfpy_lookup_objfile_by_build_id): New function. (gdbpy_lookup_objfile): New function. gdb/doc/ChangeLog: * python.texi (Objfiles In Python): Document gdb.lookup_objfile. gdb/testsuite/ChangeLog: * lib/gdb-python.exp (get_python_valueof): New function. * gdb.python/py-objfile.exp: Add tests for gdb.lookup_objfile.
This commit is contained in:
parent
f161c17134
commit
6dddd6a574
|
@ -1,3 +1,14 @@
|
|||
2014-12-12 Doug Evans <dje@google.com>
|
||||
|
||||
* NEWS: Mention gdb.lookup_objfile.
|
||||
* python/python.c (GdbMethods): Add lookup_objfile.
|
||||
* python/python-internal.h (gdbpy_lookup_objfile): Declare.
|
||||
* python/py-objfile.c: #include "symtab.h".
|
||||
(objfpy_build_id_ok, objfpy_build_id_matches): New functions.
|
||||
(objfpy_lookup_objfile_by_name): New function.
|
||||
(objfpy_lookup_objfile_by_build_id): New function.
|
||||
(gdbpy_lookup_objfile): New function.
|
||||
|
||||
2014-12-12 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
* mips-tdep.h (MSYMBOL_TARGET_FLAG_MIPS16): New macro.
|
||||
|
|
1
gdb/NEWS
1
gdb/NEWS
|
@ -28,6 +28,7 @@
|
|||
** A new event "gdb.clear_objfiles" has been added, triggered when
|
||||
selecting a new file to debug.
|
||||
** You can now add attributes to gdb.Objfile and gdb.Progspace objects.
|
||||
** New function gdb.lookup_objfile.
|
||||
|
||||
* New Python-based convenience functions:
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-12-12 Doug Evans <dje@google.com>
|
||||
|
||||
* python.texi (Objfiles In Python): Document gdb.lookup_objfile.
|
||||
|
||||
2014-12-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||
|
||||
* gdb.texinfo: Document "maint print user-registers".
|
||||
|
|
|
@ -3488,6 +3488,27 @@ Return a sequence of all the objfiles current known to @value{GDBN}.
|
|||
@xref{Objfiles In Python}.
|
||||
@end defun
|
||||
|
||||
@findex gdb.lookup_objfile
|
||||
@defun gdb.lookup_objfile (name @r{[}, by_build_id{]})
|
||||
Look up @var{name}, a file name or build ID, in the list of objfiles
|
||||
for the current program space (@pxref{Progspaces In Python}).
|
||||
If the objfile is not found throw the Python @code{ValueError} exception.
|
||||
|
||||
If @var{name} is a relative file name, then it will match any
|
||||
source file name with the same trailing components. For example, if
|
||||
@var{name} is @samp{gcc/expr.c}, then it will match source file
|
||||
name of @file{/build/trunk/gcc/expr.c}, but not
|
||||
@file{/build/trunk/libcpp/expr.c} or @file{/build/trunk/gcc/x-expr.c}.
|
||||
|
||||
If @var{by_build_id} is provided and is @code{True} then @var{name}
|
||||
is the build ID of the objfile. Otherwise, @var{name} is a file name.
|
||||
This is supported only on some operating systems, notably those which use
|
||||
the ELF format for binary files and the @sc{gnu} Binutils. For more details
|
||||
about this feature, see the description of the @option{--build-id}
|
||||
command-line option in @ref{Options, , Command Line Options, ld.info,
|
||||
The GNU Linker}.
|
||||
@end defun
|
||||
|
||||
Each objfile is represented by an instance of the @code{gdb.Objfile}
|
||||
class.
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "language.h"
|
||||
#include "build-id.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "symtab.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -384,6 +385,147 @@ objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
|
||||
Return non-zero if STRING is a potentially valid build id. */
|
||||
|
||||
static int
|
||||
objfpy_build_id_ok (const char *string)
|
||||
{
|
||||
size_t i, n = strlen (string);
|
||||
|
||||
if (n % 2 != 0)
|
||||
return 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
if (!isxdigit (string[i]))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
|
||||
Returns non-zero if BUILD_ID matches STRING.
|
||||
It is assumed that objfpy_build_id_ok (string) returns TRUE. */
|
||||
|
||||
static int
|
||||
objfpy_build_id_matches (const struct elf_build_id *build_id,
|
||||
const char *string)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (strlen (string) != 2 * build_id->size)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < build_id->size; ++i)
|
||||
{
|
||||
char c1 = string[i * 2], c2 = string[i * 2 + 1];
|
||||
int byte = (host_hex_value (c1) << 4) | host_hex_value (c2);
|
||||
|
||||
if (byte != build_id->data[i])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Subroutine of gdbpy_lookup_objfile to simplify it.
|
||||
Look up an objfile by its file name. */
|
||||
|
||||
static struct objfile *
|
||||
objfpy_lookup_objfile_by_name (const char *name)
|
||||
{
|
||||
struct objfile *objfile;
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
if ((objfile->flags & OBJF_NOT_FILENAME) != 0)
|
||||
continue;
|
||||
/* Don't return separate debug files. */
|
||||
if (objfile->separate_debug_objfile_backlink != NULL)
|
||||
continue;
|
||||
if (compare_filenames_for_search (objfile_name (objfile), name))
|
||||
return objfile;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Subroutine of gdbpy_lookup_objfile to simplify it.
|
||||
Look up an objfile by its build id. */
|
||||
|
||||
static struct objfile *
|
||||
objfpy_lookup_objfile_by_build_id (const char *build_id)
|
||||
{
|
||||
struct objfile *objfile;
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
const struct elf_build_id *obfd_build_id;
|
||||
|
||||
if (objfile->obfd == NULL)
|
||||
continue;
|
||||
/* Don't return separate debug files. */
|
||||
if (objfile->separate_debug_objfile_backlink != NULL)
|
||||
continue;
|
||||
obfd_build_id = build_id_bfd_get (objfile->obfd);
|
||||
if (obfd_build_id == NULL)
|
||||
continue;
|
||||
if (objfpy_build_id_matches (obfd_build_id, build_id))
|
||||
return objfile;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Implementation of gdb.lookup_objfile. */
|
||||
|
||||
PyObject *
|
||||
gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
static char *keywords[] = { "name", "by_build_id", NULL };
|
||||
const char *name;
|
||||
PyObject *by_build_id_obj = NULL;
|
||||
int by_build_id;
|
||||
struct objfile *objfile;
|
||||
|
||||
if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
|
||||
&name, &PyBool_Type, &by_build_id_obj))
|
||||
return NULL;
|
||||
|
||||
by_build_id = 0;
|
||||
if (by_build_id_obj != NULL)
|
||||
{
|
||||
int cmp = PyObject_IsTrue (by_build_id_obj);
|
||||
|
||||
if (cmp < 0)
|
||||
return NULL;
|
||||
by_build_id = cmp;
|
||||
}
|
||||
|
||||
if (by_build_id)
|
||||
{
|
||||
if (!objfpy_build_id_ok (name))
|
||||
{
|
||||
PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
|
||||
return NULL;
|
||||
}
|
||||
objfile = objfpy_lookup_objfile_by_build_id (name);
|
||||
}
|
||||
else
|
||||
objfile = objfpy_lookup_objfile_by_name (name);
|
||||
|
||||
if (objfile != NULL)
|
||||
{
|
||||
PyObject *result = objfile_to_objfile_object (objfile);
|
||||
|
||||
Py_XINCREF (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
PyErr_SetString (PyExc_ValueError, _("Objfile not found."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clear the OBJFILE pointer in an Objfile object and remove the
|
||||
|
|
|
@ -393,6 +393,7 @@ PyObject *objfile_to_objfile_object (struct objfile *)
|
|||
PyObject *objfpy_get_printers (PyObject *, void *);
|
||||
PyObject *objfpy_get_frame_filters (PyObject *, void *);
|
||||
PyObject *objfpy_get_xmethods (PyObject *, void *);
|
||||
PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);
|
||||
|
||||
PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch);
|
||||
|
||||
|
|
|
@ -1956,6 +1956,14 @@ 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_objfile", (PyCFunction) gdbpy_lookup_objfile,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
"lookup_objfile (name, [by_build_id]) -> objfile\n\
|
||||
Look up the specified objfile.\n\
|
||||
If by_build_id is True, the objfile is looked up by using name\n\
|
||||
as its build id." },
|
||||
|
||||
{ "block_for_pc", gdbpy_block_for_pc, METH_VARARGS,
|
||||
"Return the block containing the given pc value, or None." },
|
||||
{ "solib_name", gdbpy_solib_name, METH_VARARGS,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2014-12-12 Doug Evans <dje@google.com>
|
||||
|
||||
* lib/gdb-python.exp (get_python_valueof): New function.
|
||||
* gdb.python/py-objfile.exp: Add tests for gdb.lookup_objfile.
|
||||
|
||||
2014-12-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||
|
||||
* gdb.base/completion.exp: Add test for completion of "info
|
||||
|
|
|
@ -32,23 +32,39 @@ if ![runto_main] then {
|
|||
return 0
|
||||
}
|
||||
|
||||
set python_error_text "Error while executing Python code\\."
|
||||
|
||||
gdb_py_test_silent_cmd "python sym = gdb.lookup_symbol(\"some_var\")" \
|
||||
"Find a symbol in objfile" 1
|
||||
gdb_py_test_silent_cmd "python objfile = sym\[0\].symtab.objfile" \
|
||||
"Get backing object file" 1
|
||||
|
||||
gdb_test "python print (objfile.filename)" ".*py-objfile.*" \
|
||||
gdb_test "python print (objfile.filename)" "${testfile}" \
|
||||
"Get objfile file name"
|
||||
|
||||
gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").filename)" \
|
||||
"${testfile}"
|
||||
gdb_test "python print (gdb.lookup_objfile (\"junk\"))" \
|
||||
"Objfile not found\\.\r\n${python_error_text}"
|
||||
|
||||
set binfile_build_id [get_build_id $binfile]
|
||||
if [string compare $binfile_build_id ""] {
|
||||
verbose -log "binfile_build_id = $binfile_build_id"
|
||||
gdb_test "python print (objfile.build_id)" "$binfile_build_id" \
|
||||
"Get objfile build id"
|
||||
gdb_test "python print (gdb.lookup_objfile (\"$binfile_build_id\", by_build_id=True).filename)" \
|
||||
"${testfile}"
|
||||
} else {
|
||||
unsupported "build-id is not supported by the compiler"
|
||||
}
|
||||
|
||||
# Other lookup_objfile_by_build_id tests we can do, even if compiler doesn't
|
||||
# support them.
|
||||
gdb_test "python print (gdb.lookup_objfile (\"foo\", by_build_id=True))" \
|
||||
"Not a valid build id\\.\r\n${python_error_text}"
|
||||
gdb_test "python print (gdb.lookup_objfile (\"1234abcdef\", by_build_id=True))" \
|
||||
"Objfile not found\\.\r\n${python_error_text}"
|
||||
|
||||
gdb_test "python print (objfile.progspace)" "<gdb\.Progspace object at .*>" \
|
||||
"Get objfile program space"
|
||||
gdb_test "python print (objfile.is_valid())" "True" \
|
||||
|
@ -93,3 +109,9 @@ gdb_test "python print (sep_objfile.owner.filename)" "${testfile}2" \
|
|||
|
||||
gdb_test "p main" "= {int \\(\\)} $hex <main>" \
|
||||
"print main with debug info"
|
||||
|
||||
# Separate debug files are not findable.
|
||||
if { [get_python_valueof "sep_objfile.build_id" "None"] != "None" } {
|
||||
gdb_test "python print (gdb.lookup_objfile (sep_objfile.build_id, by_build_id=True))" \
|
||||
"Objfile not found\\.\r\n${python_error_text}"
|
||||
}
|
||||
|
|
|
@ -45,3 +45,24 @@ proc gdb_py_test_multiple { name args } {
|
|||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# Return the result of python expression EXPR.
|
||||
# DEFAULT is returned if there's an error.
|
||||
# This is modelled after get_integer_valueof.
|
||||
|
||||
proc get_python_valueof { exp default } {
|
||||
global gdb_prompt
|
||||
|
||||
set test "get python valueof \"${exp}\""
|
||||
set val ${default}
|
||||
gdb_test_multiple "python print (\"valueof: %s\" % (${exp}))" "$test" {
|
||||
-re "valueof: (\[^\r\n\]*)\[\r\n\]*$gdb_prompt $" {
|
||||
set val $expect_out(1,string)
|
||||
pass "$test ($val)"
|
||||
}
|
||||
timeout {
|
||||
fail "$test (timeout)"
|
||||
}
|
||||
}
|
||||
return ${val}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue