@Override public AbstractState strengthen( AbstractState s, Iterable<AbstractState> otherStates, CFAEdge cfaEdge, Precision precision) { ValuationState state = (ValuationState) s; ValuationState strengthenedState = null; for (AbstractState t : otherStates) { // TODO: Does not work correctly if BoundedAddressTracking returns more than // one successor state. if (t instanceof BasedNumberValuation) { BasedNumberValuation exState = (BasedNumberValuation) t; for (Map.Entry<RTLVariable, BasedNumberElement> entry : exState.getVariableValuation()) { RTLVariable var = entry.getKey(); BasedNumberElement exVal = entry.getValue(); if (exVal.isTop() || exVal.isNumberTop()) continue; if (state.getVariableValue(var).isTop()) { if (strengthenedState == null) { strengthenedState = new ValuationState(state); } strengthenedState.setVariableValue( var, new IntervalElement(exVal.getRegion(), exVal.getNumber())); // logger.debug("Strengthened state " + state.getIdentifier() + // " by setting " + var + " to " + state.getValue(var)); } } } } return strengthenedState == null ? state : strengthenedState; }
/* * @see org.jakstab.analysis.ConfigurableProgramAnalysis#merge(org.jakstab.analysis.AbstractState, org.jakstab.analysis.AbstractState) */ @Override public AbstractState merge(AbstractState s1, AbstractState s2, Precision precision) { // Widen s2 towards s1. // return ((IntervalState)s2).widen((IntervalState)s1); if (s2.isTop() || s1.isBot()) return s2; if (s1.isTop()) return s1; ValuationState current = (ValuationState) s2; ValuationState towards = (ValuationState) s1; ValuationState widenedState = new ValuationState(valueFactory); // Widen variable valuations for (Iterator<Map.Entry<RTLVariable, AbstractDomainElement>> entryIt = current.variableIterator(); entryIt.hasNext(); ) { Map.Entry<RTLVariable, AbstractDomainElement> entry = entryIt.next(); RTLVariable var = entry.getKey(); IntervalElement v = (IntervalElement) entry.getValue(); widenedState.setVariableValue(var, v.widen((IntervalElement) towards.getVariableValue(var))); } // Widen memory for (EntryIterator<MemoryRegion, Long, AbstractDomainElement> entryIt = current.storeIterator(); entryIt.hasEntry(); entryIt.next()) { MemoryRegion region = entryIt.getLeftKey(); Long offset = entryIt.getRightKey(); IntervalElement v = (IntervalElement) entryIt.getValue(); int bitWidth = v.getBitWidth(); widenedState.setMemoryValue( region, offset, bitWidth, v.widen((IntervalElement) towards.getMemoryValue(region, offset, bitWidth))); } return widenedState; }