Skip to content

Commit

Permalink
New RegistersTracker.getJrRegData method to simplify getting jr inf…
Browse files Browse the repository at this point in the history
…ormation and `RegistersTracker.processBranch` to track register usage on branches
  • Loading branch information
AngheloAlf committed Jul 19, 2024
1 parent 1e0daec commit 1c22fdc
Show file tree
Hide file tree
Showing 24 changed files with 391 additions and 9 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `RegistersTracker.getJrRegData`.
- Does what the old `RegistersTracker.getJrInfo` method does, but it returns
an actual object instead of an nullable tuple and offers extra information.
- `RegistersTracker.processBranch`.
- Allows tracking which registers has been used to decide branching.

### Deprecated

- `RegistersTracker.getJrInfo`.
- Use `RegistersTracker.getJrRegData` instead.

## [1.11.2] - 2024-07-16

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[package]
name = "rabbitizer"
# Version should be synced with include/common/RabbitizerVersion.h
version = "1.11.2"
version = "1.11.3"
edition = "2021"
authors = ["Anghelo Carvajal <[email protected]>"]
description = "MIPS instruction decoder"
Expand Down
35 changes: 35 additions & 0 deletions cplusplus/include/analysis/JrRegData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2024 Decompollaborate */
/* SPDX-License-Identifier: MIT */

#ifndef RABBITIZER_JR_REG_DATA_HPP
#define RABBITIZER_JR_REG_DATA_HPP
#pragma once

#include "analysis/RabbitizerJrRegData.h"

namespace rabbitizer {
class JrRegData {
protected:
RabbitizerJrRegData regData;

public:
JrRegData();
JrRegData(const RabbitizerJrRegData &other);

/**
* Returns a pointer to the inner RabbitizerJrRegData.
* It is recommended to not mess with it unless you know what you are doing.
*/
RabbitizerJrRegData *getCPtr();
const RabbitizerJrRegData *getCPtr() const;

bool hasInfo() const;

int offset() const;
uint32_t address() const;
bool checkedForBranching() const;
int lastBranchOffset() const;
};
}

#endif
4 changes: 4 additions & 0 deletions cplusplus/include/analysis/RegistersTracker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "analysis/RabbitizerRegistersTracker.h"

#include "analysis/LoPairingInfo.hpp"
#include "analysis/JrRegData.hpp"
#include "instructions/InstructionBase.hpp"


Expand All @@ -32,7 +33,9 @@ namespace rabbitizer {
void overwriteRegisters(const InstructionBase &instr, int instrOffset);
void unsetRegistersAfterFuncCall(const InstructionBase &instr, const InstructionBase &prevInstr);
bool getAddressIfCanSetType(const InstructionBase &instr, int instrOffset, uint32_t *dstAddress) const;
//! @deprecated: use getJrRegData instead
bool getJrInfo(const InstructionBase &instr, int *dstOffset, uint32_t *dstAddress) const;
JrRegData getJrRegData(const InstructionBase &instr) const;

void processLui(const InstructionBase &instr, int instrOffset);
void processLui(const InstructionBase &instr, int instrOffset, const InstructionBase &prevInstr);
Expand All @@ -41,6 +44,7 @@ namespace rabbitizer {
void processConstant(const InstructionBase &instr, uint32_t value, int offset);
LoPairingInfo preprocessLoAndGetInfo(const InstructionBase &instr, int instrOffset);
void processLo(const InstructionBase &instr, uint32_t value, int offset);
void processBranch(const InstructionBase &instr, int offset);
bool hasLoButNoHi(const InstructionBase &instr) const;
};
};
Expand Down
37 changes: 37 additions & 0 deletions cplusplus/src/analysis/JrRegData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* SPDX-FileCopyrightText: © 2024 Decompollaborate */
/* SPDX-License-Identifier: MIT */

#include "analysis/JrRegData.hpp"

using namespace rabbitizer;

JrRegData::JrRegData() {
RabbitizerJrRegData_init(&this->regData);
}
JrRegData::JrRegData(const RabbitizerJrRegData &other) {
RabbitizerJrRegData_copy(&this->regData, &other);
}

RabbitizerJrRegData *JrRegData::getCPtr() {
return &this->regData;
}
const RabbitizerJrRegData *JrRegData::getCPtr() const {
return &this->regData;
}

bool JrRegData::hasInfo() const {
return this->regData.hasInfo;
}

int JrRegData::offset() const {
return this->regData.offset;
}
uint32_t JrRegData::address() const {
return this->regData.address;
}
bool JrRegData::checkedForBranching() const {
return this->regData.checkedForBranching;
}
int JrRegData::lastBranchOffset() const {
return this->regData.lastBranchOffset;
}
6 changes: 6 additions & 0 deletions cplusplus/src/analysis/RegistersTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ bool RegistersTracker::getAddressIfCanSetType(const InstructionBase &instr, int
bool RegistersTracker::getJrInfo(const InstructionBase &instr, int *dstOffset, uint32_t *dstAddress) const {
return RabbitizerRegistersTracker_getJrInfo(&this->tracker, instr.getCPtr(), dstOffset, dstAddress);
}
JrRegData RegistersTracker::getJrRegData(const InstructionBase &instr) const {
return JrRegData(RabbitizerRegistersTracker_getJrRegData(&this->tracker, instr.getCPtr()));
}

void RegistersTracker::processLui(const InstructionBase &instr, int instrOffset) {
RabbitizerRegistersTracker_processLui(&this->tracker, instr.getCPtr(), instrOffset, NULL);
Expand All @@ -60,6 +63,9 @@ LoPairingInfo RegistersTracker::preprocessLoAndGetInfo(const InstructionBase &in
void RegistersTracker::processLo(const InstructionBase &instr, uint32_t value, int offset) {
RabbitizerRegistersTracker_processLo(&this->tracker, instr.getCPtr(), value, offset);
}
void RegistersTracker::processBranch(const InstructionBase &instr, int offset) {
RabbitizerRegistersTracker_processBranch(&this->tracker, instr.getCPtr(), offset);
}
bool RegistersTracker::hasLoButNoHi(const InstructionBase &instr) const {
return RabbitizerRegistersTracker_hasLoButNoHi(&this->tracker, instr.getCPtr());
}
43 changes: 43 additions & 0 deletions include/analysis/RabbitizerJrRegData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* SPDX-FileCopyrightText: © 2024 Decompollaborate */
/* SPDX-License-Identifier: MIT */

#ifndef RABBITIZER_JR_REG_DATA_H
#define RABBITIZER_JR_REG_DATA_H
#pragma once

#include <stdbool.h>
#include <stdint.h>

#include "common/Utils.h"

#include "RabbitizerTrackedRegisterState.h"

#ifdef __cplusplus
extern "C" {
#endif


typedef struct RabbitizerJrRegData {
bool hasInfo;

int offset;
uint32_t address;
bool checkedForBranching;
int lastBranchOffset;
} RabbitizerJrRegData;


NON_NULL(1)
void RabbitizerJrRegData_init(RabbitizerJrRegData *self);
NON_NULL(1, 2)
void RabbitizerJrRegData_copy(RabbitizerJrRegData *self, const RabbitizerJrRegData *other);

NON_NULL(1, 2)
void RabbitizerJrRegData_initFromRegisterState(RabbitizerJrRegData *self, const RabbitizerTrackedRegisterState *state);


#ifdef __cplusplus
}
#endif

#endif
7 changes: 7 additions & 0 deletions include/analysis/RabbitizerRegistersTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "common/Utils.h"
#include "RabbitizerTrackedRegisterState.h"
#include "RabbitizerLoPairingInfo.h"
#include "RabbitizerJrRegData.h"
#include "instructions/RabbitizerInstruction.h"

#ifdef __cplusplus
Expand Down Expand Up @@ -36,8 +37,12 @@ NON_NULL(1, 2, 3)
void RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, const RabbitizerInstruction *prevInstr);
NON_NULL(1, 2, 4)
bool RabbitizerRegistersTracker_getAddressIfCanSetType(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, uint32_t *dstAddress);

NON_NULL(1, 2, 3, 4)
//! @deprecated: use `RabbitizerRegistersTracker_getJrRegData` instead
bool RabbitizerRegistersTracker_getJrInfo(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int *dstOffset, uint32_t *dstAddress);
NON_NULL(1, 2)
RabbitizerJrRegData RabbitizerRegistersTracker_getJrRegData(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr);

// prevInstr can be NULL
NON_NULL(1, 2)
Expand All @@ -55,6 +60,8 @@ RabbitizerLoPairingInfo RabbitizerRegistersTracker_preprocessLoAndGetInfo(Rabbit
NON_NULL(1, 2)
void RabbitizerRegistersTracker_processLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, uint32_t value, int offset);
NON_NULL(1, 2)
void RabbitizerRegistersTracker_processBranch(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset);
NON_NULL(1, 2)
bool RabbitizerRegistersTracker_hasLoButNoHi(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr);


Expand Down
7 changes: 7 additions & 0 deletions include/analysis/RabbitizerTrackedRegisterState.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ typedef struct RabbitizerTrackedRegisterState {
bool dereferenced;
int dereferenceOffset;

bool checkedForBranching;
int lastBranchOffset;

uint32_t value;
} RabbitizerTrackedRegisterState;

Expand All @@ -48,6 +51,8 @@ NON_NULL(1)
void RabbitizerTrackedRegisterState_clearGp(RabbitizerTrackedRegisterState *self);
NON_NULL(1)
void RabbitizerTrackedRegisterState_clearLo(RabbitizerTrackedRegisterState *self);
NON_NULL(1)
void RabbitizerTrackedRegisterState_clearBranch(RabbitizerTrackedRegisterState *self);

NON_NULL(1, 2)
void RabbitizerTrackedRegisterState_copyState(RabbitizerTrackedRegisterState *self, const RabbitizerTrackedRegisterState *other);
Expand All @@ -58,6 +63,8 @@ NON_NULL(1)
void RabbitizerTrackedRegisterState_setGpLoad(RabbitizerTrackedRegisterState *self, uint32_t value, int offset);
NON_NULL(1)
void RabbitizerTrackedRegisterState_setLo(RabbitizerTrackedRegisterState *self, uint32_t value, int offset);
NON_NULL(1)
void RabbitizerTrackedRegisterState_setBranching(RabbitizerTrackedRegisterState *self, int offset);

NON_NULL(1)
void RabbitizerTrackedRegisterState_deref(RabbitizerTrackedRegisterState *self, int offset);
Expand Down
2 changes: 1 addition & 1 deletion include/common/RabbitizerVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern "C" {
// Header version
#define RAB_VERSION_MAJOR 1
#define RAB_VERSION_MINOR 11
#define RAB_VERSION_PATCH 2
#define RAB_VERSION_PATCH 3

#define RAB_VERSION_STR RAB_STRINGIFY(RAB_VERSION_MAJOR) "." RAB_STRINGIFY(RAB_VERSION_MINOR) "." RAB_STRINGIFY(RAB_VERSION_PATCH)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[project]
name = "rabbitizer"
# Version should be synced with include/common/RabbitizerVersion.h
version = "1.11.2"
version = "1.11.3"
description = "MIPS instruction decoder"
# license = "MIT"
readme = "README.md"
Expand Down
14 changes: 14 additions & 0 deletions rabbitizer/JrRegData.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python3

# SPDX-FileCopyrightText: © 2022-2024 Decompollaborate
# SPDX-License-Identifier: MIT

from __future__ import annotations


class JrRegData:
def hasInfo(self) -> bool: ...
def offset(self) -> int: ...
def address(self) -> int: ...
def checkedForBranching(self) -> bool: ...
def lastBranchOffset(self) -> bool: ...
4 changes: 4 additions & 0 deletions rabbitizer/RegistersTracker.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ from __future__ import annotations

from .rabbitizer import Instruction
from .LoPairingInfo import LoPairingInfo
from .JrRegData import JrRegData


class RegistersTracker:
Expand All @@ -16,7 +17,9 @@ class RegistersTracker:
def overwriteRegisters(self, instr: Instruction, instructionOffset: int) -> None: ...
def unsetRegistersAfterFuncCall(self, instr: Instruction, prevInstr: Instruction) -> None: ...
def getAddressIfCanSetType(self, instr: Instruction, instrOffset: int) -> int|None: ...
#! deprecated: use `getJrRegData` instead
def getJrInfo(self, instr: Instruction) -> tuple[int, int]|None: ...
def getJrRegData(self, instr: Instruction) -> JrRegData: ...

def processLui(self, instr: Instruction, instrOffset: int, prevInstr: Instruction|None=None) -> None: ...
def processGpLoad(self, instr: Instruction, instrOffset: int) -> None: ...
Expand All @@ -26,4 +29,5 @@ class RegistersTracker:
"""Use `.preprocessLoAndGetInfo()` instead"""
def preprocessLoAndGetInfo(self, instr: Instruction, instrOffset: int) -> LoPairingInfo: ...
def processLo(self, instr: Instruction, value: int, offset: int) -> None: ...
def processBranch(self, instr: Instruction, instrOffset: int) -> None: ...
def hasLoButNoHi(self, instr: Instruction) -> bool: ...
1 change: 1 addition & 0 deletions rabbitizer/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ from .Config import *

from .rabbitizer import *

from .JrRegData import *
from .RegistersTracker import *
4 changes: 2 additions & 2 deletions rabbitizer/rabbitizer.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ class Instruction:
"""Check if the instruction and its register is the one usually used for
jumping with jumptables.
Specfically, this checks if the instruction is a `jr` but not its register
is not `$ra`.
Specfically, this checks if the instruction is a `jr` but its register is
not `$ra`.
Returns `False` if the instruction is not a `jr` or if it is a `jr` but
the register is `$ra`.
Expand Down
1 change: 1 addition & 0 deletions rabbitizer/rabbitizer_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ static ModuleAttributes rabbitizer_module_attributes[] = {
MODULE_ATTRIBUTE_TYPE(LoPairingInfo),
MODULE_ATTRIBUTE_TYPE(TrackedRegisterState),
MODULE_ATTRIBUTE_TYPE(RegistersTracker),
MODULE_ATTRIBUTE_TYPE(JrRegData),
};

static int rabbitizer_module_attributes_Ready(void) {
Expand Down
1 change: 1 addition & 0 deletions rabbitizer/rabbitizer_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ DECL_RAB_TYPE(Instruction, instr)
DECL_RAB_TYPE(LoPairingInfo, pairingInfo)
DECL_RAB_TYPE(TrackedRegisterState, registerState)
DECL_RAB_TYPE(RegistersTracker, tracker)
DECL_RAB_TYPE(JrRegData, jrRegData)


DECL_ENUM(Abi)
Expand Down
Loading

0 comments on commit 1c22fdc

Please sign in to comment.