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

Incorrect MIPS 32 Intermediate Representation #26

Closed
jeffball55 opened this issue Jan 24, 2016 · 3 comments
Closed

Incorrect MIPS 32 Intermediate Representation #26

jeffball55 opened this issue Jan 24, 2016 · 3 comments

Comments

@jeffball55
Copy link

I'm attempting to obtain the Intermediate Representation for the MIPS32 architecture (little endian), but it appears that I'm getting incorrect results. For instance, for the instruction "jr $ra" doesn't set the pc register to $ra. The output is shown below. It appears to be missing a "PUT(pc) = t0" statement.

I'm running python 2.7.10 on Ubuntu 15.10 and installed pyvex using the recommended "pip install pyvex".

>>> import pyvex, archinfo
>>> pyvex.IRSB('\x08\x00\xE0\x03', 0x40000, archinfo.ArchMIPS32()).pp()
IRSB {
   t0:Ity_I32 t1:Ity_I32

   00 | IR-NoOp
   01 | IR-NoOp
   02 | IR-NoOp
   03 | IR-NoOp
   04 | IR-NoOp
   05 | IR-NoOp
   06 | IR-NoOp
   07 | IR-NoOp
   08 | IR-NoOp
   09 | IR-NoOp
   10 | IR-NoOp
   11 | IR-NoOp
   12 | IR-NoOp
   13 | IR-NoOp
   14 | IR-NoOp
   15 | ------ IMark(0x40000, 4, 0) ------
   16 | t0 = GET:I32(ra)
   17 | PUT(pc) = 0x00040004
   18 | t1 = GET:I32(pc)
   NEXT: PUT(pc) = t1; Ijk_Boring
}
@zardus
Copy link
Member

zardus commented Jan 26, 2016

That's really weird; it happens for me as well... @rhelmot, have you ever seen this issue? I have some sort of half-memory of running into something like this before, and I think you were there.

@jeffball55
Copy link
Author

A coworker of mine figured it out. This is due to the MIPS branch delay slot. When given another instruction in the branch delay slot, it acts as expected. So I'd say this isn't really a bug, but the correct behavior.

>>> import archinfo, pyvex
>>> pyvex.IRSB('\x08\x00\xE0\x03\x00\x00\x00\x00', 0x40000, archinfo.ArchMIPS32()).pp()
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I64 t4:Ity_I32

   00 | IR-NoOp
   01 | IR-NoOp
   02 | IR-NoOp
   03 | IR-NoOp
   04 | IR-NoOp
   05 | IR-NoOp
   06 | IR-NoOp
   07 | IR-NoOp
   08 | IR-NoOp
   09 | IR-NoOp
   10 | IR-NoOp
   11 | IR-NoOp
   12 | IR-NoOp
   13 | IR-NoOp
   14 | IR-NoOp
   15 | ------ IMark(0x40000, 4, 0) ------
   16 | t0 = GET:I32(ra)
   17 | PUT(pc) = 0x00040004
   18 | ------ IMark(0x40004, 4, 0) ------
   19 | PUT(pc) = t0
   20 | t4 = GET:I32(pc)
   NEXT: PUT(pc) = t4; Ijk_Ret
}

@zardus
Copy link
Member

zardus commented Feb 21, 2016

Ah, awesome! Sorry we didn't get to it; we've been pushing super hard toward a conference deadline.

It's interesting that vex doesn't except out when it's not given a jump delay slot, but I guess they never considered a situation where that would be the case. It'll be interesting if it's possible to craft a basic block that is just at the edge of Valgrind's block size limit so that the branch delay slot isn't included, trigger this bug, and detect Valgrind. There are plenty of other ways to do that, of course, but it'd be cool.

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

2 participants