def mk_temp_lval(self) -> AST.ASTLval: tmpname = "temp" + str(self.new_tmp_id()) varinfo = self.get_symbol(tmpname, None, None, None, None) id = self.new_id() var = AST.ASTVariable(id, varinfo) id = self.new_id() return AST.ASTLval(id, var, AST.ASTNoOffset(-1))
def mk_field_offset( self, fieldname: str, fieldtype: "BCTyp", offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTFieldOffset: id = self.new_id() return AST.ASTFieldOffset(id, fieldname, fieldtype, offset)
def get_struct_field_address(self, gaddr: int) -> AST.ASTExpr: gvname: Optional[str] = None gvinfo: Optional[AST.ASTVarInfo] = None for ((name, _), vinfo) in self.symboltable.items(): if vinfo.is_struct and vinfo.is_global: compinfo = (cast("BCTypComp", vinfo.vtype)).compinfo gvaddr = vinfo.global_address gvextent = gvaddr + compinfo.byte_size() if gaddr >= gvaddr and gaddr < gvextent: gvname = name gvinfo = vinfo break if gvname and gvinfo: compinfo = (cast("BCTypComp", gvinfo.vtype)).compinfo ioffset = gaddr - gvinfo.global_address fieldoffsets = compinfo.fieldoffsets() prevfinfo: Optional["BCFieldInfo"] = None prevoffset = -1 if ioffset == 0: id = self.new_id() var = AST.ASTVariable(id, gvinfo) lval = self.mk_lval(var, AST.ASTNoOffset(-1)) return self.mk_address_of(lval) for (foffset, finfo) in fieldoffsets: if ioffset == foffset: id = self.new_id() var = AST.ASTVariable(id, gvinfo) offset = self.mk_field_offset(finfo.fieldname, finfo.fieldtype, AST.ASTNoOffset(-1)) lval = self.mk_lval(var, offset) if finfo.fieldtype.is_array: return self.mk_lval_expr(lval) else: return self.mk_address_of(lval) raise Exception("Struct field not found for address " + hex(gaddr))
def mk_scalar_index_offset( self, index: int, offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTIndexOffset: indexexpr = self.mk_integer_constant(index) id = self.new_id() return AST.ASTIndexOffset(id, indexexpr, offset)
def mk_memref_expr( self, memexp: AST.ASTExpr, offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTExpr: memreflval = self.mk_memref_lval(memexp, offset) id = self.new_id() return AST.ASTLvalExpr(id, memreflval)
def mk_memref_lval( self, memexp: AST.ASTExpr, offset: AST.ASTOffset = AST.ASTNoOffset(-1) ) -> AST.ASTLval: memref = self.mk_memref(memexp) id = self.new_id() return AST.ASTLval(id, memref, offset)
def mk_ignored_lval(self) -> AST.ASTLval: varinfo = ignoredvariable var = AST.ASTVariable(-1, varinfo) return AST.ASTLval(-1, var, AST.ASTNoOffset(-1))
from chb.bctypes.BCFieldInfo import BCFieldInfo from chb.bctypes.BCFunArgs import BCFunArg from chb.bctypes.BCFunctionDefinition import BCFunctionDefinition from chb.bctypes.BCTyp import BCTyp, BCTypFun, BCTypComp, BCTypArray from chb.bctypes.BCVarInfo import BCVarInfo ASTSpanRecord = NewType( "ASTSpanRecord", Dict[str, Union[int, List[Dict[str, Union[str, int]]]]]) """fname -> registers/stack -> name/offset -> [span/altname -> (low, high), name].""" VariableNamesRec = NewType( "VariableNamesRec", Dict[str, Dict[str, Dict[str, List[Dict[str, Union[Tuple[str, str], str]]]]]]) ignoredvariable = AST.ASTVarInfo(-1, "ignored", None, None, None, None) nooffset = AST.ASTNoOffset(-1) class VariableNames: def __init__(self, namerecords: VariableNamesRec) -> None: self._namerecords = namerecords @property def namerecords(self) -> VariableNamesRec: return self._namerecords def has_register_variable(self, fname: str, v: str) -> bool: return (fname in self.namerecords and "registers" in self.namerecords[fname] and v in self.namerecords[fname]["registers"])