/* Python interface to objfiles.
- Copyright (C) 2008-2021 Free Software Foundation, Inc.
+ Copyright (C) 2008-2023 Free Software Foundation, Inc.
This file is part of GDB.
#include "language.h"
#include "build-id.h"
#include "symtab.h"
+#include "python.h"
+#include "inferior.h"
struct objfile_object
{
extern PyTypeObject objfile_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
-static const struct objfile_data *objfpy_objfile_data_key;
+/* Clear the OBJFILE pointer in an Objfile object and remove the
+ reference. */
+struct objfpy_deleter
+{
+ void operator() (objfile_object *obj)
+ {
+ gdbpy_enter enter_py;
+ gdbpy_ref<objfile_object> object (obj);
+ object->objfile = nullptr;
+ }
+};
+
+static const registry<objfile>::key<objfile_object, objfpy_deleter>
+ objfpy_objfile_data_key;
/* Require that OBJF be a valid objfile. */
#define OBJFPY_REQUIRE_VALID(obj) \
Py_RETURN_NONE;
}
+/* Get the 'is_file' attribute. */
+
+static PyObject *
+objfpy_get_is_file (PyObject *o, void *ignore)
+{
+ objfile_object *self = (objfile_object *) o;
+
+ if (self->objfile != nullptr)
+ return PyBool_FromLong ((self->objfile->flags & OBJF_NOT_FILENAME) == 0);
+ Py_RETURN_NONE;
+}
+
/* If SELF is a separate debug-info file, return the "backlink" field.
Otherwise return None. */
try
{
- build_id = build_id_bfd_get (objfile->obfd);
+ build_id = build_id_bfd_get (objfile->obfd.get ());
}
catch (const gdb_exception &except)
{
{
gdb_bfd_ref_ptr abfd (symfile_bfd_open (file_name));
- symbol_file_add_separate (abfd.get (), file_name, 0, obj->objfile);
+ symbol_file_add_separate (abfd, file_name, 0, obj->objfile);
}
catch (const gdb_exception &except)
{
objfile *obj = self->objfile;
if (obj == nullptr)
- return PyString_FromString ("<gdb.Objfile (invalid)>");
+ return PyUnicode_FromString ("<gdb.Objfile (invalid)>");
- return PyString_FromFormat ("<gdb.Objfile filename=%s>",
- objfile_filename (obj));
+ return PyUnicode_FromFormat ("<gdb.Objfile filename=%s>",
+ objfile_name (obj));
}
/* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
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);
+ int byte = (fromhex (c1) << 4) | fromhex (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)
-{
- for (objfile *objfile : current_program_space->objfiles ())
- {
- const char *filename;
-
- if ((objfile->flags & OBJF_NOT_FILENAME) != 0)
- continue;
- /* Don't return separate debug files. */
- if (objfile->separate_debug_objfile_backlink != NULL)
- continue;
-
- filename = objfile_filename (objfile);
- if (filename != NULL && compare_filenames_for_search (filename, name))
- return objfile;
- if (compare_filenames_for_search (objfile->original_name, 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)
-{
- for (objfile *objfile : current_program_space->objfiles ())
- {
- const struct bfd_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 *
const char *name;
PyObject *by_build_id_obj = NULL;
int by_build_id;
- struct objfile *objfile;
if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
&name, &PyBool_Type, &by_build_id_obj))
by_build_id = cmp;
}
- if (by_build_id)
+ if (by_build_id && !objfpy_build_id_ok (name))
{
- 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);
+ PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
+ return NULL;
}
+
+ struct objfile *objfile = nullptr;
+ if (by_build_id)
+ gdbarch_iterate_over_objfiles_in_search_order
+ (current_inferior ()->arch (),
+ [&objfile, name] (struct objfile *obj)
+ {
+ /* Don't return separate debug files. */
+ if (obj->separate_debug_objfile_backlink != nullptr)
+ return 0;
+
+ bfd *obfd = obj->obfd.get ();
+ if (obfd == nullptr)
+ return 0;
+
+ const bfd_build_id *obfd_build_id = build_id_bfd_get (obfd);
+ if (obfd_build_id == nullptr)
+ return 0;
+
+ if (!objfpy_build_id_matches (obfd_build_id, name))
+ return 0;
+
+ objfile = obj;
+ return 1;
+ }, gdbpy_current_objfile);
else
- objfile = objfpy_lookup_objfile_by_name (name);
+ gdbarch_iterate_over_objfiles_in_search_order
+ (current_inferior ()->arch (),
+ [&objfile, name] (struct objfile *obj)
+ {
+ /* Don't return separate debug files. */
+ if (obj->separate_debug_objfile_backlink != nullptr)
+ return 0;
+
+ if ((obj->flags & OBJF_NOT_FILENAME) != 0)
+ return 0;
+
+ const char *filename = objfile_filename (obj);
+ if (filename != NULL
+ && compare_filenames_for_search (filename, name))
+ {
+ objfile = obj;
+ return 1;
+ }
+
+ if (compare_filenames_for_search (obj->original_name, name))
+ {
+ objfile = obj;
+ return 1;
+ }
+
+ return 0;
+ }, gdbpy_current_objfile);
if (objfile != NULL)
return objfile_to_objfile_object (objfile).release ();
\f
-/* Clear the OBJFILE pointer in an Objfile object and remove the
- reference. */
-static void
-py_free_objfile (struct objfile *objfile, void *datum)
-{
- gdbpy_enter enter_py (objfile->arch (), current_language);
- gdbpy_ref<objfile_object> object ((objfile_object *) datum);
- object->objfile = NULL;
-}
-
/* Return a new reference to the Python object of type Objfile
representing OBJFILE. If the object has already been created,
return it. Otherwise, create it. Return NULL and set the Python
objfile_to_objfile_object (struct objfile *objfile)
{
PyObject *result
- = ((PyObject *) objfile_data (objfile, objfpy_objfile_data_key));
+ = (PyObject *) objfpy_objfile_data_key.get (objfile);
if (result == NULL)
{
gdbpy_ref<objfile_object> object
return NULL;
object->objfile = objfile;
- set_objfile_data (objfile, objfpy_objfile_data_key, object.get ());
+ objfpy_objfile_data_key.set (objfile, object.get ());
result = (PyObject *) object.release ();
}
return gdbpy_ref<>::new_reference (result);
}
-int
+static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_objfile (void)
{
- objfpy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, py_free_objfile);
-
if (PyType_Ready (&objfile_object_type) < 0)
return -1;
(PyObject *) &objfile_object_type);
}
+GDBPY_INITIALIZE_FILE (gdbpy_initialize_objfile);
+
\f
static PyMethodDef objfile_object_methods[] =
"Type printers.", NULL },
{ "xmethods", objfpy_get_xmethods, NULL,
"Debug methods.", NULL },
+ { "is_file", objfpy_get_is_file, nullptr,
+ "Whether this objfile came from a file.", nullptr },
{ NULL }
};