GDB (xrefs)
Loading...
Searching...
No Matches
py-lazy-string.c
Go to the documentation of this file.
1/* Python interface to lazy strings.
2
3 Copyright (C) 2010-2023 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
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. */
54};
55
56extern PyTypeObject lazy_string_object_type
57 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("lazy_string_object");
58
59static PyObject *
60stpy_get_address (PyObject *self, void *closure)
61{
62 lazy_string_object *self_string = (lazy_string_object *) self;
63
64 return gdb_py_object_from_ulongest (self_string->address).release ();
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)
76 result = PyUnicode_FromString (self_string->encoding);
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;
90
91 return gdb_py_object_from_longest (self_string->length).release ();
92}
93
94static PyObject *
95stpy_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
103static PyObject *
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 (realtype->code ())
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. */
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 {
148 }
149
150 return value_to_value_object (val);
151}
152
153static void
155{
156 lazy_string_object *self_string = (lazy_string_object *) self;
157
158 xfree (self_string->encoding);
159 Py_TYPE (self)->tp_free (self);
160}
161
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
168PyObject *
170 const char *encoding, struct type *type)
171{
172 lazy_string_object *str_obj = NULL;
173 struct type *realtype;
174
175 if (length < -1)
176 {
177 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
178 return NULL;
179 }
180
181 if (address == 0 && length != 0)
182 {
183 PyErr_SetString (gdbpy_gdb_memory_error,
184 _("Cannot create a lazy string with address 0x0, " \
185 "and a non-zero length."));
186 return NULL;
187 }
188
189 if (!type)
190 {
191 PyErr_SetString (PyExc_RuntimeError,
192 _("A lazy string's type cannot be NULL."));
193 return NULL;
194 }
195
196 realtype = check_typedef (type);
197 switch (realtype->code ())
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
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);
227 str_obj->type = type_to_type_object (type);
228
229 return (PyObject *) str_obj;
230}
231
232int
234{
235 if (PyType_Ready (&lazy_string_object_type) < 0)
236 return -1;
237
238 Py_INCREF (&lazy_string_object_type);
239 return 0;
240}
241
242/* Determine whether the printer object pointed to by OBJ is a
243 Python lazy string. */
244int
246{
247 return PyObject_TypeCheck (result, &lazy_string_object_type);
248}
249
250/* Return the type of a character in lazy string LAZY. */
251
252static struct type *
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
261 switch (realtype->code ())
262 {
263 case TYPE_CODE_PTR:
264 case TYPE_CODE_ARRAY:
265 return realtype->target_type ();
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
273/* Extract the parameters from the lazy string object STRING.
274 ENCODING may be set to NULL, if no encoding is found. */
275
276void
277gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
278 struct type **str_elt_type,
279 long *length,
280 gdb::unique_xmalloc_ptr<char> *encoding)
281{
282 lazy_string_object *lazy;
283
284 gdb_assert (gdbpy_is_lazy_string (string));
285
286 lazy = (lazy_string_object *) string;
287
288 *addr = lazy->address;
289 *str_elt_type = stpy_lazy_string_elt_type (lazy);
290 *length = lazy->length;
291 encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
292}
293
294
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
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
312 PyVarObject_HEAD_INIT (NULL, 0)
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};
void xfree(void *)
struct type * lookup_array_range_type(struct type *element_type, LONGEST low_bound, LONGEST high_bound)
Definition gdbtypes.c:1431
bool get_array_bounds(struct type *type, LONGEST *low_bound, LONGEST *high_bound)
Definition gdbtypes.c:1220
struct type * check_typedef(struct type *type)
Definition gdbtypes.c:3010
void gdbpy_extract_lazy_string(PyObject *string, CORE_ADDR *addr, struct type **str_elt_type, long *length, gdb::unique_xmalloc_ptr< char > *encoding)
static PyObject * stpy_get_address(PyObject *self, void *closure)
static PyMethodDef lazy_string_object_methods[]
PyTypeObject lazy_string_object_type
int gdbpy_initialize_lazy_string(void)
static PyObject * stpy_convert_to_value(PyObject *self, PyObject *args)
int gdbpy_is_lazy_string(PyObject *result)
PyObject * gdbpy_create_lazy_string_object(CORE_ADDR address, long length, const char *encoding, struct type *type)
static gdb_PyGetSetDef lazy_string_object_getset[]
static PyObject * stpy_get_length(PyObject *self, void *closure)
static PyObject * stpy_get_type(PyObject *self, void *closure)
static PyObject * stpy_get_encoding(PyObject *self, void *closure)
static struct type * stpy_lazy_string_elt_type(lazy_string_object *lazy)
static void stpy_dealloc(PyObject *self)
PyObject * type_to_type_object(struct type *type)
Definition py-type.c:1381
struct type * type_object_to_type(PyObject *obj)
Definition py-type.c:1404
gdbpy_ref gdb_py_object_from_longest(LONGEST l)
Definition py-utils.c:279
gdbpy_ref gdb_py_object_from_ulongest(ULONGEST l)
Definition py-utils.c:290
PyObject * value_to_value_object(struct value *val)
Definition py-value.c:1778
#define CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF(ARG)
PyObject * gdbpy_gdb_memory_error
#define GDB_PY_HANDLE_EXCEPTION(Exception)
PyObject_HEAD CORE_ADDR address
struct type * target_type() const
Definition gdbtypes.h:1000
type_code code() const
Definition gdbtypes.h:927
ULONGEST length() const
Definition gdbtypes.h:954
Definition value.c:181
struct value * value_at_lazy(struct type *type, CORE_ADDR addr)
Definition valops.c:1028
struct value * value_from_pointer(struct type *type, CORE_ADDR addr)
Definition value.c:3651
int PyObject
Definition varobj.c:41