aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2019-02-16 17:46:33 -0700
committerKevin Buettner <kevinb@redhat.com>2019-02-26 10:23:23 -0700
commitfe07eca59d0544eb6c56c3559da9ceece23cae6e (patch)
treea5330ff950e45356c2a64e43cb521ec67649c79f
parent26c897821b37af894088ec5731f93dc82e79b6d4 (diff)
downloadgdb-fe07eca59d0544eb6c56c3559da9ceece23cae6e.zip
gdb-fe07eca59d0544eb6c56c3559da9ceece23cae6e.tar.gz
gdb-fe07eca59d0544eb6c56c3559da9ceece23cae6e.tar.bz2
Define gdb.Value(bufobj, type) constructor
Provided a buffer BUFOBJ and a type TYPE, construct a gdb.Value object with type TYPE, where the value's contents are taken from BUFOBJ. E.g... (gdb) python import struct (gdb) python unsigned_int_type=gdb.lookup_type('unsigned int') (gdb) python b=struct.pack('=I',0xdeadbeef) (gdb) python v=gdb.Value(b, unsigned_int_type) ; print("%#x" % v) 0xdeadbeef This two argument form of the gdb.Value constructor may also be used to obtain gdb values from selected portions of buffers read with Inferior.read_memory(). The test case (which is in a separate patch) demonstrates this use case. gdb/ChangeLog: * python/py-value.c (convert_buffer_and_type_to_value): New function. (valpy_new): Parse arguments via gdb_PyArg_ParseTupleAndKeywords. Add support for handling an optional second argument. Call convert_buffer_and_type_to_value as appropriate.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/python/py-value.c72
2 files changed, 67 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f311a24..5d845e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2019-02-26 Kevin Buettner <kevinb@redhat.com>
+ * python/py-value.c (convert_buffer_and_type_to_value): New
+ function.
+ (valpy_new): Parse arguments via gdb_PyArg_ParseTupleAndKeywords.
+ Add support for handling an optional second argument. Call
+ convert_buffer_and_type_to_value as appropriate.
* python/python-internal.h (Py_buffer_deleter): New struct.
(Py_buffer_up): New typedef.
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 20ef582..445be72 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -107,22 +107,68 @@ note_value (value_object *value_obj)
values_in_python = value_obj;
}
+/* Convert a python object OBJ with type TYPE to a gdb value. The
+ python object in question must conform to the python buffer
+ protocol. On success, return the converted value, otherwise
+ nullptr. */
+
+static struct value *
+convert_buffer_and_type_to_value (PyObject *obj, struct type *type)
+{
+ Py_buffer_up buffer_up;
+ Py_buffer py_buf;
+
+ if (PyObject_CheckBuffer (obj)
+ && PyObject_GetBuffer (obj, &py_buf, PyBUF_SIMPLE) == 0)
+ {
+ /* Got a buffer, py_buf, out of obj. Cause it to be released
+ when it goes out of scope. */
+ buffer_up.reset (&py_buf);
+ }
+ else
+ {
+ PyErr_SetString (PyExc_TypeError,
+ _("Object must support the python buffer protocol."));
+ return nullptr;
+ }
+
+ if (TYPE_LENGTH (type) > py_buf.len)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ _("Size of type is larger than that of buffer object."));
+ return nullptr;
+ }
+
+ return value_from_contents (type, (const gdb_byte *) py_buf.buf);
+}
+
/* Called when a new gdb.Value object needs to be allocated. Returns NULL on
error, with a python exception set. */
static PyObject *
-valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
+valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
{
- struct value *value = NULL; /* Initialize to appease gcc warning. */
- value_object *value_obj;
+ static const char *keywords[] = { "val", "type", NULL };
+ PyObject *val_obj = nullptr;
+ PyObject *type_obj = nullptr;
+
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "O|O", keywords,
+ &val_obj, &type_obj))
+ return nullptr;
- if (PyTuple_Size (args) != 1)
+ struct type *type = nullptr;
+
+ if (type_obj != nullptr)
{
- PyErr_SetString (PyExc_TypeError, _("Value object creation takes only "
- "1 argument"));
- return NULL;
+ type = type_object_to_type (type_obj);
+ if (type == nullptr)
+ {
+ PyErr_SetString (PyExc_TypeError,
+ _("type argument must be a gdb.Type."));
+ return nullptr;
+ }
}
- value_obj = (value_object *) subtype->tp_alloc (subtype, 1);
+ value_object *value_obj = (value_object *) subtype->tp_alloc (subtype, 1);
if (value_obj == NULL)
{
PyErr_SetString (PyExc_MemoryError, _("Could not allocate memory to "
@@ -130,8 +176,14 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
return NULL;
}
- value = convert_value_from_python (PyTuple_GetItem (args, 0));
- if (value == NULL)
+ struct value *value;
+
+ if (type == nullptr)
+ value = convert_value_from_python (val_obj);
+ else
+ value = convert_buffer_and_type_to_value (val_obj, type);
+
+ if (value == nullptr)
{
subtype->tp_free (value_obj);
return NULL;