X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-arch.c;h=0799186ca5fda2aa3c119711768fa329a2445b77;hb=7f6aba03b929d3d893378760eeeca431005fc5cd;hp=b41de0625227de0ffa131f43ce8ba38a6c810e67;hpb=9f44fbc03496a470cf661d011d9bcdcf21859726;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c index b41de06252..0799186ca5 100644 --- a/gdb/python/py-arch.c +++ b/gdb/python/py-arch.c @@ -1,6 +1,6 @@ /* Python interface to architecture - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -29,7 +29,21 @@ typedef struct arch_object_type_object { } arch_object; static struct gdbarch_data *arch_object_data = NULL; -static PyTypeObject arch_object_type; + +/* Require a valid Architecture. */ +#define ARCHPY_REQUIRE_VALID(arch_obj, arch) \ + do { \ + arch = arch_object_to_gdbarch (arch_obj); \ + if (arch == NULL) \ + { \ + PyErr_SetString (PyExc_RuntimeError, \ + _("Architecture is invalid.")); \ + return NULL; \ + } \ + } while (0) + +extern PyTypeObject arch_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("arch_object"); /* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch post init registration mechanism (gdbarch_data_register_post_init). */ @@ -80,11 +94,13 @@ gdbarch_to_arch_object (struct gdbarch *gdbarch) static PyObject * archpy_name (PyObject *self, PyObject *args) { - struct gdbarch *gdbarch = arch_object_to_gdbarch (self); - const char *name = (gdbarch_bfd_arch_info (gdbarch))->printable_name; - PyObject *py_name = PyString_FromString (name); + struct gdbarch *gdbarch = NULL; + const char *name; + + ARCHPY_REQUIRE_VALID (self, gdbarch); - return py_name; + name = (gdbarch_bfd_arch_info (gdbarch))->printable_name; + return PyString_FromString (name); } /* Implementation of @@ -96,31 +112,41 @@ archpy_name (PyObject *self, PyObject *args) static PyObject * archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw) { - static char *keywords[] = { "start_pc", "end_pc", "count", NULL }; + static const char *keywords[] = { "start_pc", "end_pc", "count", NULL }; CORE_ADDR start, end = 0; CORE_ADDR pc; gdb_py_ulongest start_temp; long count = 0, i; - PyObject *result_list, *end_obj = NULL, *count_obj = NULL; - struct gdbarch *gdbarch = arch_object_to_gdbarch (self); + PyObject *end_obj = NULL, *count_obj = NULL; + struct gdbarch *gdbarch = NULL; + + ARCHPY_REQUIRE_VALID (self, gdbarch); - if (!PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO", keywords, - &start_temp, &end_obj, &count_obj)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO", + keywords, &start_temp, &end_obj, + &count_obj)) return NULL; start = start_temp; if (end_obj) { - if (PyObject_TypeCheck (end_obj, &PyInt_Type)) + /* Make a long logic check first. In Python 3.x, internally, + all integers are represented as longs. In Python 2.x, there + is still a differentiation internally between a PyInt and a + PyLong. Explicitly do this long check conversion first. In + GDB, for Python 3.x, we #ifdef PyInt = PyLong. This check has + to be done first to ensure we do not lose information in the + conversion process. */ + if (PyLong_Check (end_obj)) + end = PyLong_AsUnsignedLongLong (end_obj); +#if PY_MAJOR_VERSION == 2 + else if (PyInt_Check (end_obj)) /* If the end_pc value is specified without a trailing 'L', end_obj will be an integer and not a long integer. */ end = PyInt_AsLong (end_obj); - else if (PyObject_TypeCheck (end_obj, &PyLong_Type)) - end = PyLong_AsUnsignedLongLong (end_obj); +#endif else { - Py_DECREF (end_obj); - Py_XDECREF (count_obj); PyErr_SetString (PyExc_TypeError, _("Argument 'end_pc' should be a (long) integer.")); @@ -129,8 +155,6 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw) if (end < start) { - Py_DECREF (end_obj); - Py_XDECREF (count_obj); PyErr_SetString (PyExc_ValueError, _("Argument 'end_pc' should be greater than or " "equal to the argument 'start_pc'.")); @@ -143,8 +167,6 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw) count = PyInt_AsLong (count_obj); if (PyErr_Occurred () || count < 0) { - Py_DECREF (count_obj); - Py_XDECREF (end_obj); PyErr_SetString (PyExc_TypeError, _("Argument 'count' should be an non-negative " "integer.")); @@ -153,7 +175,7 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw) } } - result_list = PyList_New (0); + gdbpy_ref<> result_list (PyList_New (0)); if (result_list == NULL) return NULL; @@ -168,77 +190,54 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw) || (end_obj == NULL && count_obj == NULL && pc == start);) { int insn_len = 0; - char *as = NULL; - struct ui_file *memfile = mem_fileopen (); - PyObject *insn_dict = PyDict_New (); - volatile struct gdb_exception except; + gdbpy_ref<> insn_dict (PyDict_New ()); if (insn_dict == NULL) - { - Py_DECREF (result_list); - ui_file_delete (memfile); + return NULL; + if (PyList_Append (result_list.get (), insn_dict.get ())) + return NULL; /* PyList_Append Sets the exception. */ - return NULL; - } - if (PyList_Append (result_list, insn_dict)) - { - Py_DECREF (result_list); - Py_DECREF (insn_dict); - ui_file_delete (memfile); + string_file stb; - return NULL; /* PyList_Append Sets the exception. */ - } - - TRY_CATCH (except, RETURN_MASK_ALL) + try { - insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL); + insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL); } - if (except.reason < 0) + catch (const gdb_exception &except) { - Py_DECREF (result_list); - ui_file_delete (memfile); - - return gdbpy_convert_exception (except); + gdbpy_convert_exception (except); + return NULL; } - as = ui_file_xstrdup (memfile, NULL); - if (PyDict_SetItemString (insn_dict, "addr", + if (PyDict_SetItemString (insn_dict.get (), "addr", gdb_py_long_from_ulongest (pc)) - || PyDict_SetItemString (insn_dict, "asm", - PyString_FromString (*as ? as : "")) - || PyDict_SetItemString (insn_dict, "length", + || PyDict_SetItemString (insn_dict.get (), "asm", + PyString_FromString (!stb.empty () + ? stb.c_str () + : "")) + || PyDict_SetItemString (insn_dict.get (), "length", PyInt_FromLong (insn_len))) - { - Py_DECREF (result_list); - - ui_file_delete (memfile); - xfree (as); - - return NULL; - } + return NULL; pc += insn_len; i++; - ui_file_delete (memfile); - xfree (as); } - return result_list; + return result_list.release (); } /* Initializes the Architecture class in the gdb module. */ -void +int gdbpy_initialize_arch (void) { arch_object_data = gdbarch_data_register_post_init (arch_object_data_init); arch_object_type.tp_new = PyType_GenericNew; if (PyType_Ready (&arch_object_type) < 0) - return; + return -1; - Py_INCREF (&arch_object_type); - PyModule_AddObject (gdb_module, "Architecture", - (PyObject *) &arch_object_type); + return gdb_pymodule_addobject (gdb_module, "Architecture", + (PyObject *) &arch_object_type); } static PyMethodDef arch_object_methods [] = { @@ -253,7 +252,7 @@ END_PC." }, {NULL} /* Sentinel */ }; -static PyTypeObject arch_object_type = { +PyTypeObject arch_object_type = { PyVarObject_HEAD_INIT (NULL, 0) "gdb.Architecture", /* tp_name */ sizeof (arch_object), /* tp_basicsize */