Beispiel #1
0
 def get_value(history, instr):
     if fmt == 'S+xI':
         return buildExpr(op, history.read(instr.sourceReg,
                                           basicTypes.word),
                          algebra.Literal(instr.immediate))
     elif fmt == 'S+I':
         return buildExpr(op, history.read(instr.sourceReg,
                                           basicTypes.word),
                          algebra.Literal(extend(instr.immediate)))
     elif fmt == 'f(I)':
         return algebra.Literal(op(instr.immediate))
     elif fmt == 'F+F':
         return buildExpr(op,
                          history.read(instr.fs, basicTypes.single),
                          history.read(instr.ft, basicTypes.single),
                          flop=True)
     elif fmt == '@F':
         if op == 'id':
             return history.read(instr.fs)
         else:
             return buildExpr('@', op, history.read(instr.fs))
     elif fmt == 'T<<A':
         return buildExpr(op, history.read(instr.targetReg,
                                           basicTypes.word),
                          algebra.Literal(instr.shift))
     elif fmt == 'S+T':
         return buildExpr(op, history.read(instr.sourceReg,
                                           basicTypes.word),
                          history.read(instr.targetReg, basicTypes.word))
     elif fmt == 'T<<S':
         return buildExpr(op, history.read(instr.targetReg,
                                           basicTypes.word),
                          history.read(instr.sourceReg, basicTypes.word))
     raise Error("Bad format")
Beispiel #2
0
    def subLookup(self, fmt, base, address, others=[]):
        """Recursively find data at the given address from the start of a type"""
        if isinstance(base.type, basicTypes.Array):
            spacing = self.getSize(base.type.pointedType)
            index = algebra.Literal(address // spacing)
            canIndex = True
            for o in others:
                if (isinstance(o, algebra.Expression) and o.op == '*'
                        and o.constant and o.constant.value == spacing):
                    index = buildExpr(
                        '+', index,
                        algebra.Expression.arithmeticMerge('*', o.args))
                else:
                    canIndex = False
                    break
            if canIndex:
                element = buildExpr('[', base, index)
                if basicTypes.isIndexable(base.type.pointedType):
                    return self.subLookup(fmt, element, address % spacing)
                else:
                    return element
            else:
                return buildExpr(
                    '@', fmt,
                    algebra.Expression.arithmeticMerge(
                        '+', [base, algebra.Literal(address)] + others))
        parentStruct = None
        if isinstance(base.type, basicTypes.Pointer):
            parentStruct = base.type.pointedType
        elif isinstance(base.type, str):
            parentStruct = base.type

        if parentStruct and parentStruct in self.bindings['structs']:
            members = self.bindings['structs'][parentStruct].members
            try:
                bestOffset = max(x for x in members if x <= address)
            except ValueError:  # nothing less
                pass
            else:
                newBase = buildExpr('.', base,
                                    algebra.Symbol(*members[bestOffset]))
                if address < bestOffset + self.getSize(newBase.type):
                    if basicTypes.isIndexable(newBase.type):
                        return self.subLookup(fmt, newBase,
                                              address - bestOffset, others)
                    if not others:
                        #TODO account for reading the lower short of a word, etc.
                        return newBase
        if others:
            return buildExpr(
                '@', fmt,
                algebra.arithmeticMerge(
                    '+', [base, algebra.Literal(address)] + others))
        else:
            return buildExpr(
                '.', base,
                algebra.Symbol(
                    '{}_{:#x}'.format(basicTypes.getCode(fmt), address), fmt))
Beispiel #3
0
 def foo(instr, history):
     if instr.sourceReg == Register.SP:
         return InstrResult.register, history.write(basicTypes.Stack(extend(instr.immediate)),
                                                     history.read(instr.targetReg, datatype))
     else:
         dest = history.lookupAddress(datatype, buildExpr('+',
                                                     history.read(instr.sourceReg, basicTypes.address),
                                                     algebra.Literal(extend(instr.immediate))))
         return InstrResult.write, history.read(instr.targetReg, dest.type), dest
Beispiel #4
0
 def foo(instr, history):
     if instr.sourceReg == Register.SP:
         #TODO account for more general reads (ie, just the lower bytes of a word)
         value = history.read(basicTypes.Stack(extend(instr.immediate)), datatype)
     else:
         address = buildExpr('+', history.read(instr.sourceReg, basicTypes.address),
                                         algebra.Literal(extend(instr.immediate)))
         value = history.lookupAddress(datatype, address)
     return InstrResult.register, history.write(instr.targetReg, value)
Beispiel #5
0
 def __init__(self, bindings, args=[]):
     self.states = defaultdict(list)
     self.bindings = bindings
     self.argList = []  #arguments beyond the given ones
     self.now = Context([Branch()])
     self.write(Register.R0, algebra.Literal(0))
     self.write(Register.SP, algebra.Symbol('SP'))
     self.write(Register.RA, algebra.Symbol('RA'))
     self.write(SpecialRegister.Compare, algebra.Symbol('bad_CC'))
     for reg, name, fmt in args:
         showName = name if name else VariableHistory.getName(reg)
         self.argList.append(reg)
         self.write(reg, algebra.Symbol(showName, fmt))
Beispiel #6
0
    def read(self, var, fmt=basicTypes.unknown):
        """Retrive (an appropriate representation of) the value in a register and track its usage

            var should be a register or Stack() object

            Depending on the expected format, the stored value may be altered substantially

        """
        if var == Register.R0:  #zero is zero, shouldn't remember type info
            return algebra.Literal(0)
        if var in self.states:
            uncertain = False
            for st in reversed(self.states[var]):
                if self.now.implies(
                        st.context)[0]:  # this state definitely occurred
                    if uncertain:
                        st.explicit = True
                        break
                    else:
                        if isinstance(st.value, algebra.Literal):
                            if isinstance(fmt, basicTypes.EnumType):
                                st.value = self.getEnumValue(
                                    fmt, st.value.value)
                        elif basicTypes.isIndexable(fmt):
                            st.value = self.lookupAddress(fmt, st.value)
                        elif st.value.type in [
                                basicTypes.unknown, basicTypes.bad
                        ]:
                            st.value.type = fmt
                        return st.value
                elif self.now.isCompatibleWith(st.context):
                    st.explicit = True
                    uncertain = True
            return algebra.Symbol(VariableHistory.getName(var), fmt)
        else:
            symName = VariableHistory.getName(var)
            if VariableHistory.couldBeArg(var):
                self.argList.append(var)
                symName = 'arg_' + symName
            self.states[var].append(
                VariableState(self.getName(var), algebra.Symbol(symName, fmt),
                              self.now))
            return self.states[var][-1].value