VirtualBox

Changeset 103214 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Feb 6, 2024 2:03:41 AM (13 months ago)
Author:
vboxsync
Message:

VMM/IEMAllInst*: Liveness analysis, part 7: Flag input & modification annotations checks. bugref:10372

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r103206 r103214  
    20122012    ## @}
    20132013
    2014     def __init__(self, sSrcFile, iBeginLine, offBeginLine, oFunction, iInFunction, cchIndent = None, fDeferToCImpl = False):
     2014    def __init__(self, sSrcFile, iBeginLine, offBeginLine, oFunction, iInFunction,
     2015                 oInstruction = None, cchIndent = None, fDeferToCImpl = False):
    20152016        ## Set if IEM_MC_DEFER_TO_CIMPL_0_RET and friends, clear if IEM_MC_BEGIN/END block.
    20162017        self.fDeferToCImpl = fDeferToCImpl;
     
    20332034        ## The block number within the function.
    20342035        self.iInFunction  = iInFunction;
     2036        ## The instruction this block is associated with - can be None.
     2037        self.oInstruction = oInstruction;
     2038        ## Indentation level of the block.
    20352039        self.cchIndent    = cchIndent if cchIndent else offBeginLine;
    2036         ##< The raw lines the block is made up of.
     2040        ## The raw lines the block is made up of.
    20372041        self.asLines      = []              # type: List[str]
    20382042        ## Indicates whether the block includes macro expansion parts (kiMacroExp_None,
     
    44324436        return True;
    44334437
    4434 
    44354438    def parseTagOpHints(self, sTag, aasSections, iTagLine, iEndLine):
    44364439        """
     
    53055308        # Start a new block.
    53065309        # But don't add it to the list unless the context matches the host architecture.
    5307         self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine,
    5308                                    self.oCurFunction, self.iMcBlockInFunc, cchIndent);
     5310        self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, self.oCurFunction, self.iMcBlockInFunc,
     5311                                   oInstruction = self.aoCurInstrs[-1] if self.aoCurInstrs else None,
     5312                                   cchIndent = cchIndent);
    53095313        try:
    53105314            if (   not self.aoCppCondStack
     
    54425446
    54435447        # Start a new block.
    5444         oMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine,
    5445                            self.oCurFunction, self.iMcBlockInFunc, cchIndent, fDeferToCImpl = True);
     5448        oMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, self.oCurFunction, self.iMcBlockInFunc,
     5449                           oInstruction = self.aoCurInstrs[-1] if self.aoCurInstrs else None,
     5450                           cchIndent = cchIndent, fDeferToCImpl = True);
    54465451
    54475452        # Parse the statment.
     
    60106015                      self.cTotalMcBlocks, os.path.basename(self.sSrcFile),));
    60116016        return self.printErrors();
     6017
     6018# Some sanity checking.
     6019for sClass, dLists in SimpleParser.kdEFlagsClasses.items():
     6020    for sAttrib, asFlags in dLists.items():
     6021        for sFlag in asFlags:
     6022            assert sFlag in g_kdEFlagsMnemonics, 'sClass=%s sAttrib=%s sFlag=%s' % (sClass, sAttrib, sFlag,);
    60126023
    60136024## The parsed content of IEMAllInstCommonBodyMacros.h.
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r103181 r103214  
    15401540        raise Exception('%s:%s: error: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, ));
    15411541
     1542    def error(self, sMessage, oGenerator):
     1543        """ Emits an error via the generator object, causing it to fail. """
     1544        oGenerator.rawError('%s:%s: error: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, ));
     1545
    15421546    def warning(self, sMessage):
    15431547        """ Emits a warning. """
     
    15621566        return True;
    15631567
    1564     def analyzeCodeOperation(self, aoStmts: List[iai.McStmt], fSeenConditional = False) -> bool:
     1568    def analyzeCodeOperation(self, aoStmts: List[iai.McStmt], dEflStmts, fSeenConditional = False) -> bool:
    15651569        """
    15661570        Analyzes the code looking clues as to additional side-effects.
     
    16161620                sAnnotation = g_ksFinishAnnotation_DeferToCImpl;
    16171621
     1622            # Collect MCs working on EFLAGS.  Caller will check this.
     1623            if oStmt.sName in ('IEM_MC_FETCH_EFLAGS', 'IEM_MC_FETCH_EFLAGS_U8', 'IEM_MC_COMMIT_EFLAGS', 'IEM_MC_REF_EFLAGS',
     1624                               'IEM_MC_ARG_LOCAL_EFLAGS', ):
     1625                dEflStmts[oStmt.sName] = oStmt;
     1626            elif isinstance(oStmt, iai.McStmtCall):
     1627                if oStmt.sName in ('IEM_MC_CALL_CIMPL_0', 'IEM_MC_CALL_CIMPL_1', 'IEM_MC_CALL_CIMPL_2',
     1628                                   'IEM_MC_CALL_CIMPL_3', 'IEM_MC_CALL_CIMPL_4', 'IEM_MC_CALL_CIMPL_5',):
     1629                    if (   oStmt.asParams[0].find('IEM_CIMPL_F_RFLAGS')       >= 0
     1630                        or oStmt.asParams[0].find('IEM_CIMPL_F_STATUS_FLAGS') >= 0):
     1631                        dEflStmts[oStmt.sName] = oStmt;
     1632
    16181633            # Process branches of conditionals recursively.
    16191634            if isinstance(oStmt, iai.McStmtCond):
    1620                 oStmt.oIfBranchAnnotation = self.analyzeCodeOperation(oStmt.aoIfBranch, True);
     1635                oStmt.oIfBranchAnnotation = self.analyzeCodeOperation(oStmt.aoIfBranch, dEflStmts, True);
    16211636                if oStmt.aoElseBranch:
    1622                     oStmt.oElseBranchAnnotation = self.analyzeCodeOperation(oStmt.aoElseBranch, True);
     1637                    oStmt.oElseBranchAnnotation = self.analyzeCodeOperation(oStmt.aoElseBranch, dEflStmts, True);
    16231638
    16241639        return sAnnotation;
    16251640
    1626     def analyze(self):
     1641    def analyze(self, oGenerator):
    16271642        """
    16281643        Analyzes the code, identifying the number of parameters it requires and such.
     
    16451660        # Scan the code for IEM_CIMPL_F_ and other clues.
    16461661        self.dsCImplFlags = self.oMcBlock.dsCImplFlags.copy();
    1647         self.analyzeCodeOperation(aoStmts);
     1662        dEflStmts         = {};
     1663        self.analyzeCodeOperation(aoStmts, dEflStmts);
    16481664        if (   ('IEM_CIMPL_F_CALLS_CIMPL' in self.dsCImplFlags)
    16491665             + ('IEM_CIMPL_F_CALLS_AIMPL' in self.dsCImplFlags)
    16501666             + ('IEM_CIMPL_F_CALLS_AIMPL_WITH_FXSTATE' in self.dsCImplFlags) > 1):
    1651             self.raiseProblem('Mixing CIMPL/AIMPL/AIMPL_WITH_FXSTATE calls');
     1667            self.error('Mixing CIMPL/AIMPL/AIMPL_WITH_FXSTATE calls', oGenerator);
     1668
     1669        # Analyse EFLAGS related MCs and @opflmodify and friends.
     1670        if dEflStmts:
     1671            oInstruction = self.oMcBlock.oInstruction; # iai.Instruction
     1672            if (   oInstruction is None
     1673                or (oInstruction.asFlTest is None and oInstruction.asFlModify is None)):
     1674                sMcNames = '+'.join(dEflStmts.keys());
     1675                if len(dEflStmts) != 1 or not sMcNames.startswith('IEM_MC_CALL_CIMPL_'): # Hack for far calls
     1676                    self.error('Uses %s but has no @opflmodify, @opfltest or @opflclass with details!' % (sMcNames,), oGenerator);
     1677            elif 'IEM_MC_COMMIT_EFLAGS' in dEflStmts:
     1678                if not oInstruction.asFlModify:
     1679                    if oInstruction.sMnemonic not in [ 'not', ]:
     1680                        self.error('Uses IEM_MC_COMMIT_EFLAGS but has no flags in @opflmodify!', oGenerator);
     1681            elif (   'IEM_MC_CALL_CIMPL_0' in dEflStmts
     1682                  or 'IEM_MC_CALL_CIMPL_1' in dEflStmts
     1683                  or 'IEM_MC_CALL_CIMPL_2' in dEflStmts
     1684                  or 'IEM_MC_CALL_CIMPL_3' in dEflStmts
     1685                  or 'IEM_MC_CALL_CIMPL_4' in dEflStmts
     1686                  or 'IEM_MC_CALL_CIMPL_5' in dEflStmts ):
     1687                if not oInstruction.asFlModify:
     1688                    self.error('Uses IEM_MC_CALL_CIMPL_x or IEM_MC_DEFER_TO_CIMPL_5_RET with IEM_CIMPL_F_STATUS_FLAGS '
     1689                               'or IEM_CIMPL_F_RFLAGS but has no flags in @opflmodify!', oGenerator);
     1690            elif 'IEM_MC_REF_EFLAGS' not in dEflStmts:
     1691                if not oInstruction.asFlTest:
     1692                    if oInstruction.sMnemonic not in [ 'not', ]:
     1693                        self.error('Expected @opfltest!', oGenerator);
     1694            if oInstruction and oInstruction.asFlSet:
     1695                for sFlag in oInstruction.asFlSet:
     1696                    if sFlag not in oInstruction.asFlModify:
     1697                        self.error('"%s" in  @opflset but missing from @opflmodify (%s)!'
     1698                                   % (sFlag, ', '.join(oInstruction.asFlModify)), oGenerator);
     1699            if oInstruction and oInstruction.asFlClear:
     1700                for sFlag in oInstruction.asFlClear:
     1701                    if sFlag not in oInstruction.asFlModify:
     1702                        self.error('"%s" in  @opflclear but missing from @opflmodify (%s)!'
     1703                                   % (sFlag, ', '.join(oInstruction.asFlModify)), oGenerator);
    16521704
    16531705        # Create variations as needed.
     
    21302182        self.aoParsers       = []       # type: List[IEMAllInstPython.SimpleParser]
    21312183        self.aidxFirstFunctions = []    # type: List[int] ##< Runs parallel to aoParser giving the index of the first function.
     2184        self.cErrors         = 0;
     2185
     2186    #
     2187    # Error reporting.
     2188    #
     2189
     2190    def rawError(self, sCompleteMessage):
     2191        """ Output a raw error and increment the error counter. """
     2192        print(sCompleteMessage, file = sys.stderr);
     2193        self.cErrors += 1;
     2194        return False;
    21322195
    21332196    #
     
    21502213        dMinParamCounts = {};
    21512214        for oThreadedFunction in self.aoThreadedFuncs:
    2152             oThreadedFunction.analyze();
     2215            oThreadedFunction.analyze(self);
    21532216            for oVariation in oThreadedFunction.aoVariations:
    21542217                dRawParamCounts[len(oVariation.dParamRefs)] = dRawParamCounts.get(len(oVariation.dParamRefs), 0) + 1;
     
    22112274              % (cbMaxVarsAndArgs, cMaxVarsAndArgs, cbMaxVars, cMaxVars, cbMaxArgs, cMaxArgs,), file = sys.stderr);
    22122275
     2276        if self.cErrors > 0:
     2277            print('fatal error: %u error%s during processing. Details above.'
     2278                  % (self.cErrors, 's' if self.cErrors > 1 else '',), file = sys.stderr);
     2279            return False;
    22132280        return True;
    22142281
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette