-
Notifications
You must be signed in to change notification settings - Fork 20
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
macaw-x86-symbolic
simulates idiv
instructions incorrectly
#393
Labels
Comments
RyanGlScott
added
bug
symbolic-execution
Issues relating to macaw-symbolic and symbolic execution
arch:x86
x86 issues
labels
Jul 12, 2024
The same bug also affects unsigned division (using the // bug.c
#include <stdlib.h>
int __attribute__((noinline)) mod3(unsigned int x) {
return x % 3;
}
int __attribute__((noinline)) test_mod3(void) {
return mod3(1);
}
void _start(void) {
test_mod3();
};
|
RyanGlScott
added a commit
that referenced
this issue
Jul 12, 2024
When converting a Macaw value with the Macaw type `TupleType [x_1, ..., x_n]` to Crucible, the resulting Crucible value will have the Crucible type `StructType (EmptyCtx ::> ToCrucibleType x_n ::> ... ::> ToCrucibleType x_1)`. (See `macawListToCrucible(M)` in `Data.Macaw.Symbolic.PersistentState` for where this is implemented.) Note that the order of the tuple's fields is reversed in the process of converting it to a Crucible struct. This is a convention that one must keep in mind when dealing with Macaw tuples at the Crucible level. As it turns out, the part of `macaw-x86-symbolic` reponsible for interpreting the semantics of the `idiv` instruction (for signed quotient/remainder) and the `div` instruction (for unsigned quotient/remainder) were _not_ respecting this convention. This is because the `macaw-x86-symbolic` semantics were returning a Crucible struct consisting of `Empty :> quotient :> remainder)`, but at the Macaw level, this was interpreted as the tuple `(remainder, quotient)`, which is the opposite of the intended order. This led to subtle bugs such as those observed in #393. The solution is straightforward: have the `macaw-x86-symbolic` semantics compute `Empty :> remainder :> quotient` instead. Somewhat counterintuitive, but it does work. Fixes #393.
RyanGlScott
added a commit
that referenced
this issue
Jul 12, 2024
When converting a Macaw value with the Macaw type `TupleType [x_1, ..., x_n]` to Crucible, the resulting Crucible value will have the Crucible type `StructType (EmptyCtx ::> ToCrucibleType x_n ::> ... ::> ToCrucibleType x_1)`. (See `macawListToCrucible(M)` in `Data.Macaw.Symbolic.PersistentState` for where this is implemented.) Note that the order of the tuple's fields is reversed in the process of converting it to a Crucible struct. This is a convention that one must keep in mind when dealing with Macaw tuples at the Crucible level. As it turns out, the part of `macaw-x86-symbolic` reponsible for interpreting the semantics of the `idiv` instruction (for signed quotient/remainder) and the `div` instruction (for unsigned quotient/remainder) were _not_ respecting this convention. This is because the `macaw-x86-symbolic` semantics were returning a Crucible struct consisting of `Empty :> quotient :> remainder)`, but at the Macaw level, this was interpreted as the tuple `(remainder, quotient)`, which is the opposite of the intended order. This led to subtle bugs such as those observed in #393. The solution is straightforward: have the `macaw-x86-symbolic` semantics compute `Empty :> remainder :> quotient` instead. Somewhat counterintuitive, but it does work. Fixes #393.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Consider this C program, appropriately decorated for use in
macaw
's test suite:And consider this test harness (which was extracted from
macaw-x86-symbolic
's test suite):This test harness is set up in such a way that it will succeed if
test_mod2
returns a non-zero value. Since1 % 2
should evaluate to1
, this ought to be the case. But despite this, this test fails:The strangeness doesn't end here. Let's make a small change to this program, where instead of computing
x % 2
, we computex / 2
:This time,
test_mod2
should return zero, since1 / 2
should evaluate to0
. And yet, this test unexpectedly succeeds:Both of these issues are related, since both the
%
and/
C operators compile down toidiv
instructions. For instance, here is the x86-64 code for thex % 2
version of the program:The text was updated successfully, but these errors were encountered: