diff options
Diffstat (limited to 'test/analysis/modularintervals.py')
| -rw-r--r-- | test/analysis/modularintervals.py | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/test/analysis/modularintervals.py b/test/analysis/modularintervals.py new file mode 100644 index 00000000..36a29aa8 --- /dev/null +++ b/test/analysis/modularintervals.py @@ -0,0 +1,149 @@ +from random import shuffle, seed + +from miasm2.core.interval import interval +from miasm2.analysis.modularintervals import ModularIntervals +from miasm2.expression.expression import * +from miasm2.expression.simplifications import expr_simp + + +def gen_all_intervals(size): + """Return every possible interval for element of @size bit + -> 2**(2**size) (number of partition) + """ + nb_elements = 1 << size + for bvec in xrange(1 << nb_elements): + # Bit vector: if bit i is on, i is in the interval + to_ret = interval() + for i in xrange(nb_elements): + if bvec & i == i: + to_ret += [(i, i)] + yield to_ret + +def interval_elements(interv): + """Generator on element of an interval""" + for sub_range in interv: + for i in xrange(sub_range[0], sub_range[1] + 1): + yield i + +size = 4 +left, right = list(gen_all_intervals(size)), list(gen_all_intervals(size)) +right_int = range(1 << size) +mask = (1 << size) - 1 + +def test(left, right): + """Launch tests on left OP right""" + global size, mask + + for left_i in left: + left_i = ModularIntervals(size, left_i) + left_values = list(interval_elements(left_i)) + + # Check operations without other arguments + ## Check NEG + result = - left_i + for x in left_values: + rez = (- x) & mask + assert rez in result + + # Check operations on intervals + for right_i in right: + right_i = ModularIntervals(size, right_i) + right_values = list(interval_elements(right_i)) + + # Check operations available only on integer + if len(right_values) == 1: + # Check mod + value = right_values[0] + # Avoid division by zero + if value != 0: + result = left_i % value + for x in left_values: + rez = (x % value) & mask + assert rez in result + + # Check ADD + result = left_i + right_i + for x in left_values: + for y in right_values: + rez = (x + y) & mask + assert rez in result + + # Check OR + result = left_i | right_i + for x in left_values: + for y in right_values: + rez = (x | y) & mask + assert rez in result + + # Check AND + result = left_i & right_i + for x in left_values: + for y in right_values: + rez = (x & y) & mask + assert rez in result + + # Check XOR + result = left_i ^ right_i + for x in left_values: + for y in right_values: + rez = (x ^ y) & mask + assert rez in result + + # Check >> + result = left_i >> right_i + for x in left_values: + for y in right_values: + rez = (x >> y) & mask + assert rez in result + + # Check << + result = left_i << right_i + for x in left_values: + for y in right_values: + rez = (x << y) & mask + assert rez in result + + # Check a>> + result = left_i.arithmetic_shift_right(right_i) + for x in left_values: + x = ExprInt(x, size) + for y in right_values: + y = ExprInt(y, size) + rez = int(expr_simp(ExprOp('a>>', x, y))) + assert rez in result + + # Check >>> + result = left_i.rotation_right(right_i) + for x in left_values: + x = ExprInt(x, size) + for y in right_values: + y = ExprInt(y, size) + rez = int(expr_simp(ExprOp('>>>', x, y))) + assert rez in result + + # Check <<< + result = left_i.rotation_left(right_i) + for x in left_values: + x = ExprInt(x, size) + for y in right_values: + y = ExprInt(y, size) + rez = int(expr_simp(ExprOp('<<<', x, y))) + assert rez in result + + + +# Following tests take around 10 minutes with PyPy, but too long for Python +# interval_uniq = [interval([(i, i)]) for i in xrange(1 << size)] +# test(left, interval_uniq) +# test(interval_uniq, right) + +# Uncomment the following line for a full test over intervals, which may take +# several hours +# test(left, right) + +# Random pick for tests +seed(0) +shuffle(left) +shuffle(right) + +test(left[:100], right[:100]) |