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