]> Git Repo - binutils.git/blob - gdb/python/py-membuf.c
gdb: remove SYMBOL_CLASS macro, add getter
[binutils.git] / gdb / python / py-membuf.c
1 /* Python memory buffer interface for reading inferior memory.
2
3    Copyright (C) 2009-2022 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 (gdbpy_enter::get_gdbarch (),
87                                         membuf_obj->addr),
88                               pulongest (membuf_obj->length));
89 }
90
91 #ifdef IS_PY3K
92
93 static int
94 get_buffer (PyObject *self, Py_buffer *buf, int flags)
95 {
96   membuf_object *membuf_obj = (membuf_object *) self;
97   int ret;
98
99   ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
100                            membuf_obj->length, 0,
101                            PyBUF_CONTIG);
102
103   /* Despite the documentation saying this field is a "const char *",
104      in Python 3.4 at least, it's really a "char *".  */
105   buf->format = (char *) "c";
106
107   return ret;
108 }
109
110 #else
111
112 static Py_ssize_t
113 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
114 {
115   membuf_object *membuf_obj = (membuf_object *) self;
116
117   if (segment)
118     {
119       PyErr_SetString (PyExc_SystemError,
120                        _("The memory buffer supports only one segment."));
121       return -1;
122     }
123
124   *ptrptr = membuf_obj->buffer;
125
126   return membuf_obj->length;
127 }
128
129 static Py_ssize_t
130 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
131 {
132   return get_read_buffer (self, segment, ptrptr);
133 }
134
135 static Py_ssize_t
136 get_seg_count (PyObject *self, Py_ssize_t *lenp)
137 {
138   if (lenp)
139     *lenp = ((membuf_object *) self)->length;
140
141   return 1;
142 }
143
144 static Py_ssize_t
145 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
146 {
147   void *ptr = nullptr;
148   Py_ssize_t ret;
149
150   ret = get_read_buffer (self, segment, &ptr);
151   *ptrptr = (char *) ptr;
152
153   return ret;
154 }
155
156 #endif  /* IS_PY3K */
157
158 /* General Python initialization callback.  */
159
160 int
161 gdbpy_initialize_membuf (void)
162 {
163   membuf_object_type.tp_new = PyType_GenericNew;
164   if (PyType_Ready (&membuf_object_type) < 0)
165     return -1;
166
167   return gdb_pymodule_addobject (gdb_module, "Membuf",
168                                  (PyObject *) &membuf_object_type);
169 }
170
171 #ifdef IS_PY3K
172
173 static PyBufferProcs buffer_procs =
174 {
175   get_buffer
176 };
177
178 #else
179
180 static PyBufferProcs buffer_procs = {
181   get_read_buffer,
182   get_write_buffer,
183   get_seg_count,
184   get_char_buffer
185 };
186
187 #endif  /* IS_PY3K */
188
189 PyTypeObject membuf_object_type = {
190   PyVarObject_HEAD_INIT (nullptr, 0)
191   "gdb.Membuf",                   /*tp_name*/
192   sizeof (membuf_object),         /*tp_basicsize*/
193   0,                              /*tp_itemsize*/
194   mbpy_dealloc,                   /*tp_dealloc*/
195   0,                              /*tp_print*/
196   0,                              /*tp_getattr*/
197   0,                              /*tp_setattr*/
198   0,                              /*tp_compare*/
199   0,                              /*tp_repr*/
200   0,                              /*tp_as_number*/
201   0,                              /*tp_as_sequence*/
202   0,                              /*tp_as_mapping*/
203   0,                              /*tp_hash */
204   0,                              /*tp_call*/
205   mbpy_str,                       /*tp_str*/
206   0,                              /*tp_getattro*/
207   0,                              /*tp_setattro*/
208   &buffer_procs,                  /*tp_as_buffer*/
209   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
210   "GDB memory buffer object",     /*tp_doc*/
211   0,                              /* tp_traverse */
212   0,                              /* tp_clear */
213   0,                              /* tp_richcompare */
214   0,                              /* tp_weaklistoffset */
215   0,                              /* tp_iter */
216   0,                              /* tp_iternext */
217   0,                              /* tp_methods */
218   0,                              /* tp_members */
219   0,                              /* tp_getset */
220   0,                              /* tp_base */
221   0,                              /* tp_dict */
222   0,                              /* tp_descr_get */
223   0,                              /* tp_descr_set */
224   0,                              /* tp_dictoffset */
225   0,                              /* tp_init */
226   0,                              /* tp_alloc */
227 };
This page took 0.037039 seconds and 4 git commands to generate.