xref: /dflybsd-src/contrib/gdb-7/gdb/python/py-arch.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1*ef5ccd6cSJohn Marino /* Python interface to architecture
2*ef5ccd6cSJohn Marino 
3*ef5ccd6cSJohn Marino    Copyright (C) 2013 Free Software Foundation, Inc.
4*ef5ccd6cSJohn Marino 
5*ef5ccd6cSJohn Marino    This file is part of GDB.
6*ef5ccd6cSJohn Marino 
7*ef5ccd6cSJohn Marino    This program is free software; you can redistribute it and/or modify
8*ef5ccd6cSJohn Marino    it under the terms of the GNU General Public License as published by
9*ef5ccd6cSJohn Marino    the Free Software Foundation; either version 3 of the License, or
10*ef5ccd6cSJohn Marino    (at your option) any later version.
11*ef5ccd6cSJohn Marino 
12*ef5ccd6cSJohn Marino    This program is distributed in the hope that it will be useful,
13*ef5ccd6cSJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*ef5ccd6cSJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*ef5ccd6cSJohn Marino    GNU General Public License for more details.
16*ef5ccd6cSJohn Marino 
17*ef5ccd6cSJohn Marino    You should have received a copy of the GNU General Public License
18*ef5ccd6cSJohn Marino    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19*ef5ccd6cSJohn Marino 
20*ef5ccd6cSJohn Marino #include "defs.h"
21*ef5ccd6cSJohn Marino #include "gdbarch.h"
22*ef5ccd6cSJohn Marino #include "arch-utils.h"
23*ef5ccd6cSJohn Marino #include "disasm.h"
24*ef5ccd6cSJohn Marino #include "python-internal.h"
25*ef5ccd6cSJohn Marino 
26*ef5ccd6cSJohn Marino typedef struct arch_object_type_object {
27*ef5ccd6cSJohn Marino   PyObject_HEAD
28*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch;
29*ef5ccd6cSJohn Marino } arch_object;
30*ef5ccd6cSJohn Marino 
31*ef5ccd6cSJohn Marino static struct gdbarch_data *arch_object_data = NULL;
32*ef5ccd6cSJohn Marino static PyTypeObject arch_object_type;
33*ef5ccd6cSJohn Marino 
34*ef5ccd6cSJohn Marino /* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
35*ef5ccd6cSJohn Marino    post init registration mechanism (gdbarch_data_register_post_init).  */
36*ef5ccd6cSJohn Marino 
37*ef5ccd6cSJohn Marino static void *
arch_object_data_init(struct gdbarch * gdbarch)38*ef5ccd6cSJohn Marino arch_object_data_init (struct gdbarch *gdbarch)
39*ef5ccd6cSJohn Marino {
40*ef5ccd6cSJohn Marino   arch_object *arch_obj = PyObject_New (arch_object, &arch_object_type);
41*ef5ccd6cSJohn Marino 
42*ef5ccd6cSJohn Marino   if (arch_obj == NULL)
43*ef5ccd6cSJohn Marino     return NULL;
44*ef5ccd6cSJohn Marino 
45*ef5ccd6cSJohn Marino   arch_obj->gdbarch = gdbarch;
46*ef5ccd6cSJohn Marino 
47*ef5ccd6cSJohn Marino   return (void *) arch_obj;
48*ef5ccd6cSJohn Marino }
49*ef5ccd6cSJohn Marino 
50*ef5ccd6cSJohn Marino /* Returns the struct gdbarch value corresponding to the given Python
51*ef5ccd6cSJohn Marino    architecture object OBJ.  */
52*ef5ccd6cSJohn Marino 
53*ef5ccd6cSJohn Marino struct gdbarch *
arch_object_to_gdbarch(PyObject * obj)54*ef5ccd6cSJohn Marino arch_object_to_gdbarch (PyObject *obj)
55*ef5ccd6cSJohn Marino {
56*ef5ccd6cSJohn Marino   arch_object *py_arch = (arch_object *) obj;
57*ef5ccd6cSJohn Marino 
58*ef5ccd6cSJohn Marino   return py_arch->gdbarch;
59*ef5ccd6cSJohn Marino }
60*ef5ccd6cSJohn Marino 
61*ef5ccd6cSJohn Marino /* Returns the Python architecture object corresponding to GDBARCH.
62*ef5ccd6cSJohn Marino    Returns a new reference to the arch_object associated as data with
63*ef5ccd6cSJohn Marino    GDBARCH.  */
64*ef5ccd6cSJohn Marino 
65*ef5ccd6cSJohn Marino PyObject *
gdbarch_to_arch_object(struct gdbarch * gdbarch)66*ef5ccd6cSJohn Marino gdbarch_to_arch_object (struct gdbarch *gdbarch)
67*ef5ccd6cSJohn Marino {
68*ef5ccd6cSJohn Marino   PyObject *new_ref = (PyObject *) gdbarch_data (gdbarch, arch_object_data);
69*ef5ccd6cSJohn Marino 
70*ef5ccd6cSJohn Marino   /* new_ref could be NULL if registration of arch_object with GDBARCH failed
71*ef5ccd6cSJohn Marino      in arch_object_data_init.  */
72*ef5ccd6cSJohn Marino   Py_XINCREF (new_ref);
73*ef5ccd6cSJohn Marino 
74*ef5ccd6cSJohn Marino   return new_ref;
75*ef5ccd6cSJohn Marino }
76*ef5ccd6cSJohn Marino 
77*ef5ccd6cSJohn Marino /* Implementation of gdb.Architecture.name (self) -> String.
78*ef5ccd6cSJohn Marino    Returns the name of the architecture as a string value.  */
79*ef5ccd6cSJohn Marino 
80*ef5ccd6cSJohn Marino static PyObject *
archpy_name(PyObject * self,PyObject * args)81*ef5ccd6cSJohn Marino archpy_name (PyObject *self, PyObject *args)
82*ef5ccd6cSJohn Marino {
83*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = arch_object_to_gdbarch (self);
84*ef5ccd6cSJohn Marino   const char *name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
85*ef5ccd6cSJohn Marino   PyObject *py_name = PyString_FromString (name);
86*ef5ccd6cSJohn Marino 
87*ef5ccd6cSJohn Marino   return py_name;
88*ef5ccd6cSJohn Marino }
89*ef5ccd6cSJohn Marino 
90*ef5ccd6cSJohn Marino /* Implementation of
91*ef5ccd6cSJohn Marino    gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
92*ef5ccd6cSJohn Marino    Returns a list of instructions in a memory address range.  Each instruction
93*ef5ccd6cSJohn Marino    in the list is a Python dict object.
94*ef5ccd6cSJohn Marino */
95*ef5ccd6cSJohn Marino 
96*ef5ccd6cSJohn Marino static PyObject *
archpy_disassemble(PyObject * self,PyObject * args,PyObject * kw)97*ef5ccd6cSJohn Marino archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
98*ef5ccd6cSJohn Marino {
99*ef5ccd6cSJohn Marino   static char *keywords[] = { "start_pc", "end_pc", "count", NULL };
100*ef5ccd6cSJohn Marino   CORE_ADDR start, end = 0;
101*ef5ccd6cSJohn Marino   CORE_ADDR pc;
102*ef5ccd6cSJohn Marino   gdb_py_ulongest start_temp;
103*ef5ccd6cSJohn Marino   long count = 0, i;
104*ef5ccd6cSJohn Marino   PyObject *result_list, *end_obj = NULL, *count_obj = NULL;
105*ef5ccd6cSJohn Marino   struct gdbarch *gdbarch = arch_object_to_gdbarch (self);
106*ef5ccd6cSJohn Marino 
107*ef5ccd6cSJohn Marino   if (!PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO", keywords,
108*ef5ccd6cSJohn Marino                                     &start_temp, &end_obj, &count_obj))
109*ef5ccd6cSJohn Marino     return NULL;
110*ef5ccd6cSJohn Marino 
111*ef5ccd6cSJohn Marino   start = start_temp;
112*ef5ccd6cSJohn Marino   if (end_obj)
113*ef5ccd6cSJohn Marino     {
114*ef5ccd6cSJohn Marino       if (PyLong_Check (end_obj))
115*ef5ccd6cSJohn Marino         end = PyLong_AsUnsignedLongLong (end_obj);
116*ef5ccd6cSJohn Marino       else if (PyInt_Check (end_obj))
117*ef5ccd6cSJohn Marino         /* If the end_pc value is specified without a trailing 'L', end_obj will
118*ef5ccd6cSJohn Marino            be an integer and not a long integer.  */
119*ef5ccd6cSJohn Marino         end = PyInt_AsLong (end_obj);
120*ef5ccd6cSJohn Marino       else
121*ef5ccd6cSJohn Marino         {
122*ef5ccd6cSJohn Marino           Py_DECREF (end_obj);
123*ef5ccd6cSJohn Marino           Py_XDECREF (count_obj);
124*ef5ccd6cSJohn Marino           PyErr_SetString (PyExc_TypeError,
125*ef5ccd6cSJohn Marino                            _("Argument 'end_pc' should be a (long) integer."));
126*ef5ccd6cSJohn Marino 
127*ef5ccd6cSJohn Marino           return NULL;
128*ef5ccd6cSJohn Marino         }
129*ef5ccd6cSJohn Marino 
130*ef5ccd6cSJohn Marino       if (end < start)
131*ef5ccd6cSJohn Marino         {
132*ef5ccd6cSJohn Marino           Py_DECREF (end_obj);
133*ef5ccd6cSJohn Marino           Py_XDECREF (count_obj);
134*ef5ccd6cSJohn Marino           PyErr_SetString (PyExc_ValueError,
135*ef5ccd6cSJohn Marino                            _("Argument 'end_pc' should be greater than or "
136*ef5ccd6cSJohn Marino                              "equal to the argument 'start_pc'."));
137*ef5ccd6cSJohn Marino 
138*ef5ccd6cSJohn Marino           return NULL;
139*ef5ccd6cSJohn Marino         }
140*ef5ccd6cSJohn Marino     }
141*ef5ccd6cSJohn Marino   if (count_obj)
142*ef5ccd6cSJohn Marino     {
143*ef5ccd6cSJohn Marino       count = PyInt_AsLong (count_obj);
144*ef5ccd6cSJohn Marino       if (PyErr_Occurred () || count < 0)
145*ef5ccd6cSJohn Marino         {
146*ef5ccd6cSJohn Marino           Py_DECREF (count_obj);
147*ef5ccd6cSJohn Marino           Py_XDECREF (end_obj);
148*ef5ccd6cSJohn Marino           PyErr_SetString (PyExc_TypeError,
149*ef5ccd6cSJohn Marino                            _("Argument 'count' should be an non-negative "
150*ef5ccd6cSJohn Marino                              "integer."));
151*ef5ccd6cSJohn Marino 
152*ef5ccd6cSJohn Marino           return NULL;
153*ef5ccd6cSJohn Marino         }
154*ef5ccd6cSJohn Marino     }
155*ef5ccd6cSJohn Marino 
156*ef5ccd6cSJohn Marino   result_list = PyList_New (0);
157*ef5ccd6cSJohn Marino   if (result_list == NULL)
158*ef5ccd6cSJohn Marino     return NULL;
159*ef5ccd6cSJohn Marino 
160*ef5ccd6cSJohn Marino   for (pc = start, i = 0;
161*ef5ccd6cSJohn Marino        /* All args are specified.  */
162*ef5ccd6cSJohn Marino        (end_obj && count_obj && pc <= end && i < count)
163*ef5ccd6cSJohn Marino        /* end_pc is specified, but no count.  */
164*ef5ccd6cSJohn Marino        || (end_obj && count_obj == NULL && pc <= end)
165*ef5ccd6cSJohn Marino        /* end_pc is not specified, but a count is.  */
166*ef5ccd6cSJohn Marino        || (end_obj == NULL && count_obj && i < count)
167*ef5ccd6cSJohn Marino        /* Both end_pc and count are not specified.  */
168*ef5ccd6cSJohn Marino        || (end_obj == NULL && count_obj == NULL && pc == start);)
169*ef5ccd6cSJohn Marino     {
170*ef5ccd6cSJohn Marino       int insn_len = 0;
171*ef5ccd6cSJohn Marino       char *as = NULL;
172*ef5ccd6cSJohn Marino       struct ui_file *memfile = mem_fileopen ();
173*ef5ccd6cSJohn Marino       PyObject *insn_dict = PyDict_New ();
174*ef5ccd6cSJohn Marino       volatile struct gdb_exception except;
175*ef5ccd6cSJohn Marino 
176*ef5ccd6cSJohn Marino       if (insn_dict == NULL)
177*ef5ccd6cSJohn Marino         {
178*ef5ccd6cSJohn Marino           Py_DECREF (result_list);
179*ef5ccd6cSJohn Marino           ui_file_delete (memfile);
180*ef5ccd6cSJohn Marino 
181*ef5ccd6cSJohn Marino           return NULL;
182*ef5ccd6cSJohn Marino         }
183*ef5ccd6cSJohn Marino       if (PyList_Append (result_list, insn_dict))
184*ef5ccd6cSJohn Marino         {
185*ef5ccd6cSJohn Marino           Py_DECREF (result_list);
186*ef5ccd6cSJohn Marino           Py_DECREF (insn_dict);
187*ef5ccd6cSJohn Marino           ui_file_delete (memfile);
188*ef5ccd6cSJohn Marino 
189*ef5ccd6cSJohn Marino           return NULL;  /* PyList_Append Sets the exception.  */
190*ef5ccd6cSJohn Marino         }
191*ef5ccd6cSJohn Marino 
192*ef5ccd6cSJohn Marino       TRY_CATCH (except, RETURN_MASK_ALL)
193*ef5ccd6cSJohn Marino         {
194*ef5ccd6cSJohn Marino           insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
195*ef5ccd6cSJohn Marino         }
196*ef5ccd6cSJohn Marino       if (except.reason < 0)
197*ef5ccd6cSJohn Marino         {
198*ef5ccd6cSJohn Marino           Py_DECREF (result_list);
199*ef5ccd6cSJohn Marino           ui_file_delete (memfile);
200*ef5ccd6cSJohn Marino 
201*ef5ccd6cSJohn Marino           return gdbpy_convert_exception (except);
202*ef5ccd6cSJohn Marino         }
203*ef5ccd6cSJohn Marino 
204*ef5ccd6cSJohn Marino       as = ui_file_xstrdup (memfile, NULL);
205*ef5ccd6cSJohn Marino       if (PyDict_SetItemString (insn_dict, "addr",
206*ef5ccd6cSJohn Marino                                 gdb_py_long_from_ulongest (pc))
207*ef5ccd6cSJohn Marino           || PyDict_SetItemString (insn_dict, "asm",
208*ef5ccd6cSJohn Marino                                    PyString_FromString (*as ? as : "<unknown>"))
209*ef5ccd6cSJohn Marino           || PyDict_SetItemString (insn_dict, "length",
210*ef5ccd6cSJohn Marino                                    PyInt_FromLong (insn_len)))
211*ef5ccd6cSJohn Marino         {
212*ef5ccd6cSJohn Marino           Py_DECREF (result_list);
213*ef5ccd6cSJohn Marino 
214*ef5ccd6cSJohn Marino           ui_file_delete (memfile);
215*ef5ccd6cSJohn Marino           xfree (as);
216*ef5ccd6cSJohn Marino 
217*ef5ccd6cSJohn Marino           return NULL;
218*ef5ccd6cSJohn Marino         }
219*ef5ccd6cSJohn Marino 
220*ef5ccd6cSJohn Marino       pc += insn_len;
221*ef5ccd6cSJohn Marino       i++;
222*ef5ccd6cSJohn Marino       ui_file_delete (memfile);
223*ef5ccd6cSJohn Marino       xfree (as);
224*ef5ccd6cSJohn Marino     }
225*ef5ccd6cSJohn Marino 
226*ef5ccd6cSJohn Marino   return result_list;
227*ef5ccd6cSJohn Marino }
228*ef5ccd6cSJohn Marino 
229*ef5ccd6cSJohn Marino /* Initializes the Architecture class in the gdb module.  */
230*ef5ccd6cSJohn Marino 
231*ef5ccd6cSJohn Marino void
gdbpy_initialize_arch(void)232*ef5ccd6cSJohn Marino gdbpy_initialize_arch (void)
233*ef5ccd6cSJohn Marino {
234*ef5ccd6cSJohn Marino   arch_object_data = gdbarch_data_register_post_init (arch_object_data_init);
235*ef5ccd6cSJohn Marino   arch_object_type.tp_new = PyType_GenericNew;
236*ef5ccd6cSJohn Marino   if (PyType_Ready (&arch_object_type) < 0)
237*ef5ccd6cSJohn Marino     return;
238*ef5ccd6cSJohn Marino 
239*ef5ccd6cSJohn Marino   Py_INCREF (&arch_object_type);
240*ef5ccd6cSJohn Marino   PyModule_AddObject (gdb_module, "Architecture",
241*ef5ccd6cSJohn Marino                       (PyObject *) &arch_object_type);
242*ef5ccd6cSJohn Marino }
243*ef5ccd6cSJohn Marino 
244*ef5ccd6cSJohn Marino static PyMethodDef arch_object_methods [] = {
245*ef5ccd6cSJohn Marino   { "name", archpy_name, METH_NOARGS,
246*ef5ccd6cSJohn Marino     "name () -> String.\n\
247*ef5ccd6cSJohn Marino Return the name of the architecture as a string value." },
248*ef5ccd6cSJohn Marino   { "disassemble", (PyCFunction) archpy_disassemble,
249*ef5ccd6cSJohn Marino     METH_VARARGS | METH_KEYWORDS,
250*ef5ccd6cSJohn Marino     "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
251*ef5ccd6cSJohn Marino Return a list of at most COUNT disassembled instructions from START_PC to\n\
252*ef5ccd6cSJohn Marino END_PC." },
253*ef5ccd6cSJohn Marino   {NULL}  /* Sentinel */
254*ef5ccd6cSJohn Marino };
255*ef5ccd6cSJohn Marino 
256*ef5ccd6cSJohn Marino static PyTypeObject arch_object_type = {
257*ef5ccd6cSJohn Marino   PyVarObject_HEAD_INIT (NULL, 0)
258*ef5ccd6cSJohn Marino   "gdb.Architecture",                 /* tp_name */
259*ef5ccd6cSJohn Marino   sizeof (arch_object),               /* tp_basicsize */
260*ef5ccd6cSJohn Marino   0,                                  /* tp_itemsize */
261*ef5ccd6cSJohn Marino   0,                                  /* tp_dealloc */
262*ef5ccd6cSJohn Marino   0,                                  /* tp_print */
263*ef5ccd6cSJohn Marino   0,                                  /* tp_getattr */
264*ef5ccd6cSJohn Marino   0,                                  /* tp_setattr */
265*ef5ccd6cSJohn Marino   0,                                  /* tp_compare */
266*ef5ccd6cSJohn Marino   0,                                  /* tp_repr */
267*ef5ccd6cSJohn Marino   0,                                  /* tp_as_number */
268*ef5ccd6cSJohn Marino   0,                                  /* tp_as_sequence */
269*ef5ccd6cSJohn Marino   0,                                  /* tp_as_mapping */
270*ef5ccd6cSJohn Marino   0,                                  /* tp_hash  */
271*ef5ccd6cSJohn Marino   0,                                  /* tp_call */
272*ef5ccd6cSJohn Marino   0,                                  /* tp_str */
273*ef5ccd6cSJohn Marino   0,                                  /* tp_getattro */
274*ef5ccd6cSJohn Marino   0,                                  /* tp_setattro */
275*ef5ccd6cSJohn Marino   0,                                  /* tp_as_buffer */
276*ef5ccd6cSJohn Marino   Py_TPFLAGS_DEFAULT,                 /* tp_flags */
277*ef5ccd6cSJohn Marino   "GDB architecture object",          /* tp_doc */
278*ef5ccd6cSJohn Marino   0,                                  /* tp_traverse */
279*ef5ccd6cSJohn Marino   0,                                  /* tp_clear */
280*ef5ccd6cSJohn Marino   0,                                  /* tp_richcompare */
281*ef5ccd6cSJohn Marino   0,                                  /* tp_weaklistoffset */
282*ef5ccd6cSJohn Marino   0,                                  /* tp_iter */
283*ef5ccd6cSJohn Marino   0,                                  /* tp_iternext */
284*ef5ccd6cSJohn Marino   arch_object_methods,                /* tp_methods */
285*ef5ccd6cSJohn Marino   0,                                  /* tp_members */
286*ef5ccd6cSJohn Marino   0,                                  /* tp_getset */
287*ef5ccd6cSJohn Marino   0,                                  /* tp_base */
288*ef5ccd6cSJohn Marino   0,                                  /* tp_dict */
289*ef5ccd6cSJohn Marino   0,                                  /* tp_descr_get */
290*ef5ccd6cSJohn Marino   0,                                  /* tp_descr_set */
291*ef5ccd6cSJohn Marino   0,                                  /* tp_dictoffset */
292*ef5ccd6cSJohn Marino   0,                                  /* tp_init */
293*ef5ccd6cSJohn Marino   0,                                  /* tp_alloc */
294*ef5ccd6cSJohn Marino };
295