diff options
author | Doug Evans <dje@google.com> | 2014-12-12 09:48:13 -0800 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2014-12-12 09:48:13 -0800 |
commit | 6dddd6a5747532ef6e9703432c51680011df4e8d (patch) | |
tree | 35083e8dddfb1148d20dc1dc6808c05df7b8bb8a /gdb/python | |
parent | f161c17134bdfa5f5e72d7afb7dfccf5599a67e1 (diff) | |
download | gdb-6dddd6a5747532ef6e9703432c51680011df4e8d.zip gdb-6dddd6a5747532ef6e9703432c51680011df4e8d.tar.gz gdb-6dddd6a5747532ef6e9703432c51680011df4e8d.tar.bz2 |
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.
Diffstat (limited to 'gdb/python')
-rw-r--r-- | gdb/python/py-objfile.c | 142 | ||||
-rw-r--r-- | gdb/python/python-internal.h | 1 | ||||
-rw-r--r-- | gdb/python/python.c | 8 |
3 files changed, 151 insertions, 0 deletions
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index d90928b..e78ceba 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -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 diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 716c0de..544fe93 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -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); diff --git a/gdb/python/python.c b/gdb/python/python.c index 1362bd2..b1d8283 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -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, |