예제 #1
0
 def setx(self, loc, val, size=0):
     """
     high level method to set the expressions value associated
     to left-value loc (register or address). The value
     is possibly an integer or a symbolic expression instance.
     The input loc is either a register string, an integer address,
     or associated expressions' instances.
     Optionally, the size of the loc expression can be adjusted
     by the size argument.
     """
     if isinstance(loc, str):
         x = getattr(self.cpu, loc)
         size = x.size
     elif isinstance(loc, int):
         endian = self.cpu.get_data_endian()
         psz = self.cpu.PC().size
         x = self.cpu.mem(self.cpu.cst(addr, psz), size, endian=endian)
     else:
         x = loc
         size = x.size
     if isinstance(val, bytes):
         if x._is_mem:
             x.size = len(val) if size == 0 else size
             self.state._Mem_write(x.a, val)
         else:
             endian = self.cpu.get_data_endian()
             v = self.cpu.cst(
                 Bits(val[0:x.size:endian], bitorder=1).int(), x.size * 8)
             self.state[x] = v
     elif isinstance(val, int):
         self.state[x] = self.cpu.cst(val, size)
     else:
         self.state[x] = val
예제 #2
0
 def _Mem_read(self, a, l):
     try:
         res = self.__Mem.read(a, l)
     except MemoryError:  # no zone for location a;
         res = [exp(l * 8)]
     if exp._endian == -1: res.reverse()
     P = []
     cur = 0
     for p in res:
         plen = len(p)
         if isinstance(p, exp) and (p._is_def is False):
             if self.csi:
                 p = self.csi(mem(a, p.size, disp=cur))
             else:
                 p = mem(a, p.size, disp=cur)
         if isinstance(p, str):
             p = cst(Bits(p[::exp._endian], bitorder=1).int(), plen * 8)
         P.append(p)
         cur += plen
     return composer(P)
예제 #3
0
파일: mapper.py 프로젝트: zytMatrix/amoco
 def _Mem_read(self, a, l, endian=1):
     "read l bytes from memory address a and return an expression"
     try:
         res = self.__Mem.read(a, l)
     except MemoryError:  # no zone for location a;
         res = [exp(l * 8)]
     if endian == -1: res.reverse()
     P = []
     cur = 0
     for p in res:
         plen = len(p)
         if isinstance(p, exp) and (p._is_def is False):
             # p is "bottom":
             if self.csi:
                 p = self.csi(mem(a, p.size, disp=cur, endian=endian))
             else:
                 p = mem(a, p.size, disp=cur)
         if isinstance(p, bytes):
             p = cst(Bits(p[::endian], bitorder=1).int(), plen * 8)
         P.append(p)
         cur += plen
     return composer(P)
예제 #4
0
 def _Mem_read(self, a, l, endian=1):
     "read l bytes from memory address a and return an expression"
     try:
         res = self.__Mem.read(a, l)
     except MemoryError:  # no zone for location a;
         res = [exp(l * 8)]
     if endian == -1:
         res.reverse()
     P = []
     cur = 0
     for p in res:
         plen = len(p)
         if isinstance(p, bytes):
             p = cst(Bits(p[::endian], bitorder=1).int(), plen * 8)
         elif isinstance(p, exp):
             if p._is_def == 0:
                 # p is "bottom":
                 p = mem(a, p.size, disp=cur)
             elif p._is_ext and p._subrefs.get("mmio_r", None):
                 p = p.stub(self, mode="r")
         P.append(p)
         cur += plen
     return composer(P)
예제 #5
0
class mapper(object):
    assume_no_aliasing = False

    __slots__ = ['__map', '__Mem', 'conds', 'csi']

    # a mapper is inited with a list of instructions
    # provided by a disassembler
    def __init__(self, instrlist=None, csi=None):
        self.__map = generation()
        self.__map.lastw = 0
        self.__Mem = MemoryMap()
        self.conds = []
        self.csi = csi
        icache = []
        # if the __map needs to be inited before executing instructions
        # one solution is to prepend the instrlist with a function dedicated
        # to this init phase...
        for instr in instrlist or []:
            # call the instruction with this mapper:
            if not instr.misc['delayed']: instr(self)
            else: icache.append(instr)
        for instr in icache:
            instr(self)

    def __len__(self):
        return len(self.__map)

    def __str__(self):
        return '\n'.join(["%s <- %s" % x for x in self])

    def pp(self, **kargs):
        lv = [(l.pp(**kargs), v.pp(**kargs)) for (l, v) in self]
        return '\n'.join(["%s <- %s" % x for x in lv])

    def __getstate__(self):
        return (self.__map, self.csi)

    def __setstate__(self, state):
        self.__map, self.csi = state
        self.__Mem = MemoryMap()
        for loc, v in self:
            if loc._is_ptr: self._Mem_write(loc, v)

    # list antecedent locations (used in the mapping)
    def inputs(self):
        return sum(map(locations_of, self.__map.itervalues()), [])

    # list image locations (modified in the mapping)
    def outputs(self):
        L = []
        for l in sum(map(locations_of, self.__map.iterkeys()), []):
            if l._is_ptr: l = mem(l, self.__map[l].size)
            L.append(l)
        return L

    def has(self, loc):
        for l in self.__map.keys():
            if loc == l: return True
        return False

    def history(self, loc):
        return self.__map._generation__getall(loc)

    def rw(self):
        r = filter(lambda x: x._is_mem, self.inputs())
        w = filter(lambda x: x._is_mem, self.outputs())
        sr = [x.size for x in r]
        sw = [x.size for x in w]
        return (sr, sw)

    def clear(self):
        self.__map.clear()
        self.__Mem = MemoryMap()

    def memory(self):
        return self.__Mem

    def generation(self):
        return self.__map

    # compare self with mapper m:
    def __cmp__(self, m):
        d = cmp(self.__map.lastdict(), m.__map.lastdict())
        return d

    # iterate over ordered correspondances:
    def __iter__(self):
        for (loc, v) in self.__map.iteritems():
            yield (loc, v)

    # get a (plain) register value:
    def R(self, x):
        if self.csi:
            return self.__map.get(x, self.csi(x))
        else:
            return self.__map.get(x, x)

    # get a memory location value (fetch) :
    # k must be mem expressions
    def M(self, k):
        if k.a.base._is_ext: return k.a.base
        n = self.aliasing(k)
        if n > 0:
            f = lambda e: e[0]._is_ptr
            items = filter(f, self.__map.items()[0:n])
            res = mem(k.a, k.size, mods=items)
        else:
            res = self._Mem_read(k.a, k.length)
            res.sf = k.sf
        return res

    def aliasing(self, k):
        if self.assume_no_aliasing: return 0
        K = self.__map.keys()
        n = self.__map.lastw
        try:
            i = K.index(k.a)
        except ValueError:
            # k has never been written to explicitly
            # but it is maybe in a zone that was written to
            i = -1
        for l in K[i + 1:n]:
            if not l._is_ptr: continue
            if l.base == k.a.base: continue
            return n
        return 0

    # read MemoryMap and return the result as an expression:
    def _Mem_read(self, a, l):
        try:
            res = self.__Mem.read(a, l)
        except MemoryError, e:  # no zone for location a;
            res = [top(l * 8)]
        if exp._endian == -1: res.reverse()
        P = []
        cur = 0
        for p in res:
            plen = len(p)
            if isinstance(p, exp) and not p._is_def:
                if self.csi:
                    p = self.csi(mem(a, p.size, disp=cur))
                else:
                    p = mem(a, p.size, disp=cur)
            if isinstance(p, str):
                p = cst(Bits(p[::exp._endian], bitorder=1).int(), plen * 8)
            P.append(p)
            cur += plen
        return composer(P)