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
108 if (self_string->address == 0)
109 {
110 PyErr_SetString (gdbpy_gdb_memory_error,
111 _("Cannot create a value from NULL."));
112 return NULL;
113 }
114
115 PyObject *result = nullptr;
116 try
117 {
118 scoped_value_mark free_values;
119
120 struct type *type = type_object_to_type (self_string->type);
121 struct type *realtype;
122 struct value *val;
123
124 gdb_assert (type != NULL);
125 realtype = check_typedef (type);
126 switch (realtype->code ())
127 {
128 case TYPE_CODE_PTR:
129 /* If a length is specified we need to convert this to an array
130 of the specified size. */
131 if (self_string->length != -1)
132 {
133 /* PR 20786: There's no way to specify an array of length zero.
134 Record a length of [0,-1] which is how Ada does it. Anything
135 we do is broken, but this is one possible solution. */
137 0, self_string->length - 1);
138 val = value_at_lazy (type, self_string->address);
139 }
140 else
141 val = value_from_pointer (type, self_string->address);
142 break;
143 default:
144 val = value_at_lazy (type, self_string->address);
145 break;
146 }
147
148 result = value_to_value_object (val);
149 }
150 catch (const gdb_exception &except)
151 {
153 }
154
155 return result;
156}
157
158static void
160{
161 lazy_string_object *self_string = (lazy_string_object *) self;
162
163 xfree (self_string->encoding);
164 Py_TYPE (self)->tp_free (self);
165}
166
167/* Low level routine to create a <gdb.LazyString> object.
168
169 Note: If TYPE is an array, LENGTH either must be -1 (meaning to use the
170 size of the array, which may itself be unknown in which case a length of
171 -1 is still used) or must be the length of the array. */
172
173PyObject *
175 const char *encoding, struct type *type)
176{
177 lazy_string_object *str_obj = NULL;
178 struct type *realtype;
179
180 if (length < -1)
181 {
182 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
183 return NULL;
184 }
185
186 if (address == 0 && length != 0)
187 {
188 PyErr_SetString (gdbpy_gdb_memory_error,
189 _("Cannot create a lazy string with address 0x0, " \
190 "and a non-zero length."));
191 return NULL;
192 }
193
194 if (!type)
195 {
196 PyErr_SetString (PyExc_RuntimeError,
197 _("A lazy string's type cannot be NULL."));
198 return NULL;
199 }
200
201 realtype = check_typedef (type);
202 switch (realtype->code ())
203 {
204 case TYPE_CODE_ARRAY:
205 {
206 LONGEST array_length = -1;
207 LONGEST low_bound, high_bound;
208
209 if (get_array_bounds (realtype, &low_bound, &high_bound))
210 array_length = high_bound - low_bound + 1;
211 if (length == -1)
212 length = array_length;
213 else if (length != array_length)
214 {
215 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
216 return NULL;
217 }
218 break;
219 }
220 }
221
222 str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
223 if (!str_obj)
224 return NULL;
225
226 str_obj->address = address;
227 str_obj->length = length;
228 if (encoding == NULL || !strcmp (encoding, ""))
229 str_obj->encoding = NULL;
230 else
231 str_obj->encoding = xstrdup (encoding);
232 str_obj->type = type_to_type_object (type);
233
234 return (PyObject *) str_obj;
235}
236
239{
240 if (PyType_Ready (&lazy_string_object_type) < 0)
241 return -1;
242
243 Py_INCREF (&lazy_string_object_type);
244 return 0;
245}
246
247/* Determine whether the printer object pointed to by OBJ is a
248 Python lazy string. */
249int
251{
252 return PyObject_TypeCheck (result, &lazy_string_object_type);
253}
254
255/* Return the type of a character in lazy string LAZY. */
256
257static struct type *
259{
260 struct type *type = type_object_to_type (lazy->type);
261 struct type *realtype;
262
263 gdb_assert (type != NULL);
264 realtype = check_typedef (type);
265
266 switch (realtype->code ())
267 {
268 case TYPE_CODE_PTR:
269 case TYPE_CODE_ARRAY:
270 return realtype->target_type ();
271 default:
272 /* This is done to preserve existing behaviour. PR 20769.
273 E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type. */
274 return realtype;
275 }
276}
277
278/* Extract the parameters from the lazy string object STRING.
279 ENCODING may be set to NULL, if no encoding is found. */
280
281void
282gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
283 struct type **str_elt_type,
284 long *length,
285 gdb::unique_xmalloc_ptr<char> *encoding)
286{
287 lazy_string_object *lazy;
288
289 gdb_assert (gdbpy_is_lazy_string (string));
290
291 lazy = (lazy_string_object *) string;
292
293 *addr = lazy->address;
294 *str_elt_type = stpy_lazy_string_elt_type (lazy);
295 *length = lazy->length;
296 encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
297}
298
299/* __str__ for LazyString. */
300
301static PyObject *
303{
305
306 struct value_print_options opts;
308 opts.addressprint = false;
309
310 string_file stream;
311 try
312 {
313 struct type *type = stpy_lazy_string_elt_type (str);
314 val_print_string (type, str->encoding, str->address, str->length,
315 &stream, &opts);
316 }
317 catch (const gdb_exception &exc)
318 {
320 }
321
322 return host_string_to_python_string (stream.c_str ()).release ();
323}
324
326
327
328
329static PyMethodDef lazy_string_object_methods[] = {
330 { "value", stpy_convert_to_value, METH_NOARGS,
331 "Create a (lazy) value that contains a pointer to the string." },
332 {NULL} /* Sentinel */
333};
334
335
337 { "address", stpy_get_address, NULL, "Address of the string.", NULL },
338 { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
339 { "length", stpy_get_length, NULL, "Length of the string.", NULL },
340 { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
341 { NULL } /* Sentinel */
342};
343
345 PyVarObject_HEAD_INIT (NULL, 0)
346 "gdb.LazyString", /*tp_name*/
347 sizeof (lazy_string_object), /*tp_basicsize*/
348 0, /*tp_itemsize*/
349 stpy_dealloc, /*tp_dealloc*/
350 0, /*tp_print*/
351 0, /*tp_getattr*/
352 0, /*tp_setattr*/
353 0, /*tp_compare*/
354 0, /*tp_repr*/
355 0, /*tp_as_number*/
356 0, /*tp_as_sequence*/
357 0, /*tp_as_mapping*/
358 0, /*tp_hash */
359 0, /*tp_call*/
360 stpy_str, /*tp_str*/
361 0, /*tp_getattro*/
362 0, /*tp_setattro*/
363 0, /*tp_as_buffer*/
364 Py_TPFLAGS_DEFAULT, /*tp_flags*/
365 "GDB lazy string object", /* tp_doc */
366 0, /* tp_traverse */
367 0, /* tp_clear */
368 0, /* tp_richcompare */
369 0, /* tp_weaklistoffset */
370 0, /* tp_iter */
371 0, /* tp_iternext */
372 lazy_string_object_methods, /* tp_methods */
373 0, /* tp_members */
374 lazy_string_object_getset /* tp_getset */
375};
void xfree(void *)
const char * c_str() const
Definition ui-file.h:222
struct type * lookup_array_range_type(struct type *element_type, LONGEST low_bound, LONGEST high_bound)
Definition gdbtypes.c:1397
bool get_array_bounds(struct type *type, LONGEST *low_bound, LONGEST *high_bound)
Definition gdbtypes.c:1211
struct type * check_typedef(struct type *type)
Definition gdbtypes.c:2966
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
static PyObject * stpy_str(PyObject *self)
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 int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION gdbpy_initialize_lazy_string(void)
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:1460
struct type * type_object_to_type(PyObject *obj)
Definition py-type.c:1483
gdbpy_ref host_string_to_python_string(const char *str)
Definition py-utils.c:154
gdbpy_ref gdb_py_object_from_longest(LONGEST l)
Definition py-utils.c:282
gdbpy_ref gdb_py_object_from_ulongest(ULONGEST l)
Definition py-utils.c:293
PyObject * value_to_value_object(struct value *val)
Definition py-value.c:1854
#define CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF(ARG)
#define CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
#define GDBPY_INITIALIZE_FILE(INIT,...)
PyObject * gdbpy_gdb_memory_error
#define GDB_PY_HANDLE_EXCEPTION(Exception)
PyObject_HEAD CORE_ADDR address
struct type * target_type() const
Definition gdbtypes.h:1037
type_code code() const
Definition gdbtypes.h:956
ULONGEST length() const
Definition gdbtypes.h:983
Definition value.h:130
CORE_ADDR address
Definition value.h:658
struct value * value_at_lazy(struct type *type, CORE_ADDR addr, frame_info_ptr frame)
Definition valops.c:1036
int val_print_string(struct type *elttype, const char *encoding, CORE_ADDR addr, int len, struct ui_file *stream, const struct value_print_options *options)
Definition valprint.c:2643
void get_user_print_options(struct value_print_options *opts)
Definition valprint.c:135
struct value * value_from_pointer(struct type *type, CORE_ADDR addr)
Definition value.c:3500
int PyObject
Definition varobj.c:41