Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bin2llvmir does not generate jump for MIPS uncoditional branch instruction #88

Closed
Felis-Sapiens opened this issue Jan 14, 2018 · 2 comments

Comments

@Felis-Sapiens
Copy link

Short example:

00400000                 b       loc_400008
00400004                 nop
00400008 loc_400008:
00400008                 beq     $v0, $v0, loc_400010
0040000C                 nop
00400010 loc_400010:
00400010                 nop
00400014                 b       loc_400010
00400018                 nop

Commands to reproduce:

echo -en "\x01\x00\x00\x10\x00\x00\x00\x00\x01\x00\x42\x10\x00\x00\x00\x00\x00\x00\x00\x00\xFE\xFF\x00\x10\x00\x00\x00\x00" > ./test_b.bin
echo "{}" > ./test_b.json
retdec-config ./test_b.json --write --endian little --format raw --arch mips --bit-size 32 --file-class 32 --entry-point 0x400000 --section-vma 0x400000 --input-file ./test_b.bin
bin2llvmir -provider-init -config-path ./test_b.json -decoder -o ./test_b.backend.bc

bin2llvmir output:

; 400000
  store volatile i64 4194304, i64* @_asm_program_counter, !asm !1    ; <<< ?

; 400004
  store volatile i64 4194308, i64* @_asm_program_counter, !asm !2

; 400008
  store volatile i64 4194312, i64* @_asm_program_counter, !asm !3
  %0 = load i32, i32* @v0
  %1 = load i32, i32* @v0
  %2 = icmp eq i32 %0, %1
  call void @__pseudo_cond_branch(i1 %2, i32 4194320)                ; <<< OK

; 40000c
  store volatile i64 4194316, i64* @_asm_program_counter, !asm !4

; 400010
  store volatile i64 4194320, i64* @_asm_program_counter, !asm !5

; 400014
  store volatile i64 4194324, i64* @_asm_program_counter, !asm !6    ; <<< ?

; 400018
  store volatile i64 4194328, i64* @_asm_program_counter, !asm !7
  ret i32 0
@PeterMatula
Copy link
Collaborator

Test binary: test.zip
Test command:

retdec-decompiler.py test.bin -m raw -a mips -e little --raw-entry-point 0x400000 --raw-section-vma 0x400000

PeterMatula added a commit to avast/retdec-regression-tests that referenced this issue Feb 21, 2019
@PeterMatula
Copy link
Collaborator

The current LLVM IR output right after decoding:

dec_label_pc_400000:

; 0x400000
  store volatile i64 4194304, i64* @_asm_program_counter

; 0x400004
  store volatile i64 4194308, i64* @_asm_program_counter
  br label %dec_label_pc_400008

dec_label_pc_400008:                              ; preds = %dec_label_pc_400000

; 0x400008
  store volatile i64 4194312, i64* @_asm_program_counter
  %0 = load i32, i32* @v0
  %1 = load i32, i32* @v0
  %2 = icmp eq i32 %0, %1

; 0x40000c
  store volatile i64 4194316, i64* @_asm_program_counter
  br i1 %2, label %dec_label_pc_400010, label %dec_label_pc_400010

dec_label_pc_400010:                              ; preds = %dec_label_pc_400010, %dec_label_pc_400008, %dec_label_pc_400008

; 0x400010
  store volatile i64 4194320, i64* @_asm_program_counter

; 0x400014
  store volatile i64 4194324, i64* @_asm_program_counter

; 0x400018
  store volatile i64 4194328, i64* @_asm_program_counter
  br label %dec_label_pc_400010

Which is ok - there are all 3 branches. They are moved to the next instruction, because that is the way RetDec is currently dealing with MIPS delay slots - which in itself may not be ok, I think there is a ticket somewhere that shows that this might cause us problems, but that is not the point of this issue.
Unfortunately we are not currently able to test LLVM IR right after decoding, there is no mechanism for it. So I added a test of the LLVM IR after the bin2llvmir tool is finished (avast/retdec-regression-tests@6449f6a). It is not ideal, only two branches survive the optimization, but better than nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants