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