Enhance gdb.lookup_objfile so that it works with a symlinked binary.
[deliverable/binutils-gdb.git] / gdb / python / py-objfile.c
CommitLineData
89c73ade
TT
1/* Python interface to objfiles.
2
32d0add0 3 Copyright (C) 2008-2015 Free Software Foundation, Inc.
89c73ade
TT
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"
d452c4bc 24#include "language.h"
7c50a931
DE
25#include "build-id.h"
26#include "elf-bfd.h"
6dddd6a5 27#include "symtab.h"
89c73ade
TT
28
29typedef struct
30{
31 PyObject_HEAD
32
33 /* The corresponding objfile. */
34 struct objfile *objfile;
35
02be9a71
DE
36 /* Dictionary holding user-added attributes.
37 This is the __dict__ attribute of the object. */
38 PyObject *dict;
39
89c73ade
TT
40 /* The pretty-printer list of functions. */
41 PyObject *printers;
18a9fc12 42
1e611234
PM
43 /* The frame filter list of functions. */
44 PyObject *frame_filters;
18a9fc12
TT
45 /* The type-printer list. */
46 PyObject *type_printers;
883964a7
SC
47
48 /* The debug method matcher list. */
49 PyObject *xmethods;
89c73ade
TT
50} objfile_object;
51
62eec1a5
TT
52static PyTypeObject objfile_object_type
53 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
89c73ade
TT
54
55static const struct objfile_data *objfpy_objfile_data_key;
56
7c50a931
DE
57/* Require that OBJF be a valid objfile. */
58#define OBJFPY_REQUIRE_VALID(obj) \
59 do { \
60 if (!(obj)->objfile) \
61 { \
62 PyErr_SetString (PyExc_RuntimeError, \
63 _("Objfile no longer exists.")); \
64 return NULL; \
65 } \
66 } while (0)
67
89c73ade
TT
68\f
69
70/* An Objfile method which returns the objfile's file name, or None. */
7c50a931 71
89c73ade
TT
72static PyObject *
73objfpy_get_filename (PyObject *self, void *closure)
74{
75 objfile_object *obj = (objfile_object *) self;
d59b6f6c 76
d31d2fc3 77 if (obj->objfile)
4262abfb
JK
78 return PyString_Decode (objfile_name (obj->objfile),
79 strlen (objfile_name (obj->objfile)),
89c73ade
TT
80 host_charset (), NULL);
81 Py_RETURN_NONE;
82}
83
a0be3e44
DE
84/* If SELF is a separate debug-info file, return the "backlink" field.
85 Otherwise return None. */
86
87static PyObject *
88objfpy_get_owner (PyObject *self, void *closure)
89{
90 objfile_object *obj = (objfile_object *) self;
91 struct objfile *objfile = obj->objfile;
92 struct objfile *owner;
93
94 OBJFPY_REQUIRE_VALID (obj);
95
96 owner = objfile->separate_debug_objfile_backlink;
a0be3e44 97 if (owner != NULL)
d4d1e336
DE
98 {
99 PyObject *result = objfile_to_objfile_object (owner);
100
101 Py_XINCREF (result);
102 return result;
103 }
a0be3e44
DE
104 Py_RETURN_NONE;
105}
106
7c50a931
DE
107/* An Objfile method which returns the objfile's build id, or None. */
108
109static PyObject *
110objfpy_get_build_id (PyObject *self, void *closure)
111{
112 objfile_object *obj = (objfile_object *) self;
113 struct objfile *objfile = obj->objfile;
114 const struct elf_build_id *build_id = NULL;
115 volatile struct gdb_exception except;
116
117 OBJFPY_REQUIRE_VALID (obj);
118
119 TRY_CATCH (except, RETURN_MASK_ALL)
120 {
121 build_id = build_id_bfd_get (objfile->obfd);
122 }
123 GDB_PY_HANDLE_EXCEPTION (except);
124
125 if (build_id != NULL)
126 {
127 char *hex_form = make_hex_string (build_id->data, build_id->size);
128 PyObject *result;
129
130 result = PyString_Decode (hex_form, strlen (hex_form),
131 host_charset (), NULL);
132 xfree (hex_form);
133 return result;
134 }
135
136 Py_RETURN_NONE;
137}
138
d096d8c1
DE
139/* An Objfile method which returns the objfile's progspace, or None. */
140
141static PyObject *
142objfpy_get_progspace (PyObject *self, void *closure)
143{
144 objfile_object *obj = (objfile_object *) self;
145
146 if (obj->objfile)
147 {
148 PyObject *pspace = pspace_to_pspace_object (obj->objfile->pspace);
149
150 Py_XINCREF (pspace);
151 return pspace;
152 }
153
154 Py_RETURN_NONE;
155}
156
89c73ade
TT
157static void
158objfpy_dealloc (PyObject *o)
159{
160 objfile_object *self = (objfile_object *) o;
d59b6f6c 161
02be9a71 162 Py_XDECREF (self->dict);
89c73ade 163 Py_XDECREF (self->printers);
1e611234 164 Py_XDECREF (self->frame_filters);
18a9fc12 165 Py_XDECREF (self->type_printers);
883964a7 166 Py_XDECREF (self->xmethods);
9a27f2c6 167 Py_TYPE (self)->tp_free (self);
89c73ade
TT
168}
169
4e1bbde0
DE
170/* Initialize an objfile_object.
171 The result is a boolean indicating success. */
172
173static int
174objfpy_initialize (objfile_object *self)
175{
176 self->objfile = NULL;
02be9a71 177 self->dict = NULL;
4e1bbde0
DE
178
179 self->printers = PyList_New (0);
180 if (self->printers == NULL)
181 return 0;
182
183 self->frame_filters = PyDict_New ();
184 if (self->frame_filters == NULL)
185 return 0;
186
187 self->type_printers = PyList_New (0);
188 if (self->type_printers == NULL)
189 return 0;
190
191 self->xmethods = PyList_New (0);
192 if (self->xmethods == NULL)
193 return 0;
194
195 return 1;
196}
197
89c73ade
TT
198static PyObject *
199objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
200{
201 objfile_object *self = (objfile_object *) type->tp_alloc (type, 0);
d59b6f6c 202
89c73ade
TT
203 if (self)
204 {
4e1bbde0 205 if (!objfpy_initialize (self))
883964a7
SC
206 {
207 Py_DECREF (self);
208 return NULL;
209 }
89c73ade 210 }
4e1bbde0 211
89c73ade
TT
212 return (PyObject *) self;
213}
214
215PyObject *
216objfpy_get_printers (PyObject *o, void *ignore)
217{
218 objfile_object *self = (objfile_object *) o;
d59b6f6c 219
89c73ade
TT
220 Py_INCREF (self->printers);
221 return self->printers;
222}
223
224static int
225objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
226{
227 PyObject *tmp;
228 objfile_object *self = (objfile_object *) o;
d59b6f6c 229
89c73ade
TT
230 if (! value)
231 {
232 PyErr_SetString (PyExc_TypeError,
044c0f87 233 _("Cannot delete the pretty_printers attribute."));
89c73ade
TT
234 return -1;
235 }
236
237 if (! PyList_Check (value))
238 {
239 PyErr_SetString (PyExc_TypeError,
044c0f87 240 _("The pretty_printers attribute must be a list."));
89c73ade
TT
241 return -1;
242 }
243
244 /* Take care in case the LHS and RHS are related somehow. */
245 tmp = self->printers;
246 Py_INCREF (value);
247 self->printers = value;
248 Py_XDECREF (tmp);
249
250 return 0;
251}
252
1e611234
PM
253/* Return the Python dictionary attribute containing frame filters for
254 this object file. */
255PyObject *
256objfpy_get_frame_filters (PyObject *o, void *ignore)
257{
258 objfile_object *self = (objfile_object *) o;
259
260 Py_INCREF (self->frame_filters);
261 return self->frame_filters;
262}
263
264/* Set this object file's frame filters dictionary to FILTERS. */
265static int
266objfpy_set_frame_filters (PyObject *o, PyObject *filters, void *ignore)
267{
268 PyObject *tmp;
269 objfile_object *self = (objfile_object *) o;
270
271 if (! filters)
272 {
273 PyErr_SetString (PyExc_TypeError,
274 _("Cannot delete the frame filters attribute."));
275 return -1;
276 }
277
278 if (! PyDict_Check (filters))
279 {
280 PyErr_SetString (PyExc_TypeError,
281 _("The frame_filters attribute must be a dictionary."));
282 return -1;
283 }
284
285 /* Take care in case the LHS and RHS are related somehow. */
286 tmp = self->frame_filters;
287 Py_INCREF (filters);
288 self->frame_filters = filters;
289 Py_XDECREF (tmp);
290
291 return 0;
292}
293
18a9fc12
TT
294/* Get the 'type_printers' attribute. */
295
296static PyObject *
297objfpy_get_type_printers (PyObject *o, void *ignore)
298{
299 objfile_object *self = (objfile_object *) o;
300
301 Py_INCREF (self->type_printers);
302 return self->type_printers;
303}
304
883964a7
SC
305/* Get the 'xmethods' attribute. */
306
307PyObject *
308objfpy_get_xmethods (PyObject *o, void *ignore)
309{
310 objfile_object *self = (objfile_object *) o;
311
312 Py_INCREF (self->xmethods);
313 return self->xmethods;
314}
315
18a9fc12
TT
316/* Set the 'type_printers' attribute. */
317
318static int
319objfpy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
320{
321 PyObject *tmp;
322 objfile_object *self = (objfile_object *) o;
323
324 if (! value)
325 {
326 PyErr_SetString (PyExc_TypeError,
327 _("Cannot delete the type_printers attribute."));
328 return -1;
329 }
330
331 if (! PyList_Check (value))
332 {
333 PyErr_SetString (PyExc_TypeError,
334 _("The type_printers attribute must be a list."));
335 return -1;
336 }
337
338 /* Take care in case the LHS and RHS are related somehow. */
339 tmp = self->type_printers;
340 Py_INCREF (value);
341 self->type_printers = value;
342 Py_XDECREF (tmp);
343
344 return 0;
345}
346
29703da4
PM
347/* Implementation of gdb.Objfile.is_valid (self) -> Boolean.
348 Returns True if this object file still exists in GDB. */
349
350static PyObject *
351objfpy_is_valid (PyObject *self, PyObject *args)
352{
353 objfile_object *obj = (objfile_object *) self;
354
355 if (! obj->objfile)
356 Py_RETURN_FALSE;
357
358 Py_RETURN_TRUE;
359}
360
86e4ed39
DE
361/* Implementation of gdb.Objfile.add_separate_debug_file (self) -> Boolean. */
362
363static PyObject *
364objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw)
365{
366 static char *keywords[] = { "file_name", NULL };
367 objfile_object *obj = (objfile_object *) self;
368 const char *file_name;
369 int symfile_flags = 0;
370 volatile struct gdb_exception except;
371
372 OBJFPY_REQUIRE_VALID (obj);
373
374 if (!PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &file_name))
375 return NULL;
376
377 TRY_CATCH (except, RETURN_MASK_ALL)
378 {
379 bfd *abfd = symfile_bfd_open (file_name);
380
381 symbol_file_add_separate (abfd, file_name, symfile_flags, obj->objfile);
382 }
383 GDB_PY_HANDLE_EXCEPTION (except);
384
385 Py_RETURN_NONE;
386}
387
6dddd6a5
DE
388/* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
389 Return non-zero if STRING is a potentially valid build id. */
390
391static int
392objfpy_build_id_ok (const char *string)
393{
394 size_t i, n = strlen (string);
395
396 if (n % 2 != 0)
397 return 0;
398 for (i = 0; i < n; ++i)
399 {
400 if (!isxdigit (string[i]))
401 return 0;
402 }
403 return 1;
404}
405
406/* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
407 Returns non-zero if BUILD_ID matches STRING.
408 It is assumed that objfpy_build_id_ok (string) returns TRUE. */
409
410static int
411objfpy_build_id_matches (const struct elf_build_id *build_id,
412 const char *string)
413{
414 size_t i;
415
416 if (strlen (string) != 2 * build_id->size)
417 return 0;
418
419 for (i = 0; i < build_id->size; ++i)
420 {
421 char c1 = string[i * 2], c2 = string[i * 2 + 1];
422 int byte = (host_hex_value (c1) << 4) | host_hex_value (c2);
423
424 if (byte != build_id->data[i])
425 return 0;
426 }
427
428 return 1;
429}
430
431/* Subroutine of gdbpy_lookup_objfile to simplify it.
432 Look up an objfile by its file name. */
433
434static struct objfile *
435objfpy_lookup_objfile_by_name (const char *name)
436{
437 struct objfile *objfile;
438
439 ALL_OBJFILES (objfile)
440 {
e02c96a7
DE
441 const char *filename;
442
6dddd6a5
DE
443 if ((objfile->flags & OBJF_NOT_FILENAME) != 0)
444 continue;
445 /* Don't return separate debug files. */
446 if (objfile->separate_debug_objfile_backlink != NULL)
447 continue;
e02c96a7
DE
448
449 filename = objfile_filename (objfile);
450 if (filename != NULL && compare_filenames_for_search (filename, name))
451 return objfile;
452 if (compare_filenames_for_search (objfile->original_name, name))
6dddd6a5
DE
453 return objfile;
454 }
455
456 return NULL;
457}
458
459/* Subroutine of gdbpy_lookup_objfile to simplify it.
460 Look up an objfile by its build id. */
461
462static struct objfile *
463objfpy_lookup_objfile_by_build_id (const char *build_id)
464{
465 struct objfile *objfile;
466
467 ALL_OBJFILES (objfile)
468 {
469 const struct elf_build_id *obfd_build_id;
470
471 if (objfile->obfd == NULL)
472 continue;
473 /* Don't return separate debug files. */
474 if (objfile->separate_debug_objfile_backlink != NULL)
475 continue;
476 obfd_build_id = build_id_bfd_get (objfile->obfd);
477 if (obfd_build_id == NULL)
478 continue;
479 if (objfpy_build_id_matches (obfd_build_id, build_id))
480 return objfile;
481 }
482
483 return NULL;
484}
485
486/* Implementation of gdb.lookup_objfile. */
487
488PyObject *
489gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
490{
491 static char *keywords[] = { "name", "by_build_id", NULL };
492 const char *name;
493 PyObject *by_build_id_obj = NULL;
494 int by_build_id;
495 struct objfile *objfile;
496
497 if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
498 &name, &PyBool_Type, &by_build_id_obj))
499 return NULL;
500
501 by_build_id = 0;
502 if (by_build_id_obj != NULL)
503 {
504 int cmp = PyObject_IsTrue (by_build_id_obj);
505
506 if (cmp < 0)
507 return NULL;
508 by_build_id = cmp;
509 }
510
511 if (by_build_id)
512 {
513 if (!objfpy_build_id_ok (name))
514 {
515 PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
516 return NULL;
517 }
518 objfile = objfpy_lookup_objfile_by_build_id (name);
519 }
520 else
521 objfile = objfpy_lookup_objfile_by_name (name);
522
523 if (objfile != NULL)
524 {
525 PyObject *result = objfile_to_objfile_object (objfile);
526
527 Py_XINCREF (result);
528 return result;
529 }
530
531 PyErr_SetString (PyExc_ValueError, _("Objfile not found."));
532 return NULL;
533}
534
89c73ade
TT
535\f
536
537/* Clear the OBJFILE pointer in an Objfile object and remove the
538 reference. */
539static void
c1bd65d0 540py_free_objfile (struct objfile *objfile, void *datum)
89c73ade 541{
d452c4bc 542 struct cleanup *cleanup;
89c73ade
TT
543 objfile_object *object = datum;
544
d452c4bc 545 cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
89c73ade
TT
546 object->objfile = NULL;
547 Py_DECREF ((PyObject *) object);
d452c4bc 548 do_cleanups (cleanup);
89c73ade
TT
549}
550
551/* Return a borrowed reference to the Python object of type Objfile
552 representing OBJFILE. If the object has already been created,
553 return it. Otherwise, create it. Return NULL and set the Python
554 error on failure. */
4e1bbde0 555
89c73ade
TT
556PyObject *
557objfile_to_objfile_object (struct objfile *objfile)
558{
559 objfile_object *object;
560
561 object = objfile_data (objfile, objfpy_objfile_data_key);
562 if (!object)
563 {
564 object = PyObject_New (objfile_object, &objfile_object_type);
565 if (object)
566 {
4e1bbde0 567 if (!objfpy_initialize (object))
883964a7
SC
568 {
569 Py_DECREF (object);
570 return NULL;
571 }
572
4e1bbde0 573 object->objfile = objfile;
89c73ade
TT
574 set_objfile_data (objfile, objfpy_objfile_data_key, object);
575 }
576 }
577
578 return (PyObject *) object;
579}
580
999633ed 581int
89c73ade
TT
582gdbpy_initialize_objfile (void)
583{
584 objfpy_objfile_data_key
c1bd65d0 585 = register_objfile_data_with_cleanup (NULL, py_free_objfile);
89c73ade
TT
586
587 if (PyType_Ready (&objfile_object_type) < 0)
999633ed 588 return -1;
89c73ade 589
aa36459a
TT
590 return gdb_pymodule_addobject (gdb_module, "Objfile",
591 (PyObject *) &objfile_object_type);
89c73ade
TT
592}
593
594\f
595
29703da4
PM
596static PyMethodDef objfile_object_methods[] =
597{
598 { "is_valid", objfpy_is_valid, METH_NOARGS,
599 "is_valid () -> Boolean.\n\
600Return true if this object file is valid, false if not." },
601
86e4ed39
DE
602 { "add_separate_debug_file", (PyCFunction) objfpy_add_separate_debug_file,
603 METH_VARARGS | METH_KEYWORDS,
604 "add_separate_debug_file (file_name).\n\
605Add FILE_NAME to the list of files containing debug info for the objfile." },
606
29703da4
PM
607 { NULL }
608};
609
89c73ade
TT
610static PyGetSetDef objfile_getset[] =
611{
02be9a71
DE
612 { "__dict__", gdb_py_generic_dict, NULL,
613 "The __dict__ for this objfile.", &objfile_object_type },
89c73ade
TT
614 { "filename", objfpy_get_filename, NULL,
615 "The objfile's filename, or None.", NULL },
a0be3e44
DE
616 { "owner", objfpy_get_owner, NULL,
617 "The objfile owner of separate debug info objfiles, or None.",
618 NULL },
7c50a931
DE
619 { "build_id", objfpy_get_build_id, NULL,
620 "The objfile's build id, or None.", NULL },
d096d8c1
DE
621 { "progspace", objfpy_get_progspace, NULL,
622 "The objfile's progspace, or None.", NULL },
89c73ade
TT
623 { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
624 "Pretty printers.", NULL },
1e611234
PM
625 { "frame_filters", objfpy_get_frame_filters,
626 objfpy_set_frame_filters, "Frame Filters.", NULL },
18a9fc12
TT
627 { "type_printers", objfpy_get_type_printers, objfpy_set_type_printers,
628 "Type printers.", NULL },
883964a7
SC
629 { "xmethods", objfpy_get_xmethods, NULL,
630 "Debug methods.", NULL },
89c73ade
TT
631 { NULL }
632};
633
634static PyTypeObject objfile_object_type =
635{
9a27f2c6 636 PyVarObject_HEAD_INIT (NULL, 0)
89c73ade
TT
637 "gdb.Objfile", /*tp_name*/
638 sizeof (objfile_object), /*tp_basicsize*/
639 0, /*tp_itemsize*/
640 objfpy_dealloc, /*tp_dealloc*/
641 0, /*tp_print*/
642 0, /*tp_getattr*/
643 0, /*tp_setattr*/
644 0, /*tp_compare*/
645 0, /*tp_repr*/
646 0, /*tp_as_number*/
647 0, /*tp_as_sequence*/
648 0, /*tp_as_mapping*/
649 0, /*tp_hash */
650 0, /*tp_call*/
651 0, /*tp_str*/
652 0, /*tp_getattro*/
653 0, /*tp_setattro*/
654 0, /*tp_as_buffer*/
655 Py_TPFLAGS_DEFAULT, /*tp_flags*/
656 "GDB objfile object", /* tp_doc */
657 0, /* tp_traverse */
658 0, /* tp_clear */
659 0, /* tp_richcompare */
660 0, /* tp_weaklistoffset */
661 0, /* tp_iter */
662 0, /* tp_iternext */
29703da4 663 objfile_object_methods, /* tp_methods */
89c73ade
TT
664 0, /* tp_members */
665 objfile_getset, /* tp_getset */
666 0, /* tp_base */
667 0, /* tp_dict */
668 0, /* tp_descr_get */
669 0, /* tp_descr_set */
02be9a71 670 offsetof (objfile_object, dict), /* tp_dictoffset */
89c73ade
TT
671 0, /* tp_init */
672 0, /* tp_alloc */
673 objfpy_new, /* tp_new */
674};
This page took 0.602377 seconds and 4 git commands to generate.