forked from Imagelibrary/binutils-gdb
Python: Move and rename gdb.BtraceInstruction
Remove gdb.BtraceInstruction and replace by gdb.RecordInstruction.
This commit is contained in:
@@ -1,3 +1,40 @@
|
|||||||
|
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||||
|
|
||||||
|
* python/py-record-btrace.c (BTPY_REQUIRE_VALID_INSN): Remove.
|
||||||
|
(btpy_object, btpy_insn_type, btpy_new): Remove.
|
||||||
|
(btpy_list_object): Use gdb.RecordInstruction type instead of
|
||||||
|
gdb.BtraceInstruction type.
|
||||||
|
(btrace_insn_from_recpy_insn): New function.
|
||||||
|
(btpy_insn_or_gap_new): Adjust comment. Use recpy_insn_new instead of
|
||||||
|
btpy_new.
|
||||||
|
(btpy_call_new, btpy_list_item): Do not use btpy_new anymore.
|
||||||
|
(btpy_number, btpy_hash, btpy_call_level, btpy_call_symbol,
|
||||||
|
btpy_call_instructions, btpy_call_up, btpy_call_prev_sibling,
|
||||||
|
btpy_call_next_sibling, btpy_richcompare): Use recpy_element_object
|
||||||
|
instead of btpy_object.
|
||||||
|
(btpy_insn_sal, btpy_insn_pc, btpy_insn_size, btpy_insn_is_speculative,
|
||||||
|
btpy_insn_data, btpy_insn_decode): Rename to ...
|
||||||
|
(recpy_bt_insn_sal, recpy_bt_insn_pc, recpy_bt_insn_size,
|
||||||
|
recpy_bt_insn_is_speculative, recpy_bt_insn_data,
|
||||||
|
recpy_bt_insn_decode): This. Also, use new helper functions.
|
||||||
|
(btpy_list_position, recpy_bt_goto): Use recpy_element_object and
|
||||||
|
recpy_insn_type.
|
||||||
|
(btpy_insn_getset): Remove.
|
||||||
|
(gdbpy_initialize_btrace): Remove code to initialize
|
||||||
|
gdb.BtraceInstruction. Use recpy_element_object.
|
||||||
|
* python/py-record-btrace.h (recpy_bt_insn_number, recpy_bt_insn_sal,
|
||||||
|
recpy_bt_insn_pc, recpy_bt_insn_data, recpy_bt_insn_decoded,
|
||||||
|
recpy_bt_insn_size, recpy_bt_insn_is_speculative): New export.
|
||||||
|
* python/py-record.c (recpy_insn_type): New static object.
|
||||||
|
(recpy_insn_new, recpy_insn_sal, recpy_insn_pc, recpy_insn_data,
|
||||||
|
recpy_insn_decoded, recpy_insn_size, recpy_insn_is_speculative,
|
||||||
|
recpy_element_number, recpy_element_hash, recpy_element_richcompare):
|
||||||
|
New function.
|
||||||
|
(recpy_insn_getset): New static object.
|
||||||
|
(gdbpy_initialize_record): Initialize gdb.RecordInstruction.
|
||||||
|
* python/py-record.h (recpy_element_object): New typedef.
|
||||||
|
(recpy_insn_type, recpy_insn_new): New export.
|
||||||
|
|
||||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||||
|
|
||||||
* py-record-btrace.c (btpy_insn_new): Removed.
|
* py-record-btrace.c (btpy_insn_new): Removed.
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||||
|
|
||||||
|
* python.texi (Recording in Python): Replace gdb.BtraceInstruction with
|
||||||
|
gdb.RecordInstruction
|
||||||
|
|
||||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||||
|
|
||||||
* python.texi (Recording in Python): Add documentation for
|
* python.texi (Recording in Python): Add documentation for
|
||||||
|
|||||||
@@ -3149,41 +3149,38 @@ A @code{gdb.Record} object has the following methods:
|
|||||||
Move the replay position to the given @var{instruction}.
|
Move the replay position to the given @var{instruction}.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
The attributes and methods of instruction objects depend on the current
|
A @code{gdb.RecordInstruction} object has the following attributes:
|
||||||
recording method. Currently, only btrace instructions are supported.
|
|
||||||
|
|
||||||
A @code{gdb.BtraceInstruction} object has the following attributes:
|
@defvar RecordInstruction.number
|
||||||
|
|
||||||
@defvar BtraceInstruction.number
|
|
||||||
An integer identifying this instruction. @var{number} corresponds to
|
An integer identifying this instruction. @var{number} corresponds to
|
||||||
the numbers seen in @code{record instruction-history}
|
the numbers seen in @code{record instruction-history}
|
||||||
(@pxref{Process Record and Replay}).
|
(@pxref{Process Record and Replay}).
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceInstruction.sal
|
@defvar RecordInstruction.sal
|
||||||
A @code{gdb.Symtab_and_line} object representing the associated symtab
|
A @code{gdb.Symtab_and_line} object representing the associated symtab
|
||||||
and line of this instruction. May be @code{None} if no debug information is
|
and line of this instruction. May be @code{None} if no debug information is
|
||||||
available.
|
available.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceInstruction.pc
|
@defvar RecordInstruction.pc
|
||||||
An integer representing this instruction's address.
|
An integer representing this instruction's address.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceInstruction.data
|
@defvar RecordInstruction.data
|
||||||
A buffer with the raw instruction data. In Python 3, the return value is a
|
A buffer with the raw instruction data. In Python 3, the return value is a
|
||||||
@code{memoryview} object.
|
@code{memoryview} object.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceInstruction.decoded
|
@defvar RecordInstruction.decoded
|
||||||
A human readable string with the disassembled instruction.
|
A human readable string with the disassembled instruction.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceInstruction.size
|
@defvar RecordInstruction.size
|
||||||
The size of the instruction in bytes.
|
The size of the instruction in bytes.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceInstruction.is_speculative
|
@defvar RecordInstruction.is_speculative
|
||||||
A boolean indicating whether the instruction was executed
|
A boolean indicating whether the instruction was executed
|
||||||
speculatively.
|
speculatively.
|
||||||
@end defvar
|
@end defvar
|
||||||
@@ -3230,7 +3227,7 @@ An integer representing the function call's stack level. May be
|
|||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar BtraceFunctionCall.instructions
|
@defvar BtraceFunctionCall.instructions
|
||||||
A list of @code{gdb.BtraceInstruction} or @code{gdb.RecordGap} objects
|
A list of @code{gdb.RecordInstruction} or @code{gdb.RecordGap} objects
|
||||||
associated with this function call.
|
associated with this function call.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
|
|||||||
@@ -36,16 +36,6 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BTPY_REQUIRE_VALID_INSN(obj, iter) \
|
|
||||||
do { \
|
|
||||||
struct thread_info *tinfo = find_thread_ptid (obj->ptid); \
|
|
||||||
if (tinfo == NULL || btrace_is_empty (tinfo)) \
|
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("Empty branch trace.")); \
|
|
||||||
if (0 == btrace_find_insn_by_number (&iter, &tinfo->btrace, \
|
|
||||||
obj->number)) \
|
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction.")); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define BTPY_REQUIRE_VALID_CALL(obj, iter) \
|
#define BTPY_REQUIRE_VALID_CALL(obj, iter) \
|
||||||
do { \
|
do { \
|
||||||
struct thread_info *tinfo = find_thread_ptid (obj->ptid); \
|
struct thread_info *tinfo = find_thread_ptid (obj->ptid); \
|
||||||
@@ -56,20 +46,6 @@
|
|||||||
return PyErr_Format (gdbpy_gdb_error, _("No such call segment."));\
|
return PyErr_Format (gdbpy_gdb_error, _("No such call segment."));\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* This can either be a btrace instruction or a function call segment,
|
|
||||||
depending on the chosen type. */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
|
|
||||||
/* The thread this object belongs to. */
|
|
||||||
ptid_t ptid;
|
|
||||||
|
|
||||||
/* Instruction number or function call segment number, depending on the type
|
|
||||||
of this object. */
|
|
||||||
Py_ssize_t number;
|
|
||||||
} btpy_object;
|
|
||||||
|
|
||||||
/* Python object for btrace record lists. */
|
/* Python object for btrace record lists. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -87,16 +63,10 @@ typedef struct {
|
|||||||
/* Stride size. */
|
/* Stride size. */
|
||||||
Py_ssize_t step;
|
Py_ssize_t step;
|
||||||
|
|
||||||
/* Either &BTPY_CALL_TYPE or &BTPY_INSN_TYPE. */
|
/* Either &BTPY_CALL_TYPE or &RECPY_INSN_TYPE. */
|
||||||
PyTypeObject* element_type;
|
PyTypeObject* element_type;
|
||||||
} btpy_list_object;
|
} btpy_list_object;
|
||||||
|
|
||||||
/* Python type for btrace instructions. */
|
|
||||||
|
|
||||||
static PyTypeObject btpy_insn_type = {
|
|
||||||
PyVarObject_HEAD_INIT (NULL, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Python type for btrace function-calls. */
|
/* Python type for btrace function-calls. */
|
||||||
|
|
||||||
static PyTypeObject btpy_call_type = {
|
static PyTypeObject btpy_call_type = {
|
||||||
@@ -109,25 +79,50 @@ static PyTypeObject btpy_list_type = {
|
|||||||
PyVarObject_HEAD_INIT (NULL, 0)
|
PyVarObject_HEAD_INIT (NULL, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create a new gdb.BtraceInstruction or gdb.BtraceFunctionCall object,
|
/* Returns either a btrace_insn for the given Python gdb.RecordInstruction
|
||||||
depending on TYPE. */
|
object or sets an appropriate Python exception and returns NULL. */
|
||||||
|
|
||||||
static PyObject *
|
static const btrace_insn *
|
||||||
btpy_new (ptid_t ptid, Py_ssize_t number, PyTypeObject* type)
|
btrace_insn_from_recpy_insn (const PyObject * const pyobject)
|
||||||
{
|
{
|
||||||
btpy_object * const obj = PyObject_New (btpy_object, type);
|
const btrace_insn *insn;
|
||||||
|
const recpy_element_object *obj;
|
||||||
|
thread_info *tinfo;
|
||||||
|
btrace_insn_iterator iter;
|
||||||
|
|
||||||
if (obj == NULL)
|
if (Py_TYPE (pyobject) != &recpy_insn_type)
|
||||||
return NULL;
|
{
|
||||||
|
PyErr_Format (gdbpy_gdb_error, _("Must be gdb.RecordInstruction"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
obj->ptid = ptid;
|
obj = (const recpy_element_object *) pyobject;
|
||||||
obj->number = number;
|
tinfo = find_thread_ptid (obj->ptid);
|
||||||
|
|
||||||
return (PyObject *) obj;
|
if (tinfo == NULL || btrace_is_empty (tinfo))
|
||||||
|
{
|
||||||
|
PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btrace_find_insn_by_number (&iter, &tinfo->btrace, obj->number) == 0)
|
||||||
|
{
|
||||||
|
PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
insn = btrace_insn_get (&iter);
|
||||||
|
if (insn == NULL)
|
||||||
|
{
|
||||||
|
PyErr_Format (gdbpy_gdb_error, _("Not a valid instruction."));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Looks at the recorded item with the number NUMBER and create a
|
/* Looks at the recorded item with the number NUMBER and create a
|
||||||
gdb.BtraceInstruction or gdb.RecordGap object for it accordingly. */
|
gdb.RecordInstruction or gdb.RecordGap object for it accordingly. */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number)
|
btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number)
|
||||||
@@ -149,7 +144,7 @@ btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number)
|
|||||||
return recpy_gap_new (err_code, err_string, number);
|
return recpy_gap_new (err_code, err_string, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
return btpy_new (tinfo->ptid, number, &btpy_insn_type);
|
return recpy_insn_new (tinfo->ptid, RECORD_METHOD_BTRACE, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new gdb.BtraceFunctionCall object. */
|
/* Create a new gdb.BtraceFunctionCall object. */
|
||||||
@@ -157,7 +152,17 @@ btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_new (ptid_t ptid, Py_ssize_t number)
|
btpy_call_new (ptid_t ptid, Py_ssize_t number)
|
||||||
{
|
{
|
||||||
return btpy_new (ptid, number, &btpy_call_type);
|
recpy_element_object * const obj = PyObject_New (recpy_element_object,
|
||||||
|
&btpy_call_type);
|
||||||
|
|
||||||
|
if (obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
obj->ptid = ptid;
|
||||||
|
obj->method = RECORD_METHOD_BTRACE;
|
||||||
|
obj->number = number;
|
||||||
|
|
||||||
|
return (PyObject *) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new gdb.BtraceList object. */
|
/* Create a new gdb.BtraceList object. */
|
||||||
@@ -187,7 +192,7 @@ btpy_list_new (ptid_t ptid, Py_ssize_t first, Py_ssize_t last, Py_ssize_t step,
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_number (PyObject *self, void *closure)
|
btpy_number (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
|
|
||||||
return PyInt_FromSsize_t (obj->number);
|
return PyInt_FromSsize_t (obj->number);
|
||||||
}
|
}
|
||||||
@@ -198,27 +203,22 @@ btpy_number (PyObject *self, void *closure)
|
|||||||
static Py_hash_t
|
static Py_hash_t
|
||||||
btpy_hash (PyObject *self)
|
btpy_hash (PyObject *self)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
|
|
||||||
return obj->number;
|
return obj->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceInstruction.sal [gdb.Symtab_and_line].
|
/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line] for btrace.
|
||||||
Return the SAL associated with this instruction. */
|
Returns the SAL associated with this instruction. */
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
btpy_insn_sal (PyObject *self, void *closure)
|
recpy_bt_insn_sal (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_insn_iterator iter;
|
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
|
|
||||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
|
||||||
|
|
||||||
insn = btrace_insn_get (&iter);
|
|
||||||
if (insn == NULL)
|
if (insn == NULL)
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
return NULL;
|
||||||
|
|
||||||
TRY
|
TRY
|
||||||
{
|
{
|
||||||
@@ -233,59 +233,44 @@ btpy_insn_sal (PyObject *self, void *closure)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceInstruction.pc [int]. Returns
|
/* Implementation of RecordInstruction.pc [int] for btrace.
|
||||||
the instruction address. */
|
Returns the instruction address. */
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
btpy_insn_pc (PyObject *self, void *closure)
|
recpy_bt_insn_pc (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_insn_iterator iter;
|
|
||||||
|
|
||||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
|
||||||
|
|
||||||
insn = btrace_insn_get (&iter);
|
|
||||||
if (insn == NULL)
|
if (insn == NULL)
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
return NULL;
|
||||||
|
|
||||||
return gdb_py_long_from_ulongest (insn->pc);
|
return gdb_py_long_from_ulongest (insn->pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceInstruction.size [int]. Returns
|
/* Implementation of RecordInstruction.size [int] for btrace.
|
||||||
the instruction size. */
|
Returns the instruction size. */
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
btpy_insn_size (PyObject *self, void *closure)
|
recpy_bt_insn_size (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_insn_iterator iter;
|
|
||||||
|
|
||||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
|
||||||
|
|
||||||
insn = btrace_insn_get (&iter);
|
|
||||||
if (insn == NULL)
|
if (insn == NULL)
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
return NULL;
|
||||||
|
|
||||||
return PyInt_FromLong (insn->size);
|
return PyInt_FromLong (insn->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceInstruction.is_speculative [bool].
|
/* Implementation of RecordInstruction.is_speculative [bool] for btrace.
|
||||||
Returns if this instruction was executed speculatively. */
|
Returns if this instruction was executed speculatively. */
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
btpy_insn_is_speculative (PyObject *self, void *closure)
|
recpy_bt_insn_is_speculative (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_insn_iterator iter;
|
|
||||||
|
|
||||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
|
||||||
|
|
||||||
insn = btrace_insn_get (&iter);
|
|
||||||
if (insn == NULL)
|
if (insn == NULL)
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
return NULL;
|
||||||
|
|
||||||
if (insn->flags & BTRACE_INSN_FLAG_SPECULATIVE)
|
if (insn->flags & BTRACE_INSN_FLAG_SPECULATIVE)
|
||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
@@ -293,23 +278,18 @@ btpy_insn_is_speculative (PyObject *self, void *closure)
|
|||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceInstruction.data [buffer].
|
/* Implementation of RecordInstruction.data [buffer] for btrace.
|
||||||
Returns raw instruction data. */
|
Returns raw instruction data. */
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
btpy_insn_data (PyObject *self, void *closure)
|
recpy_bt_insn_data (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_insn_iterator iter;
|
|
||||||
gdb_byte *buffer = NULL;
|
gdb_byte *buffer = NULL;
|
||||||
PyObject *object;
|
PyObject *object;
|
||||||
|
|
||||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
|
||||||
|
|
||||||
insn = btrace_insn_get (&iter);
|
|
||||||
if (insn == NULL)
|
if (insn == NULL)
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
return NULL;
|
||||||
|
|
||||||
TRY
|
TRY
|
||||||
{
|
{
|
||||||
@@ -337,22 +317,17 @@ btpy_insn_data (PyObject *self, void *closure)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceInstruction.decode [str]. Returns
|
/* Implementation of RecordInstruction.decoded [str] for btrace.
|
||||||
the instruction as human readable string. */
|
Returns the instruction as human readable string. */
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
btpy_insn_decode (PyObject *self, void *closure)
|
recpy_bt_insn_decoded (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||||
const struct btrace_insn *insn;
|
|
||||||
struct btrace_insn_iterator iter;
|
|
||||||
string_file strfile;
|
string_file strfile;
|
||||||
|
|
||||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
|
||||||
|
|
||||||
insn = btrace_insn_get (&iter);
|
|
||||||
if (insn == NULL)
|
if (insn == NULL)
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
return NULL;
|
||||||
|
|
||||||
TRY
|
TRY
|
||||||
{
|
{
|
||||||
@@ -375,7 +350,7 @@ btpy_insn_decode (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_level (PyObject *self, void *closure)
|
btpy_call_level (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
const struct btrace_function *func;
|
const struct btrace_function *func;
|
||||||
struct btrace_call_iterator iter;
|
struct btrace_call_iterator iter;
|
||||||
|
|
||||||
@@ -394,7 +369,7 @@ btpy_call_level (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_symbol (PyObject *self, void *closure)
|
btpy_call_symbol (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
const struct btrace_function *func;
|
const struct btrace_function *func;
|
||||||
struct btrace_call_iterator iter;
|
struct btrace_call_iterator iter;
|
||||||
|
|
||||||
@@ -416,7 +391,7 @@ btpy_call_symbol (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_instructions (PyObject *self, void *closure)
|
btpy_call_instructions (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
const struct btrace_function *func;
|
const struct btrace_function *func;
|
||||||
struct btrace_call_iterator iter;
|
struct btrace_call_iterator iter;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@@ -434,7 +409,7 @@ btpy_call_instructions (PyObject *self, void *closure)
|
|||||||
len = 1;
|
len = 1;
|
||||||
|
|
||||||
return btpy_list_new (obj->ptid, func->insn_offset, func->insn_offset + len,
|
return btpy_list_new (obj->ptid, func->insn_offset, func->insn_offset + len,
|
||||||
1, &btpy_insn_type);
|
1, &recpy_insn_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceFunctionCall.up [gdb.BtraceRecordCall].
|
/* Implementation of BtraceFunctionCall.up [gdb.BtraceRecordCall].
|
||||||
@@ -443,7 +418,7 @@ btpy_call_instructions (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_up (PyObject *self, void *closure)
|
btpy_call_up (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
const struct btrace_function *func;
|
const struct btrace_function *func;
|
||||||
struct btrace_call_iterator iter;
|
struct btrace_call_iterator iter;
|
||||||
|
|
||||||
@@ -465,7 +440,7 @@ btpy_call_up (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_prev_sibling (PyObject *self, void *closure)
|
btpy_call_prev_sibling (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
const struct btrace_function *func;
|
const struct btrace_function *func;
|
||||||
struct btrace_call_iterator iter;
|
struct btrace_call_iterator iter;
|
||||||
|
|
||||||
@@ -487,7 +462,7 @@ btpy_call_prev_sibling (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_call_next_sibling (PyObject *self, void *closure)
|
btpy_call_next_sibling (PyObject *self, void *closure)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj = (btpy_object *) self;
|
const recpy_element_object * const obj = (const recpy_element_object *) self;
|
||||||
const struct btrace_function *func;
|
const struct btrace_function *func;
|
||||||
struct btrace_call_iterator iter;
|
struct btrace_call_iterator iter;
|
||||||
|
|
||||||
@@ -509,8 +484,8 @@ btpy_call_next_sibling (PyObject *self, void *closure)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
btpy_richcompare (PyObject *self, PyObject *other, int op)
|
btpy_richcompare (PyObject *self, PyObject *other, int op)
|
||||||
{
|
{
|
||||||
const btpy_object * const obj1 = (btpy_object *) self;
|
const recpy_element_object * const obj1 = (recpy_element_object *) self;
|
||||||
const btpy_object * const obj2 = (btpy_object *) other;
|
const recpy_element_object * const obj2 = (recpy_element_object *) other;
|
||||||
|
|
||||||
if (Py_TYPE (self) != Py_TYPE (other))
|
if (Py_TYPE (self) != Py_TYPE (other))
|
||||||
{
|
{
|
||||||
@@ -564,13 +539,18 @@ btpy_list_item (PyObject *self, Py_ssize_t index)
|
|||||||
{
|
{
|
||||||
const btpy_list_object * const obj = (btpy_list_object *) self;
|
const btpy_list_object * const obj = (btpy_list_object *) self;
|
||||||
struct thread_info * const tinfo = find_thread_ptid (obj->ptid);
|
struct thread_info * const tinfo = find_thread_ptid (obj->ptid);
|
||||||
|
Py_ssize_t number;
|
||||||
|
|
||||||
if (index < 0 || index >= btpy_list_length (self))
|
if (index < 0 || index >= btpy_list_length (self))
|
||||||
return PyErr_Format (PyExc_IndexError, _("Index out of range: %zd."),
|
return PyErr_Format (PyExc_IndexError, _("Index out of range: %zd."),
|
||||||
index);
|
index);
|
||||||
|
|
||||||
return btpy_new (obj->ptid, obj->first + (obj->step * index),
|
number = obj->first + (obj->step * index);
|
||||||
obj->element_type);
|
|
||||||
|
if (obj->element_type == &recpy_insn_type)
|
||||||
|
return recpy_insn_new (obj->ptid, RECORD_METHOD_BTRACE, number);
|
||||||
|
else
|
||||||
|
return btpy_call_new (obj->ptid, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */
|
/* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */
|
||||||
@@ -612,7 +592,7 @@ static LONGEST
|
|||||||
btpy_list_position (PyObject *self, PyObject *value)
|
btpy_list_position (PyObject *self, PyObject *value)
|
||||||
{
|
{
|
||||||
const btpy_list_object * const list_obj = (btpy_list_object *) self;
|
const btpy_list_object * const list_obj = (btpy_list_object *) self;
|
||||||
const btpy_object * const obj = (btpy_object *) value;
|
const recpy_element_object * const obj = (const recpy_element_object *) value;
|
||||||
Py_ssize_t index = obj->number;
|
Py_ssize_t index = obj->number;
|
||||||
|
|
||||||
if (list_obj->element_type != Py_TYPE (value))
|
if (list_obj->element_type != Py_TYPE (value))
|
||||||
@@ -830,7 +810,7 @@ recpy_bt_instruction_history (PyObject *self, void *closure)
|
|||||||
btrace_insn_end (&iterator, &tinfo->btrace);
|
btrace_insn_end (&iterator, &tinfo->btrace);
|
||||||
last = btrace_insn_number (&iterator);
|
last = btrace_insn_number (&iterator);
|
||||||
|
|
||||||
return btpy_list_new (record->ptid, first, last, 1, &btpy_insn_type);
|
return btpy_list_new (record->ptid, first, last, 1, &recpy_insn_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of
|
/* Implementation of
|
||||||
@@ -869,7 +849,7 @@ recpy_bt_goto (PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||||
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||||
const btpy_object *obj;
|
const recpy_element_object *obj;
|
||||||
|
|
||||||
if (tinfo == NULL || btrace_is_empty (tinfo))
|
if (tinfo == NULL || btrace_is_empty (tinfo))
|
||||||
return PyErr_Format (gdbpy_gdb_error, _("Empty branch trace."));
|
return PyErr_Format (gdbpy_gdb_error, _("Empty branch trace."));
|
||||||
@@ -877,7 +857,7 @@ recpy_bt_goto (PyObject *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple (args, "O", &obj))
|
if (!PyArg_ParseTuple (args, "O", &obj))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (Py_TYPE (obj) != &btpy_insn_type)
|
if (Py_TYPE (obj) != &recpy_insn_type)
|
||||||
return PyErr_Format (PyExc_TypeError, _("Argument must be instruction."));
|
return PyErr_Format (PyExc_TypeError, _("Argument must be instruction."));
|
||||||
|
|
||||||
TRY
|
TRY
|
||||||
@@ -900,22 +880,6 @@ recpy_bt_goto (PyObject *self, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BtraceInstruction members. */
|
|
||||||
|
|
||||||
struct gdb_PyGetSetDef btpy_insn_getset[] =
|
|
||||||
{
|
|
||||||
{ "number", btpy_number, NULL, "instruction number", NULL},
|
|
||||||
{ "sal", btpy_insn_sal, NULL, "associated symbol and line", NULL},
|
|
||||||
{ "pc", btpy_insn_pc, NULL, "instruction address", NULL},
|
|
||||||
{ "data", btpy_insn_data, NULL, "raw instruction data", NULL},
|
|
||||||
{ "decoded", btpy_insn_decode, NULL, "decoded instruction or error message \
|
|
||||||
if the instruction is a gap", NULL},
|
|
||||||
{ "size", btpy_insn_size, NULL, "instruction size in byte", NULL},
|
|
||||||
{ "is_speculative", btpy_insn_is_speculative, NULL, "if the instruction was \
|
|
||||||
executed speculatively", NULL},
|
|
||||||
{NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* BtraceFunctionCall members. */
|
/* BtraceFunctionCall members. */
|
||||||
|
|
||||||
static gdb_PyGetSetDef btpy_call_getset[] =
|
static gdb_PyGetSetDef btpy_call_getset[] =
|
||||||
@@ -961,18 +925,9 @@ static PyMappingMethods btpy_list_mapping_methods =
|
|||||||
int
|
int
|
||||||
gdbpy_initialize_btrace (void)
|
gdbpy_initialize_btrace (void)
|
||||||
{
|
{
|
||||||
btpy_insn_type.tp_new = PyType_GenericNew;
|
|
||||||
btpy_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
|
||||||
btpy_insn_type.tp_basicsize = sizeof (btpy_object);
|
|
||||||
btpy_insn_type.tp_name = "gdb.BtraceInstruction";
|
|
||||||
btpy_insn_type.tp_doc = "GDB btrace instruction object";
|
|
||||||
btpy_insn_type.tp_getset = btpy_insn_getset;
|
|
||||||
btpy_insn_type.tp_richcompare = btpy_richcompare;
|
|
||||||
btpy_insn_type.tp_hash = btpy_hash;
|
|
||||||
|
|
||||||
btpy_call_type.tp_new = PyType_GenericNew;
|
btpy_call_type.tp_new = PyType_GenericNew;
|
||||||
btpy_call_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
btpy_call_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||||
btpy_call_type.tp_basicsize = sizeof (btpy_object);
|
btpy_call_type.tp_basicsize = sizeof (recpy_element_object);
|
||||||
btpy_call_type.tp_name = "gdb.BtraceFunctionCall";
|
btpy_call_type.tp_name = "gdb.BtraceFunctionCall";
|
||||||
btpy_call_type.tp_doc = "GDB btrace call object";
|
btpy_call_type.tp_doc = "GDB btrace call object";
|
||||||
btpy_call_type.tp_getset = btpy_call_getset;
|
btpy_call_type.tp_getset = btpy_call_getset;
|
||||||
@@ -995,8 +950,7 @@ gdbpy_initialize_btrace (void)
|
|||||||
|
|
||||||
btpy_list_mapping_methods.mp_subscript = btpy_list_slice;
|
btpy_list_mapping_methods.mp_subscript = btpy_list_slice;
|
||||||
|
|
||||||
if (PyType_Ready (&btpy_insn_type) < 0
|
if (PyType_Ready (&btpy_call_type) < 0
|
||||||
|| PyType_Ready (&btpy_call_type) < 0
|
|
||||||
|| PyType_Ready (&btpy_list_type) < 0)
|
|| PyType_Ready (&btpy_list_type) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -46,4 +46,25 @@ extern PyObject *recpy_bt_begin (PyObject *self, void *closure);
|
|||||||
/* Implementation of record.end [instruction]. */
|
/* Implementation of record.end [instruction]. */
|
||||||
extern PyObject *recpy_bt_end (PyObject *self, void *closure);
|
extern PyObject *recpy_bt_end (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.number [int]. */
|
||||||
|
extern PyObject *recpy_bt_insn_number (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line]. */
|
||||||
|
extern PyObject *recpy_bt_insn_sal (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.pc [int]. */
|
||||||
|
extern PyObject *recpy_bt_insn_pc (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.data [buffer]. */
|
||||||
|
extern PyObject *recpy_bt_insn_data (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.decoded [str]. */
|
||||||
|
extern PyObject *recpy_bt_insn_decoded (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.size [int]. */
|
||||||
|
extern PyObject *recpy_bt_insn_size (PyObject *self, void *closure);
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.is_speculative [bool]. */
|
||||||
|
extern PyObject *recpy_bt_insn_is_speculative (PyObject *self, void *closure);
|
||||||
|
|
||||||
#endif /* GDB_PY_RECORD_BTRACE_H */
|
#endif /* GDB_PY_RECORD_BTRACE_H */
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ static PyTypeObject recpy_record_type = {
|
|||||||
PyVarObject_HEAD_INIT (NULL, 0)
|
PyVarObject_HEAD_INIT (NULL, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Python RecordInstruction type. */
|
||||||
|
|
||||||
|
PyTypeObject recpy_insn_type = {
|
||||||
|
PyVarObject_HEAD_INIT (NULL, 0)
|
||||||
|
};
|
||||||
|
|
||||||
/* Python RecordGap type. */
|
/* Python RecordGap type. */
|
||||||
|
|
||||||
PyTypeObject recpy_gap_type = {
|
PyTypeObject recpy_gap_type = {
|
||||||
@@ -160,6 +166,161 @@ recpy_end (PyObject *self, void* closure)
|
|||||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a new gdb.RecordInstruction object. */
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
recpy_insn_new (ptid_t ptid, enum record_method method, Py_ssize_t number)
|
||||||
|
{
|
||||||
|
recpy_element_object * const obj = PyObject_New (recpy_element_object,
|
||||||
|
&recpy_insn_type);
|
||||||
|
|
||||||
|
if (obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
obj->ptid = ptid;
|
||||||
|
obj->method = method;
|
||||||
|
obj->number = number;
|
||||||
|
|
||||||
|
return (PyObject *) obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_insn_sal (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
if (obj->method == RECORD_METHOD_BTRACE)
|
||||||
|
return recpy_bt_insn_sal (self, closure);
|
||||||
|
|
||||||
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.pc [int]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_insn_pc (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
if (obj->method == RECORD_METHOD_BTRACE)
|
||||||
|
return recpy_bt_insn_pc (self, closure);
|
||||||
|
|
||||||
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.data [buffer]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_insn_data (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
if (obj->method == RECORD_METHOD_BTRACE)
|
||||||
|
return recpy_bt_insn_data (self, closure);
|
||||||
|
|
||||||
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.decoded [str]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_insn_decoded (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
if (obj->method == RECORD_METHOD_BTRACE)
|
||||||
|
return recpy_bt_insn_decoded (self, closure);
|
||||||
|
|
||||||
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.size [int]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_insn_size (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
if (obj->method == RECORD_METHOD_BTRACE)
|
||||||
|
return recpy_bt_insn_size (self, closure);
|
||||||
|
|
||||||
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.is_speculative [bool]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_insn_is_speculative (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
if (obj->method == RECORD_METHOD_BTRACE)
|
||||||
|
return recpy_bt_insn_is_speculative (self, closure);
|
||||||
|
|
||||||
|
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.number [int]. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_element_number (PyObject *self, void* closure)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
return PyInt_FromSsize_t (obj->number);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of RecordInstruction.__hash__ [int]. */
|
||||||
|
static Py_hash_t
|
||||||
|
recpy_element_hash (PyObject *self)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||||
|
|
||||||
|
return obj->number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of operator == and != of RecordInstruction. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
recpy_element_richcompare (PyObject *self, PyObject *other, int op)
|
||||||
|
{
|
||||||
|
const recpy_element_object * const obj1 = (recpy_element_object *) self;
|
||||||
|
const recpy_element_object * const obj2 = (recpy_element_object *) other;
|
||||||
|
|
||||||
|
if (Py_TYPE (self) != Py_TYPE (other))
|
||||||
|
{
|
||||||
|
Py_INCREF (Py_NotImplemented);
|
||||||
|
return Py_NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case Py_EQ:
|
||||||
|
if (ptid_equal (obj1->ptid, obj2->ptid)
|
||||||
|
&& obj1->method == obj2->method
|
||||||
|
&& obj1->number == obj2->number)
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
else
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
|
||||||
|
case Py_NE:
|
||||||
|
if (!ptid_equal (obj1->ptid, obj2->ptid)
|
||||||
|
|| obj1->method != obj2->method
|
||||||
|
|| obj1->number != obj2->number)
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
else
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_INCREF (Py_NotImplemented);
|
||||||
|
return Py_NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a new gdb.RecordGap object. */
|
/* Create a new gdb.RecordGap object. */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
@@ -236,6 +397,20 @@ the current instruction and is used for e.g. record.goto (record.end).", NULL },
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* RecordInstruction member list. */
|
||||||
|
|
||||||
|
static gdb_PyGetSetDef recpy_insn_getset[] = {
|
||||||
|
{ "number", recpy_element_number, NULL, "instruction number", NULL},
|
||||||
|
{ "sal", recpy_insn_sal, NULL, "associated symbol and line", NULL},
|
||||||
|
{ "pc", recpy_insn_pc, NULL, "instruction address", NULL},
|
||||||
|
{ "data", recpy_insn_data, NULL, "raw instruction data", NULL},
|
||||||
|
{ "decoded", recpy_insn_decoded, NULL, "decoded instruction", NULL},
|
||||||
|
{ "size", recpy_insn_size, NULL, "instruction size in byte", NULL},
|
||||||
|
{ "is_speculative", recpy_insn_is_speculative, NULL, "if the instruction was \
|
||||||
|
executed speculatively", NULL},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
/* RecordGap member list. */
|
/* RecordGap member list. */
|
||||||
|
|
||||||
static gdb_PyGetSetDef recpy_gap_getset[] = {
|
static gdb_PyGetSetDef recpy_gap_getset[] = {
|
||||||
@@ -258,6 +433,15 @@ gdbpy_initialize_record (void)
|
|||||||
recpy_record_type.tp_methods = recpy_record_methods;
|
recpy_record_type.tp_methods = recpy_record_methods;
|
||||||
recpy_record_type.tp_getset = recpy_record_getset;
|
recpy_record_type.tp_getset = recpy_record_getset;
|
||||||
|
|
||||||
|
recpy_insn_type.tp_new = PyType_GenericNew;
|
||||||
|
recpy_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||||
|
recpy_insn_type.tp_basicsize = sizeof (recpy_element_object);
|
||||||
|
recpy_insn_type.tp_name = "gdb.RecordInstruction";
|
||||||
|
recpy_insn_type.tp_doc = "GDB recorded instruction object";
|
||||||
|
recpy_insn_type.tp_getset = recpy_insn_getset;
|
||||||
|
recpy_insn_type.tp_richcompare = recpy_element_richcompare;
|
||||||
|
recpy_insn_type.tp_hash = recpy_element_hash;
|
||||||
|
|
||||||
recpy_gap_type.tp_new = PyType_GenericNew;
|
recpy_gap_type.tp_new = PyType_GenericNew;
|
||||||
recpy_gap_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
recpy_gap_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||||
recpy_gap_type.tp_basicsize = sizeof (recpy_gap_object);
|
recpy_gap_type.tp_basicsize = sizeof (recpy_gap_object);
|
||||||
@@ -266,6 +450,7 @@ gdbpy_initialize_record (void)
|
|||||||
recpy_gap_type.tp_getset = recpy_gap_getset;
|
recpy_gap_type.tp_getset = recpy_gap_getset;
|
||||||
|
|
||||||
if (PyType_Ready (&recpy_record_type) < 0
|
if (PyType_Ready (&recpy_record_type) < 0
|
||||||
|
|| PyType_Ready (&recpy_insn_type) < 0
|
||||||
|| PyType_Ready (&recpy_gap_type) < 0)
|
|| PyType_Ready (&recpy_gap_type) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "record.h"
|
#include "record.h"
|
||||||
|
|
||||||
/* Python Record object. */
|
/* Python Record object. */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
@@ -37,6 +36,30 @@ typedef struct
|
|||||||
enum record_method method;
|
enum record_method method;
|
||||||
} recpy_record_object;
|
} recpy_record_object;
|
||||||
|
|
||||||
|
/* Python recorded element object. This is generic enough to represent
|
||||||
|
recorded instructions as well as recorded function call segments, hence the
|
||||||
|
generic name. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PyObject_HEAD
|
||||||
|
|
||||||
|
/* The ptid this object refers to. */
|
||||||
|
ptid_t ptid;
|
||||||
|
|
||||||
|
/* The current recording method. */
|
||||||
|
enum record_method method;
|
||||||
|
|
||||||
|
/* Element number. */
|
||||||
|
Py_ssize_t number;
|
||||||
|
} recpy_element_object;
|
||||||
|
|
||||||
|
/* Python RecordInstruction type. */
|
||||||
|
extern PyTypeObject recpy_insn_type;
|
||||||
|
|
||||||
|
/* Create a new gdb.RecordInstruction object. */
|
||||||
|
extern PyObject *recpy_insn_new (ptid_t ptid, enum record_method method,
|
||||||
|
Py_ssize_t number);
|
||||||
|
|
||||||
/* Create a new gdb.RecordGap object. */
|
/* Create a new gdb.RecordGap object. */
|
||||||
extern PyObject *recpy_gap_new (int reason_code, const char *reason_string,
|
extern PyObject *recpy_gap_new (int reason_code, const char *reason_string,
|
||||||
Py_ssize_t number);
|
Py_ssize_t number);
|
||||||
|
|||||||
Reference in New Issue
Block a user