py-objfile.c revision 1.10 1 /* Python interface to objfiles.
2
3 Copyright (C) 2008-2023 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "python-internal.h"
22 #include "charset.h"
23 #include "objfiles.h"
24 #include "language.h"
25 #include "build-id.h"
26 #include "symtab.h"
27 #include "python.h"
28
29 struct objfile_object
30 {
31 PyObject_HEAD
32
33 /* The corresponding objfile. */
34 struct objfile *objfile;
35
36 /* Dictionary holding user-added attributes.
37 This is the __dict__ attribute of the object. */
38 PyObject *dict;
39
40 /* The pretty-printer list of functions. */
41 PyObject *printers;
42
43 /* The frame filter list of functions. */
44 PyObject *frame_filters;
45
46 /* The list of frame unwinders. */
47 PyObject *frame_unwinders;
48
49 /* The type-printer list. */
50 PyObject *type_printers;
51
52 /* The debug method matcher list. */
53 PyObject *xmethods;
54 };
55
56 extern PyTypeObject objfile_object_type
57 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
58
59 /* Clear the OBJFILE pointer in an Objfile object and remove the
60 reference. */
61 struct objfpy_deleter
62 {
63 void operator() (objfile_object *obj)
64 {
65 gdbpy_enter enter_py;
66 gdbpy_ref<objfile_object> object (obj);
67 object->objfile = nullptr;
68 }
69 };
70
71 static const registry<objfile>::key<objfile_object, objfpy_deleter>
72 objfpy_objfile_data_key;
73
74 /* Require that OBJF be a valid objfile. */
75 #define OBJFPY_REQUIRE_VALID(obj) \
76 do { \
77 if (!(obj)->objfile) \
78 { \
79 PyErr_SetString (PyExc_RuntimeError, \
80 _("Objfile no longer exists.")); \
81 return NULL; \
82 } \
83 } while (0)
84
85
86
88 /* An Objfile method which returns the objfile's file name, or None. */
89
90 static PyObject *
91 objfpy_get_filename (PyObject *self, void *closure)
92 {
93 objfile_object *obj = (objfile_object *) self;
94
95 if (obj->objfile)
96 return (host_string_to_python_string (objfile_name (obj->objfile))
97 .release ());
98 Py_RETURN_NONE;
99 }
100
101 /* An Objfile method which returns the objfile's file name, as specified
102 by the user, or None. */
103
104 static PyObject *
105 objfpy_get_username (PyObject *self, void *closure)
106 {
107 objfile_object *obj = (objfile_object *) self;
108
109 if (obj->objfile)
110 {
111 const char *username = obj->objfile->original_name;
112
113 return host_string_to_python_string (username).release ();
114 }
115
116 Py_RETURN_NONE;
117 }
118
119 /* Get the 'is_file' attribute. */
120
121 static PyObject *
122 objfpy_get_is_file (PyObject *o, void *ignore)
123 {
124 objfile_object *self = (objfile_object *) o;
125
126 if (self->objfile != nullptr)
127 return PyBool_FromLong ((self->objfile->flags & OBJF_NOT_FILENAME) == 0);
128 Py_RETURN_NONE;
129 }
130
131 /* If SELF is a separate debug-info file, return the "backlink" field.
132 Otherwise return None. */
133
134 static PyObject *
135 objfpy_get_owner (PyObject *self, void *closure)
136 {
137 objfile_object *obj = (objfile_object *) self;
138 struct objfile *objfile = obj->objfile;
139 struct objfile *owner;
140
141 OBJFPY_REQUIRE_VALID (obj);
142
143 owner = objfile->separate_debug_objfile_backlink;
144 if (owner != NULL)
145 return objfile_to_objfile_object (owner).release ();
146 Py_RETURN_NONE;
147 }
148
149 /* An Objfile method which returns the objfile's build id, or None. */
150
151 static PyObject *
152 objfpy_get_build_id (PyObject *self, void *closure)
153 {
154 objfile_object *obj = (objfile_object *) self;
155 struct objfile *objfile = obj->objfile;
156 const struct bfd_build_id *build_id = NULL;
157
158 OBJFPY_REQUIRE_VALID (obj);
159
160 try
161 {
162 build_id = build_id_bfd_get (objfile->obfd.get ());
163 }
164 catch (const gdb_exception &except)
165 {
166 GDB_PY_HANDLE_EXCEPTION (except);
167 }
168
169 if (build_id != NULL)
170 {
171 std::string hex_form = bin2hex (build_id->data, build_id->size);
172
173 return host_string_to_python_string (hex_form.c_str ()).release ();
174 }
175
176 Py_RETURN_NONE;
177 }
178
179 /* An Objfile method which returns the objfile's progspace, or None. */
180
181 static PyObject *
182 objfpy_get_progspace (PyObject *self, void *closure)
183 {
184 objfile_object *obj = (objfile_object *) self;
185
186 if (obj->objfile)
187 return pspace_to_pspace_object (obj->objfile->pspace).release ();
188
189 Py_RETURN_NONE;
190 }
191
192 static void
193 objfpy_dealloc (PyObject *o)
194 {
195 objfile_object *self = (objfile_object *) o;
196
197 Py_XDECREF (self->dict);
198 Py_XDECREF (self->printers);
199 Py_XDECREF (self->frame_filters);
200 Py_XDECREF (self->frame_unwinders);
201 Py_XDECREF (self->type_printers);
202 Py_XDECREF (self->xmethods);
203 Py_TYPE (self)->tp_free (self);
204 }
205
206 /* Initialize an objfile_object.
207 The result is a boolean indicating success. */
208
209 static int
210 objfpy_initialize (objfile_object *self)
211 {
212 self->objfile = NULL;
213
214 self->dict = PyDict_New ();
215 if (self->dict == NULL)
216 return 0;
217
218 self->printers = PyList_New (0);
219 if (self->printers == NULL)
220 return 0;
221
222 self->frame_filters = PyDict_New ();
223 if (self->frame_filters == NULL)
224 return 0;
225
226 self->frame_unwinders = PyList_New (0);
227 if (self->frame_unwinders == NULL)
228 return 0;
229
230 self->type_printers = PyList_New (0);
231 if (self->type_printers == NULL)
232 return 0;
233
234 self->xmethods = PyList_New (0);
235 if (self->xmethods == NULL)
236 return 0;
237
238 return 1;
239 }
240
241 static PyObject *
242 objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
243 {
244 gdbpy_ref<objfile_object> self ((objfile_object *) type->tp_alloc (type, 0));
245
246 if (self != NULL)
247 {
248 if (!objfpy_initialize (self.get ()))
249 return NULL;
250 }
251
252 return (PyObject *) self.release ();
253 }
254
255 PyObject *
256 objfpy_get_printers (PyObject *o, void *ignore)
257 {
258 objfile_object *self = (objfile_object *) o;
259
260 Py_INCREF (self->printers);
261 return self->printers;
262 }
263
264 static int
265 objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
266 {
267 objfile_object *self = (objfile_object *) o;
268
269 if (! value)
270 {
271 PyErr_SetString (PyExc_TypeError,
272 _("Cannot delete the pretty_printers attribute."));
273 return -1;
274 }
275
276 if (! PyList_Check (value))
277 {
278 PyErr_SetString (PyExc_TypeError,
279 _("The pretty_printers attribute must be a list."));
280 return -1;
281 }
282
283 /* Take care in case the LHS and RHS are related somehow. */
284 gdbpy_ref<> tmp (self->printers);
285 Py_INCREF (value);
286 self->printers = value;
287
288 return 0;
289 }
290
291 /* Return the Python dictionary attribute containing frame filters for
292 this object file. */
293 PyObject *
294 objfpy_get_frame_filters (PyObject *o, void *ignore)
295 {
296 objfile_object *self = (objfile_object *) o;
297
298 Py_INCREF (self->frame_filters);
299 return self->frame_filters;
300 }
301
302 /* Set this object file's frame filters dictionary to FILTERS. */
303 static int
304 objfpy_set_frame_filters (PyObject *o, PyObject *filters, void *ignore)
305 {
306 objfile_object *self = (objfile_object *) o;
307
308 if (! filters)
309 {
310 PyErr_SetString (PyExc_TypeError,
311 _("Cannot delete the frame filters attribute."));
312 return -1;
313 }
314
315 if (! PyDict_Check (filters))
316 {
317 PyErr_SetString (PyExc_TypeError,
318 _("The frame_filters attribute must be a dictionary."));
319 return -1;
320 }
321
322 /* Take care in case the LHS and RHS are related somehow. */
323 gdbpy_ref<> tmp (self->frame_filters);
324 Py_INCREF (filters);
325 self->frame_filters = filters;
326
327 return 0;
328 }
329
330 /* Return the frame unwinders attribute for this object file. */
331
332 PyObject *
333 objfpy_get_frame_unwinders (PyObject *o, void *ignore)
334 {
335 objfile_object *self = (objfile_object *) o;
336
337 Py_INCREF (self->frame_unwinders);
338 return self->frame_unwinders;
339 }
340
341 /* Set this object file's frame unwinders list to UNWINDERS. */
342
343 static int
344 objfpy_set_frame_unwinders (PyObject *o, PyObject *unwinders, void *ignore)
345 {
346 objfile_object *self = (objfile_object *) o;
347
348 if (!unwinders)
349 {
350 PyErr_SetString (PyExc_TypeError,
351 _("Cannot delete the frame unwinders attribute."));
352 return -1;
353 }
354
355 if (!PyList_Check (unwinders))
356 {
357 PyErr_SetString (PyExc_TypeError,
358 _("The frame_unwinders attribute must be a list."));
359 return -1;
360 }
361
362 /* Take care in case the LHS and RHS are related somehow. */
363 gdbpy_ref<> tmp (self->frame_unwinders);
364 Py_INCREF (unwinders);
365 self->frame_unwinders = unwinders;
366
367 return 0;
368 }
369
370 /* Get the 'type_printers' attribute. */
371
372 static PyObject *
373 objfpy_get_type_printers (PyObject *o, void *ignore)
374 {
375 objfile_object *self = (objfile_object *) o;
376
377 Py_INCREF (self->type_printers);
378 return self->type_printers;
379 }
380
381 /* Get the 'xmethods' attribute. */
382
383 PyObject *
384 objfpy_get_xmethods (PyObject *o, void *ignore)
385 {
386 objfile_object *self = (objfile_object *) o;
387
388 Py_INCREF (self->xmethods);
389 return self->xmethods;
390 }
391
392 /* Set the 'type_printers' attribute. */
393
394 static int
395 objfpy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
396 {
397 objfile_object *self = (objfile_object *) o;
398
399 if (! value)
400 {
401 PyErr_SetString (PyExc_TypeError,
402 _("Cannot delete the type_printers attribute."));
403 return -1;
404 }
405
406 if (! PyList_Check (value))
407 {
408 PyErr_SetString (PyExc_TypeError,
409 _("The type_printers attribute must be a list."));
410 return -1;
411 }
412
413 /* Take care in case the LHS and RHS are related somehow. */
414 gdbpy_ref<> tmp (self->type_printers);
415 Py_INCREF (value);
416 self->type_printers = value;
417
418 return 0;
419 }
420
421 /* Implementation of gdb.Objfile.is_valid (self) -> Boolean.
422 Returns True if this object file still exists in GDB. */
423
424 static PyObject *
425 objfpy_is_valid (PyObject *self, PyObject *args)
426 {
427 objfile_object *obj = (objfile_object *) self;
428
429 if (! obj->objfile)
430 Py_RETURN_FALSE;
431
432 Py_RETURN_TRUE;
433 }
434
435 /* Implementation of gdb.Objfile.add_separate_debug_file (self, string). */
436
437 static PyObject *
438 objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw)
439 {
440 static const char *keywords[] = { "file_name", NULL };
441 objfile_object *obj = (objfile_object *) self;
442 const char *file_name;
443
444 OBJFPY_REQUIRE_VALID (obj);
445
446 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &file_name))
447 return NULL;
448
449 try
450 {
451 gdb_bfd_ref_ptr abfd (symfile_bfd_open (file_name));
452
453 symbol_file_add_separate (abfd, file_name, 0, obj->objfile);
454 }
455 catch (const gdb_exception &except)
456 {
457 GDB_PY_HANDLE_EXCEPTION (except);
458 }
459
460 Py_RETURN_NONE;
461 }
462
463 /* Implementation of
464 gdb.Objfile.lookup_global_symbol (self, string [, domain]) -> gdb.Symbol. */
465
466 static PyObject *
467 objfpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw)
468 {
469 static const char *keywords[] = { "name", "domain", NULL };
470 objfile_object *obj = (objfile_object *) self;
471 const char *symbol_name;
472 int domain = VAR_DOMAIN;
473
474 OBJFPY_REQUIRE_VALID (obj);
475
476 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &symbol_name,
477 &domain))
478 return nullptr;
479
480 try
481 {
482 struct symbol *sym = lookup_global_symbol_from_objfile
483 (obj->objfile, GLOBAL_BLOCK, symbol_name, (domain_enum) domain).symbol;
484 if (sym == nullptr)
485 Py_RETURN_NONE;
486
487 return symbol_to_symbol_object (sym);
488 }
489 catch (const gdb_exception &except)
490 {
491 GDB_PY_HANDLE_EXCEPTION (except);
492 }
493
494 Py_RETURN_NONE;
495 }
496
497 /* Implementation of
498 gdb.Objfile.lookup_static_symbol (self, string [, domain]) -> gdb.Symbol. */
499
500 static PyObject *
501 objfpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw)
502 {
503 static const char *keywords[] = { "name", "domain", NULL };
504 objfile_object *obj = (objfile_object *) self;
505 const char *symbol_name;
506 int domain = VAR_DOMAIN;
507
508 OBJFPY_REQUIRE_VALID (obj);
509
510 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &symbol_name,
511 &domain))
512 return nullptr;
513
514 try
515 {
516 struct symbol *sym = lookup_global_symbol_from_objfile
517 (obj->objfile, STATIC_BLOCK, symbol_name, (domain_enum) domain).symbol;
518 if (sym == nullptr)
519 Py_RETURN_NONE;
520
521 return symbol_to_symbol_object (sym);
522 }
523 catch (const gdb_exception &except)
524 {
525 GDB_PY_HANDLE_EXCEPTION (except);
526 }
527
528 Py_RETURN_NONE;
529 }
530
531 /* Implement repr() for gdb.Objfile. */
532
533 static PyObject *
534 objfpy_repr (PyObject *self_)
535 {
536 objfile_object *self = (objfile_object *) self_;
537 objfile *obj = self->objfile;
538
539 if (obj == nullptr)
540 return PyUnicode_FromString ("<gdb.Objfile (invalid)>");
541
542 return PyUnicode_FromFormat ("<gdb.Objfile filename=%s>",
543 objfile_name (obj));
544 }
545
546 /* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
547 Return non-zero if STRING is a potentially valid build id. */
548
549 static int
550 objfpy_build_id_ok (const char *string)
551 {
552 size_t i, n = strlen (string);
553
554 if (n % 2 != 0)
555 return 0;
556 for (i = 0; i < n; ++i)
557 {
558 if (!isxdigit (string[i]))
559 return 0;
560 }
561 return 1;
562 }
563
564 /* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
565 Returns non-zero if BUILD_ID matches STRING.
566 It is assumed that objfpy_build_id_ok (string) returns TRUE. */
567
568 static int
569 objfpy_build_id_matches (const struct bfd_build_id *build_id,
570 const char *string)
571 {
572 size_t i;
573
574 if (strlen (string) != 2 * build_id->size)
575 return 0;
576
577 for (i = 0; i < build_id->size; ++i)
578 {
579 char c1 = string[i * 2], c2 = string[i * 2 + 1];
580 int byte = (fromhex (c1) << 4) | fromhex (c2);
581
582 if (byte != build_id->data[i])
583 return 0;
584 }
585
586 return 1;
587 }
588
589 /* Implementation of gdb.lookup_objfile. */
590
591 PyObject *
592 gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
593 {
594 static const char *keywords[] = { "name", "by_build_id", NULL };
595 const char *name;
596 PyObject *by_build_id_obj = NULL;
597 int by_build_id;
598
599 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
600 &name, &PyBool_Type, &by_build_id_obj))
601 return NULL;
602
603 by_build_id = 0;
604 if (by_build_id_obj != NULL)
605 {
606 int cmp = PyObject_IsTrue (by_build_id_obj);
607
608 if (cmp < 0)
609 return NULL;
610 by_build_id = cmp;
611 }
612
613 if (by_build_id && !objfpy_build_id_ok (name))
614 {
615 PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
616 return NULL;
617 }
618
619 struct objfile *objfile = nullptr;
620 if (by_build_id)
621 gdbarch_iterate_over_objfiles_in_search_order
622 (target_gdbarch (),
623 [&objfile, name] (struct objfile *obj)
624 {
625 /* Don't return separate debug files. */
626 if (obj->separate_debug_objfile_backlink != nullptr)
627 return 0;
628
629 bfd *obfd = obj->obfd.get ();
630 if (obfd == nullptr)
631 return 0;
632
633 const bfd_build_id *obfd_build_id = build_id_bfd_get (obfd);
634 if (obfd_build_id == nullptr)
635 return 0;
636
637 if (!objfpy_build_id_matches (obfd_build_id, name))
638 return 0;
639
640 objfile = obj;
641 return 1;
642 }, gdbpy_current_objfile);
643 else
644 gdbarch_iterate_over_objfiles_in_search_order
645 (target_gdbarch (),
646 [&objfile, name] (struct objfile *obj)
647 {
648 /* Don't return separate debug files. */
649 if (obj->separate_debug_objfile_backlink != nullptr)
650 return 0;
651
652 if ((obj->flags & OBJF_NOT_FILENAME) != 0)
653 return 0;
654
655 const char *filename = objfile_filename (obj);
656 if (filename != NULL
657 && compare_filenames_for_search (filename, name))
658 {
659 objfile = obj;
660 return 1;
661 }
662
663 if (compare_filenames_for_search (obj->original_name, name))
664 {
665 objfile = obj;
666 return 1;
667 }
668
669 return 0;
670 }, gdbpy_current_objfile);
671
672 if (objfile != NULL)
673 return objfile_to_objfile_object (objfile).release ();
674
675 PyErr_SetString (PyExc_ValueError, _("Objfile not found."));
676 return NULL;
677 }
678
679
680
682 /* Return a new reference to the Python object of type Objfile
683 representing OBJFILE. If the object has already been created,
684 return it. Otherwise, create it. Return NULL and set the Python
685 error on failure. */
686
687 gdbpy_ref<>
688 objfile_to_objfile_object (struct objfile *objfile)
689 {
690 PyObject *result
691 = (PyObject *) objfpy_objfile_data_key.get (objfile);
692 if (result == NULL)
693 {
694 gdbpy_ref<objfile_object> object
695 ((objfile_object *) PyObject_New (objfile_object, &objfile_object_type));
696 if (object == NULL)
697 return NULL;
698 if (!objfpy_initialize (object.get ()))
699 return NULL;
700
701 object->objfile = objfile;
702 objfpy_objfile_data_key.set (objfile, object.get ());
703 result = (PyObject *) object.release ();
704 }
705
706 return gdbpy_ref<>::new_reference (result);
707 }
708
709 int
710 gdbpy_initialize_objfile (void)
711 {
712 if (PyType_Ready (&objfile_object_type) < 0)
713 return -1;
714
715 return gdb_pymodule_addobject (gdb_module, "Objfile",
716 (PyObject *) &objfile_object_type);
717 }
718
719
720
722 static PyMethodDef objfile_object_methods[] =
723 {
724 { "is_valid", objfpy_is_valid, METH_NOARGS,
725 "is_valid () -> Boolean.\n\
726 Return true if this object file is valid, false if not." },
727
728 { "add_separate_debug_file", (PyCFunction) objfpy_add_separate_debug_file,
729 METH_VARARGS | METH_KEYWORDS,
730 "add_separate_debug_file (file_name).\n\
731 Add FILE_NAME to the list of files containing debug info for the objfile." },
732
733 { "lookup_global_symbol", (PyCFunction) objfpy_lookup_global_symbol,
734 METH_VARARGS | METH_KEYWORDS,
735 "lookup_global_symbol (name [, domain]).\n\
736 Look up a global symbol in this objfile and return it." },
737
738 { "lookup_static_symbol", (PyCFunction) objfpy_lookup_static_symbol,
739 METH_VARARGS | METH_KEYWORDS,
740 "lookup_static_symbol (name [, domain]).\n\
741 Look up a static-linkage global symbol in this objfile and return it." },
742
743 { NULL }
744 };
745
746 static gdb_PyGetSetDef objfile_getset[] =
747 {
748 { "__dict__", gdb_py_generic_dict, NULL,
749 "The __dict__ for this objfile.", &objfile_object_type },
750 { "filename", objfpy_get_filename, NULL,
751 "The objfile's filename, or None.", NULL },
752 { "username", objfpy_get_username, NULL,
753 "The name of the objfile as provided by the user, or None.", NULL },
754 { "owner", objfpy_get_owner, NULL,
755 "The objfile owner of separate debug info objfiles, or None.",
756 NULL },
757 { "build_id", objfpy_get_build_id, NULL,
758 "The objfile's build id, or None.", NULL },
759 { "progspace", objfpy_get_progspace, NULL,
760 "The objfile's progspace, or None.", NULL },
761 { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
762 "Pretty printers.", NULL },
763 { "frame_filters", objfpy_get_frame_filters,
764 objfpy_set_frame_filters, "Frame Filters.", NULL },
765 { "frame_unwinders", objfpy_get_frame_unwinders,
766 objfpy_set_frame_unwinders, "Frame Unwinders", NULL },
767 { "type_printers", objfpy_get_type_printers, objfpy_set_type_printers,
768 "Type printers.", NULL },
769 { "xmethods", objfpy_get_xmethods, NULL,
770 "Debug methods.", NULL },
771 { "is_file", objfpy_get_is_file, nullptr,
772 "Whether this objfile came from a file.", nullptr },
773 { NULL }
774 };
775
776 PyTypeObject objfile_object_type =
777 {
778 PyVarObject_HEAD_INIT (NULL, 0)
779 "gdb.Objfile", /*tp_name*/
780 sizeof (objfile_object), /*tp_basicsize*/
781 0, /*tp_itemsize*/
782 objfpy_dealloc, /*tp_dealloc*/
783 0, /*tp_print*/
784 0, /*tp_getattr*/
785 0, /*tp_setattr*/
786 0, /*tp_compare*/
787 objfpy_repr, /*tp_repr*/
788 0, /*tp_as_number*/
789 0, /*tp_as_sequence*/
790 0, /*tp_as_mapping*/
791 0, /*tp_hash */
792 0, /*tp_call*/
793 0, /*tp_str*/
794 0, /*tp_getattro*/
795 0, /*tp_setattro*/
796 0, /*tp_as_buffer*/
797 Py_TPFLAGS_DEFAULT, /*tp_flags*/
798 "GDB objfile object", /* tp_doc */
799 0, /* tp_traverse */
800 0, /* tp_clear */
801 0, /* tp_richcompare */
802 0, /* tp_weaklistoffset */
803 0, /* tp_iter */
804 0, /* tp_iternext */
805 objfile_object_methods, /* tp_methods */
806 0, /* tp_members */
807 objfile_getset, /* tp_getset */
808 0, /* tp_base */
809 0, /* tp_dict */
810 0, /* tp_descr_get */
811 0, /* tp_descr_set */
812 offsetof (objfile_object, dict), /* tp_dictoffset */
813 0, /* tp_init */
814 0, /* tp_alloc */
815 objfpy_new, /* tp_new */
816 };
817