]> Git Repo - binutils.git/blob - gdb/python/py-membuf.c
gdb/gdbsupport: make xstrprintf and xstrvprintf return a unique_ptr
[binutils.git] / gdb / python / py-membuf.c
1 /* Python memory buffer interface for reading inferior memory.
2
3    Copyright (C) 2009-2021 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
23 struct membuf_object {
24   PyObject_HEAD
25
26   /* Pointer to the raw data, and array of gdb_bytes.  */
27   void *buffer;
28
29   /* The address from where the data was read, held for mbpy_str.  */
30   CORE_ADDR addr;
31
32   /* The number of octets in BUFFER.  */
33   CORE_ADDR length;
34 };
35
36 extern PyTypeObject membuf_object_type
37     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
38
39 /* Wrap BUFFER, ADDRESS, and LENGTH into a gdb.Membuf object.  ADDRESS is
40    the address within the inferior that the contents of BUFFER were read,
41    and LENGTH is the number of octets in BUFFER.  */
42
43 PyObject *
44 gdbpy_buffer_to_membuf (gdb::unique_xmalloc_ptr<gdb_byte> buffer,
45                         CORE_ADDR address,
46                         ULONGEST length)
47 {
48   gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
49                                                      &membuf_object_type));
50   if (membuf_obj == nullptr)
51     return nullptr;
52
53   membuf_obj->buffer = buffer.release ();
54   membuf_obj->addr = address;
55   membuf_obj->length = length;
56
57   PyObject *result;
58 #ifdef IS_PY3K
59   result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
60 #else
61   result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0,
62                                          Py_END_OF_BUFFER);
63 #endif
64
65   return result;
66 }
67
68 /* Destructor for gdb.Membuf objects.  */
69
70 static void
71 mbpy_dealloc (PyObject *self)
72 {
73   xfree (((membuf_object *) self)->buffer);
74   Py_TYPE (self)->tp_free (self);
75 }
76
77 /* Return a description of the gdb.Membuf object.  */
78
79 static PyObject *
80 mbpy_str (PyObject *self)
81 {
82   membuf_object *membuf_obj = (membuf_object *) self;
83
84   return PyString_FromFormat (_("Memory buffer for address %s, \
85 which is %s bytes long."),
86                               paddress (python_gdbarch, membuf_obj->addr),
87                               pulongest (membuf_obj->length));
88 }
89
90 #ifdef IS_PY3K
91
92 static int
93 get_buffer (PyObject *self, Py_buffer *buf, int flags)
94 {
95   membuf_object *membuf_obj = (membuf_object *) self;
96   int ret;
97
98   ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
99                            membuf_obj->length, 0,
100                            PyBUF_CONTIG);
101
102   /* Despite the documentation saying this field is a "const char *",
103      in Python 3.4 at least, it's really a "char *".  */
104   buf->format = (char *) "c";
105
106   return ret;
107 }
108
109 #else
110
111 static Py_ssize_t
112 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
113 {
114   membuf_object *membuf_obj = (membuf_object *) self;
115
116   if (segment)
117     {
118       PyErr_SetString (PyExc_SystemError,
119                        _("The memory buffer supports only one segment."));
120       return -1;
121     }
122
123   *ptrptr = membuf_obj->buffer;
124
125   return membuf_obj->length;
126 }
127
128 static Py_ssize_t
129 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
130 {
131   return get_read_buffer (self, segment, ptrptr);
132 }
133
134 static Py_ssize_t
135 get_seg_count (PyObject *self, Py_ssize_t *lenp)
136 {
137   if (lenp)
138     *lenp = ((membuf_object *) self)->length;
139
140   return 1;
141 }
142
143 static Py_ssize_t
144 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
145 {
146   void *ptr = nullptr;
147   Py_ssize_t ret;
148
149   ret = get_read_buffer (self, segment, &ptr);
150   *ptrptr = (char *) ptr;
151
152   return ret;
153 }
154
155 #endif  /* IS_PY3K */
156
157 /* General Python initialization callback.  */
158
159 int
160 gdbpy_initialize_membuf (void)
161 {
162   membuf_object_type.tp_new = PyType_GenericNew;
163   if (PyType_Ready (&membuf_object_type) < 0)
164     return -1;
165
166   return gdb_pymodule_addobject (gdb_module, "Membuf",
167                                  (PyObject *) &membuf_object_type);
168 }
169
170 #ifdef IS_PY3K
171
172 static PyBufferProcs buffer_procs =
173 {
174   get_buffer
175 };
176
177 #else
178
179 static PyBufferProcs buffer_procs = {
180   get_read_buffer,
181   get_write_buffer,
182   get_seg_count,
183   get_char_buffer
184 };
185
186 #endif  /* IS_PY3K */
187
188 PyTypeObject membuf_object_type = {
189   PyVarObject_HEAD_INIT (nullptr, 0)
190   "gdb.Membuf",                   /*tp_name*/
191   sizeof (membuf_object),         /*tp_basicsize*/
192   0,                              /*tp_itemsize*/
193   mbpy_dealloc,                   /*tp_dealloc*/
194   0,                              /*tp_print*/
195   0,                              /*tp_getattr*/
196   0,                              /*tp_setattr*/
197   0,                              /*tp_compare*/
198   0,                              /*tp_repr*/
199   0,                              /*tp_as_number*/
200   0,                              /*tp_as_sequence*/
201   0,                              /*tp_as_mapping*/
202   0,                              /*tp_hash */
203   0,                              /*tp_call*/
204   mbpy_str,                       /*tp_str*/
205   0,                              /*tp_getattro*/
206   0,                              /*tp_setattro*/
207   &buffer_procs,                  /*tp_as_buffer*/
208   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
209   "GDB memory buffer object",     /*tp_doc*/
210   0,                              /* tp_traverse */
211   0,                              /* tp_clear */
212   0,                              /* tp_richcompare */
213   0,                              /* tp_weaklistoffset */
214   0,                              /* tp_iter */
215   0,                              /* tp_iternext */
216   0,                              /* tp_methods */
217   0,                              /* tp_members */
218   0,                              /* tp_getset */
219   0,                              /* tp_base */
220   0,                              /* tp_dict */
221   0,                              /* tp_descr_get */
222   0,                              /* tp_descr_set */
223   0,                              /* tp_dictoffset */
224   0,                              /* tp_init */
225   0,                              /* tp_alloc */
226 };
This page took 0.039273 seconds and 4 git commands to generate.