From 739ba4cb63450c7c7727f1edc2044602382155d2 Mon Sep 17 00:00:00 2001 From: angie Date: Sat, 11 Jun 2022 19:43:05 -0400 Subject: [PATCH] First draft for exposing RegistersTracker to python --- include/analysis/RabbitizerRegistersTracker.h | 17 +++ rabbitizer/rabbitizer_module.c | 1 + rabbitizer/rabbitizer_module.h | 10 ++ rabbitizer/rabbitizer_type_Instruction.c | 7 -- rabbitizer/rabbitizer_type_RegistersTracker.c | 108 ++++++++++++++++++ setup.py | 2 +- src/analysis/RabbitizerRegistersTracker.c | 2 +- 7 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 rabbitizer/rabbitizer_type_RegistersTracker.c diff --git a/include/analysis/RabbitizerRegistersTracker.h b/include/analysis/RabbitizerRegistersTracker.h index 1e9eb8b..b8d6f02 100644 --- a/include/analysis/RabbitizerRegistersTracker.h +++ b/include/analysis/RabbitizerRegistersTracker.h @@ -14,4 +14,21 @@ typedef struct RabbitizerRegistersTracker { } RabbitizerRegistersTracker; +void RabbitizerRegistersTracker_init(RabbitizerRegistersTracker *self, const RabbitizerRegistersTracker *other); +void RabbitizerRegistersTracker_destroy(RabbitizerRegistersTracker *self); + +bool RabbitizerRegistersTracker_moveRegisters(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr); +void RabbitizerRegistersTracker_overwriteRegisters(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset); +void RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, const RabbitizerInstruction *prevInstr); +bool RabbitizerRegistersTracker_getAddressIfCanSetType(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, int *dstAddress); +bool RabbitizerRegistersTracker_getJrInfo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int *dstOffset, int *dstAddress); + +// prevInstr can be NULL +void RabbitizerRegistersTracker_processLui(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, const RabbitizerInstruction *prevInstr, int instrOffset); +bool RabbitizerRegistersTracker_getLuiOffsetForConstant(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int *dstOffset); +void RabbitizerRegistersTracker_processConstant(RabbitizerRegistersTracker *self, int value, const RabbitizerInstruction *instr, int offset); +bool RabbitizerRegistersTracker_getLuiOffsetForLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, int *dstOffset, bool *dstIsGp); +void RabbitizerRegistersTracker_processLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int value, int offset); + + #endif diff --git a/rabbitizer/rabbitizer_module.c b/rabbitizer/rabbitizer_module.c index e29e7c0..e08dcde 100644 --- a/rabbitizer/rabbitizer_module.c +++ b/rabbitizer/rabbitizer_module.c @@ -40,6 +40,7 @@ static ModuleAttributes rabbitizer_module_attributes[] = { MODULE_ATTRIBUTE_ENUM(InstrCategory), MODULE_ATTRIBUTE_ENUM(InstrId), MODULE_ATTRIBUTE_TYPE(Instruction), + MODULE_ATTRIBUTE_TYPE(RegistersTracker), }; static int rabbitizer_module_attributes_Ready(void) { diff --git a/rabbitizer/rabbitizer_module.h b/rabbitizer/rabbitizer_module.h index 0777fd5..98f41f9 100644 --- a/rabbitizer/rabbitizer_module.h +++ b/rabbitizer/rabbitizer_module.h @@ -11,8 +11,17 @@ #include "enums/enums_utils.h" +#include "instructions/RabbitizerInstruction.h" + // TODO: clean up this... + +typedef struct PyRabbitizerInstruction { + PyObject_HEAD + RabbitizerInstruction instr; +} PyRabbitizerInstruction; + + extern RabbitizerEnumMetadata rabbitizer_enum_Abi_enumvalues[]; extern RabbitizerEnumMetadata rabbitizer_enum_InstrId_enumvalues[]; @@ -25,6 +34,7 @@ extern PyTypeObject rabbitizer_global_config_TypeObject; extern PyTypeObject rabbitizer_type_Enum_TypeObject; extern PyTypeObject rabbitizer_type_Instruction_TypeObject; +extern PyTypeObject rabbitizer_type_RegistersTracker_TypeObject; PyObject *rabbitizer_enum_Abi_Init(void); PyObject *rabbitizer_enum_InstrCategory_Init(void); diff --git a/rabbitizer/rabbitizer_type_Instruction.c b/rabbitizer/rabbitizer_type_Instruction.c index 02b3985..e470cf3 100644 --- a/rabbitizer/rabbitizer_type_Instruction.c +++ b/rabbitizer/rabbitizer_type_Instruction.c @@ -3,13 +3,6 @@ #include "rabbitizer_module.h" -#include "instructions/RabbitizerInstruction.h" - - -typedef struct PyRabbitizerInstruction { - PyObject_HEAD - RabbitizerInstruction instr; -} PyRabbitizerInstruction; extern PyTypeObject rabbitizer_type_Instruction_TypeObject; diff --git a/rabbitizer/rabbitizer_type_RegistersTracker.c b/rabbitizer/rabbitizer_type_RegistersTracker.c new file mode 100644 index 0000000..c8cadb3 --- /dev/null +++ b/rabbitizer/rabbitizer_type_RegistersTracker.c @@ -0,0 +1,108 @@ +/* SPDX-FileCopyrightText: © 2022 Decompollaborate */ +/* SPDX-License-Identifier: MIT */ + +#include "rabbitizer_module.h" + +#include "analysis/RabbitizerRegistersTracker.h" + + +typedef struct PyRabbitizerRegistersTracker { + PyObject_HEAD + RabbitizerRegistersTracker tracker; +} PyRabbitizerRegistersTracker; + + +static void rabbitizer_type_RegistersTracker_dealloc(PyRabbitizerRegistersTracker *self) { + RabbitizerRegistersTracker_destroy(&self->tracker); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static int rabbitizer_type_RegistersTracker_init(PyRabbitizerRegistersTracker *self, PyObject *args, PyObject *kwds) { + static char *kwlist[] = { "other", NULL }; + PyRabbitizerRegistersTracker *pyOther = NULL; + RabbitizerRegistersTracker *other = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", kwlist, &rabbitizer_type_RegistersTracker_TypeObject, &pyOther)) { + return -1; + } + + if (pyOther != NULL) { + other = &pyOther->tracker; + } + + RabbitizerRegistersTracker_init(&self->tracker, other); + + return 0; +} + + +static PyObject *rabbitizer_type_RegistersTracker_moveRegisters(PyRabbitizerRegistersTracker *self, PyObject *args, PyObject *kwds) { + static char *kwlist[] = { "instr", NULL }; + PyRabbitizerInstruction *instr; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist, &rabbitizer_type_Instruction_TypeObject, &instr)) { + return NULL; + } + + if (RabbitizerRegistersTracker_moveRegisters(&self->tracker, &instr->instr)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyObject *rabbitizer_type_RegistersTracker_overwriteRegisters(PyRabbitizerRegistersTracker *self, PyObject *args, PyObject *kwds) { + static char *kwlist[] = { "instr", "instrOffset", NULL }; + PyRabbitizerInstruction *instr; + int instrOffset; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!i", kwlist, &rabbitizer_type_Instruction_TypeObject, &instr, &instrOffset)) { + return NULL; + } + + RabbitizerRegistersTracker_overwriteRegisters(&self->tracker, &instr->instr, instrOffset); + + Py_RETURN_NONE; +} + +static PyObject *rabbitizer_type_RegistersTracker_unsetRegistersAfterFuncCall(PyRabbitizerRegistersTracker *self, PyObject *args, PyObject *kwds) { + static char *kwlist[] = { "instr", "prevInstr", NULL }; + PyRabbitizerInstruction *instr; + PyRabbitizerInstruction *prevInstr; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &rabbitizer_type_Instruction_TypeObject, &instr, &rabbitizer_type_Instruction_TypeObject, &prevInstr)) { + return NULL; + } + + RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(&self->tracker, &instr->instr, &prevInstr->instr); + + Py_RETURN_NONE; +} + + +#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_RegistersTracker_##name, METH_NOARGS, PyDoc_STR(docs) } +#define METHOD_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_RegistersTracker_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) } + +static PyMethodDef rabbitizer_type_RegistersTracker_methods[] = { + METHOD_ARGS(moveRegisters, ""), + METHOD_ARGS(overwriteRegisters, ""), + METHOD_ARGS(unsetRegistersAfterFuncCall, ""), + + { 0 }, +}; + + +PyTypeObject rabbitizer_type_RegistersTracker_TypeObject = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "rabbitizer.RegistersTracker", + .tp_doc = PyDoc_STR("RegistersTracker"), + .tp_basicsize = sizeof(PyRabbitizerRegistersTracker), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_new = PyType_GenericNew, + .tp_init = (initproc) rabbitizer_type_RegistersTracker_init, + .tp_dealloc = (destructor) rabbitizer_type_RegistersTracker_dealloc, + // .tp_repr = (reprfunc) rabbitizer_type_RegistersTracker_repr, + // .tp_str = (reprfunc) rabbitizer_type_RegistersTracker_str, + .tp_methods = rabbitizer_type_RegistersTracker_methods, + // .tp_getset = rabbitizer_type_RegistersTracker_getsetters, +}; diff --git a/setup.py b/setup.py index 30317f6..0b09220 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( ext_modules=[ Extension( name="rabbitizer", - sources=["rabbitizer/rabbitizer_module.c", "rabbitizer/rabbitizer_submodule_Utils.c", "rabbitizer/rabbitizer_type_Instruction.c", "rabbitizer/rabbitizer_global_config.c", + sources=["rabbitizer/rabbitizer_module.c", "rabbitizer/rabbitizer_submodule_Utils.c", "rabbitizer/rabbitizer_type_Instruction.c", "rabbitizer/rabbitizer_global_config.c", "rabbitizer/rabbitizer_type_RegistersTracker.c", "rabbitizer/enums/rabbitizer_type_Enum.c", "rabbitizer/enums/enums_utils.c", "rabbitizer/enums/rabbitizer_enum_InstrCategory.c", "rabbitizer/enums/rabbitizer_enum_InstrId.c", "rabbitizer/enums/rabbitizer_enum_Abi.c", "src/instructions/RabbitizerInstruction/RabbitizerInstruction_Disassemble.c", "src/instructions/RabbitizerInstruction/RabbitizerInstruction_ProcessUniqueId.c", "src/instructions/RabbitizerInstruction/RabbitizerInstruction.c", "src/instructions/RabbitizerInstruction/RabbitizerInstruction_Examination.c", "src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp.c", "src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_ProcessUniqueId.c", diff --git a/src/analysis/RabbitizerRegistersTracker.c b/src/analysis/RabbitizerRegistersTracker.c index 3bb14c7..728f5b8 100644 --- a/src/analysis/RabbitizerRegistersTracker.c +++ b/src/analysis/RabbitizerRegistersTracker.c @@ -319,7 +319,7 @@ bool RabbitizerRegistersTracker_getLuiOffsetForLo(RabbitizerRegistersTracker *se void RabbitizerRegistersTracker_processLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int value, int offset) { RabbitizerTrackedRegisterState *stateDst; - if (!RabbitizerInstrDescriptor_modifiesRt(instr)) { + if (!RabbitizerInstrDescriptor_modifiesRt(instr->descriptor)) { return; }