xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-membuf.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1*6881a400Schristos /* Python memory buffer interface for reading inferior memory.
2*6881a400Schristos 
3*6881a400Schristos    Copyright (C) 2009-2023 Free Software Foundation, Inc.
4*6881a400Schristos 
5*6881a400Schristos    This file is part of GDB.
6*6881a400Schristos 
7*6881a400Schristos    This program is free software; you can redistribute it and/or modify
8*6881a400Schristos    it under the terms of the GNU General Public License as published by
9*6881a400Schristos    the Free Software Foundation; either version 3 of the License, or
10*6881a400Schristos    (at your option) any later version.
11*6881a400Schristos 
12*6881a400Schristos    This program is distributed in the hope that it will be useful,
13*6881a400Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*6881a400Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*6881a400Schristos    GNU General Public License for more details.
16*6881a400Schristos 
17*6881a400Schristos    You should have received a copy of the GNU General Public License
18*6881a400Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19*6881a400Schristos 
20*6881a400Schristos #include "defs.h"
21*6881a400Schristos #include "python-internal.h"
22*6881a400Schristos 
23*6881a400Schristos struct membuf_object {
24*6881a400Schristos   PyObject_HEAD
25*6881a400Schristos 
26*6881a400Schristos   /* Pointer to the raw data, and array of gdb_bytes.  */
27*6881a400Schristos   void *buffer;
28*6881a400Schristos 
29*6881a400Schristos   /* The address from where the data was read, held for mbpy_str.  */
30*6881a400Schristos   CORE_ADDR addr;
31*6881a400Schristos 
32*6881a400Schristos   /* The number of octets in BUFFER.  */
33*6881a400Schristos   CORE_ADDR length;
34*6881a400Schristos };
35*6881a400Schristos 
36*6881a400Schristos extern PyTypeObject membuf_object_type
37*6881a400Schristos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
38*6881a400Schristos 
39*6881a400Schristos /* Wrap BUFFER, ADDRESS, and LENGTH into a gdb.Membuf object.  ADDRESS is
40*6881a400Schristos    the address within the inferior that the contents of BUFFER were read,
41*6881a400Schristos    and LENGTH is the number of octets in BUFFER.  */
42*6881a400Schristos 
43*6881a400Schristos PyObject *
44*6881a400Schristos gdbpy_buffer_to_membuf (gdb::unique_xmalloc_ptr<gdb_byte> buffer,
45*6881a400Schristos 			CORE_ADDR address,
46*6881a400Schristos 			ULONGEST length)
47*6881a400Schristos {
48*6881a400Schristos   gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
49*6881a400Schristos 						     &membuf_object_type));
50*6881a400Schristos   if (membuf_obj == nullptr)
51*6881a400Schristos     return nullptr;
52*6881a400Schristos 
53*6881a400Schristos   membuf_obj->buffer = buffer.release ();
54*6881a400Schristos   membuf_obj->addr = address;
55*6881a400Schristos   membuf_obj->length = length;
56*6881a400Schristos 
57*6881a400Schristos   return PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
58*6881a400Schristos }
59*6881a400Schristos 
60*6881a400Schristos /* Destructor for gdb.Membuf objects.  */
61*6881a400Schristos 
62*6881a400Schristos static void
63*6881a400Schristos mbpy_dealloc (PyObject *self)
64*6881a400Schristos {
65*6881a400Schristos   xfree (((membuf_object *) self)->buffer);
66*6881a400Schristos   Py_TYPE (self)->tp_free (self);
67*6881a400Schristos }
68*6881a400Schristos 
69*6881a400Schristos /* Return a description of the gdb.Membuf object.  */
70*6881a400Schristos 
71*6881a400Schristos static PyObject *
72*6881a400Schristos mbpy_str (PyObject *self)
73*6881a400Schristos {
74*6881a400Schristos   membuf_object *membuf_obj = (membuf_object *) self;
75*6881a400Schristos 
76*6881a400Schristos   return PyUnicode_FromFormat (_("Memory buffer for address %s, \
77*6881a400Schristos which is %s bytes long."),
78*6881a400Schristos 			       paddress (gdbpy_enter::get_gdbarch (),
79*6881a400Schristos 					 membuf_obj->addr),
80*6881a400Schristos 			       pulongest (membuf_obj->length));
81*6881a400Schristos }
82*6881a400Schristos 
83*6881a400Schristos static int
84*6881a400Schristos get_buffer (PyObject *self, Py_buffer *buf, int flags)
85*6881a400Schristos {
86*6881a400Schristos   membuf_object *membuf_obj = (membuf_object *) self;
87*6881a400Schristos   int ret;
88*6881a400Schristos 
89*6881a400Schristos   ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
90*6881a400Schristos 			   membuf_obj->length, 0,
91*6881a400Schristos 			   PyBUF_CONTIG);
92*6881a400Schristos 
93*6881a400Schristos   /* Despite the documentation saying this field is a "const char *",
94*6881a400Schristos      in Python 3.4 at least, it's really a "char *".  */
95*6881a400Schristos   buf->format = (char *) "c";
96*6881a400Schristos 
97*6881a400Schristos   return ret;
98*6881a400Schristos }
99*6881a400Schristos 
100*6881a400Schristos /* General Python initialization callback.  */
101*6881a400Schristos 
102*6881a400Schristos int
103*6881a400Schristos gdbpy_initialize_membuf (void)
104*6881a400Schristos {
105*6881a400Schristos   membuf_object_type.tp_new = PyType_GenericNew;
106*6881a400Schristos   if (PyType_Ready (&membuf_object_type) < 0)
107*6881a400Schristos     return -1;
108*6881a400Schristos 
109*6881a400Schristos   return gdb_pymodule_addobject (gdb_module, "Membuf",
110*6881a400Schristos 				 (PyObject *) &membuf_object_type);
111*6881a400Schristos }
112*6881a400Schristos 
113*6881a400Schristos static PyBufferProcs buffer_procs =
114*6881a400Schristos {
115*6881a400Schristos   get_buffer
116*6881a400Schristos };
117*6881a400Schristos 
118*6881a400Schristos PyTypeObject membuf_object_type = {
119*6881a400Schristos   PyVarObject_HEAD_INIT (nullptr, 0)
120*6881a400Schristos   "gdb.Membuf",			  /*tp_name*/
121*6881a400Schristos   sizeof (membuf_object),	  /*tp_basicsize*/
122*6881a400Schristos   0,				  /*tp_itemsize*/
123*6881a400Schristos   mbpy_dealloc,			  /*tp_dealloc*/
124*6881a400Schristos   0,				  /*tp_print*/
125*6881a400Schristos   0,				  /*tp_getattr*/
126*6881a400Schristos   0,				  /*tp_setattr*/
127*6881a400Schristos   0,				  /*tp_compare*/
128*6881a400Schristos   0,				  /*tp_repr*/
129*6881a400Schristos   0,				  /*tp_as_number*/
130*6881a400Schristos   0,				  /*tp_as_sequence*/
131*6881a400Schristos   0,				  /*tp_as_mapping*/
132*6881a400Schristos   0,				  /*tp_hash */
133*6881a400Schristos   0,				  /*tp_call*/
134*6881a400Schristos   mbpy_str,			  /*tp_str*/
135*6881a400Schristos   0,				  /*tp_getattro*/
136*6881a400Schristos   0,				  /*tp_setattro*/
137*6881a400Schristos   &buffer_procs,		  /*tp_as_buffer*/
138*6881a400Schristos   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
139*6881a400Schristos   "GDB memory buffer object", 	  /*tp_doc*/
140*6881a400Schristos   0,				  /* tp_traverse */
141*6881a400Schristos   0,				  /* tp_clear */
142*6881a400Schristos   0,				  /* tp_richcompare */
143*6881a400Schristos   0,				  /* tp_weaklistoffset */
144*6881a400Schristos   0,				  /* tp_iter */
145*6881a400Schristos   0,				  /* tp_iternext */
146*6881a400Schristos   0,				  /* tp_methods */
147*6881a400Schristos   0,				  /* tp_members */
148*6881a400Schristos   0,				  /* tp_getset */
149*6881a400Schristos   0,				  /* tp_base */
150*6881a400Schristos   0,				  /* tp_dict */
151*6881a400Schristos   0,				  /* tp_descr_get */
152*6881a400Schristos   0,				  /* tp_descr_set */
153*6881a400Schristos   0,				  /* tp_dictoffset */
154*6881a400Schristos   0,				  /* tp_init */
155*6881a400Schristos   0,				  /* tp_alloc */
156*6881a400Schristos };
157