diff options
author | Kevin Buettner <kevinb@redhat.com> | 2019-02-16 17:46:33 -0700 |
---|---|---|
committer | Kevin Buettner <kevinb@redhat.com> | 2019-02-26 10:23:23 -0700 |
commit | fe07eca59d0544eb6c56c3559da9ceece23cae6e (patch) | |
tree | a5330ff950e45356c2a64e43cb521ec67649c79f | |
parent | 26c897821b37af894088ec5731f93dc82e79b6d4 (diff) | |
download | gdb-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/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/python/py-value.c | 72 |
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; |