about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2017-01-04 14:35:41 +0100
committerAjax <commial@gmail.com>2017-01-04 17:14:55 +0100
commit67c7679c6168bf658bd0f0c7d4e388cb0bf00fc8 (patch)
tree62511b917c01b3c44fa21fc2af9c65ef9944c0e4
parent99232651632a7633968025cf5db546a451fc8d60 (diff)
downloadmiasm-67c7679c6168bf658bd0f0c7d4e388cb0bf00fc8.tar.gz
miasm-67c7679c6168bf658bd0f0c7d4e388cb0bf00fc8.zip
Force the undefined behavior of shifts to be 0
This is an arbitrary convention describing the behavior of '>>', '<<'
and 'a>>' Miasm IR operator (contrary to the usual ones)
-rw-r--r--miasm2/jitter/llvmconvert.py26
1 files changed, 20 insertions, 6 deletions
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 415df0e5..237217dc 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -682,6 +682,26 @@ class LLVMFunction():
                 self.update_cache(expr, ret)
                 return ret
 
+            if op in [">>", "<<", "a>>"]:
+                assert len(expr.args) == 2
+                # Undefined behavior must be enforced to 0
+                count = self.add_ir(expr.args[1])
+                value = self.add_ir(expr.args[0])
+                itype = LLVMType.IntType(expr.size)
+                cond_ok = self.builder.icmp_unsigned("<", count,
+                                                     itype(expr.size))
+                if op == ">>":
+                    callback = builder.lshr
+                elif op == "<<":
+                    callback = builder.shl
+                elif op == "a>>":
+                    callback = builder.ashr
+
+                ret = self.builder.select(cond_ok, callback(value, count),
+                                          itype(0))
+                self.update_cache(expr, ret)
+                return ret
+
             if len(expr.args) > 1:
 
                 if op == "*":
@@ -694,12 +714,6 @@ class LLVMFunction():
                     callback = builder.xor
                 elif op == "|":
                     callback = builder.or_
-                elif op == ">>":
-                    callback = builder.lshr
-                elif op == "<<":
-                    callback = builder.shl
-                elif op == "a>>":
-                    callback = builder.ashr
                 elif op == "%":
                     callback = builder.urem
                 elif op == "/":