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

Support for MIPS16 ASE opcodes in MIPS32 binaries not working? #241

Closed
pastcompute opened this issue Dec 30, 2014 · 19 comments
Closed

Support for MIPS16 ASE opcodes in MIPS32 binaries not working? #241

pastcompute opened this issue Dec 30, 2014 · 19 comments

Comments

@pastcompute
Copy link

Many platforms now (e.g. RT5350) include the MIPS16e ASE which uses 16-bits per instruction for some instructions where enabled, instead of 32 (the CPU is still using in 32-bit words). OpenWRT is now turning this on by default with -mips16 option to gcc now.
To be clear, this is a MIPS ASE, the 16-bit opcodes are additional instructions alongside the existing 32-bit instructions.

(References: radareorg/radare2#1917 )

I can't work out how to turn interpretation of this extension on in capstone, or see if it is supported.

The constant CS_MODE_16 returns the following error so I am not sure if that is for something else:

capstone.CsError: Invalid mode (CS_ERR_MODE)

(Regardless if used as (Python))

md = Cs(CS_ARCH_MIPS, CS_MODE_16 | CS_MODE_BIG_ENDIAN)

or

md = Cs(CS_ARCH_MIPS, CS_MODE_32 | CS_MODE_16 | CS_MODE_BIG_ENDIAN)

Given the following code correctly disassembled by Openwrt oolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-objdump:

00400330 <main>:
  400330:       f008 64d4       save    a0-a1,32,ra,s1
  400334:       0104            addiu   s1,sp,16
  400336:       b407            lw      a0,400350 <main+0x20>
  400338:       1e00 00d8       jalx    400360 <.pic.puts>
  40033c:       6500            nop
  40033e:       6a00            li      v0,0
  400340:       651a            move    t8,v0
  400342:       6758            move    v0,t8
  400344:       651a            move    t8,v0
  400346:       6758            move    v0,t8
  400348:       65b9            move    sp,s1
  40034a:       6452            restore 16,ra,s1
  40034c:       e8a0            jrc     ra
  40034e:       6500            nop
  400350:       0040            addiu   s0,sp,256
  400352:       32b0            sll     v0,a1,4

Capstone produces:

0x400330: f00864d4 :     ~~~~UNDEFINED~~~~
0x400334: 0104b407 :     ~~~~UNDEFINED~~~~
0x400338: 1e0000d8 :    bgtz    $s0, 0x40069c
0x40033c: 65006a00 :     ~~~~UNDEFINED~~~~
0x400340: 651a6758 :     ~~~~UNDEFINED~~~~
0x400344: 651a6758 :     ~~~~UNDEFINED~~~~
0x400348: 65b96452 :     ~~~~UNDEFINED~~~~
0x40034c: e8a06500 :    swc2    $0, 0x6500($a1)
0x400350: 004032b0 :    tge     $v0, $zero, 0xca
0x400354: 65006500 :     ~~~~UNDEFINED~~~~
0x400358: 65006500 :     ~~~~UNDEFINED~~~~
0x40035c: 65006500 :     ~~~~UNDEFINED~~~~

Python used to produce this (sorry, its a bit ugly):

from capstone import *
import binascii

def to_hex(s):
#    if _python3:
#        return " ".join("0x{0:02x}".format(c) for c in s)  # <-- Python 3 is OK
#    else:
        return " ".join("0x{0:02x}".format(ord(c)) for c in s)
# CODE = "\x55\x48\x8b\x05\xb8\x13\x00\x00"

infile = open("hello16.bin")

md = Cs(CS_ARCH_MIPS, CS_MODE_32 | CS_MODE_BIG_ENDIAN)
md.detail = True

# MIPS will either be 4 bytes per instn, or pairs of 2 (MIPS16)

address = 0x00400140
j = 0
while True:
  bytes = infile.read(4)
  if len(bytes) == 0: break
  #print binascii.hexlify(bytes)
  nb = len(bytes)
  next_address = address + nb
  d = md.disasm(bytes, address)
  first_address = -1
  k = 0
  for i in d:
    if first_address == -1:
      if i.address != address:
        print "Skipped some bytes"        
      first_address = i.address
    #print "%4d %4d 0x%x: 0x%x : %2u : %2u : %s : \t%s\t%s" %(j, k, i.address, address, nb, len(i.bytes), binascii.hexlify(i.bytes), i.mnemonic, i.op_str)
    print "0x%x: %s : \t%s\t%s" %(i.address, binascii.hexlify(i.bytes), i.mnemonic, i.op_str)
    k += 1
  if first_address == -1:
    print "0x%x: %s : \t ~~~~UNDEFINED~~~~" %(address, binascii.hexlify(bytes))
  address = next_address
  j += 1

(I tested the above python program does produce correct disassembly for non-MIPS16e functions in the same program!)

@aquynh
Copy link
Collaborator

aquynh commented Dec 30, 2014

can you try again with CS_MODE_LITTLE_ENDIAN?

but anyway, support for Mips16 is still behind at the moment.
you have to wait for the next update for Mips engine, which is supposed to be in February.

thanks.

@pastcompute
Copy link
Author

I can, but I'll have to setup a LE toolchain to recompile my example. Will get back to you...

@aquynh
Copy link
Collaborator

aquynh commented Dec 30, 2014

no, i mean with the same input, you try to initialize Capstone with CS_MODE_LITTLE_ENDIAN (rather than CS_MODE_BIT_ENDIAN)

@pastcompute
Copy link
Author

The rest of the program is junk now too (but I assume you knew that!)

0x400330: f00864d4 :    ldc1    $f4, 0x8f0($v1)
0x400334: 0104b407 :     ~~~~UNDEFINED~~~~
0x400338: 1e0000d8 :    ldc2    $0, 0x1e($zero)
0x40033c: 65006a00 :     ~~~~UNDEFINED~~~~
0x400340: 651a6758 :     ~~~~UNDEFINED~~~~
0x400344: 651a6758 :     ~~~~UNDEFINED~~~~
0x400348: 65b96452 :    beql    $s3, $a0, 0x3ee8e0
0x40034c: e8a06500 :     ~~~~UNDEFINED~~~~
0x400350: 004032b0 :     ~~~~UNDEFINED~~~~
0x400354: 65006500 :     ~~~~UNDEFINED~~~~
0x400358: 65006500 :     ~~~~UNDEFINED~~~~
0x40035c: 65006500 :     ~~~~UNDEFINED~~~~

@aquynh
Copy link
Collaborator

aquynh commented Dec 30, 2014

mips16 is not in a good shape in Capstone 3.0, so this is not surprise.
so for now you have no choice, but to wait for the next version 4.0.

@nihilus
Copy link

nihilus commented Sep 22, 2015

any news on this?

@aquynh
Copy link
Collaborator

aquynh commented Sep 22, 2015

let me check again by this weekend to see if LLVM improved on this area.

@aquynh
Copy link
Collaborator

aquynh commented Sep 28, 2015

unfortunately, it seems Mips16 is still not in a good shape as the LLVM developers focus more on other modes.

@nihilus
Copy link

nihilus commented Sep 28, 2015

Like ASE or MIPS32r6?

@aquynh
Copy link
Collaborator

aquynh commented Sep 29, 2015

do you mean ASE in Mips32R6? what is the hexcode then?

@nihilus
Copy link

nihilus commented Sep 29, 2015

ASE 3-D actually... That was a trick question ;-)

@XVilka
Copy link
Contributor

XVilka commented Apr 14, 2016

Any update on this?

@nihilus
Copy link

nihilus commented Aug 1, 2016

@aquynh have you checked if the LLVM guys have fixed this yet?

@aquynh
Copy link
Collaborator

aquynh commented Aug 4, 2016

Need to double check, but last time it was not there yet.

@XVilka
Copy link
Contributor

XVilka commented Jul 12, 2017

Any news on this one?

@Maijin
Copy link

Maijin commented Sep 11, 2017

ping

@aquynh
Copy link
Collaborator

aquynh commented Sep 12, 2017 via email

@d3dave
Copy link

d3dave commented Jan 12, 2019

@aquynh any updates on this?

@aquynh
Copy link
Collaborator

aquynh commented Jan 12, 2019

we plan to fix this in v5: #1319

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

No branches or pull requests

7 participants