]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/python/py-lazy-string.c
[gdb/testsuite] Use support_displaced_stepping in gdb.arch/amd64-disp-step-avx.exp
[thirdparty/binutils-gdb.git] / gdb / python / py-lazy-string.c
CommitLineData
be759fcf
PM
1/* Python interface to lazy strings.
2
d01e8234 3 Copyright (C) 2010-2025 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
be759fcf
PM
20#include "python-internal.h"
21#include "charset.h"
22#include "value.h"
be759fcf
PM
23#include "valprint.h"
24#include "language.h"
25
f99b5177 26struct lazy_string_object {
be759fcf 27 PyObject_HEAD
34b43320 28
be759fcf
PM
29 /* Holds the address of the lazy string. */
30 CORE_ADDR address;
31
32 /* Holds the encoding that will be applied to the string
33 when the string is printed by GDB. If the encoding is set
34 to None then GDB will select the most appropriate
586ccf78 35 encoding when the string is printed. */
be759fcf
PM
36 char *encoding;
37
34b43320
DE
38 /* If TYPE is an array: If the length is known, then this value is the
39 array's length, otherwise it is -1.
40 If TYPE is not an array: Then this value represents the string's length.
41 In either case, if the value is -1 then the string will be fetched and
42 encoded up to the first null of appropriate width. */
be759fcf
PM
43 long length;
44
34b43320
DE
45 /* This attribute holds the type of the string.
46 For example if the lazy string was created from a C "char*" then TYPE
47 represents a C "char*".
48 To get the type of the character in the string call
49 stpy_lazy_string_elt_type.
50 This is recorded as a PyObject so that we take advantage of support for
51 preserving the type should its owning objfile go away. */
52 PyObject *type;
f99b5177 53};
be759fcf 54
e36122e9 55extern PyTypeObject lazy_string_object_type
62eec1a5 56 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("lazy_string_object");
be759fcf
PM
57
58static PyObject *
59stpy_get_address (PyObject *self, void *closure)
60{
61 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 62
d1cab987 63 return gdb_py_object_from_ulongest (self_string->address).release ();
be759fcf
PM
64}
65
66static PyObject *
67stpy_get_encoding (PyObject *self, void *closure)
68{
69 lazy_string_object *self_string = (lazy_string_object *) self;
70 PyObject *result;
71
72 /* An encoding can be set to NULL by the user, so check before
73 attempting a Python FromString call. If NULL return Py_None. */
74 if (self_string->encoding)
5aee4587 75 result = PyUnicode_FromString (self_string->encoding);
be759fcf
PM
76 else
77 {
78 result = Py_None;
79 Py_INCREF (result);
80 }
81
82 return result;
83}
84
85static PyObject *
86stpy_get_length (PyObject *self, void *closure)
87{
88 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 89
062534d4 90 return gdb_py_object_from_longest (self_string->length).release ();
be759fcf
PM
91}
92
49a8461d 93static PyObject *
be759fcf
PM
94stpy_get_type (PyObject *self, void *closure)
95{
96 lazy_string_object *str_obj = (lazy_string_object *) self;
d59b6f6c 97
34b43320
DE
98 Py_INCREF (str_obj->type);
99 return str_obj->type;
be759fcf
PM
100}
101
102static PyObject *
34b43320 103stpy_convert_to_value (PyObject *self, PyObject *args)
be759fcf
PM
104{
105 lazy_string_object *self_string = (lazy_string_object *) self;
be759fcf 106
fff5cc64
PM
107 if (self_string->address == 0)
108 {
4ea6efe9 109 PyErr_SetString (gdbpy_gdb_memory_error,
044c0f87 110 _("Cannot create a value from NULL."));
fff5cc64
PM
111 return NULL;
112 }
113
f3d3bbbc 114 PyObject *result = nullptr;
a70b8144 115 try
76dce0be 116 {
f3d3bbbc
TT
117 scoped_value_mark free_values;
118
34b43320
DE
119 struct type *type = type_object_to_type (self_string->type);
120 struct type *realtype;
f3d3bbbc 121 struct value *val;
34b43320
DE
122
123 gdb_assert (type != NULL);
124 realtype = check_typedef (type);
78134374 125 switch (realtype->code ())
34b43320
DE
126 {
127 case TYPE_CODE_PTR:
128 /* If a length is specified we need to convert this to an array
129 of the specified size. */
130 if (self_string->length != -1)
131 {
132 /* PR 20786: There's no way to specify an array of length zero.
133 Record a length of [0,-1] which is how Ada does it. Anything
134 we do is broken, but this is one possible solution. */
27710edb 135 type = lookup_array_range_type (realtype->target_type (),
34b43320
DE
136 0, self_string->length - 1);
137 val = value_at_lazy (type, self_string->address);
138 }
139 else
140 val = value_from_pointer (type, self_string->address);
141 break;
142 default:
143 val = value_at_lazy (type, self_string->address);
144 break;
145 }
f3d3bbbc
TT
146
147 result = value_to_value_object (val);
76dce0be 148 }
230d2906 149 catch (const gdb_exception &except)
492d29ea 150 {
1ccb6f10 151 return gdbpy_handle_gdb_exception (nullptr, except);
492d29ea 152 }
76dce0be 153
f3d3bbbc 154 return result;
be759fcf
PM
155}
156
157static void
158stpy_dealloc (PyObject *self)
159{
160 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 161
be759fcf 162 xfree (self_string->encoding);
2e953aca 163 Py_TYPE (self)->tp_free (self);
be759fcf
PM
164}
165
34b43320
DE
166/* Low level routine to create a <gdb.LazyString> object.
167
168 Note: If TYPE is an array, LENGTH either must be -1 (meaning to use the
169 size of the array, which may itself be unknown in which case a length of
170 -1 is still used) or must be the length of the array. */
171
be759fcf
PM
172PyObject *
173gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
34b43320 174 const char *encoding, struct type *type)
be759fcf
PM
175{
176 lazy_string_object *str_obj = NULL;
34b43320
DE
177 struct type *realtype;
178
179 if (length < -1)
180 {
181 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
182 return NULL;
183 }
be759fcf 184
be759fcf
PM
185 if (!type)
186 {
187 PyErr_SetString (PyExc_RuntimeError,
044c0f87 188 _("A lazy string's type cannot be NULL."));
be759fcf
PM
189 return NULL;
190 }
191
34b43320 192 realtype = check_typedef (type);
78134374 193 switch (realtype->code ())
34b43320
DE
194 {
195 case TYPE_CODE_ARRAY:
196 {
197 LONGEST array_length = -1;
198 LONGEST low_bound, high_bound;
199
200 if (get_array_bounds (realtype, &low_bound, &high_bound))
201 array_length = high_bound - low_bound + 1;
202 if (length == -1)
203 length = array_length;
204 else if (length != array_length)
205 {
206 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
207 return NULL;
208 }
209 break;
210 }
c286bfe1
TT
211
212 case TYPE_CODE_PTR:
213 if (address == 0)
214 {
215 if (length > 0)
216 {
217 PyErr_SetString (gdbpy_gdb_memory_error,
218 _("Cannot create a lazy string with address 0x0, " \
219 "and a non-zero length."));
220 return nullptr;
221 }
222 length = 0;
223 }
224 break;
225
226 default:
227 gdb_assert_not_reached ("invalid type in gdbpy_create_lazy_string_object");
34b43320
DE
228 }
229
be759fcf
PM
230 str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
231 if (!str_obj)
232 return NULL;
233
234 str_obj->address = address;
235 str_obj->length = length;
236 if (encoding == NULL || !strcmp (encoding, ""))
237 str_obj->encoding = NULL;
238 else
239 str_obj->encoding = xstrdup (encoding);
34b43320 240 str_obj->type = type_to_type_object (type);
be759fcf
PM
241
242 return (PyObject *) str_obj;
243}
244
3965bff5 245static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
be759fcf
PM
246gdbpy_initialize_lazy_string (void)
247{
336bb2a1 248 return gdbpy_type_ready (&lazy_string_object_type);
be759fcf
PM
249}
250
251/* Determine whether the printer object pointed to by OBJ is a
252 Python lazy string. */
253int
254gdbpy_is_lazy_string (PyObject *result)
255{
256 return PyObject_TypeCheck (result, &lazy_string_object_type);
257}
258
34b43320
DE
259/* Return the type of a character in lazy string LAZY. */
260
261static struct type *
262stpy_lazy_string_elt_type (lazy_string_object *lazy)
263{
264 struct type *type = type_object_to_type (lazy->type);
265 struct type *realtype;
266
267 gdb_assert (type != NULL);
268 realtype = check_typedef (type);
269
78134374 270 switch (realtype->code ())
34b43320
DE
271 {
272 case TYPE_CODE_PTR:
273 case TYPE_CODE_ARRAY:
8130c1a4 274 return check_typedef (realtype->target_type ());
34b43320 275 default:
2134b0b4 276 gdb_assert_not_reached ("invalid lazy string");
34b43320
DE
277 }
278}
279
09ca9e2e 280/* Extract the parameters from the lazy string object STRING.
1eba6383 281 ENCODING may be set to NULL, if no encoding is found. */
be759fcf 282
09ca9e2e
TT
283void
284gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
34b43320 285 struct type **str_elt_type,
1eba6383
TT
286 long *length,
287 gdb::unique_xmalloc_ptr<char> *encoding)
09ca9e2e
TT
288{
289 lazy_string_object *lazy;
be759fcf 290
09ca9e2e 291 gdb_assert (gdbpy_is_lazy_string (string));
be759fcf 292
09ca9e2e 293 lazy = (lazy_string_object *) string;
be759fcf 294
09ca9e2e 295 *addr = lazy->address;
34b43320 296 *str_elt_type = stpy_lazy_string_elt_type (lazy);
09ca9e2e 297 *length = lazy->length;
1eba6383 298 encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
be759fcf
PM
299}
300
ee81567c
TT
301/* __str__ for LazyString. */
302
303static PyObject *
304stpy_str (PyObject *self)
305{
306 lazy_string_object *str = (lazy_string_object *) self;
307
308 struct value_print_options opts;
309 get_user_print_options (&opts);
310 opts.addressprint = false;
311
312 string_file stream;
313 try
314 {
315 struct type *type = stpy_lazy_string_elt_type (str);
316 val_print_string (type, str->encoding, str->address, str->length,
317 &stream, &opts);
318 }
319 catch (const gdb_exception &exc)
320 {
1ccb6f10 321 return gdbpy_handle_gdb_exception (nullptr, exc);
ee81567c
TT
322 }
323
324 return host_string_to_python_string (stream.c_str ()).release ();
325}
326
3965bff5
AB
327GDBPY_INITIALIZE_FILE (gdbpy_initialize_lazy_string);
328
be759fcf
PM
329\f
330
331static PyMethodDef lazy_string_object_methods[] = {
332 { "value", stpy_convert_to_value, METH_NOARGS,
333 "Create a (lazy) value that contains a pointer to the string." },
334 {NULL} /* Sentinel */
335};
336
337
0d1f4ceb 338static gdb_PyGetSetDef lazy_string_object_getset[] = {
be759fcf
PM
339 { "address", stpy_get_address, NULL, "Address of the string.", NULL },
340 { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
341 { "length", stpy_get_length, NULL, "Length of the string.", NULL },
342 { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
343 { NULL } /* Sentinel */
344};
345
e36122e9 346PyTypeObject lazy_string_object_type = {
9a27f2c6 347 PyVarObject_HEAD_INIT (NULL, 0)
be759fcf
PM
348 "gdb.LazyString", /*tp_name*/
349 sizeof (lazy_string_object), /*tp_basicsize*/
350 0, /*tp_itemsize*/
351 stpy_dealloc, /*tp_dealloc*/
352 0, /*tp_print*/
353 0, /*tp_getattr*/
354 0, /*tp_setattr*/
355 0, /*tp_compare*/
356 0, /*tp_repr*/
357 0, /*tp_as_number*/
358 0, /*tp_as_sequence*/
359 0, /*tp_as_mapping*/
360 0, /*tp_hash */
361 0, /*tp_call*/
ee81567c 362 stpy_str, /*tp_str*/
be759fcf
PM
363 0, /*tp_getattro*/
364 0, /*tp_setattro*/
365 0, /*tp_as_buffer*/
366 Py_TPFLAGS_DEFAULT, /*tp_flags*/
367 "GDB lazy string object", /* tp_doc */
368 0, /* tp_traverse */
369 0, /* tp_clear */
370 0, /* tp_richcompare */
371 0, /* tp_weaklistoffset */
372 0, /* tp_iter */
373 0, /* tp_iternext */
374 lazy_string_object_methods, /* tp_methods */
375 0, /* tp_members */
376 lazy_string_object_getset /* tp_getset */
377};