diff options
| author | Ajax <commial@gmail.com> | 2017-01-04 14:35:41 +0100 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2017-01-04 17:14:55 +0100 |
| commit | 67c7679c6168bf658bd0f0c7d4e388cb0bf00fc8 (patch) | |
| tree | 62511b917c01b3c44fa21fc2af9c65ef9944c0e4 | |
| parent | 99232651632a7633968025cf5db546a451fc8d60 (diff) | |
| download | miasm-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.py | 26 |
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 == "/": |