svf-tools 1.0.985 → 1.0.987
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/Graphs/ICFGNode.h +1 -1
- package/svf/include/MTA/LockAnalysis.h +9 -3
- package/svf/include/MTA/MHP.h +10 -6
- package/svf/include/MTA/TCT.h +3 -3
- package/svf/include/SABER/SaberCheckerAPI.h +4 -4
- package/svf/include/Util/SVFUtil.h +12 -49
- package/svf/include/Util/ThreadAPI.h +10 -33
- package/svf/lib/AE/Svfexe/AEDetector.cpp +11 -14
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +254 -167
- package/svf/lib/CFL/CFLAlias.cpp +1 -1
- package/svf/lib/Graphs/CallGraph.cpp +2 -2
- package/svf/lib/MTA/LockAnalysis.cpp +2 -2
- package/svf/lib/MTA/MHP.cpp +9 -7
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +2 -2
- package/svf/lib/SABER/DoubleFreeChecker.cpp +1 -1
- package/svf/lib/SABER/LeakChecker.cpp +1 -1
- package/svf/lib/Util/CallGraphBuilder.cpp +4 -4
- package/svf/lib/Util/SVFBugReport.cpp +2 -1
- package/svf/lib/Util/SVFUtil.cpp +25 -10
- package/svf/lib/Util/ThreadAPI.cpp +32 -12
- package/svf/lib/WPA/Andersen.cpp +1 -1
- package/svf/lib/WPA/Steensgaard.cpp +1 -1
- package/svf-llvm/lib/ICFGBuilder.cpp +1 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +1 -1
|
@@ -616,8 +616,7 @@ void AbstractInterpretation::handleCallSite(const ICFGNode* node)
|
|
|
616
616
|
|
|
617
617
|
bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode)
|
|
618
618
|
{
|
|
619
|
-
|
|
620
|
-
return SVFUtil::isExtCall(callfun);
|
|
619
|
+
return SVFUtil::isExtCall(callNode->getCalledFunction());
|
|
621
620
|
}
|
|
622
621
|
|
|
623
622
|
void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
|
|
@@ -629,8 +628,7 @@ void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
|
|
|
629
628
|
|
|
630
629
|
bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode *callNode)
|
|
631
630
|
{
|
|
632
|
-
|
|
633
|
-
return recursiveFuns.find(callfun) != recursiveFuns.end();
|
|
631
|
+
return recursiveFuns.find(callNode->getCalledFunction()) != recursiveFuns.end();
|
|
634
632
|
}
|
|
635
633
|
|
|
636
634
|
void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode)
|
|
@@ -654,18 +652,16 @@ void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode
|
|
|
654
652
|
|
|
655
653
|
bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode)
|
|
656
654
|
{
|
|
657
|
-
|
|
658
|
-
return funcToWTO.find(callfun) != funcToWTO.end();
|
|
655
|
+
return funcToWTO.find(callNode->getCalledFunction()) != funcToWTO.end();
|
|
659
656
|
}
|
|
660
657
|
void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode)
|
|
661
658
|
{
|
|
662
659
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
663
|
-
const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
|
|
664
660
|
callSiteStack.push_back(callNode);
|
|
665
661
|
|
|
666
662
|
abstractTrace[callNode] = as;
|
|
667
663
|
|
|
668
|
-
ICFGWTO* wto = funcToWTO[
|
|
664
|
+
ICFGWTO* wto = funcToWTO[callNode->getCalledFunction()];
|
|
669
665
|
handleWTOComponents(wto->getWTOComponents());
|
|
670
666
|
|
|
671
667
|
callSiteStack.pop_back();
|
|
@@ -819,7 +815,6 @@ void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt)
|
|
|
819
815
|
void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
|
|
820
816
|
{
|
|
821
817
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
822
|
-
const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
|
|
823
818
|
const RetICFGNode *retNode = callNode->getRetICFGNode();
|
|
824
819
|
if (retNode->getSVFStmts().size() > 0)
|
|
825
820
|
{
|
|
@@ -843,7 +838,7 @@ void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
|
|
|
843
838
|
}
|
|
844
839
|
FIFOWorkList<const SVFBasicBlock *> blkWorkList;
|
|
845
840
|
FIFOWorkList<const ICFGNode *> instWorklist;
|
|
846
|
-
for (const SVFBasicBlock * bb:
|
|
841
|
+
for (const SVFBasicBlock * bb: callNode->getCalledFunction()->getReachableBBs())
|
|
847
842
|
{
|
|
848
843
|
for (const ICFGNode* node: bb->getICFGNodeList())
|
|
849
844
|
{
|
|
@@ -1000,7 +995,6 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1000
995
|
checkpoints.erase(callNode);
|
|
1001
996
|
u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
|
|
1002
997
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1003
|
-
as[arg0].getInterval().meet_with(IntervalValue(1, 1));
|
|
1004
998
|
if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
|
|
1005
999
|
{
|
|
1006
1000
|
SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
|
|
@@ -1014,6 +1008,25 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1014
1008
|
};
|
|
1015
1009
|
func_map["svf_assert"] = sse_svf_assert;
|
|
1016
1010
|
|
|
1011
|
+
auto svf_assert_eq = [this](const CallICFGNode* callNode)
|
|
1012
|
+
{
|
|
1013
|
+
checkpoints.erase(callNode);
|
|
1014
|
+
u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
|
|
1015
|
+
u32_t arg1 = svfir->getValueNode(callNode->getArgument(1));
|
|
1016
|
+
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1017
|
+
if (as[arg0].getInterval().equals(as[arg1].getInterval()))
|
|
1018
|
+
{
|
|
1019
|
+
SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
|
|
1020
|
+
}
|
|
1021
|
+
else
|
|
1022
|
+
{
|
|
1023
|
+
SVFUtil::errs() <<"svf_assert_eq Fail. " << callNode->toString() << "\n";
|
|
1024
|
+
assert(false);
|
|
1025
|
+
}
|
|
1026
|
+
return;
|
|
1027
|
+
};
|
|
1028
|
+
func_map["svf_assert_eq"] = svf_assert_eq;
|
|
1029
|
+
|
|
1017
1030
|
auto svf_print = [&](const CallICFGNode* callNode)
|
|
1018
1031
|
{
|
|
1019
1032
|
if (callNode->arg_size() < 2) return;
|
|
@@ -1022,11 +1035,38 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1022
1035
|
std::string text = strRead(as, callNode->getArgument(1));
|
|
1023
1036
|
assert(as.inVarToValTable(num_id) && "print() should pass integer");
|
|
1024
1037
|
IntervalValue itv = as[num_id].getInterval();
|
|
1025
|
-
std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
|
|
1038
|
+
std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
|
|
1039
|
+
<< ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
|
|
1026
1040
|
return;
|
|
1027
1041
|
};
|
|
1028
1042
|
func_map["svf_print"] = svf_print;
|
|
1029
1043
|
|
|
1044
|
+
auto svf_set_value = [&](const CallICFGNode* callNode)
|
|
1045
|
+
{
|
|
1046
|
+
if (callNode->arg_size() < 2) return;
|
|
1047
|
+
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1048
|
+
AbstractValue& num = as[svfir->getValueNode(callNode->getArgument(0))];
|
|
1049
|
+
AbstractValue& lb = as[svfir->getValueNode(callNode->getArgument(1))];
|
|
1050
|
+
AbstractValue& ub = as[svfir->getValueNode(callNode->getArgument(2))];
|
|
1051
|
+
assert(lb.getInterval().is_numeral() && ub.getInterval().is_numeral());
|
|
1052
|
+
num.getInterval().set_to_top();
|
|
1053
|
+
num.getInterval().meet_with(IntervalValue(lb.getInterval().lb(), ub.getInterval().ub()));
|
|
1054
|
+
if (icfg->hasICFGNode(SVFUtil::cast<SVFInstruction>(callNode->getArgument(0))))
|
|
1055
|
+
{
|
|
1056
|
+
const ICFGNode* node = icfg->getICFGNode(SVFUtil::cast<SVFInstruction>(callNode->getArgument(0)));
|
|
1057
|
+
for (const SVFStmt* stmt: node->getSVFStmts())
|
|
1058
|
+
{
|
|
1059
|
+
if (SVFUtil::isa<LoadStmt>(stmt))
|
|
1060
|
+
{
|
|
1061
|
+
const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
|
|
1062
|
+
NodeID rhsId = load->getRHSVarID();
|
|
1063
|
+
as.storeValue(rhsId, num);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return;
|
|
1068
|
+
};
|
|
1069
|
+
func_map["set_value"] = svf_set_value;
|
|
1030
1070
|
|
|
1031
1071
|
auto sse_scanf = [&](const CallICFGNode* callNode)
|
|
1032
1072
|
{
|
|
@@ -1333,7 +1373,7 @@ std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* r
|
|
|
1333
1373
|
void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
|
|
1334
1374
|
{
|
|
1335
1375
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1336
|
-
const SVFFunction *fun =
|
|
1376
|
+
const SVFFunction *fun = call->getCalledFunction();
|
|
1337
1377
|
assert(fun && "SVFFunction* is nullptr");
|
|
1338
1378
|
ExtAPIType extType = UNCLASSIFIED;
|
|
1339
1379
|
// get type of mem api
|
|
@@ -1404,7 +1444,7 @@ void AbstractInterpretation::collectCheckPoint()
|
|
|
1404
1444
|
const ICFGNode* node = it->second;
|
|
1405
1445
|
if (const CallICFGNode *call = SVFUtil::dyn_cast<CallICFGNode>(node))
|
|
1406
1446
|
{
|
|
1407
|
-
if (const SVFFunction *fun =
|
|
1447
|
+
if (const SVFFunction *fun = call->getCalledFunction())
|
|
1408
1448
|
{
|
|
1409
1449
|
if (checkpoint_names.find(fun->getName()) !=
|
|
1410
1450
|
checkpoint_names.end())
|
|
@@ -1527,7 +1567,7 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
|
|
|
1527
1567
|
// __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
|
|
1528
1568
|
// to check it is strcat group or strncat group
|
|
1529
1569
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1530
|
-
const SVFFunction *fun =
|
|
1570
|
+
const SVFFunction *fun = call->getCalledFunction();
|
|
1531
1571
|
const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
|
|
1532
1572
|
const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
|
|
1533
1573
|
if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
|
|
@@ -1713,8 +1753,27 @@ void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi)
|
|
|
1713
1753
|
const ICFGNode* opICFGNode = phi->getOpICFGNode(i);
|
|
1714
1754
|
if (hasAbsStateFromTrace(opICFGNode))
|
|
1715
1755
|
{
|
|
1756
|
+
AbstractState tmpEs = abstractTrace[opICFGNode];
|
|
1716
1757
|
AbstractState& opAs = getAbsStateFromTrace(opICFGNode);
|
|
1717
|
-
|
|
1758
|
+
const ICFGEdge* edge = icfg->getICFGEdge(opICFGNode, icfgNode, ICFGEdge::IntraCF);
|
|
1759
|
+
// if IntraEdge, check the condition, if it is feasible, join the value
|
|
1760
|
+
// if IntraEdge but not conditional edge, join the value
|
|
1761
|
+
// if not IntraEdge, join the value
|
|
1762
|
+
if (edge)
|
|
1763
|
+
{
|
|
1764
|
+
const IntraCFGEdge* intraEdge = SVFUtil::cast<IntraCFGEdge>(edge);
|
|
1765
|
+
if (intraEdge->getCondition())
|
|
1766
|
+
{
|
|
1767
|
+
if (isBranchFeasible(intraEdge, tmpEs))
|
|
1768
|
+
rhs.join_with(opAs[curId]);
|
|
1769
|
+
}
|
|
1770
|
+
else
|
|
1771
|
+
rhs.join_with(opAs[curId]);
|
|
1772
|
+
}
|
|
1773
|
+
else
|
|
1774
|
+
{
|
|
1775
|
+
rhs.join_with(opAs[curId]);
|
|
1776
|
+
}
|
|
1718
1777
|
}
|
|
1719
1778
|
}
|
|
1720
1779
|
as[res] = rhs;
|
|
@@ -1815,181 +1874,209 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp)
|
|
|
1815
1874
|
AbstractState& as = getAbsStateFromTrace(cmp->getICFGNode());
|
|
1816
1875
|
u32_t op0 = cmp->getOpVarID(0);
|
|
1817
1876
|
u32_t op1 = cmp->getOpVarID(1);
|
|
1818
|
-
if
|
|
1819
|
-
if (
|
|
1820
|
-
u32_t res = cmp->getResID();
|
|
1821
|
-
if (as.inVarToValTable(op0) && as.inVarToValTable(op1))
|
|
1877
|
+
// if it is address
|
|
1878
|
+
if (as.inVarToAddrsTable(op0) && as.inVarToAddrsTable(op1))
|
|
1822
1879
|
{
|
|
1823
1880
|
IntervalValue resVal;
|
|
1824
|
-
|
|
1881
|
+
AddressValue addrOp0 = as[op0].getAddrs();
|
|
1882
|
+
AddressValue addrOp1 = as[op1].getAddrs();
|
|
1883
|
+
u32_t res = cmp->getResID();
|
|
1884
|
+
if (addrOp0.equals(addrOp1))
|
|
1825
1885
|
{
|
|
1826
|
-
|
|
1827
|
-
//AbstractValue
|
|
1828
|
-
auto predicate = cmp->getPredicate();
|
|
1829
|
-
switch (predicate)
|
|
1830
|
-
{
|
|
1831
|
-
case CmpStmt::ICMP_EQ:
|
|
1832
|
-
case CmpStmt::FCMP_OEQ:
|
|
1833
|
-
case CmpStmt::FCMP_UEQ:
|
|
1834
|
-
resVal = (lhs == rhs);
|
|
1835
|
-
// resVal = (lhs.getInterval() == rhs.getInterval());
|
|
1836
|
-
break;
|
|
1837
|
-
case CmpStmt::ICMP_NE:
|
|
1838
|
-
case CmpStmt::FCMP_ONE:
|
|
1839
|
-
case CmpStmt::FCMP_UNE:
|
|
1840
|
-
resVal = (lhs != rhs);
|
|
1841
|
-
break;
|
|
1842
|
-
case CmpStmt::ICMP_UGT:
|
|
1843
|
-
case CmpStmt::ICMP_SGT:
|
|
1844
|
-
case CmpStmt::FCMP_OGT:
|
|
1845
|
-
case CmpStmt::FCMP_UGT:
|
|
1846
|
-
resVal = (lhs > rhs);
|
|
1847
|
-
break;
|
|
1848
|
-
case CmpStmt::ICMP_UGE:
|
|
1849
|
-
case CmpStmt::ICMP_SGE:
|
|
1850
|
-
case CmpStmt::FCMP_OGE:
|
|
1851
|
-
case CmpStmt::FCMP_UGE:
|
|
1852
|
-
resVal = (lhs >= rhs);
|
|
1853
|
-
break;
|
|
1854
|
-
case CmpStmt::ICMP_ULT:
|
|
1855
|
-
case CmpStmt::ICMP_SLT:
|
|
1856
|
-
case CmpStmt::FCMP_OLT:
|
|
1857
|
-
case CmpStmt::FCMP_ULT:
|
|
1858
|
-
resVal = (lhs < rhs);
|
|
1859
|
-
break;
|
|
1860
|
-
case CmpStmt::ICMP_ULE:
|
|
1861
|
-
case CmpStmt::ICMP_SLE:
|
|
1862
|
-
case CmpStmt::FCMP_OLE:
|
|
1863
|
-
case CmpStmt::FCMP_ULE:
|
|
1864
|
-
resVal = (lhs <= rhs);
|
|
1865
|
-
break;
|
|
1866
|
-
case CmpStmt::FCMP_FALSE:
|
|
1867
|
-
resVal = IntervalValue(0, 0);
|
|
1868
|
-
break;
|
|
1869
|
-
case CmpStmt::FCMP_TRUE:
|
|
1870
|
-
resVal = IntervalValue(1, 1);
|
|
1871
|
-
break;
|
|
1872
|
-
default:
|
|
1873
|
-
{
|
|
1874
|
-
assert(false && "undefined compare: ");
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
as[res] = resVal;
|
|
1886
|
+
resVal = IntervalValue(1, 1);
|
|
1878
1887
|
}
|
|
1879
|
-
else if (
|
|
1888
|
+
else if (addrOp0.hasIntersect(addrOp1))
|
|
1880
1889
|
{
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1890
|
+
resVal = IntervalValue(0, 1);
|
|
1891
|
+
}
|
|
1892
|
+
else
|
|
1893
|
+
{
|
|
1894
|
+
resVal = IntervalValue(0, 0);
|
|
1895
|
+
}
|
|
1896
|
+
as[res] = resVal;
|
|
1897
|
+
}
|
|
1898
|
+
else
|
|
1899
|
+
{
|
|
1900
|
+
if (!as.inVarToValTable(op0))
|
|
1901
|
+
as[op0] = IntervalValue::top();
|
|
1902
|
+
if (!as.inVarToValTable(op1))
|
|
1903
|
+
as[op1] = IntervalValue::top();
|
|
1904
|
+
u32_t res = cmp->getResID();
|
|
1905
|
+
if (as.inVarToValTable(op0) && as.inVarToValTable(op1))
|
|
1906
|
+
{
|
|
1907
|
+
IntervalValue resVal;
|
|
1908
|
+
if (as[op0].isInterval() && as[op1].isInterval())
|
|
1888
1909
|
{
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
{
|
|
1895
|
-
resVal = IntervalValue(1, 1);
|
|
1896
|
-
}
|
|
1897
|
-
else
|
|
1910
|
+
IntervalValue &lhs = as[op0].getInterval(),
|
|
1911
|
+
&rhs = as[op1].getInterval();
|
|
1912
|
+
// AbstractValue
|
|
1913
|
+
auto predicate = cmp->getPredicate();
|
|
1914
|
+
switch (predicate)
|
|
1898
1915
|
{
|
|
1916
|
+
case CmpStmt::ICMP_EQ:
|
|
1917
|
+
case CmpStmt::FCMP_OEQ:
|
|
1918
|
+
case CmpStmt::FCMP_UEQ:
|
|
1919
|
+
resVal = (lhs == rhs);
|
|
1920
|
+
// resVal = (lhs.getInterval() == rhs.getInterval());
|
|
1921
|
+
break;
|
|
1922
|
+
case CmpStmt::ICMP_NE:
|
|
1923
|
+
case CmpStmt::FCMP_ONE:
|
|
1924
|
+
case CmpStmt::FCMP_UNE:
|
|
1925
|
+
resVal = (lhs != rhs);
|
|
1926
|
+
break;
|
|
1927
|
+
case CmpStmt::ICMP_UGT:
|
|
1928
|
+
case CmpStmt::ICMP_SGT:
|
|
1929
|
+
case CmpStmt::FCMP_OGT:
|
|
1930
|
+
case CmpStmt::FCMP_UGT:
|
|
1931
|
+
resVal = (lhs > rhs);
|
|
1932
|
+
break;
|
|
1933
|
+
case CmpStmt::ICMP_UGE:
|
|
1934
|
+
case CmpStmt::ICMP_SGE:
|
|
1935
|
+
case CmpStmt::FCMP_OGE:
|
|
1936
|
+
case CmpStmt::FCMP_UGE:
|
|
1937
|
+
resVal = (lhs >= rhs);
|
|
1938
|
+
break;
|
|
1939
|
+
case CmpStmt::ICMP_ULT:
|
|
1940
|
+
case CmpStmt::ICMP_SLT:
|
|
1941
|
+
case CmpStmt::FCMP_OLT:
|
|
1942
|
+
case CmpStmt::FCMP_ULT:
|
|
1943
|
+
resVal = (lhs < rhs);
|
|
1944
|
+
break;
|
|
1945
|
+
case CmpStmt::ICMP_ULE:
|
|
1946
|
+
case CmpStmt::ICMP_SLE:
|
|
1947
|
+
case CmpStmt::FCMP_OLE:
|
|
1948
|
+
case CmpStmt::FCMP_ULE:
|
|
1949
|
+
resVal = (lhs <= rhs);
|
|
1950
|
+
break;
|
|
1951
|
+
case CmpStmt::FCMP_FALSE:
|
|
1899
1952
|
resVal = IntervalValue(0, 0);
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
case CmpStmt::FCMP_UNE:
|
|
1906
|
-
{
|
|
1907
|
-
if (lhs.hasIntersect(rhs))
|
|
1908
|
-
{
|
|
1909
|
-
resVal = IntervalValue(0, 1);
|
|
1910
|
-
}
|
|
1911
|
-
else if (lhs.empty() && rhs.empty())
|
|
1953
|
+
break;
|
|
1954
|
+
case CmpStmt::FCMP_TRUE:
|
|
1955
|
+
resVal = IntervalValue(1, 1);
|
|
1956
|
+
break;
|
|
1957
|
+
default:
|
|
1912
1958
|
{
|
|
1913
|
-
|
|
1959
|
+
assert(false && "undefined compare: ");
|
|
1914
1960
|
}
|
|
1915
|
-
else
|
|
1916
|
-
{
|
|
1917
|
-
resVal = IntervalValue(1, 1);
|
|
1918
1961
|
}
|
|
1919
|
-
|
|
1962
|
+
as[res] = resVal;
|
|
1920
1963
|
}
|
|
1921
|
-
|
|
1922
|
-
case CmpStmt::ICMP_SGT:
|
|
1923
|
-
case CmpStmt::FCMP_OGT:
|
|
1924
|
-
case CmpStmt::FCMP_UGT:
|
|
1964
|
+
else if (as[op0].isAddr() && as[op1].isAddr())
|
|
1925
1965
|
{
|
|
1926
|
-
|
|
1966
|
+
AddressValue &lhs = as[op0].getAddrs(),
|
|
1967
|
+
&rhs = as[op1].getAddrs();
|
|
1968
|
+
auto predicate = cmp->getPredicate();
|
|
1969
|
+
switch (predicate)
|
|
1927
1970
|
{
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1971
|
+
case CmpStmt::ICMP_EQ:
|
|
1972
|
+
case CmpStmt::FCMP_OEQ:
|
|
1973
|
+
case CmpStmt::FCMP_UEQ:
|
|
1931
1974
|
{
|
|
1932
|
-
|
|
1975
|
+
if (lhs.hasIntersect(rhs))
|
|
1976
|
+
{
|
|
1977
|
+
resVal = IntervalValue(0, 1);
|
|
1978
|
+
}
|
|
1979
|
+
else if (lhs.empty() && rhs.empty())
|
|
1980
|
+
{
|
|
1981
|
+
resVal = IntervalValue(1, 1);
|
|
1982
|
+
}
|
|
1983
|
+
else
|
|
1984
|
+
{
|
|
1985
|
+
resVal = IntervalValue(0, 0);
|
|
1986
|
+
}
|
|
1987
|
+
break;
|
|
1933
1988
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
case CmpStmt::ICMP_SGE:
|
|
1938
|
-
case CmpStmt::FCMP_OGE:
|
|
1939
|
-
case CmpStmt::FCMP_UGE:
|
|
1940
|
-
{
|
|
1941
|
-
if (lhs.size() == 1 && rhs.size() == 1)
|
|
1989
|
+
case CmpStmt::ICMP_NE:
|
|
1990
|
+
case CmpStmt::FCMP_ONE:
|
|
1991
|
+
case CmpStmt::FCMP_UNE:
|
|
1942
1992
|
{
|
|
1943
|
-
|
|
1993
|
+
if (lhs.hasIntersect(rhs))
|
|
1994
|
+
{
|
|
1995
|
+
resVal = IntervalValue(0, 1);
|
|
1996
|
+
}
|
|
1997
|
+
else if (lhs.empty() && rhs.empty())
|
|
1998
|
+
{
|
|
1999
|
+
resVal = IntervalValue(0, 0);
|
|
2000
|
+
}
|
|
2001
|
+
else
|
|
2002
|
+
{
|
|
2003
|
+
resVal = IntervalValue(1, 1);
|
|
2004
|
+
}
|
|
2005
|
+
break;
|
|
1944
2006
|
}
|
|
1945
|
-
|
|
2007
|
+
case CmpStmt::ICMP_UGT:
|
|
2008
|
+
case CmpStmt::ICMP_SGT:
|
|
2009
|
+
case CmpStmt::FCMP_OGT:
|
|
2010
|
+
case CmpStmt::FCMP_UGT:
|
|
1946
2011
|
{
|
|
1947
|
-
|
|
2012
|
+
if (lhs.size() == 1 && rhs.size() == 1)
|
|
2013
|
+
{
|
|
2014
|
+
resVal = IntervalValue(*lhs.begin() > *rhs.begin());
|
|
2015
|
+
}
|
|
2016
|
+
else
|
|
2017
|
+
{
|
|
2018
|
+
resVal = IntervalValue(0, 1);
|
|
2019
|
+
}
|
|
2020
|
+
break;
|
|
1948
2021
|
}
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
case CmpStmt::FCMP_OLT:
|
|
1954
|
-
case CmpStmt::FCMP_ULT:
|
|
1955
|
-
{
|
|
1956
|
-
if (lhs.size() == 1 && rhs.size() == 1)
|
|
2022
|
+
case CmpStmt::ICMP_UGE:
|
|
2023
|
+
case CmpStmt::ICMP_SGE:
|
|
2024
|
+
case CmpStmt::FCMP_OGE:
|
|
2025
|
+
case CmpStmt::FCMP_UGE:
|
|
1957
2026
|
{
|
|
1958
|
-
|
|
2027
|
+
if (lhs.size() == 1 && rhs.size() == 1)
|
|
2028
|
+
{
|
|
2029
|
+
resVal = IntervalValue(*lhs.begin() >= *rhs.begin());
|
|
2030
|
+
}
|
|
2031
|
+
else
|
|
2032
|
+
{
|
|
2033
|
+
resVal = IntervalValue(0, 1);
|
|
2034
|
+
}
|
|
2035
|
+
break;
|
|
1959
2036
|
}
|
|
1960
|
-
|
|
2037
|
+
case CmpStmt::ICMP_ULT:
|
|
2038
|
+
case CmpStmt::ICMP_SLT:
|
|
2039
|
+
case CmpStmt::FCMP_OLT:
|
|
2040
|
+
case CmpStmt::FCMP_ULT:
|
|
1961
2041
|
{
|
|
1962
|
-
|
|
2042
|
+
if (lhs.size() == 1 && rhs.size() == 1)
|
|
2043
|
+
{
|
|
2044
|
+
resVal = IntervalValue(*lhs.begin() < *rhs.begin());
|
|
2045
|
+
}
|
|
2046
|
+
else
|
|
2047
|
+
{
|
|
2048
|
+
resVal = IntervalValue(0, 1);
|
|
2049
|
+
}
|
|
2050
|
+
break;
|
|
1963
2051
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
case CmpStmt::FCMP_OLE:
|
|
1969
|
-
case CmpStmt::FCMP_ULE:
|
|
1970
|
-
{
|
|
1971
|
-
if (lhs.size() == 1 && rhs.size() == 1)
|
|
2052
|
+
case CmpStmt::ICMP_ULE:
|
|
2053
|
+
case CmpStmt::ICMP_SLE:
|
|
2054
|
+
case CmpStmt::FCMP_OLE:
|
|
2055
|
+
case CmpStmt::FCMP_ULE:
|
|
1972
2056
|
{
|
|
1973
|
-
|
|
2057
|
+
if (lhs.size() == 1 && rhs.size() == 1)
|
|
2058
|
+
{
|
|
2059
|
+
resVal = IntervalValue(*lhs.begin() <= *rhs.begin());
|
|
2060
|
+
}
|
|
2061
|
+
else
|
|
2062
|
+
{
|
|
2063
|
+
resVal = IntervalValue(0, 1);
|
|
2064
|
+
}
|
|
2065
|
+
break;
|
|
1974
2066
|
}
|
|
1975
|
-
|
|
2067
|
+
case CmpStmt::FCMP_FALSE:
|
|
2068
|
+
resVal = IntervalValue(0, 0);
|
|
2069
|
+
break;
|
|
2070
|
+
case CmpStmt::FCMP_TRUE:
|
|
2071
|
+
resVal = IntervalValue(1, 1);
|
|
2072
|
+
break;
|
|
2073
|
+
default:
|
|
1976
2074
|
{
|
|
1977
|
-
|
|
2075
|
+
assert(false && "undefined compare: ");
|
|
1978
2076
|
}
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
case CmpStmt::FCMP_FALSE:
|
|
1982
|
-
resVal = IntervalValue(0, 0);
|
|
1983
|
-
break;
|
|
1984
|
-
case CmpStmt::FCMP_TRUE:
|
|
1985
|
-
resVal = IntervalValue(1, 1);
|
|
1986
|
-
break;
|
|
1987
|
-
default:
|
|
1988
|
-
{
|
|
1989
|
-
assert(false && "undefined compare: ");
|
|
1990
|
-
}
|
|
2077
|
+
}
|
|
2078
|
+
as[res] = resVal;
|
|
1991
2079
|
}
|
|
1992
|
-
as[res] = resVal;
|
|
1993
2080
|
}
|
|
1994
2081
|
}
|
|
1995
2082
|
}
|
|
@@ -2057,8 +2144,8 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2057
2144
|
return IntervalValue::top(); // TODO: may have better solution
|
|
2058
2145
|
};
|
|
2059
2146
|
|
|
2060
|
-
auto getTruncValue = [](const AbstractState& as, const SVF::SVFVar* var,
|
|
2061
|
-
|
|
2147
|
+
auto getTruncValue = [&](const AbstractState& as, const SVF::SVFVar* var,
|
|
2148
|
+
const SVFType* dstType)
|
|
2062
2149
|
{
|
|
2063
2150
|
const IntervalValue& itv = as[var->getId()].getInterval();
|
|
2064
2151
|
if(itv.isBottom()) return itv;
|
|
@@ -2075,7 +2162,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2075
2162
|
if (s8_lb > s8_ub)
|
|
2076
2163
|
{
|
|
2077
2164
|
// return range of s8
|
|
2078
|
-
return
|
|
2165
|
+
return this->getRangeLimitFromType(dstType);
|
|
2079
2166
|
}
|
|
2080
2167
|
return IntervalValue(s8_lb, s8_ub);
|
|
2081
2168
|
}
|
|
@@ -2087,7 +2174,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2087
2174
|
if (s16_lb > s16_ub)
|
|
2088
2175
|
{
|
|
2089
2176
|
// return range of s16
|
|
2090
|
-
return
|
|
2177
|
+
return this->getRangeLimitFromType(dstType);
|
|
2091
2178
|
}
|
|
2092
2179
|
return IntervalValue(s16_lb, s16_ub);
|
|
2093
2180
|
}
|
|
@@ -2099,7 +2186,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2099
2186
|
if (s32_lb > s32_ub)
|
|
2100
2187
|
{
|
|
2101
2188
|
// return range of s32
|
|
2102
|
-
return
|
|
2189
|
+
return this->getRangeLimitFromType(dstType);
|
|
2103
2190
|
}
|
|
2104
2191
|
return IntervalValue(s32_lb, s32_ub);
|
|
2105
2192
|
}
|
package/svf/lib/CFL/CFLAlias.cpp
CHANGED
|
@@ -143,7 +143,7 @@ void CFLAlias::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunct
|
|
|
143
143
|
|
|
144
144
|
void CFLAlias::heapAllocatorViaIndCall(const CallICFGNode* cs)
|
|
145
145
|
{
|
|
146
|
-
assert(
|
|
146
|
+
assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
|
|
147
147
|
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
148
148
|
const PAGNode* cs_return = svfir->getCallSiteRet(retBlockNode);
|
|
149
149
|
NodeID srcret;
|
|
@@ -45,13 +45,13 @@ CallSiteID CallGraph::totalCallSiteNum = 1;
|
|
|
45
45
|
//@{
|
|
46
46
|
void CallGraphEdge::addDirectCallSite(const CallICFGNode* call)
|
|
47
47
|
{
|
|
48
|
-
assert(
|
|
48
|
+
assert(call->getCalledFunction() && "not a direct callsite??");
|
|
49
49
|
directCalls.insert(call);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
void CallGraphEdge::addInDirectCallSite(const CallICFGNode* call)
|
|
53
53
|
{
|
|
54
|
-
assert((nullptr ==
|
|
54
|
+
assert((nullptr == call->getCalledFunction() || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call))) && "not an indirect callsite??");
|
|
55
55
|
indirectCalls.insert(call);
|
|
56
56
|
}
|
|
57
57
|
//@}
|
|
@@ -76,11 +76,11 @@ void LockAnalysis::collectLockUnlocksites()
|
|
|
76
76
|
{
|
|
77
77
|
for (const ICFGNode* icfgNode : bb->getICFGNodeList())
|
|
78
78
|
{
|
|
79
|
-
if (tcg->getThreadAPI()->isTDRelease(icfgNode))
|
|
79
|
+
if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDRelease(cast<CallICFGNode>(icfgNode)))
|
|
80
80
|
{
|
|
81
81
|
unlocksites.insert(icfgNode);
|
|
82
82
|
}
|
|
83
|
-
if (tcg->getThreadAPI()->isTDAcquire(icfgNode))
|
|
83
|
+
if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDAcquire(cast<CallICFGNode>(icfgNode)))
|
|
84
84
|
{
|
|
85
85
|
locksites.insert(icfgNode);
|
|
86
86
|
}
|
package/svf/lib/MTA/MHP.cpp
CHANGED
|
@@ -233,10 +233,11 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
233
233
|
void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
234
234
|
{
|
|
235
235
|
|
|
236
|
-
const ICFGNode* call = cts.getStmt();
|
|
237
236
|
const CallStrCxt& curCxt = cts.getContext();
|
|
238
237
|
|
|
239
|
-
assert(isTDJoin(
|
|
238
|
+
assert(isTDJoin(cts.getStmt()));
|
|
239
|
+
|
|
240
|
+
const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(cts.getStmt());
|
|
240
241
|
|
|
241
242
|
NodeBS joinedTids = getDirAndIndJoinedTid(curCxt, call);
|
|
242
243
|
if (!joinedTids.empty())
|
|
@@ -479,8 +480,9 @@ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
|
479
480
|
*/
|
|
480
481
|
bool MHP::isMustJoin(NodeID curTid, const ICFGNode* joinsite)
|
|
481
482
|
{
|
|
482
|
-
|
|
483
|
-
|
|
483
|
+
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(joinsite);
|
|
484
|
+
assert(call && isTDJoin(call) && "not a join site!");
|
|
485
|
+
return !isMultiForkedThread(curTid) && !tct->isJoinSiteInRecursion(call);
|
|
484
486
|
}
|
|
485
487
|
|
|
486
488
|
/*!
|
|
@@ -821,9 +823,9 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
821
823
|
|
|
822
824
|
if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite), SVFUtil::cast<CallICFGNode>(joinSite)))
|
|
823
825
|
{
|
|
824
|
-
if (hasJoinLoop(
|
|
826
|
+
if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
|
|
825
827
|
{
|
|
826
|
-
LoopBBs& joinLoop = getJoinLoop(
|
|
828
|
+
LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite));
|
|
827
829
|
std::vector<const SVFBasicBlock *> exitbbs;
|
|
828
830
|
joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
|
|
829
831
|
while (!exitbbs.empty())
|
|
@@ -853,7 +855,7 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
853
855
|
/// we process the loop exit
|
|
854
856
|
else
|
|
855
857
|
{
|
|
856
|
-
if (hasJoinLoop(
|
|
858
|
+
if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
|
|
857
859
|
{
|
|
858
860
|
std::vector<const SVFBasicBlock*> exitbbs;
|
|
859
861
|
joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
|