]> Git Repo - binutils.git/blob - gdb/python/py-lazy-string.c
Rename gdb exception types
[binutils.git] / gdb / python / py-lazy-string.c
1 /* Python interface to lazy strings.
2
3    Copyright (C) 2010-2019 Free Software Foundation, Inc.
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 "value.h"
24 #include "valprint.h"
25 #include "language.h"
26
27 typedef struct {
28   PyObject_HEAD
29
30   /*  Holds the address of the lazy string.  */
31   CORE_ADDR address;
32
33   /*  Holds the encoding that will be applied to the string
34       when the string is printed by GDB.  If the encoding is set
35       to None then GDB will select the most appropriate
36       encoding when the sting is printed.  */
37   char *encoding;
38
39   /* If TYPE is an array: If the length is known, then this value is the
40      array's length, otherwise it is -1.
41      If TYPE is not an array: Then this value represents the string's length.
42      In either case, if the value is -1 then the string will be fetched and
43      encoded up to the first null of appropriate width.  */
44   long length;
45
46   /* This attribute holds the type of the string.
47      For example if the lazy string was created from a C "char*" then TYPE
48      represents a C "char*".
49      To get the type of the character in the string call
50      stpy_lazy_string_elt_type.
51      This is recorded as a PyObject so that we take advantage of support for
52      preserving the type should its owning objfile go away.  */
53   PyObject *type;
54 } lazy_string_object;
55
56 extern PyTypeObject lazy_string_object_type
57     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("lazy_string_object");
58
59 static PyObject *
60 stpy_get_address (PyObject *self, void *closure)
61 {
62   lazy_string_object *self_string = (lazy_string_object *) self;
63
64   return gdb_py_long_from_ulongest (self_string->address);
65 }
66
67 static PyObject *
68 stpy_get_encoding (PyObject *self, void *closure)
69 {
70   lazy_string_object *self_string = (lazy_string_object *) self;
71   PyObject *result;
72
73   /* An encoding can be set to NULL by the user, so check before
74      attempting a Python FromString call.  If NULL return Py_None.  */
75   if (self_string->encoding)
76     result = PyString_FromString (self_string->encoding);
77   else
78     {
79       result = Py_None;
80       Py_INCREF (result);
81     }
82
83   return result;
84 }
85
86 static PyObject *
87 stpy_get_length (PyObject *self, void *closure)
88 {
89   lazy_string_object *self_string = (lazy_string_object *) self;
90
91   return PyLong_FromLong (self_string->length);
92 }
93
94 static PyObject *
95 stpy_get_type (PyObject *self, void *closure)
96 {
97   lazy_string_object *str_obj = (lazy_string_object *) self;
98
99   Py_INCREF (str_obj->type);
100   return str_obj->type;
101 }
102
103 static PyObject *
104 stpy_convert_to_value (PyObject *self, PyObject *args)
105 {
106   lazy_string_object *self_string = (lazy_string_object *) self;
107   struct value *val = NULL;
108
109   if (self_string->address == 0)
110     {
111       PyErr_SetString (gdbpy_gdb_memory_error,
112                        _("Cannot create a value from NULL."));
113       return NULL;
114     }
115
116   try
117     {
118       struct type *type = type_object_to_type (self_string->type);
119       struct type *realtype;
120
121       gdb_assert (type != NULL);
122       realtype = check_typedef (type);
123       switch (TYPE_CODE (realtype))
124         {
125         case TYPE_CODE_PTR:
126           /* If a length is specified we need to convert this to an array
127              of the specified size.  */
128           if (self_string->length != -1)
129             {
130               /* PR 20786: There's no way to specify an array of length zero.
131                  Record a length of [0,-1] which is how Ada does it.  Anything
132                  we do is broken, but this is one possible solution.  */
133               type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
134                                               0, self_string->length - 1);
135               val = value_at_lazy (type, self_string->address);
136             }
137           else
138             val = value_from_pointer (type, self_string->address);
139           break;
140         default:
141           val = value_at_lazy (type, self_string->address);
142           break;
143         }
144     }
145   catch (const gdb_exception &except)
146     {
147       GDB_PY_HANDLE_EXCEPTION (except);
148     }
149
150   return value_to_value_object (val);
151 }
152
153 static void
154 stpy_dealloc (PyObject *self)
155 {
156   lazy_string_object *self_string = (lazy_string_object *) self;
157
158   xfree (self_string->encoding);
159 }
160
161 /* Low level routine to create a <gdb.LazyString> object.
162
163    Note: If TYPE is an array, LENGTH either must be -1 (meaning to use the
164    size of the array, which may itself be unknown in which case a length of
165    -1 is still used) or must be the length of the array.  */
166
167 PyObject *
168 gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
169                                  const char *encoding, struct type *type)
170 {
171   lazy_string_object *str_obj = NULL;
172   struct type *realtype;
173
174   if (length < -1)
175     {
176       PyErr_SetString (PyExc_ValueError, _("Invalid length."));
177       return NULL;
178     }
179
180   if (address == 0 && length != 0)
181     {
182       PyErr_SetString (gdbpy_gdb_memory_error,
183                        _("Cannot create a lazy string with address 0x0, " \
184                          "and a non-zero length."));
185       return NULL;
186     }
187
188   if (!type)
189     {
190       PyErr_SetString (PyExc_RuntimeError,
191                        _("A lazy string's type cannot be NULL."));
192       return NULL;
193     }
194
195   realtype = check_typedef (type);
196   switch (TYPE_CODE (realtype))
197     {
198     case TYPE_CODE_ARRAY:
199       {
200         LONGEST array_length = -1;
201         LONGEST low_bound, high_bound;
202
203         if (get_array_bounds (realtype, &low_bound, &high_bound))
204           array_length = high_bound - low_bound + 1;
205         if (length == -1)
206           length = array_length;
207         else if (length != array_length)
208           {
209             PyErr_SetString (PyExc_ValueError, _("Invalid length."));
210             return NULL;
211           }
212         break;
213       }
214     }
215
216   str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
217   if (!str_obj)
218     return NULL;
219
220   str_obj->address = address;
221   str_obj->length = length;
222   if (encoding == NULL || !strcmp (encoding, ""))
223     str_obj->encoding = NULL;
224   else
225     str_obj->encoding = xstrdup (encoding);
226   str_obj->type = type_to_type_object (type);
227
228   return (PyObject *) str_obj;
229 }
230
231 int
232 gdbpy_initialize_lazy_string (void)
233 {
234   if (PyType_Ready (&lazy_string_object_type) < 0)
235     return -1;
236
237   Py_INCREF (&lazy_string_object_type);
238   return 0;
239 }
240
241 /* Determine whether the printer object pointed to by OBJ is a
242    Python lazy string.  */
243 int
244 gdbpy_is_lazy_string (PyObject *result)
245 {
246   return PyObject_TypeCheck (result, &lazy_string_object_type);
247 }
248
249 /* Return the type of a character in lazy string LAZY.  */
250
251 static struct type *
252 stpy_lazy_string_elt_type (lazy_string_object *lazy)
253 {
254   struct type *type = type_object_to_type (lazy->type);
255   struct type *realtype;
256
257   gdb_assert (type != NULL);
258   realtype = check_typedef (type);
259
260   switch (TYPE_CODE (realtype))
261     {
262     case TYPE_CODE_PTR:
263     case TYPE_CODE_ARRAY:
264       return TYPE_TARGET_TYPE (realtype);
265     default:
266       /* This is done to preserve existing behaviour.  PR 20769.
267          E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type.  */
268       return realtype;
269     }
270 }
271
272 /* Extract the parameters from the lazy string object STRING.
273    ENCODING may be set to NULL, if no encoding is found.  */
274
275 void
276 gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
277                            struct type **str_elt_type,
278                            long *length,
279                            gdb::unique_xmalloc_ptr<char> *encoding)
280 {
281   lazy_string_object *lazy;
282
283   gdb_assert (gdbpy_is_lazy_string (string));
284
285   lazy = (lazy_string_object *) string;
286
287   *addr = lazy->address;
288   *str_elt_type = stpy_lazy_string_elt_type (lazy);
289   *length = lazy->length;
290   encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
291 }
292
293 \f
294
295 static PyMethodDef lazy_string_object_methods[] = {
296   { "value", stpy_convert_to_value, METH_NOARGS,
297     "Create a (lazy) value that contains a pointer to the string." },
298   {NULL}  /* Sentinel */
299 };
300
301
302 static gdb_PyGetSetDef lazy_string_object_getset[] = {
303   { "address", stpy_get_address, NULL, "Address of the string.", NULL },
304   { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
305   { "length", stpy_get_length, NULL, "Length of the string.", NULL },
306   { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
307   { NULL }  /* Sentinel */
308 };
309
310 PyTypeObject lazy_string_object_type = {
311   PyVarObject_HEAD_INIT (NULL, 0)
312   "gdb.LazyString",               /*tp_name*/
313   sizeof (lazy_string_object),    /*tp_basicsize*/
314   0,                              /*tp_itemsize*/
315   stpy_dealloc,                   /*tp_dealloc*/
316   0,                              /*tp_print*/
317   0,                              /*tp_getattr*/
318   0,                              /*tp_setattr*/
319   0,                              /*tp_compare*/
320   0,                              /*tp_repr*/
321   0,                              /*tp_as_number*/
322   0,                              /*tp_as_sequence*/
323   0,                              /*tp_as_mapping*/
324   0,                              /*tp_hash */
325   0,                              /*tp_call*/
326   0,                              /*tp_str*/
327   0,                              /*tp_getattro*/
328   0,                              /*tp_setattro*/
329   0,                              /*tp_as_buffer*/
330   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
331   "GDB lazy string object",       /* tp_doc */
332   0,                              /* tp_traverse */
333   0,                              /* tp_clear */
334   0,                              /* tp_richcompare */
335   0,                              /* tp_weaklistoffset */
336   0,                              /* tp_iter */
337   0,                              /* tp_iternext */
338   lazy_string_object_methods,     /* tp_methods */
339   0,                              /* tp_members */
340   lazy_string_object_getset       /* tp_getset */
341 };
This page took 0.079837 seconds and 4 git commands to generate.