Home | History | Annotate | Line # | Download | only in python
      1 /* Python memory buffer interface for reading inferior memory.
      2 
      3    Copyright (C) 2009-2024 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 "python-internal.h"
     21 
     22 struct membuf_object {
     23   PyObject_HEAD
     24 
     25   /* Pointer to the raw data, and array of gdb_bytes.  */
     26   void *buffer;
     27 
     28   /* The address from where the data was read, held for mbpy_str.  */
     29   CORE_ADDR addr;
     30 
     31   /* The number of octets in BUFFER.  */
     32   CORE_ADDR length;
     33 };
     34 
     35 extern PyTypeObject membuf_object_type
     36     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
     37 
     38 /* Wrap BUFFER, ADDRESS, and LENGTH into a gdb.Membuf object.  ADDRESS is
     39    the address within the inferior that the contents of BUFFER were read,
     40    and LENGTH is the number of octets in BUFFER.  */
     41 
     42 PyObject *
     43 gdbpy_buffer_to_membuf (gdb::unique_xmalloc_ptr<gdb_byte> buffer,
     44 			CORE_ADDR address,
     45 			ULONGEST length)
     46 {
     47   gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
     48 						     &membuf_object_type));
     49   if (membuf_obj == nullptr)
     50     return nullptr;
     51 
     52   membuf_obj->buffer = buffer.release ();
     53   membuf_obj->addr = address;
     54   membuf_obj->length = length;
     55 
     56   return PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
     57 }
     58 
     59 /* Destructor for gdb.Membuf objects.  */
     60 
     61 static void
     62 mbpy_dealloc (PyObject *self)
     63 {
     64   xfree (((membuf_object *) self)->buffer);
     65   Py_TYPE (self)->tp_free (self);
     66 }
     67 
     68 /* Return a description of the gdb.Membuf object.  */
     69 
     70 static PyObject *
     71 mbpy_str (PyObject *self)
     72 {
     73   membuf_object *membuf_obj = (membuf_object *) self;
     74 
     75   return PyUnicode_FromFormat (_("Memory buffer for address %s, \
     76 which is %s bytes long."),
     77 			       paddress (gdbpy_enter::get_gdbarch (),
     78 					 membuf_obj->addr),
     79 			       pulongest (membuf_obj->length));
     80 }
     81 
     82 static int
     83 get_buffer (PyObject *self, Py_buffer *buf, int flags)
     84 {
     85   membuf_object *membuf_obj = (membuf_object *) self;
     86   int ret;
     87 
     88   ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
     89 			   membuf_obj->length, 0,
     90 			   PyBUF_CONTIG);
     91 
     92   /* Despite the documentation saying this field is a "const char *",
     93      in Python 3.4 at least, it's really a "char *".  */
     94   buf->format = (char *) "c";
     95 
     96   return ret;
     97 }
     98 
     99 /* General Python initialization callback.  */
    100 
    101 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
    102 gdbpy_initialize_membuf (void)
    103 {
    104   membuf_object_type.tp_new = PyType_GenericNew;
    105   if (PyType_Ready (&membuf_object_type) < 0)
    106     return -1;
    107 
    108   return gdb_pymodule_addobject (gdb_module, "Membuf",
    109 				 (PyObject *) &membuf_object_type);
    110 }
    111 
    112 GDBPY_INITIALIZE_FILE (gdbpy_initialize_membuf);
    113 
    114 
    115 
    117 static PyBufferProcs buffer_procs =
    118 {
    119   get_buffer
    120 };
    121 
    122 PyTypeObject membuf_object_type = {
    123   PyVarObject_HEAD_INIT (nullptr, 0)
    124   "gdb.Membuf",			  /*tp_name*/
    125   sizeof (membuf_object),	  /*tp_basicsize*/
    126   0,				  /*tp_itemsize*/
    127   mbpy_dealloc,			  /*tp_dealloc*/
    128   0,				  /*tp_print*/
    129   0,				  /*tp_getattr*/
    130   0,				  /*tp_setattr*/
    131   0,				  /*tp_compare*/
    132   0,				  /*tp_repr*/
    133   0,				  /*tp_as_number*/
    134   0,				  /*tp_as_sequence*/
    135   0,				  /*tp_as_mapping*/
    136   0,				  /*tp_hash */
    137   0,				  /*tp_call*/
    138   mbpy_str,			  /*tp_str*/
    139   0,				  /*tp_getattro*/
    140   0,				  /*tp_setattro*/
    141   &buffer_procs,		  /*tp_as_buffer*/
    142   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
    143   "GDB memory buffer object", 	  /*tp_doc*/
    144   0,				  /* tp_traverse */
    145   0,				  /* tp_clear */
    146   0,				  /* tp_richcompare */
    147   0,				  /* tp_weaklistoffset */
    148   0,				  /* tp_iter */
    149   0,				  /* tp_iternext */
    150   0,				  /* tp_methods */
    151   0,				  /* tp_members */
    152   0,				  /* tp_getset */
    153   0,				  /* tp_base */
    154   0,				  /* tp_dict */
    155   0,				  /* tp_descr_get */
    156   0,				  /* tp_descr_set */
    157   0,				  /* tp_dictoffset */
    158   0,				  /* tp_init */
    159   0,				  /* tp_alloc */
    160 };
    161