Skip to content

Commit

Permalink
Merge pull request #64 from Decompollaborate/develop
Browse files Browse the repository at this point in the history
1.11.1
  • Loading branch information
AngheloAlf authored Jul 12, 2024
2 parents 34ecb56 + ee77a95 commit 4493e61
Show file tree
Hide file tree
Showing 13 changed files with 73 additions and 8 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.11.1] - 2024-07-12

### Added

- `Instruction.isFunctionCall`: Checks if the given instruciton is a function
call.
- If `config.toolchainTweaks_treatJAsUnconditionalBranch` is turned off then
`j` instructions will be considered as function calls too. Useful for tail
call optimizations.

### Fixed

- Fix registers not being cleared after a `j` tail call, which was messing with
the pointer pairing logic.

## [1.11.0] - 2024-05-22

### Added
Expand Down Expand Up @@ -618,6 +633,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- First version

[unreleased]: https://github.com/Decompollaborate/rabbitizer/compare/master...develop
[1.11.1]: https://github.com/Decompollaborate/rabbitizer/compare/1.11.0...1.11.1
[1.11.0]: https://github.com/Decompollaborate/rabbitizer/compare/1.10.0...1.11.0
[1.10.0]: https://github.com/Decompollaborate/rabbitizer/compare/1.9.5...1.10.0
[1.9.5]: https://github.com/Decompollaborate/rabbitizer/compare/1.9.4...1.9.5
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.0"
version = "1.11.1"
edition = "2021"
authors = ["Anghelo Carvajal <[email protected]>"]
description = "MIPS instruction decoder"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ If you use a `requirements.txt` file in your repository, then you can add this
library with the following line:

```txt
rabbitizer>=1.11.0,<2.0.0
rabbitizer>=1.11.1,<2.0.0
```

### Development version
Expand Down Expand Up @@ -109,7 +109,7 @@ cargo add rabbitizer
Or you can add it manually to your `Cargo.toml`:

```toml
rabbitizer = "1.11.0"
rabbitizer = "1.11.1"
```

See this crate at <https://crates.io/crates/rabbitizer>.
Expand Down
1 change: 1 addition & 0 deletions cplusplus/include/instructions/InstructionBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ namespace rabbitizer {
bool isLikelyHandwritten() const;
bool isNop() const;
bool isUnconditionalBranch() const;
bool isFunctionCall() const;

bool isReturn() const;
bool isJumptableJump() const;
Expand Down
3 changes: 3 additions & 0 deletions cplusplus/src/instructions/InstructionBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,9 @@ bool InstructionBase::isNop() const {
bool InstructionBase::isUnconditionalBranch() const {
return RabbitizerInstruction_isUnconditionalBranch(&this->instr);
}
bool InstructionBase::isFunctionCall() const {
return RabbitizerInstruction_isFunctionCall(&this->instr);
}

bool InstructionBase::isReturn() const {
return RabbitizerInstruction_isReturn(&this->instr);
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 0
#define RAB_VERSION_PATCH 1

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

Expand Down
2 changes: 2 additions & 0 deletions include/instructions/RabbitizerInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isNop(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isUnconditionalBranch(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isFunctionCall(const RabbitizerInstruction *self);

NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isReturn(const RabbitizerInstruction *self);
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.0"
version = "1.11.1"
description = "MIPS instruction decoder"
# license = "MIT"
readme = "README.md"
Expand Down
13 changes: 12 additions & 1 deletion rabbitizer/rabbitizer.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class Instruction:
def isNop(self) -> bool:
"""Check if the instruction is literally the `nop` instruction."""
def isUnconditionalBranch(self) -> bool:
"""Check if the instruction is an instruction that will always (unconditionally).
"""Check if the instruction is an instruction that will always branch unconditionally.
This is always true for the `b` instruction.
Expand All @@ -190,6 +190,17 @@ class Instruction:
can be configured with the `config.toolchainTweaks_treatJAsUnconditionalBranch`
option.
"""
def isFunctionCall(self) -> bool:
"""Check if this is an instruction used for function calls.
This is always true for "and link" instructions.
Some compilers use the `j` instruction for tail call optimizations, meaning
we may require to give special treatment to this instruction if we are
analyzing code emitted by one of those compilers, like clearing registers
after a tail call. This can be configured by turning off the
`config.toolchainTweaks_treatJAsUnconditionalBranch` option.
"""

def isReturn(self) -> bool:
"""Check if the instruction and its register is the one usually used for
Expand Down
2 changes: 2 additions & 0 deletions rabbitizer/rabbitizer_type_Instruction.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ DEF_METHOD_BOOL(isImplemented)
DEF_METHOD_BOOL(isLikelyHandwritten)
DEF_METHOD_BOOL(isNop)
DEF_METHOD_BOOL(isUnconditionalBranch)
DEF_METHOD_BOOL(isFunctionCall)

DEF_METHOD_BOOL(isReturn)
DEF_METHOD_BOOL(isJumptableJump)
Expand Down Expand Up @@ -650,6 +651,7 @@ static PyMethodDef rabbitizer_type_Instruction_methods[] = {
METHOD_NO_ARGS(isLikelyHandwritten, ""),
METHOD_NO_ARGS(isNop, ""),
METHOD_NO_ARGS(isUnconditionalBranch, ""),
METHOD_NO_ARGS(isFunctionCall, ""),

METHOD_NO_ARGS(isReturn, ""),
METHOD_NO_ARGS(isJumptableJump, ""),
Expand Down
4 changes: 4 additions & 0 deletions rust/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ extern "C" {
fn RabbitizerInstruction_isLikelyHandwritten(self_: *const Instruction) -> bool;
fn RabbitizerInstruction_isNop(self_: *const Instruction) -> bool;
fn RabbitizerInstruction_isUnconditionalBranch(self_: *const Instruction) -> bool;
fn RabbitizerInstruction_isFunctionCall(self_: *const Instruction) -> bool;
fn RabbitizerInstruction_isReturn(self_: *const Instruction) -> bool;
fn RabbitizerInstruction_isJumptableJump(self_: *const Instruction) -> bool;

Expand Down Expand Up @@ -546,6 +547,9 @@ impl Instruction {
pub fn is_unconditional_branch(&self) -> bool {
unsafe { RabbitizerInstruction_isUnconditionalBranch(self) }
}
pub fn is_function_call(&self) -> bool {
unsafe { RabbitizerInstruction_isFunctionCall(self) }
}

pub fn is_return(&self) -> bool {
unsafe { RabbitizerInstruction_isReturn(self) }
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/RabbitizerRegistersTracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void RabbitizerRegistersTracker_overwriteRegisters(RabbitizerRegistersTracker *s
void RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(RabbitizerRegistersTracker *self,
UNUSED const RabbitizerInstruction *instr,
const RabbitizerInstruction *prevInstr) {
if (!RabbitizerInstrDescriptor_doesLink(prevInstr->descriptor)) {
if (!RabbitizerInstruction_isFunctionCall(prevInstr)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ bool RabbitizerInstruction_isNop(const RabbitizerInstruction *self) {
}

/**
* Check if the instruction is an instruction that will always (unconditionally).
* Check if the instruction is an instruction that will always branch unconditionally.
*
* This is always true for the `b` instruction.
*
Expand Down Expand Up @@ -81,6 +81,32 @@ bool RabbitizerInstruction_isUnconditionalBranch(const RabbitizerInstruction *se
}
}

/**
* Check if this is an instruction used for function calls.
*
* This is always true for "and link" instructions.
*
* Some compilers use the `j` instruction for tail call optimizations, meaning
* we may require to give special treatment to this instruction if we are
* analyzing code emitted by one of those compilers, like clearing registers
* after a tail call. This can be configured by turning off the
* `config.toolchainTweaks_treatJAsUnconditionalBranch` option.
*/
bool RabbitizerInstruction_isFunctionCall(const RabbitizerInstruction *self) {
if (RabbitizerInstrDescriptor_doesLink(self->descriptor)) {
return true;
}

switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_j:
case RABBITIZER_INSTR_ID_rsp_j:
return !RabbitizerConfig_Cfg.toolchainTweaks.treatJAsUnconditionalBranch;

default:
return false;
}
}

/**
* Check if the instruction and its register is the one usually used for
* returning from a function.
Expand Down

0 comments on commit 4493e61

Please sign in to comment.