Example #1
0
    def get_global_denotation(
            self, gvinfo: AST.ASTVarInfo, gaddr: str,
            offset: AST.ASTOffset) -> Tuple[AST.ASTVariable, AST.ASTOffset]:
        addr = int(gaddr, 16)
        if gvinfo.is_struct:
            compinfo = (cast("BCTypComp", gvinfo.vtype)).compinfo
            ioffset = addr - gvinfo.global_address
            fieldoffsets = compinfo.fieldoffsets()
            prevfinfo: Optional["BCFieldInfo"] = None
            prevoffset = -1
            for (foffset, finfo) in fieldoffsets:
                if ioffset == foffset:
                    id = self.new_id()
                    var = AST.ASTVariable(id, gvinfo)
                    if finfo.fieldtype.is_array:
                        offset = self.mk_scalar_index_offset(0, offset)
                    offset = self.mk_field_offset(finfo.fieldname,
                                                  finfo.fieldtype, offset)
                    return (var, offset)
                elif ioffset > foffset:
                    prevfinfo = finfo
                    prevoffset = foffset
                else:
                    if prevfinfo is None:
                        raise Exception("Offset mismatch")
                    if prevfinfo.fieldtype.is_array:
                        ftype = cast("BCTypArray", prevfinfo.fieldtype)
                        eltsize = ftype.tgttyp.byte_size()
                        aoffset = ioffset - prevoffset
                        if aoffset % eltsize == 0:
                            aindex = aoffset // eltsize
                            offset = self.mk_scalar_index_offset(
                                aindex, offset)
                        else:
                            raise Exception("Offset mismatch")
                        id = self.new_id()
                        var = AST.ASTVariable(id, gvinfo)
                        offset = self.mk_field_offset(prevfinfo.fieldname,
                                                      prevfinfo.fieldtype,
                                                      offset)
                        return (var, offset)
                    else:
                        name = "gv_" + gaddr
                        return (self.mk_global_variable(name,
                                                        globaladdress=int(
                                                            gaddr,
                                                            16)), offset)
            else:
                name = "gv_" + gaddr
                return (self.mk_global_variable(name,
                                                globaladdress=int(gaddr,
                                                                  16)), offset)

        else:
            id = self.new_id()
            var = AST.ASTVariable(id, gvinfo)
            return (var, offset)
Example #2
0
 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))
Example #3
0
 def mk_global_variable(
         self,
         name: str,
         vtype: Optional["BCTyp"] = None,
         globaladdress: Optional[int] = None) -> AST.ASTVariable:
     id = self.new_id()
     varinfo = self.get_symbol(name, vtype, None, None, globaladdress)
     return AST.ASTVariable(id, varinfo)
Example #4
0
    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))
Example #5
0
 def mk_returnval_variable(self, iaddr: str,
                           vtype: Optional["BCTyp"]) -> AST.ASTVariable:
     id = self.new_id()
     name = "rtn_" + iaddr
     altname = self.other_variable_name(name)
     if (altname and self.has_functiondef()
             and self.functiondef.has_localvar(altname)):
         localvinfo = self.functiondef.localvar(altname)
         varinfo = self.get_symbol(name, localvinfo.vtype, altname, None,
                                   None)
     else:
         varinfo = self.get_symbol(name, vtype, altname, None, None)
     return AST.ASTVariable(id, varinfo)
Example #6
0
 def mk_register_variable(
         self,
         name: str,
         vtype: Optional["BCTyp"] = None,
         parameter: Optional[int] = None) -> AST.ASTVariable:
     id = self.new_id()
     altname = self.register_variable_name(name)
     if (altname and self.has_functiondef()
             and self.functiondef.has_localvar(altname)):
         localvinfo = self.functiondef.localvar(altname)
         varinfo = self.get_symbol(name, localvinfo.vtype, altname,
                                   parameter, None)
     else:
         varinfo = self.get_symbol(name, vtype, altname, parameter, None)
     return AST.ASTVariable(id, varinfo)
Example #7
0
 def mk_stack_variable(self, offset: int) -> AST.ASTVariable:
     id = self.new_id()
     if offset < 0:
         name = "localvar_" + str(-offset)
     elif offset == 0:
         name = "localvar_0"
     else:
         name = "argvar_" + str(offset)
     altname = self.stack_variable_name(offset)
     if (altname and self.has_functiondef()
             and self.functiondef.has_localvar(altname)):
         localvinfo = self.functiondef.localvar(altname)
         varinfo = self.get_symbol(name, localvinfo.vtype, altname, None,
                                   None)
     else:
         varinfo = self.get_symbol(name, None, altname, None, None)
     return AST.ASTVariable(id, varinfo)
Example #8
0
 def mk_ignored_lval(self) -> AST.ASTLval:
     varinfo = ignoredvariable
     var = AST.ASTVariable(-1, varinfo)
     return AST.ASTLval(-1, var, AST.ASTNoOffset(-1))
Example #9
0
 def mk_variable(self, name: str) -> AST.ASTVariable:
     id = self.new_id()
     altname = self.other_variable_name(name)
     varinfo = self.get_symbol(name, None, altname, None, None)
     return AST.ASTVariable(id, varinfo)