Skip to content

Fix #8389 - Make MIPS branch offsets relative to the instruction address ##asm - #27332

Merged
trufae merged 1 commit into
radareorg:masterfrom
Thanatos9404:mips-branch-pc
Nov 4, 2026
Merged

trufae merged 1 commit into
radareorg:masterfrom
Thanatos9404:mips-branch-pc

Conversation

@Thanatos9404

Copy link
Copy Markdown
Contributor
  • Mark this if you consider it ready to merge
  • I've added tests (optional)
  • I wrote some lines in the book (optional)

Description

Fixes #8389. mips_i encoded a branch target as target / 4 - 1 (and 0 for targets up to 4), which is the offset only for a branch at address 0. mips_assemble already gets pc but never used it for branches. So:

  • beq t0, zero, 0x100 at 0x100 jumped forward instead of to itself;
  • branches back to an earlier label, like the loop in the issue, could not be assembled.

The offset is now (target - (pc + 4)) / 4, counted from the instruction after the branch and computed in 32 bits. A misaligned or out-of-range target now fails with the usual "Cannot assemble" error instead of being rounded.

While labels are sized, a label defined further down is still unknown, so encode reports the 4 bytes of every MIPS instruction in that pass instead of failing; otherwise every later label would be placed 4 bytes short.

The issue's loop now assembles to ffff0810feff0814, which disassembles to the same two branches back to 0.

A numeric target is now an address, like the ones pd prints and GNU as takes. Before, at any address other than 0 it acted as a distance from the branch: b 0x8 at 0x100 went to 0x108.

Testing

  • test/db/asm/mips_32 (new) has assemble lines at different addresses for beq, bne, b and bal. Four of them fail on master; the one for a branch at address 0 passes on master too.
  • test/db/tools/rasm2 covers the issue's backward loop, a forward label, and two targets that do not fit.
  • All MIPS asm, anal and esil tests pass, as do db/tools/rasm2 and db/cmd/archs. sys/lint.py --all is clean.

…tion address ##asm

The assembler encoded a branch target as if the branch were at address
0, so `beq t0, zero, 0x100` at 0x100 jumped forward and branches back to
an earlier label could not be assembled. Encode the offset from the
next instruction, and fail when it is misaligned or out of range.

While labels are sized, a label defined further down is not known yet,
so let encode report 4 bytes for a branch that cannot be resolved then.
@trufae
trufae merged commit 5aa3e2f into radareorg:master Nov 4, 2026
50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mips|mips.gnu plugin assembler error in branch labels?

2 participants