Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two sequential branch instructions in MIPS assembly?

I am trying to reverse engineer a MIPS firmware. The firmware is big endian encoded, for a 32bit r4kec processor.

I have disassembled (using objdump) the binary to see what the assembly looks like, and everything looks like valid code, but right at the beginning of the code I see the following two instructions:

bfc00220    152a0001    bne t1, t2, 0xbfc00228
bfc00224    10000009    b   0xbfc0024c

The first instruction checks the values of the t1 and t2 registers, and jumps to an address if they are not equal. The second instruction seems to handle the fall-through case, to skip directly to a subsequent address. So far so good, or not?

To my knowledge, this is not legal. All of the available MIPS documentation that I have read state that the instruction directly following any branch/jump instruction is treated as a jump delay slot, whose instruction is always (except for the branch-likely class of instructions) executed before the actual jump is performed.

The key problem here is that another branch/jump is not allowed in the jump delay slot, and this will leave the processor in an undefined state.

So what I am to make of this code? I don't believe that this is handcrafted assembly (although it would not be too farfetched for it to be) for a cpu that handles this situation in a known deterministic fashion. I also cannot believe that a compiler will knowingly produce code like this. The other possibility is that I am using the wrong decompiler for the binary, or that I have the endianness wrong, or something else...

Can anyone explain what is going on here?

like image 782
gorby Avatar asked Feb 09 '14 23:02

gorby


People also ask

How do branch instructions work in MIPS?

Branches in MIPS assembly work by adding or subtracting the value of the immediate part of the instruction from the $pc register. So if a branch is taken, $pc is updated by the immediate value, and control of the program continues at the labeled instruction..

What is a branch instruction in assembly?

The branch instructions are used to change the sequence of instruction execution. Use branch instructions to change the sequence of instruction execution. Since all branch instructions are on word boundaries, the processor performing the branch ignores bits 30 and 31 of the generated branch target address.

What type of instruction is branch?

A branch instruction is generally classified as direct, indirect or relative. It means the instruction contains the target address, specifies where the target address is to be found (e.g., a register or memory location), or specifies the difference between the current and target addresses.


1 Answers

The "undefined behavior" means just that - that it's not specified what will happen. It may lead to CPU locking up, or it might actually execute the instruction.

See this post about some tricks with delay slots that were used in M88K:

http://www.pagetable.com/?p=313

Or the answer may be even simpler: you may be looking at data, not code. Since a raw binary has no info about code/data boundaries, objdump defaults to disassembling everything, whether it makes sense or not.

like image 172
Igor Skochinsky Avatar answered Sep 22 '22 15:09

Igor Skochinsky