]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/python/py-lazy-string.c
Remove infrun_thread_thread_exit observer
[thirdparty/binutils-gdb.git] / gdb / python / py-lazy-string.c
CommitLineData
be759fcf
PM
1/* Python interface to lazy strings.
2
213516ef 3 Copyright (C) 2010-2023 Free Software Foundation, Inc.
be759fcf
PM
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"
be759fcf
PM
24#include "valprint.h"
25#include "language.h"
26
f99b5177 27struct lazy_string_object {
be759fcf 28 PyObject_HEAD
34b43320 29
be759fcf
PM
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
34b43320
DE
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. */
be759fcf
PM
44 long length;
45
34b43320
DE
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;
f99b5177 54};
be759fcf 55
e36122e9 56extern PyTypeObject lazy_string_object_type
62eec1a5 57 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("lazy_string_object");
be759fcf
PM
58
59static PyObject *
60stpy_get_address (PyObject *self, void *closure)
61{
62 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 63
d1cab987 64 return gdb_py_object_from_ulongest (self_string->address).release ();
be759fcf
PM
65}
66
67static PyObject *
68stpy_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)
5aee4587 76 result = PyUnicode_FromString (self_string->encoding);
be759fcf
PM
77 else
78 {
79 result = Py_None;
80 Py_INCREF (result);
81 }
82
83 return result;
84}
85
86static PyObject *
87stpy_get_length (PyObject *self, void *closure)
88{
89 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 90
062534d4 91 return gdb_py_object_from_longest (self_string->length).release ();
be759fcf
PM
92}
93
49a8461d 94static PyObject *
be759fcf
PM
95stpy_get_type (PyObject *self, void *closure)
96{
97 lazy_string_object *str_obj = (lazy_string_object *) self;
d59b6f6c 98
34b43320
DE
99 Py_INCREF (str_obj->type);
100 return str_obj->type;
be759fcf
PM
101}
102
103static PyObject *
34b43320 104stpy_convert_to_value (PyObject *self, PyObject *args)
be759fcf
PM
105{
106 lazy_string_object *self_string = (lazy_string_object *) self;
76dce0be 107 struct value *val = NULL;
be759fcf 108
fff5cc64
PM
109 if (self_string->address == 0)
110 {
4ea6efe9 111 PyErr_SetString (gdbpy_gdb_memory_error,
044c0f87 112 _("Cannot create a value from NULL."));
fff5cc64
PM
113 return NULL;
114 }
115
a70b8144 116 try
76dce0be 117 {
34b43320
DE
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);
78134374 123 switch (realtype->code ())
34b43320
DE
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. */
27710edb 133 type = lookup_array_range_type (realtype->target_type (),
34b43320
DE
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 }
76dce0be 144 }
230d2906 145 catch (const gdb_exception &except)
492d29ea
PA
146 {
147 GDB_PY_HANDLE_EXCEPTION (except);
148 }
76dce0be 149
be759fcf
PM
150 return value_to_value_object (val);
151}
152
153static void
154stpy_dealloc (PyObject *self)
155{
156 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 157
be759fcf 158 xfree (self_string->encoding);
2e953aca 159 Py_TYPE (self)->tp_free (self);
be759fcf
PM
160}
161
34b43320
DE
162/* Low level routine to create a <gdb.LazyString> object.
163
164 Note: If TYPE is an array, LENGTH either must be -1 (meaning to use the
165 size of the array, which may itself be unknown in which case a length of
166 -1 is still used) or must be the length of the array. */
167
be759fcf
PM
168PyObject *
169gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
34b43320 170 const char *encoding, struct type *type)
be759fcf
PM
171{
172 lazy_string_object *str_obj = NULL;
34b43320
DE
173 struct type *realtype;
174
175 if (length < -1)
176 {
177 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
178 return NULL;
179 }
be759fcf 180
fff5cc64 181 if (address == 0 && length != 0)
be759fcf 182 {
4ea6efe9 183 PyErr_SetString (gdbpy_gdb_memory_error,
fff5cc64
PM
184 _("Cannot create a lazy string with address 0x0, " \
185 "and a non-zero length."));
be759fcf
PM
186 return NULL;
187 }
188
189 if (!type)
190 {
191 PyErr_SetString (PyExc_RuntimeError,
044c0f87 192 _("A lazy string's type cannot be NULL."));
be759fcf
PM
193 return NULL;
194 }
195
34b43320 196 realtype = check_typedef (type);
78134374 197 switch (realtype->code ())
34b43320
DE
198 {
199 case TYPE_CODE_ARRAY:
200 {
201 LONGEST array_length = -1;
202 LONGEST low_bound, high_bound;
203
204 if (get_array_bounds (realtype, &low_bound, &high_bound))
205 array_length = high_bound - low_bound + 1;
206 if (length == -1)
207 length = array_length;
208 else if (length != array_length)
209 {
210 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
211 return NULL;
212 }
213 break;
214 }
215 }
216
be759fcf
PM
217 str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
218 if (!str_obj)
219 return NULL;
220
221 str_obj->address = address;
222 str_obj->length = length;
223 if (encoding == NULL || !strcmp (encoding, ""))
224 str_obj->encoding = NULL;
225 else
226 str_obj->encoding = xstrdup (encoding);
34b43320 227 str_obj->type = type_to_type_object (type);
be759fcf
PM
228
229 return (PyObject *) str_obj;
230}
231
999633ed 232int
be759fcf
PM
233gdbpy_initialize_lazy_string (void)
234{
235 if (PyType_Ready (&lazy_string_object_type) < 0)
999633ed 236 return -1;
be759fcf
PM
237
238 Py_INCREF (&lazy_string_object_type);
999633ed 239 return 0;
be759fcf
PM
240}
241
242/* Determine whether the printer object pointed to by OBJ is a
243 Python lazy string. */
244int
245gdbpy_is_lazy_string (PyObject *result)
246{
247 return PyObject_TypeCheck (result, &lazy_string_object_type);
248}
249
34b43320
DE
250/* Return the type of a character in lazy string LAZY. */
251
252static struct type *
253stpy_lazy_string_elt_type (lazy_string_object *lazy)
254{
255 struct type *type = type_object_to_type (lazy->type);
256 struct type *realtype;
257
258 gdb_assert (type != NULL);
259 realtype = check_typedef (type);
260
78134374 261 switch (realtype->code ())
34b43320
DE
262 {
263 case TYPE_CODE_PTR:
264 case TYPE_CODE_ARRAY:
27710edb 265 return realtype->target_type ();
34b43320
DE
266 default:
267 /* This is done to preserve existing behaviour. PR 20769.
268 E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type. */
269 return realtype;
270 }
271}
272
09ca9e2e 273/* Extract the parameters from the lazy string object STRING.
1eba6383 274 ENCODING may be set to NULL, if no encoding is found. */
be759fcf 275
09ca9e2e
TT
276void
277gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
34b43320 278 struct type **str_elt_type,
1eba6383
TT
279 long *length,
280 gdb::unique_xmalloc_ptr<char> *encoding)
09ca9e2e
TT
281{
282 lazy_string_object *lazy;
be759fcf 283
09ca9e2e 284 gdb_assert (gdbpy_is_lazy_string (string));
be759fcf 285
09ca9e2e 286 lazy = (lazy_string_object *) string;
be759fcf 287
09ca9e2e 288 *addr = lazy->address;
34b43320 289 *str_elt_type = stpy_lazy_string_elt_type (lazy);
09ca9e2e 290 *length = lazy->length;
1eba6383 291 encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
be759fcf
PM
292}
293
294\f
295
296static PyMethodDef lazy_string_object_methods[] = {
297 { "value", stpy_convert_to_value, METH_NOARGS,
298 "Create a (lazy) value that contains a pointer to the string." },
299 {NULL} /* Sentinel */
300};
301
302
0d1f4ceb 303static gdb_PyGetSetDef lazy_string_object_getset[] = {
be759fcf
PM
304 { "address", stpy_get_address, NULL, "Address of the string.", NULL },
305 { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
306 { "length", stpy_get_length, NULL, "Length of the string.", NULL },
307 { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
308 { NULL } /* Sentinel */
309};
310
e36122e9 311PyTypeObject lazy_string_object_type = {
9a27f2c6 312 PyVarObject_HEAD_INIT (NULL, 0)
be759fcf
PM
313 "gdb.LazyString", /*tp_name*/
314 sizeof (lazy_string_object), /*tp_basicsize*/
315 0, /*tp_itemsize*/
316 stpy_dealloc, /*tp_dealloc*/
317 0, /*tp_print*/
318 0, /*tp_getattr*/
319 0, /*tp_setattr*/
320 0, /*tp_compare*/
321 0, /*tp_repr*/
322 0, /*tp_as_number*/
323 0, /*tp_as_sequence*/
324 0, /*tp_as_mapping*/
325 0, /*tp_hash */
326 0, /*tp_call*/
327 0, /*tp_str*/
328 0, /*tp_getattro*/
329 0, /*tp_setattro*/
330 0, /*tp_as_buffer*/
331 Py_TPFLAGS_DEFAULT, /*tp_flags*/
332 "GDB lazy string object", /* tp_doc */
333 0, /* tp_traverse */
334 0, /* tp_clear */
335 0, /* tp_richcompare */
336 0, /* tp_weaklistoffset */
337 0, /* tp_iter */
338 0, /* tp_iternext */
339 lazy_string_object_methods, /* tp_methods */
340 0, /* tp_members */
341 lazy_string_object_getset /* tp_getset */
342};