about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/disasm/callback.py3
-rw-r--r--example/ida/ctype_propagation.py1
-rw-r--r--miasm2/analysis/dse.py1
-rw-r--r--miasm2/arch/aarch64/arch.py229
-rw-r--r--miasm2/core/asmblock.py37
-rw-r--r--miasm2/ir/translators/C.py8
-rw-r--r--miasm2/jitter/Jittcc.c6
-rw-r--r--miasm2/jitter/jitcore.py2
-rw-r--r--miasm2/jitter/vm_mngr.c77
-rw-r--r--miasm2/jitter/vm_mngr.h48
-rw-r--r--test/arch/aarch64/arch.py4
-rw-r--r--test/core/asmblock.py10
12 files changed, 276 insertions, 150 deletions
diff --git a/example/disasm/callback.py b/example/disasm/callback.py
index 5aae7f6f..63987e85 100644
--- a/example/disasm/callback.py
+++ b/example/disasm/callback.py
@@ -54,9 +54,6 @@ cb_x86_funcs.append(cb_x86_callpop)
 ## Other method:
 ## mdis.dis_bloc_callback = cb_x86_callpop
 
-# Clean disassembly cache
-mdis.job_done.clear()
-
 print "=" * 40
 print "With callback:\n"
 blocks_after = mdis.dis_multiblock(0)
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py
index a48179e9..cb342213 100644
--- a/example/ida/ctype_propagation.py
+++ b/example/ida/ctype_propagation.py
@@ -57,7 +57,6 @@ Dependency Graph Settings
 
 def get_block(ir_arch, mdis, addr):
     """Get IRBlock at address @addr"""
-    mdis.job_done.clear()
     lbl = ir_arch.get_label(addr)
     if not lbl in ir_arch.blocks:
         block = mdis.dis_block(lbl.offset)
diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py
index 41872f5f..74cc87e9 100644
--- a/miasm2/analysis/dse.py
+++ b/miasm2/analysis/dse.py
@@ -297,7 +297,6 @@ class DSEEngine(object):
         else:
 
             ## Reset cache structures
-            self.mdis.job_done.clear()
             self.ir_arch.blocks.clear()# = {}
 
             ## Update current state
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py
index 7c8f22ef..09af57b1 100644
--- a/miasm2/arch/aarch64/arch.py
+++ b/miasm2/arch/aarch64/arch.py
@@ -1066,21 +1066,204 @@ class aarch64_gpreg_sftimm(reg_noarg, m_arg):
 
 
 def ror(value, amount, size):
-    return (value >> amount) | (value << (size - amount))
+    mask = (1 << size) - 1
+    return ((value >> amount) | (value << (size - amount))) & mask
 
 
 def rol(value, amount, size):
-    return (value << amount) | (value >> (size - amount))
+    mask = (1 << size) - 1
+    return ((value << amount) | (value >> (size - amount)) & mask)
 
-UINTS = {32: uint32, 64: uint64}
+# This implementation is inspired from ARM ISA v8.2
+# Exact Reference name:
+# "ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile"
 
+class ReservedValue(Exception):
+    """Reserved Value, should not happen"""
+    pass
+
+class NotEncodable(Exception):
+    """Instruction is not encodable"""
+    pass
+
+class bits(object):
+    """Stand for ARM ASL 'bits' type, ie. a bit vector"""
+
+    __slots__ = ["size", "value"]
+
+    def __init__(self, size, value):
+        """Instanciate a bitvector of size @size with value @value"""
+        self.size = size
+        if value & self.mask != value:
+            raise ValueError("Value %s is too large for %d bits",
+                             hex(value), size)
+        self.value = value
 
-def imm_to_imm_rot_form(value, size):
-    for i in xrange(0, size):
-        mod_value = int(rol(value, i, size))
-        if (mod_value + 1) & mod_value == 0:
+    def concat_left(self, other_bits):
+        """Return a new bits instance for @other_bits . self"""
+        return bits(self.size + other_bits.size,
+                    self.value | (other_bits.value << self.size))
+
+    @property
+    def mask(self):
+        return (1 << self.size) - 1
+
+    def __invert__(self):
+        return bits(self.size, self.value ^ self.mask)
+
+    def __int__(self):
+        return self.value
+
+    def __and__(self, other_bits):
+        assert other_bits.size == self.size
+        return bits(self.size, self.value & other_bits.value)
+
+    def __eq__(self, other_bits):
+        return all((self.size == other_bits.size,
+                    self.value == other_bits.value))
+
+    def __getitem__(self, info):
+        if isinstance(info, slice):
+            start = info.start if info.start else 0
+            stop = info.stop if info.stop else self.value
+            if info.step is not None:
+                raise RuntimeError("Not implemented")
+            mask = (1 << stop) - 1
+            return bits(stop - start,
+                        (self.value >> start) & mask)
+        else:
+            raise RuntimeError("Not implemented")
+
+    @property
+    def pop_count(self):
+        "Population count: number of bit set"
+        count = 0
+        value = self.value
+        while (value > 0):
+            if value & 1 == 1:
+                count += 1
+            value >>= 1
+        return count
+
+    def __str__(self):
+        return "'%s'" % "".join('1' if self.value & (1 << i) else '0'
+                                for i in reversed(xrange(self.size)))
+
+# From J1-6035
+def HighestSetBit(x):
+    for i in reversed(xrange(x.size)):
+        if x.value & (1 << i):
             return i
-    return None
+    return - 1
+
+# From J1-6037
+def Ones(N):
+    return bits(N, (1 << N) - 1)
+
+# From J1-6038
+def ROR(x, shift):
+    if shift == 0:
+        return x
+    return bits(x.size, ror(UInt(x), shift, x.size))
+
+# From J1-6038
+def Replicate(x, N):
+    assert N % x.size == 0
+    new = x
+    while new.size < N:
+        new = new.concat_left(x)
+    return new
+
+# From J1-6039
+def UInt(x):
+    return int(x)
+
+# From J1-6039
+def ZeroExtend(x, N):
+    assert N >= x.size
+    return bits(N, x.value)
+
+# From J1-5906
+def DecodeBitMasks(M, immN, imms, immr, immediate):
+    """
+    @M: 32 or 64
+    @immN: 1-bit
+    @imms: 6-bit
+    @immr: 6-bit
+    @immediate: boolean
+    """
+    len_ = HighestSetBit((~imms).concat_left(immN))
+    if len_ < 1:
+        raise ReservedValue()
+    assert M >= (1 << len_)
+
+    levels = ZeroExtend(Ones(len_), 6)
+
+    if immediate and (imms & levels) == levels:
+        raise ReservedValue()
+    S = UInt(imms & levels);
+    R = UInt(immr & levels);
+
+    esize = 1 << len_
+    welem = ZeroExtend(Ones(S + 1), esize)
+    wmask = Replicate(ROR(welem, R), M)
+
+    # For now, 'tmask' is unused:
+    #
+    # diff = S - R;
+    # d = UInt(bits(len_, diff))
+    # telem = ZeroExtend(Ones(d + 1), esize)
+    # tmask = Replicate(telem, M)
+
+    return wmask, None
+
+# EncodeBitMasks doesn't have any equivalent in ARM ASL shared functions
+# This implementation "reverses" DecodeBitMasks flow
+def EncodeBitMasks(wmask):
+    # Find replicate
+    M = wmask.size
+    for i in xrange(1, M + 1):
+        if M % i != 0:
+            continue
+        if wmask == Replicate(wmask[:i], M):
+            break
+    else:
+        raise NotEncodable
+
+    # Find ROR value: welem is only '1's
+    welem_after_ror = wmask[:i]
+    esize = welem_after_ror.size
+    S = welem_after_ror.pop_count - 1
+    welem = ZeroExtend(Ones(S + 1), esize)
+    for i in xrange(welem_after_ror.size):
+        if ROR(welem, i) == welem_after_ror:
+            break
+    else:
+        raise NotEncodable
+    R = i
+
+    # Find len value
+    for i in xrange(M):
+        if (1 << i) == esize:
+            break
+    else:
+        raise NotEncodable
+    len_ = i
+    levels = ZeroExtend(Ones(len_), 6)
+    levels = UInt(levels)
+
+    if len_ == 6:
+        # N = 1
+        immn = 1
+        imms = S
+    else:
+        # N = 0, NOT(imms) have to be considered
+        immn = 0
+        mask = (1 << ((6 - len_ - 1))) - 1
+        mask <<= (len_ + 1)
+        imms = S | mask
+    immr = R
+    return immr, imms, immn
 
 
 class aarch64_imm_nsr(aarch64_imm_sf, m_arg):
@@ -1088,9 +1271,14 @@ class aarch64_imm_nsr(aarch64_imm_sf, m_arg):
 
     def decode(self, v):
         size = 64 if self.parent.sf.value else 32
-        mask = UINTS[size]((1 << (v + 1)) - 1)
-        mask = ror(mask, self.parent.immr.value, size)
-        self.expr = m2_expr.ExprInt(mask, size)
+        bitmask, _ = DecodeBitMasks(size,
+                                    bits(1, self.parent.immn.value),
+                                    bits(6, v),
+                                    bits(6, self.parent.immr.value),
+                                    True
+        )
+        self.expr = m2_expr.ExprInt(UInt(bitmask),
+                                    size)
         return True
 
     def encode(self):
@@ -1102,20 +1290,13 @@ class aarch64_imm_nsr(aarch64_imm_sf, m_arg):
         if value == 0:
             return False
 
-        index = imm_to_imm_rot_form(value, self.expr.size)
-        if index == None:
-            return False
-        power = int(rol(value, index, self.expr.size)) + 1
-        length = None
-        for i in xrange(self.expr.size):
-            if 1 << i == power:
-                length = i
-                break
-        if length is None:
+        try:
+            immr, imms, immn = EncodeBitMasks(bits(self.expr.size, value))
+        except NotEncodable:
             return False
-        self.parent.immr.value = index
-        self.value = length - 1
-        self.parent.immn.value = 1 if self.expr.size == 64 else 0
+        self.parent.immr.value = immr
+        self.parent.immn.value = immn
+        self.value = imms
         return True
 
 
diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py
index 6cbe37a4..5b95976f 100644
--- a/miasm2/core/asmblock.py
+++ b/miasm2/core/asmblock.py
@@ -1351,12 +1351,6 @@ class disasmEngine(object):
     + callback(arch, attrib, pool_bin, cur_bloc, offsets_to_dis,
                symbol_pool)
      - dis_bloc_callback: callback after each new disassembled block
-
-    The engine also tracks already handled block, for performance and to avoid
-    infinite cycling.
-    Addresses of disassembled block is in the attribute `job_done`.
-    To force a new disassembly, the targeted offset must first be removed from
-    this structure.
     """
 
     def __init__(self, arch, attrib, bin_stream, **kwargs):
@@ -1370,7 +1364,6 @@ class disasmEngine(object):
         self.attrib = attrib
         self.bin_stream = bin_stream
         self.symbol_pool = AsmSymbolPool()
-        self.job_done = set()
 
         # Setup options
         self.dont_dis = []
@@ -1386,11 +1379,26 @@ class disasmEngine(object):
         # Override options if needed
         self.__dict__.update(kwargs)
 
-    def _dis_block(self, offset):
+    def get_job_done(self):
+        warnings.warn("""DEPRECATION WARNING: "job_done" is not needed anymore, support is dropped.""")
+        return set()
+
+    def set_job_done(self, _):
+        warnings.warn("""DEPRECATION WARNING: "job_done" is not needed anymore, support is dropped.""")
+        return
+
+
+    # Deprecated
+    job_done = property(get_job_done, set_job_done)
+
+    def _dis_block(self, offset, job_done=None):
         """Disassemble the block at offset @offset
+        @job_done: a set of already disassembled addresses
         Return the created AsmBlock and future offsets to disassemble
         """
 
+        if job_done is None:
+            job_done = set()
         lines_cpt = 0
         in_delayslot = False
         delayslot_count = self.arch.delayslot
@@ -1405,7 +1413,7 @@ class disasmEngine(object):
 
             if offset in self.dont_dis:
                 if not cur_block.lines:
-                    self.job_done.add(offset)
+                    job_done.add(offset)
                     # Block is empty -> bad block
                     cur_block = AsmBlockBad(label, errno=2)
                 else:
@@ -1426,7 +1434,7 @@ class disasmEngine(object):
                 log_asmblock.debug("lines watchdog reached at %X", int(offset))
                 break
 
-            if offset in self.job_done:
+            if offset in job_done:
                 cur_block.add_cst(offset, AsmConstraint.c_next,
                                   self.symbol_pool)
                 break
@@ -1441,7 +1449,7 @@ class disasmEngine(object):
             if instr is None:
                 log_asmblock.warning("cannot disasm at %X", int(off_i))
                 if not cur_block.lines:
-                    self.job_done.add(offset)
+                    job_done.add(offset)
                     # Block is empty -> bad block
                     cur_block = AsmBlockBad(label, errno=0)
                 else:
@@ -1469,7 +1477,7 @@ class disasmEngine(object):
                 add_next_offset = True
                 break
 
-            self.job_done.add(offset)
+            job_done.add(offset)
             log_asmblock.debug("dis at %X", int(offset))
 
             offset += instr.l
@@ -1544,6 +1552,7 @@ class disasmEngine(object):
                 merge with
         """
         log_asmblock.info("dis bloc all")
+        job_done = set()
         if blocks is None:
             blocks = AsmCFG()
         todo = [offset]
@@ -1557,9 +1566,9 @@ class disasmEngine(object):
 
             target_offset = int(todo.pop(0))
             if (target_offset is None or
-                    target_offset in self.job_done):
+                    target_offset in job_done):
                 continue
-            cur_block, nexts = self._dis_block(target_offset)
+            cur_block, nexts = self._dis_block(target_offset, job_done)
             todo += nexts
             blocks.add_node(cur_block)
 
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index 1dfdbb00..7a3080ca 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -76,10 +76,10 @@ class TranslatorC(Translator):
                     self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                     self.from_expr(expr.args[1]), size2mask(expr.args[1].size))
             elif expr.op in self.dct_shift:
-                return 'shift_%s_%.2d(%s , %s)' % (self.dct_shift[expr.op],
-                                                   expr.args[0].size,
-                                                   self.from_expr(expr.args[0]),
-                                                   self.from_expr(expr.args[1]))
+                return 'SHIFT_%s(%d, %s, %s)' % (self.dct_shift[expr.op].upper(),
+                                                 expr.args[0].size,
+                                                 self.from_expr(expr.args[0]),
+                                                 self.from_expr(expr.args[1]))
             elif expr.is_associative() or expr.op in ["%", "/"]:
                 oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                         for arg in expr.args]
diff --git a/miasm2/jitter/Jittcc.c b/miasm2/jitter/Jittcc.c
index 2a85375d..955491ad 100644
--- a/miasm2/jitter/Jittcc.c
+++ b/miasm2/jitter/Jittcc.c
@@ -88,8 +88,7 @@ PyObject* tcc_set_emul_lib_path(PyObject* self, PyObject* args)
 			include_array_count ++;
 			include_array = realloc(include_array,
 						     include_array_count * sizeof(char*));
-			if (include_array == NULL)
-			{
+			if (include_array == NULL) {
 				fprintf(stderr, "cannot realloc char* include_array\n");
 				exit(EXIT_FAILURE);
 			}
@@ -107,8 +106,7 @@ PyObject* tcc_set_emul_lib_path(PyObject* self, PyObject* args)
 			lib_array_count ++;
 			lib_array = realloc(lib_array,
 						 lib_array_count * sizeof(char*));
-			if (lib_array == NULL)
-			{
+			if (lib_array == NULL) {
 				fprintf(stderr, "cannot realloc char* lib_array\n");
 				exit(EXIT_FAILURE);
 			}
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 741760cd..9c35f829 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -47,7 +47,6 @@ class JitCore(object):
         self.log_regs = False
         self.log_newbloc = False
         self.segm_to_do = set()
-        self.job_done = set()
         self.jitcount = 0
         self.addr2obj = {}
         self.addr2objref = {}
@@ -140,7 +139,6 @@ class JitCore(object):
             addr = addr.offset
 
         # Prepare disassembler
-        self.mdis.job_done.clear()
         self.mdis.lines_wd = self.options["jit_maxline"]
         self.mdis.dis_bloc_callback = self.disasm_cb
 
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index 1114185b..59cbdf6e 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -103,6 +103,10 @@ void memory_access_list_add(struct memory_access_list * access, uint64_t start,
 		else
 			access->allocated *= 2;
 		access->array = realloc(access->array, access->allocated * sizeof(struct memory_access));
+		if (access->array == NULL) {
+			fprintf(stderr, "cannot realloc struct memory_access access->array\n");
+			exit(EXIT_FAILURE);
+		}
 	}
 	access->array[access->num].start = start;
 	access->array[access->num].stop = stop;
@@ -669,66 +673,6 @@ int is_mapped(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size)
        return 1;
 }
 
-int shift_right_arith(unsigned int size, int a, unsigned int b)
-{
-    int i32_a;
-    short i16_a;
-    char i8_a;
-    switch(size){
-	    case 8:
-		    i8_a = a;
-		    return (i8_a >> b)&0xff;
-	    case 16:
-		    i16_a = a;
-		    return (i16_a >> b)&0xffff;
-	    case 32:
-		    i32_a = a;
-		    return (i32_a >> b)&0xffffffff;
-	    default:
-		    fprintf(stderr, "inv size in shift %d\n", size);
-		    exit(0);
-    }
-}
-
-uint64_t shift_right_logic(uint64_t size,
-			   uint64_t a, uint64_t b)
-{
-    uint64_t u32_a;
-    unsigned short u16_a;
-    unsigned char u8_a;
-    switch(size){
-	    case 8:
-		    u8_a = a;
-		    return (u8_a >> b)&0xff;
-	    case 16:
-		    u16_a = a;
-		    return (u16_a >> b)&0xffff;
-	    case 32:
-		    u32_a = a;
-		    return (u32_a >> b)&0xffffffff;
-	    default:
-		    fprintf(stderr, "inv size in shift %"PRIx64"\n", size);
-		    exit(0);
-    }
-}
-
-uint64_t shift_left_logic(uint64_t size, uint64_t a, uint64_t b)
-{
-    switch(size){
-	    case 8:
-		    return (a<<b)&0xff;
-	    case 16:
-		    return (a<<b)&0xffff;
-	    case 32:
-		    return (a<<b)&0xffffffff;
-	    case 64:
-		    return (a<<b)&0xffffffffffffffff;
-	    default:
-		    fprintf(stderr, "inv size in shift %"PRIx64"\n", size);
-		    exit(0);
-    }
-}
-
 unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b)
 {
 	unsigned int mask;
@@ -1602,6 +1546,11 @@ void add_memory_page(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a)
 	vm_mngr->memory_pages_array = realloc(vm_mngr->memory_pages_array,
 					      sizeof(struct memory_page_node) *
 					      (vm_mngr->memory_pages_number+1));
+	if (vm_mngr->memory_pages_array == NULL) {
+		fprintf(stderr, "cannot realloc struct memory_page_node vm_mngr->memory_pages_array\n");
+		exit(EXIT_FAILURE);
+	}
+
 
 	memmove(&vm_mngr->memory_pages_array[i+1],
 		&vm_mngr->memory_pages_array[i],
@@ -1629,8 +1578,8 @@ char* dump(vm_mngr_t* vm_mngr)
 
 	buf_final = malloc(total_len);
 	if (buf_final == NULL) {
-		fprintf(stderr, "Error: cannot alloc\n");
-		exit(0);
+		fprintf(stderr, "Error: cannot alloc char* buf_final\n");
+		exit(EXIT_FAILURE);
 	}
 	strcpy(buf_final, intro);
 	for (i=0; i< vm_mngr->memory_pages_number; i++) {
@@ -1653,8 +1602,8 @@ char* dump(vm_mngr_t* vm_mngr)
 		total_len += length + 1 + 1;
 		buf_final = realloc(buf_final, total_len);
 		if (buf_final == NULL) {
-			fprintf(stderr, "Error: cannot alloc\n");
-			exit(0);
+			fprintf(stderr, "cannot realloc char* buf_final\n");
+			exit(EXIT_FAILURE);
 		}
 		strcat(buf_final, buf);
 	}
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index 74ad49ad..757c3b3e 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -199,10 +199,7 @@ unsigned int my_imul08(unsigned int a, unsigned int b);
 
 int is_mapped(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size);
 void vm_throw(vm_mngr_t* vm_mngr, unsigned long flags);
-int shift_right_arith(unsigned int size, int a, unsigned int b);
 
-uint64_t shift_right_logic(uint64_t size, uint64_t a, uint64_t b);
-uint64_t shift_left_logic(uint64_t size, uint64_t a, uint64_t b);
 unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b);
 unsigned int mul_hi_op(unsigned int size, unsigned int a, unsigned int b);
 unsigned int imul_lo_op_08(char a, char b);
@@ -402,32 +399,23 @@ unsigned int load_segment_limit(unsigned int d);
 unsigned int load_segment_limit_ok(unsigned int d);
 
 unsigned int load_tr_segment_selector(unsigned int d);
-#define shift_right_arith_08(a, b)\
-	((((char)(a)) >> ((int)(b)&0x1f))&0xff)
-#define shift_right_arith_16(a, b)\
-	((((short)(a)) >> ((int)(b)&0x1f))&0xffff)
-#define shift_right_arith_32(a, b)\
-	((((int)(a)) >> ((int)(b)&0x1f))&0xffffffff)
-#define shift_right_arith_64(a, b)\
-	((((int64_t)(a)) >> ((int64_t)(b)&0x3f))&0xffffffffffffffff)
-
-
-#define shift_right_logic_08(a, b)\
-	((((unsigned char)(a)) >> ((unsigned int)(b)&0x1f))&0xff)
-#define shift_right_logic_16(a, b)\
-	((((unsigned short)(a)) >> ((unsigned int)(b)&0x1f))&0xffff)
-#define shift_right_logic_32(a, b)\
-	((((unsigned int)(a)) >> ((unsigned int)(b)&0x1f))&0xffffffff)
-#define shift_right_logic_64(a, b)\
-	((((uint64_t)(a)) >> ((uint64_t)(b)&0x3f))&0xffffffffffffffff)
-
-#define shift_left_logic_08(a, b)\
-	(((a)<<((b)&0x1f))&0xff)
-#define shift_left_logic_16(a, b)\
-	(((a)<<((b)&0x1f))&0xffff)
-#define shift_left_logic_32(a, b)\
-	(((a)<<((b)&0x1f))&0xffffffff)
-#define shift_left_logic_64(a, b)\
-	(((a)<<((b)&0x3f))&0xffffffffffffffff)
+
+
+#define SHIFT_RIGHT_ARITH(size, value, shift)				\
+	((uint ## size ## _t)((((uint64_t) (shift)) > ((size) - 1))?	\
+			      (((int ## size ## _t) (value)) < 0 ? -1 : 0) : \
+			      (((int ## size ## _t) (value)) >> (shift))))
+
+#define SHIFT_RIGHT_LOGIC(size, value, shift)				\
+	((uint ## size ## _t)((((uint64_t) (shift)) > ((size) - 1))?	\
+			      0 :					\
+			      (((uint ## size ## _t) (value)) >> (shift))))
+
+#define SHIFT_LEFT_LOGIC(size, value, shift)		\
+	((uint ## size ## _t)((((uint64_t) (shift)) > ((size) - 1))?	\
+			      0 :					\
+			      (((uint ## size ## _t) (value)) << (shift))))
+
+
 
 #endif
diff --git a/test/arch/aarch64/arch.py b/test/arch/aarch64/arch.py
index ec978024..8364fcf1 100644
--- a/test/arch/aarch64/arch.py
+++ b/test/arch/aarch64/arch.py
@@ -1786,6 +1786,10 @@ reg_tests_aarch64 = [
      "E003809A"),
     ("XXXXXXXX    ADD        X0, SP, XZR UXTX 0x0",
      "E0633F8B"),
+
+    ("XXXXXXXX    ORR        X8, 0x0, 0x1000100010001",
+     "E88300B2"),
+
 ]
 
 
diff --git a/test/core/asmblock.py b/test/core/asmblock.py
index c3b220df..eb7b54b2 100644
--- a/test/core/asmblock.py
+++ b/test/core/asmblock.py
@@ -19,12 +19,16 @@ first_block = mdis.dis_block(0)
 assert len(first_block.lines) == 5
 print first_block
 
+## Test redisassemble blocks
+first_block_bis = mdis.dis_block(0)
+assert len(first_block.lines) == len(first_block_bis.lines)
+print first_block_bis
+
 ## Disassembly of several block, with cache
 blocks = mdis.dis_multiblock(0)
-assert len(blocks) == 0
+assert len(blocks) == 17
 
-## Test cache
-mdis.job_done.clear()
+## Test redisassemble blocks
 blocks = mdis.dis_multiblock(0)
 assert len(blocks) == 17
 ## Equality between assembly lines is not yet implemented