svf-tools 1.0.987 → 1.0.989
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/AE/Svfexe/AEDetector.h +15 -2
- package/svf/include/AE/Svfexe/AbsExtAPI.h +147 -0
- package/svf/include/AE/Svfexe/AbstractInterpretation.h +25 -92
- package/svf/include/SVFIR/SVFValue.h +0 -11
- package/svf/include/Util/ExtAPI.h +10 -0
- package/svf/include/Util/SVFUtil.h +1 -7
- package/svf/lib/AE/Svfexe/AEDetector.cpp +108 -28
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +765 -0
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +24 -797
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -2
- package/svf/lib/Util/ExtAPI.cpp +33 -10
- package/svf/lib/Util/SVFUtil.cpp +0 -15
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -58
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +10 -19
- package/svf-llvm/lib/CHGBuilder.cpp +2 -2
- package/svf-llvm/lib/LLVMModule.cpp +216 -230
- package/svf-llvm/lib/LLVMUtil.cpp +32 -228
- package/svf-llvm/lib/ObjTypeInference.cpp +2 -2
- package/svf-llvm/lib/SVFIRBuilder.cpp +0 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +5 -6
- package/svf-llvm/lib/extapi.c +0 -1
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
//
|
|
27
27
|
|
|
28
28
|
#include "AE/Svfexe/AbstractInterpretation.h"
|
|
29
|
+
#include "AE/Svfexe/AbsExtAPI.h"
|
|
29
30
|
#include "SVFIR/SVFIR.h"
|
|
30
31
|
#include "Util/Options.h"
|
|
31
32
|
#include "Util/WorkList.h"
|
|
@@ -89,6 +90,7 @@ void AbstractInterpretation::runOnModule(ICFG *_icfg)
|
|
|
89
90
|
stat->startClk();
|
|
90
91
|
icfg = _icfg;
|
|
91
92
|
svfir = PAG::getPAG();
|
|
93
|
+
utils = new AbsExtAPI(abstractTrace);
|
|
92
94
|
|
|
93
95
|
/// collect checkpoint
|
|
94
96
|
collectCheckPoint();
|
|
@@ -106,7 +108,6 @@ void AbstractInterpretation::runOnModule(ICFG *_icfg)
|
|
|
106
108
|
AbstractInterpretation::AbstractInterpretation()
|
|
107
109
|
{
|
|
108
110
|
stat = new AEStat(this);
|
|
109
|
-
initExtFunMap();
|
|
110
111
|
}
|
|
111
112
|
/// Destructor
|
|
112
113
|
AbstractInterpretation::~AbstractInterpretation()
|
|
@@ -622,7 +623,11 @@ bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode)
|
|
|
622
623
|
void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
|
|
623
624
|
{
|
|
624
625
|
callSiteStack.push_back(callNode);
|
|
625
|
-
handleExtAPI(callNode);
|
|
626
|
+
utils->handleExtAPI(callNode);
|
|
627
|
+
for (auto& detector : detectors)
|
|
628
|
+
{
|
|
629
|
+
detector->handleStubFunctions(callNode);
|
|
630
|
+
}
|
|
626
631
|
callSiteStack.pop_back();
|
|
627
632
|
}
|
|
628
633
|
|
|
@@ -955,490 +960,12 @@ void AEStat::performStat()
|
|
|
955
960
|
SVFUtil::outs().flush();
|
|
956
961
|
}
|
|
957
962
|
|
|
958
|
-
void AbstractInterpretation::initExtFunMap()
|
|
959
|
-
{
|
|
960
|
-
#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
|
|
961
|
-
auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
|
|
962
|
-
/* run real ext function */ \
|
|
963
|
-
AbstractState& as = getAbsStateFromTrace(callNode); \
|
|
964
|
-
u32_t rhs_id = svfir->getValueNode(callNode->getArgument(0)); \
|
|
965
|
-
if (!as.inVarToValTable(rhs_id)) return; \
|
|
966
|
-
u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \
|
|
967
|
-
s32_t res = FUNC_NAME(rhs); \
|
|
968
|
-
u32_t lhsId = svfir->getValueNode(callNode->getCallSite()); \
|
|
969
|
-
as[lhsId] = IntervalValue(res); \
|
|
970
|
-
return; \
|
|
971
|
-
}; \
|
|
972
|
-
func_map[#FUNC_NAME] = sse_##FUNC_NAME;
|
|
973
|
-
|
|
974
|
-
SSE_FUNC_PROCESS(isalnum, isalnum);
|
|
975
|
-
SSE_FUNC_PROCESS(isalpha, isalpha);
|
|
976
|
-
SSE_FUNC_PROCESS(isblank, isblank);
|
|
977
|
-
SSE_FUNC_PROCESS(iscntrl, iscntrl);
|
|
978
|
-
SSE_FUNC_PROCESS(isdigit, isdigit);
|
|
979
|
-
SSE_FUNC_PROCESS(isgraph, isgraph);
|
|
980
|
-
SSE_FUNC_PROCESS(isprint, isprint);
|
|
981
|
-
SSE_FUNC_PROCESS(ispunct, ispunct);
|
|
982
|
-
SSE_FUNC_PROCESS(isspace, isspace);
|
|
983
|
-
SSE_FUNC_PROCESS(isupper, isupper);
|
|
984
|
-
SSE_FUNC_PROCESS(isxdigit, isxdigit);
|
|
985
|
-
SSE_FUNC_PROCESS(llvm.sin.f64, sin);
|
|
986
|
-
SSE_FUNC_PROCESS(llvm.cos.f64, cos);
|
|
987
|
-
SSE_FUNC_PROCESS(llvm.tan.f64, tan);
|
|
988
|
-
SSE_FUNC_PROCESS(llvm.log.f64, log);
|
|
989
|
-
SSE_FUNC_PROCESS(sinh, sinh);
|
|
990
|
-
SSE_FUNC_PROCESS(cosh, cosh);
|
|
991
|
-
SSE_FUNC_PROCESS(tanh, tanh);
|
|
992
|
-
|
|
993
|
-
auto sse_svf_assert = [this](const CallICFGNode* callNode)
|
|
994
|
-
{
|
|
995
|
-
checkpoints.erase(callNode);
|
|
996
|
-
u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
|
|
997
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
998
|
-
if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
|
|
999
|
-
{
|
|
1000
|
-
SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
|
|
1001
|
-
}
|
|
1002
|
-
else
|
|
1003
|
-
{
|
|
1004
|
-
SVFUtil::errs() <<"svf_assert Fail. " << callNode->toString() << "\n";
|
|
1005
|
-
assert(false);
|
|
1006
|
-
}
|
|
1007
|
-
return;
|
|
1008
|
-
};
|
|
1009
|
-
func_map["svf_assert"] = sse_svf_assert;
|
|
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
|
-
|
|
1030
|
-
auto svf_print = [&](const CallICFGNode* callNode)
|
|
1031
|
-
{
|
|
1032
|
-
if (callNode->arg_size() < 2) return;
|
|
1033
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1034
|
-
u32_t num_id = svfir->getValueNode(callNode->getArgument(0));
|
|
1035
|
-
std::string text = strRead(as, callNode->getArgument(1));
|
|
1036
|
-
assert(as.inVarToValTable(num_id) && "print() should pass integer");
|
|
1037
|
-
IntervalValue itv = as[num_id].getInterval();
|
|
1038
|
-
std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
|
|
1039
|
-
<< ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
|
|
1040
|
-
return;
|
|
1041
|
-
};
|
|
1042
|
-
func_map["svf_print"] = svf_print;
|
|
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;
|
|
1070
|
-
|
|
1071
|
-
auto sse_scanf = [&](const CallICFGNode* callNode)
|
|
1072
|
-
{
|
|
1073
|
-
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
1074
|
-
//scanf("%d", &data);
|
|
1075
|
-
if (callNode->arg_size() < 2) return;
|
|
1076
|
-
|
|
1077
|
-
u32_t dst_id = svfir->getValueNode(callNode->getArgument(1));
|
|
1078
|
-
if (!as.inVarToAddrsTable(dst_id))
|
|
1079
|
-
{
|
|
1080
|
-
return;
|
|
1081
|
-
}
|
|
1082
|
-
else
|
|
1083
|
-
{
|
|
1084
|
-
AbstractValue Addrs = as[dst_id];
|
|
1085
|
-
for (auto vaddr: Addrs.getAddrs())
|
|
1086
|
-
{
|
|
1087
|
-
u32_t objId = AbstractState::getInternalID(vaddr);
|
|
1088
|
-
AbstractValue range = getRangeLimitFromType(svfir->getGNode(objId)->getType());
|
|
1089
|
-
as.store(vaddr, range);
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
};
|
|
1093
|
-
auto sse_fscanf = [&](const CallICFGNode* callNode)
|
|
1094
|
-
{
|
|
1095
|
-
//fscanf(stdin, "%d", &data);
|
|
1096
|
-
if (callNode->arg_size() < 3) return;
|
|
1097
|
-
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
1098
|
-
u32_t dst_id = svfir->getValueNode(callNode->getArgument(2));
|
|
1099
|
-
if (!as.inVarToAddrsTable(dst_id))
|
|
1100
|
-
{
|
|
1101
|
-
}
|
|
1102
|
-
else
|
|
1103
|
-
{
|
|
1104
|
-
AbstractValue Addrs = as[dst_id];
|
|
1105
|
-
for (auto vaddr: Addrs.getAddrs())
|
|
1106
|
-
{
|
|
1107
|
-
u32_t objId = AbstractState::getInternalID(vaddr);
|
|
1108
|
-
AbstractValue range = getRangeLimitFromType(svfir->getGNode(objId)->getType());
|
|
1109
|
-
as.store(vaddr, range);
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
};
|
|
1113
|
-
|
|
1114
|
-
func_map["__isoc99_fscanf"] = sse_fscanf;
|
|
1115
|
-
func_map["__isoc99_scanf"] = sse_scanf;
|
|
1116
|
-
func_map["__isoc99_vscanf"] = sse_scanf;
|
|
1117
|
-
func_map["fscanf"] = sse_fscanf;
|
|
1118
|
-
func_map["scanf"] = sse_scanf;
|
|
1119
|
-
func_map["sscanf"] = sse_scanf;
|
|
1120
|
-
func_map["__isoc99_sscanf"] = sse_scanf;
|
|
1121
|
-
func_map["vscanf"] = sse_scanf;
|
|
1122
|
-
|
|
1123
|
-
auto sse_fread = [&](const CallICFGNode *callNode)
|
|
1124
|
-
{
|
|
1125
|
-
if (callNode->arg_size() < 3) return;
|
|
1126
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1127
|
-
u32_t block_count_id = svfir->getValueNode(callNode->getArgument(2));
|
|
1128
|
-
u32_t block_size_id = svfir->getValueNode(callNode->getArgument(1));
|
|
1129
|
-
IntervalValue block_count = as[block_count_id].getInterval();
|
|
1130
|
-
IntervalValue block_size = as[block_size_id].getInterval();
|
|
1131
|
-
IntervalValue block_byte = block_count * block_size;
|
|
1132
|
-
};
|
|
1133
|
-
func_map["fread"] = sse_fread;
|
|
1134
|
-
|
|
1135
|
-
auto sse_sprintf = [&](const CallICFGNode *callNode)
|
|
1136
|
-
{
|
|
1137
|
-
// printf is difficult to predict since it has no byte size arguments
|
|
1138
|
-
};
|
|
1139
|
-
|
|
1140
|
-
auto sse_snprintf = [&](const CallICFGNode *callNode)
|
|
1141
|
-
{
|
|
1142
|
-
if (callNode->arg_size() < 2) return;
|
|
1143
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1144
|
-
u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
|
|
1145
|
-
u32_t dst_id = svfir->getValueNode(callNode->getArgument(0));
|
|
1146
|
-
// get elem size of arg2
|
|
1147
|
-
u32_t elemSize = 1;
|
|
1148
|
-
if (callNode->getArgument(2)->getType()->isArrayTy())
|
|
1149
|
-
{
|
|
1150
|
-
elemSize = SVFUtil::dyn_cast<SVFArrayType>(callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
|
|
1151
|
-
}
|
|
1152
|
-
else if (callNode->getArgument(2)->getType()->isPointerTy())
|
|
1153
|
-
{
|
|
1154
|
-
elemSize = as.getPointeeElement(svfir->getValueNode(callNode->getArgument(2)))->getByteSize();
|
|
1155
|
-
}
|
|
1156
|
-
else
|
|
1157
|
-
{
|
|
1158
|
-
return;
|
|
1159
|
-
// assert(false && "we cannot support this type");
|
|
1160
|
-
}
|
|
1161
|
-
IntervalValue size = as[size_id].getInterval() * IntervalValue(elemSize) - IntervalValue(1);
|
|
1162
|
-
if (!as.inVarToAddrsTable(dst_id))
|
|
1163
|
-
{
|
|
1164
|
-
}
|
|
1165
|
-
};
|
|
1166
|
-
func_map["__snprintf_chk"] = sse_snprintf;
|
|
1167
|
-
func_map["__vsprintf_chk"] = sse_sprintf;
|
|
1168
|
-
func_map["__sprintf_chk"] = sse_sprintf;
|
|
1169
|
-
func_map["snprintf"] = sse_snprintf;
|
|
1170
|
-
func_map["sprintf"] = sse_sprintf;
|
|
1171
|
-
func_map["vsprintf"] = sse_sprintf;
|
|
1172
|
-
func_map["vsnprintf"] = sse_snprintf;
|
|
1173
|
-
func_map["__vsnprintf_chk"] = sse_snprintf;
|
|
1174
|
-
func_map["swprintf"] = sse_snprintf;
|
|
1175
|
-
func_map["_snwprintf"] = sse_snprintf;
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
auto sse_itoa = [&](const CallICFGNode* callNode)
|
|
1179
|
-
{
|
|
1180
|
-
// itoa(num, ch, 10);
|
|
1181
|
-
// num: int, ch: char*, 10 is decimal
|
|
1182
|
-
if (callNode->arg_size() < 3) return;
|
|
1183
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1184
|
-
u32_t num_id = svfir->getValueNode(callNode->getArgument(0));
|
|
1185
|
-
|
|
1186
|
-
u32_t num = (u32_t) as[num_id].getInterval().getNumeral();
|
|
1187
|
-
std::string snum = std::to_string(num);
|
|
1188
|
-
};
|
|
1189
|
-
func_map["itoa"] = sse_itoa;
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
auto sse_strlen = [&](const CallICFGNode *callNode)
|
|
1193
|
-
{
|
|
1194
|
-
// check the arg size
|
|
1195
|
-
if (callNode->arg_size() < 1) return;
|
|
1196
|
-
const SVFValue* strValue = callNode->getArgument(0);
|
|
1197
|
-
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
1198
|
-
NodeID value_id = svfir->getValueNode(strValue);
|
|
1199
|
-
u32_t lhsId = svfir->getValueNode(callNode->getCallSite());
|
|
1200
|
-
u32_t dst_size = 0;
|
|
1201
|
-
for (const auto& addr : as[value_id].getAddrs())
|
|
1202
|
-
{
|
|
1203
|
-
NodeID objId = AbstractState::getInternalID(addr);
|
|
1204
|
-
if (svfir->getBaseObj(objId)->isConstantByteSize())
|
|
1205
|
-
{
|
|
1206
|
-
dst_size = svfir->getBaseObj(objId)->getByteSizeOfObj();
|
|
1207
|
-
}
|
|
1208
|
-
else
|
|
1209
|
-
{
|
|
1210
|
-
const ICFGNode* addrNode = svfir->getICFG()->getICFGNode(SVFUtil::cast<SVFInstruction>(svfir->getBaseObj(objId)->getValue()));
|
|
1211
|
-
for (const SVFStmt* stmt2: addrNode->getSVFStmts())
|
|
1212
|
-
{
|
|
1213
|
-
if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
|
|
1214
|
-
{
|
|
1215
|
-
dst_size = as.getAllocaInstByteSize(addrStmt);
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
u32_t len = 0;
|
|
1221
|
-
NodeID dstid = svfir->getValueNode(strValue);
|
|
1222
|
-
if (as.inVarToAddrsTable(dstid))
|
|
1223
|
-
{
|
|
1224
|
-
for (u32_t index = 0; index < dst_size; index++)
|
|
1225
|
-
{
|
|
1226
|
-
AbstractValue expr0 =
|
|
1227
|
-
as.getGepObjAddrs(dstid, IntervalValue(index));
|
|
1228
|
-
AbstractValue val;
|
|
1229
|
-
for (const auto &addr: expr0.getAddrs())
|
|
1230
|
-
{
|
|
1231
|
-
val.join_with(as.load(addr));
|
|
1232
|
-
}
|
|
1233
|
-
if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
|
|
1234
|
-
{
|
|
1235
|
-
break;
|
|
1236
|
-
}
|
|
1237
|
-
++len;
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
if (len == 0)
|
|
1241
|
-
{
|
|
1242
|
-
as[lhsId] = IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit());
|
|
1243
|
-
}
|
|
1244
|
-
else
|
|
1245
|
-
{
|
|
1246
|
-
as[lhsId] = IntervalValue(len);
|
|
1247
|
-
}
|
|
1248
|
-
};
|
|
1249
|
-
func_map["strlen"] = sse_strlen;
|
|
1250
|
-
func_map["wcslen"] = sse_strlen;
|
|
1251
|
-
|
|
1252
|
-
auto sse_recv = [&](const CallICFGNode *callNode)
|
|
1253
|
-
{
|
|
1254
|
-
// recv(sockfd, buf, len, flags);
|
|
1255
|
-
if (callNode->arg_size() < 4) return;
|
|
1256
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1257
|
-
u32_t len_id = svfir->getValueNode(callNode->getArgument(2));
|
|
1258
|
-
IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
|
|
1259
|
-
u32_t lhsId = svfir->getValueNode(callNode->getCallSite());
|
|
1260
|
-
as[lhsId] = len;
|
|
1261
|
-
};
|
|
1262
|
-
func_map["recv"] = sse_recv;
|
|
1263
|
-
func_map["__recv"] = sse_recv;
|
|
1264
|
-
auto safe_bufaccess = [&](const CallICFGNode *callNode)
|
|
1265
|
-
{
|
|
1266
|
-
checkpoints.erase(callNode);
|
|
1267
|
-
//void SAFE_BUFACCESS(void* data, int size);
|
|
1268
|
-
if (callNode->arg_size() < 2) return;
|
|
1269
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1270
|
-
u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
|
|
1271
|
-
IntervalValue val = as[size_id].getInterval();
|
|
1272
|
-
if (val.isBottom())
|
|
1273
|
-
{
|
|
1274
|
-
val = IntervalValue(0);
|
|
1275
|
-
assert(false && "SAFE_BUFACCESS size is bottom");
|
|
1276
|
-
}
|
|
1277
|
-
for (auto& detector: detectors)
|
|
1278
|
-
{
|
|
1279
|
-
// if detector is a buffer overflow detector, call it
|
|
1280
|
-
if (SVFUtil::isa<BufOverflowDetector>(detector))
|
|
1281
|
-
{
|
|
1282
|
-
BufOverflowDetector* bufDetector = SVFUtil::cast<BufOverflowDetector>(detector.get());
|
|
1283
|
-
bool isSafe = bufDetector->canSafelyAccessMemory(as, callNode->getArgument(0), val);
|
|
1284
|
-
if (isSafe)
|
|
1285
|
-
{
|
|
1286
|
-
std::cout << "safe buffer access success: " << callNode->toString() << std::endl;
|
|
1287
|
-
return;
|
|
1288
|
-
}
|
|
1289
|
-
else
|
|
1290
|
-
{
|
|
1291
|
-
std::string err_msg = "this SAFE_BUFACCESS should be a safe access but detected buffer overflow. Pos: ";
|
|
1292
|
-
err_msg += callNode->getSourceLoc();
|
|
1293
|
-
std::cerr << err_msg << std::endl;
|
|
1294
|
-
assert(false);
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
};
|
|
1299
|
-
func_map["SAFE_BUFACCESS"] = safe_bufaccess;
|
|
1300
|
-
|
|
1301
|
-
auto unsafe_bufaccess = [&](const CallICFGNode *callNode)
|
|
1302
|
-
{
|
|
1303
|
-
checkpoints.erase(callNode);
|
|
1304
|
-
//void UNSAFE_BUFACCESS(void* data, int size);
|
|
1305
|
-
if (callNode->arg_size() < 2) return;
|
|
1306
|
-
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1307
|
-
u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
|
|
1308
|
-
IntervalValue val = as[size_id].getInterval();
|
|
1309
|
-
if (val.isBottom())
|
|
1310
|
-
{
|
|
1311
|
-
assert(false && "UNSAFE_BUFACCESS size is bottom");
|
|
1312
|
-
}
|
|
1313
|
-
for (auto& detector: detectors)
|
|
1314
|
-
{
|
|
1315
|
-
// if detector is a buffer overflow detector, call it
|
|
1316
|
-
if (SVFUtil::isa<BufOverflowDetector>(detector))
|
|
1317
|
-
{
|
|
1318
|
-
BufOverflowDetector* bufDetector = SVFUtil::cast<BufOverflowDetector>(detector.get());
|
|
1319
|
-
bool isSafe = bufDetector->canSafelyAccessMemory(as, callNode->getArgument(0), val);
|
|
1320
|
-
if (!isSafe)
|
|
1321
|
-
{
|
|
1322
|
-
std::cout << "detect buffer overflow success: " << callNode->toString() << std::endl;
|
|
1323
|
-
return;
|
|
1324
|
-
}
|
|
1325
|
-
else
|
|
1326
|
-
{
|
|
1327
|
-
std::string err_msg = "this UNSAFE_BUFACCESS should be a buffer overflow but not detected. Pos: ";
|
|
1328
|
-
err_msg += callNode->getSourceLoc();
|
|
1329
|
-
std::cerr << err_msg << std::endl;
|
|
1330
|
-
assert(false);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
};
|
|
1335
|
-
func_map["UNSAFE_BUFACCESS"] = unsafe_bufaccess;
|
|
1336
|
-
|
|
1337
|
-
// init checkpoint_names
|
|
1338
|
-
checkpoint_names.insert("svf_assert");
|
|
1339
|
-
checkpoint_names.insert("UNSAFE_ACCESS");
|
|
1340
|
-
checkpoint_names.insert("SAFE_ACCESS");
|
|
1341
|
-
};
|
|
1342
|
-
|
|
1343
|
-
std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* rhs)
|
|
1344
|
-
{
|
|
1345
|
-
// sse read string nodeID->string
|
|
1346
|
-
std::string str0;
|
|
1347
|
-
|
|
1348
|
-
for (u32_t index = 0; index < Options::MaxFieldLimit(); index++)
|
|
1349
|
-
{
|
|
1350
|
-
// dead loop for string and break if there's a \0. If no \0, it will throw err.
|
|
1351
|
-
if (!as.inVarToAddrsTable(svfir->getValueNode(rhs))) continue;
|
|
1352
|
-
AbstractValue expr0 =
|
|
1353
|
-
as.getGepObjAddrs(svfir->getValueNode(rhs), IntervalValue(index));
|
|
1354
|
-
|
|
1355
|
-
AbstractValue val;
|
|
1356
|
-
for (const auto &addr: expr0.getAddrs())
|
|
1357
|
-
{
|
|
1358
|
-
val.join_with(as.load(addr));
|
|
1359
|
-
}
|
|
1360
|
-
if (!val.getInterval().is_numeral())
|
|
1361
|
-
{
|
|
1362
|
-
break;
|
|
1363
|
-
}
|
|
1364
|
-
if ((char) val.getInterval().getIntNumeral() == '\0')
|
|
1365
|
-
{
|
|
1366
|
-
break;
|
|
1367
|
-
}
|
|
1368
|
-
str0.push_back((char) val.getInterval().getIntNumeral());
|
|
1369
|
-
}
|
|
1370
|
-
return str0;
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
|
|
1374
|
-
{
|
|
1375
|
-
AbstractState& as = getAbsStateFromTrace(call);
|
|
1376
|
-
const SVFFunction *fun = call->getCalledFunction();
|
|
1377
|
-
assert(fun && "SVFFunction* is nullptr");
|
|
1378
|
-
ExtAPIType extType = UNCLASSIFIED;
|
|
1379
|
-
// get type of mem api
|
|
1380
|
-
for (const std::string &annotation: fun->getAnnotations())
|
|
1381
|
-
{
|
|
1382
|
-
if (annotation.find("MEMCPY") != std::string::npos)
|
|
1383
|
-
extType = MEMCPY;
|
|
1384
|
-
if (annotation.find("MEMSET") != std::string::npos)
|
|
1385
|
-
extType = MEMSET;
|
|
1386
|
-
if (annotation.find("STRCPY") != std::string::npos)
|
|
1387
|
-
extType = STRCPY;
|
|
1388
|
-
if (annotation.find("STRCAT") != std::string::npos)
|
|
1389
|
-
extType = STRCAT;
|
|
1390
|
-
}
|
|
1391
|
-
if (extType == UNCLASSIFIED)
|
|
1392
|
-
{
|
|
1393
|
-
if (func_map.find(fun->getName()) != func_map.end())
|
|
1394
|
-
{
|
|
1395
|
-
func_map[fun->getName()](call);
|
|
1396
|
-
}
|
|
1397
|
-
else
|
|
1398
|
-
{
|
|
1399
|
-
u32_t lhsId = svfir->getValueNode(call->getCallSite());
|
|
1400
|
-
if (as.inVarToAddrsTable(lhsId))
|
|
1401
|
-
{
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
else
|
|
1405
|
-
{
|
|
1406
|
-
as[lhsId] = IntervalValue();
|
|
1407
|
-
}
|
|
1408
|
-
return;
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
// 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
|
|
1412
|
-
else if (extType == MEMCPY)
|
|
1413
|
-
{
|
|
1414
|
-
IntervalValue len = as[svfir->getValueNode(call->getArgument(2))].getInterval();
|
|
1415
|
-
handleMemcpy(as, call->getArgument(0), call->getArgument(1), len, 0);
|
|
1416
|
-
}
|
|
1417
|
-
else if (extType == MEMSET)
|
|
1418
|
-
{
|
|
1419
|
-
// memset dst is arg0, elem is arg1, size is arg2
|
|
1420
|
-
IntervalValue len = as[svfir->getValueNode(call->getArgument(2))].getInterval();
|
|
1421
|
-
IntervalValue elem = as[svfir->getValueNode(call->getArgument(1))].getInterval();
|
|
1422
|
-
handleMemset(as,call->getArgument(0), elem, len);
|
|
1423
|
-
}
|
|
1424
|
-
else if (extType == STRCPY)
|
|
1425
|
-
{
|
|
1426
|
-
handleStrcpy(call);
|
|
1427
|
-
}
|
|
1428
|
-
else if (extType == STRCAT)
|
|
1429
|
-
{
|
|
1430
|
-
handleStrcat(call);
|
|
1431
|
-
}
|
|
1432
|
-
else
|
|
1433
|
-
{
|
|
1434
|
-
|
|
1435
|
-
}
|
|
1436
|
-
return;
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
963
|
void AbstractInterpretation::collectCheckPoint()
|
|
1440
964
|
{
|
|
1441
965
|
// traverse every ICFGNode
|
|
966
|
+
Set<std::string> ae_checkpoint_names = {"svf_assert"};
|
|
967
|
+
Set<std::string> buf_checkpoint_names = {"UNSAFE_BUFACCESS", "SAFE_BUFACCESS"};
|
|
968
|
+
|
|
1442
969
|
for (auto it = svfir->getICFG()->begin(); it != svfir->getICFG()->end(); ++it)
|
|
1443
970
|
{
|
|
1444
971
|
const ICFGNode* node = it->second;
|
|
@@ -1446,11 +973,19 @@ void AbstractInterpretation::collectCheckPoint()
|
|
|
1446
973
|
{
|
|
1447
974
|
if (const SVFFunction *fun = call->getCalledFunction())
|
|
1448
975
|
{
|
|
1449
|
-
if (
|
|
1450
|
-
|
|
976
|
+
if (ae_checkpoint_names.find(fun->getName()) !=
|
|
977
|
+
ae_checkpoint_names.end())
|
|
1451
978
|
{
|
|
1452
979
|
checkpoints.insert(call);
|
|
1453
980
|
}
|
|
981
|
+
if (Options::BufferOverflowCheck())
|
|
982
|
+
{
|
|
983
|
+
if (buf_checkpoint_names.find(fun->getName()) !=
|
|
984
|
+
buf_checkpoint_names.end())
|
|
985
|
+
{
|
|
986
|
+
checkpoints.insert(call);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
1454
989
|
}
|
|
1455
990
|
}
|
|
1456
991
|
}
|
|
@@ -1472,241 +1007,6 @@ void AbstractInterpretation::checkPointAllSet()
|
|
|
1472
1007
|
|
|
1473
1008
|
}
|
|
1474
1009
|
|
|
1475
|
-
|
|
1476
|
-
void AbstractInterpretation::handleStrcpy(const CallICFGNode *call)
|
|
1477
|
-
{
|
|
1478
|
-
// strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
|
|
1479
|
-
// get the dst and src
|
|
1480
|
-
AbstractState& as = getAbsStateFromTrace(call);
|
|
1481
|
-
const SVFValue* arg0Val = call->getArgument(0);
|
|
1482
|
-
const SVFValue* arg1Val = call->getArgument(1);
|
|
1483
|
-
IntervalValue strLen = getStrlen(as, arg1Val);
|
|
1484
|
-
// no need to -1, since it has \0 as the last byte
|
|
1485
|
-
handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral());
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SVFValue *strValue)
|
|
1489
|
-
{
|
|
1490
|
-
NodeID value_id = svfir->getValueNode(strValue);
|
|
1491
|
-
u32_t dst_size = 0;
|
|
1492
|
-
for (const auto& addr : as[value_id].getAddrs())
|
|
1493
|
-
{
|
|
1494
|
-
NodeID objId = AbstractState::getInternalID(addr);
|
|
1495
|
-
if (svfir->getBaseObj(objId)->isConstantByteSize())
|
|
1496
|
-
{
|
|
1497
|
-
dst_size = svfir->getBaseObj(objId)->getByteSizeOfObj();
|
|
1498
|
-
}
|
|
1499
|
-
else
|
|
1500
|
-
{
|
|
1501
|
-
const ICFGNode* addrNode = svfir->getICFG()->getICFGNode(SVFUtil::cast<SVFInstruction>(svfir->getBaseObj(objId)->getValue()));
|
|
1502
|
-
for (const SVFStmt* stmt2: addrNode->getSVFStmts())
|
|
1503
|
-
{
|
|
1504
|
-
if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
|
|
1505
|
-
{
|
|
1506
|
-
dst_size = as.getAllocaInstByteSize(addrStmt);
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
u32_t len = 0;
|
|
1512
|
-
NodeID dstid = svfir->getValueNode(strValue);
|
|
1513
|
-
u32_t elemSize = 1;
|
|
1514
|
-
if (as.inVarToAddrsTable(dstid))
|
|
1515
|
-
{
|
|
1516
|
-
for (u32_t index = 0; index < dst_size; index++)
|
|
1517
|
-
{
|
|
1518
|
-
AbstractValue expr0 =
|
|
1519
|
-
as.getGepObjAddrs(dstid, IntervalValue(index));
|
|
1520
|
-
AbstractValue val;
|
|
1521
|
-
for (const auto &addr: expr0.getAddrs())
|
|
1522
|
-
{
|
|
1523
|
-
val.join_with(as.load(addr));
|
|
1524
|
-
}
|
|
1525
|
-
if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
|
|
1526
|
-
{
|
|
1527
|
-
break;
|
|
1528
|
-
}
|
|
1529
|
-
++len;
|
|
1530
|
-
}
|
|
1531
|
-
if (strValue->getType()->isArrayTy())
|
|
1532
|
-
{
|
|
1533
|
-
elemSize = SVFUtil::dyn_cast<SVFArrayType>(strValue->getType())->getTypeOfElement()->getByteSize();
|
|
1534
|
-
}
|
|
1535
|
-
else if (strValue->getType()->isPointerTy())
|
|
1536
|
-
{
|
|
1537
|
-
if (const SVFType* elemType = as.getPointeeElement(svfir->getValueNode(strValue)))
|
|
1538
|
-
{
|
|
1539
|
-
if (elemType->isArrayTy())
|
|
1540
|
-
elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
|
|
1541
|
-
else
|
|
1542
|
-
elemSize = elemType->getByteSize();
|
|
1543
|
-
}
|
|
1544
|
-
else
|
|
1545
|
-
{
|
|
1546
|
-
elemSize = 1;
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
else
|
|
1550
|
-
{
|
|
1551
|
-
assert(false && "we cannot support this type");
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
if (len == 0)
|
|
1555
|
-
{
|
|
1556
|
-
return IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit());
|
|
1557
|
-
}
|
|
1558
|
-
else
|
|
1559
|
-
{
|
|
1560
|
-
return IntervalValue(len * elemSize);
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
|
|
1566
|
-
{
|
|
1567
|
-
// __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
|
|
1568
|
-
// to check it is strcat group or strncat group
|
|
1569
|
-
AbstractState& as = getAbsStateFromTrace(call);
|
|
1570
|
-
const SVFFunction *fun = call->getCalledFunction();
|
|
1571
|
-
const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
|
|
1572
|
-
const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
|
|
1573
|
-
if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
|
|
1574
|
-
{
|
|
1575
|
-
const SVFValue* arg0Val = call->getArgument(0);
|
|
1576
|
-
const SVFValue* arg1Val = call->getArgument(1);
|
|
1577
|
-
IntervalValue strLen0 = getStrlen(as, arg0Val);
|
|
1578
|
-
IntervalValue strLen1 = getStrlen(as, arg1Val);
|
|
1579
|
-
IntervalValue totalLen = strLen0 + strLen1;
|
|
1580
|
-
handleMemcpy(as, arg0Val, arg1Val, strLen1, strLen0.lb().getIntNumeral());
|
|
1581
|
-
// do memcpy
|
|
1582
|
-
}
|
|
1583
|
-
else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
|
|
1584
|
-
{
|
|
1585
|
-
const SVFValue* arg0Val = call->getArgument(0);
|
|
1586
|
-
const SVFValue* arg1Val = call->getArgument(1);
|
|
1587
|
-
const SVFValue* arg2Val = call->getArgument(2);
|
|
1588
|
-
IntervalValue arg2Num = as[svfir->getValueNode(arg2Val)].getInterval();
|
|
1589
|
-
IntervalValue strLen0 = getStrlen(as, arg0Val);
|
|
1590
|
-
IntervalValue totalLen = strLen0 + arg2Num;
|
|
1591
|
-
handleMemcpy(as, arg0Val, arg1Val, arg2Num, strLen0.lb().getIntNumeral());
|
|
1592
|
-
// do memcpy
|
|
1593
|
-
}
|
|
1594
|
-
else
|
|
1595
|
-
{
|
|
1596
|
-
assert(false && "unknown strcat function, please add it to strcatGroup or strncatGroup");
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue *dst, const SVF::SVFValue *src, IntervalValue len, u32_t start_idx)
|
|
1601
|
-
{
|
|
1602
|
-
u32_t dstId = svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType().
|
|
1603
|
-
u32_t srcId = svfir->getValueNode(src);
|
|
1604
|
-
u32_t elemSize = 1;
|
|
1605
|
-
if (dst->getType()->isArrayTy())
|
|
1606
|
-
{
|
|
1607
|
-
elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
|
|
1608
|
-
}
|
|
1609
|
-
// memcpy(i32*, i32*, 40)
|
|
1610
|
-
else if (dst->getType()->isPointerTy())
|
|
1611
|
-
{
|
|
1612
|
-
if (const SVFType* elemType = as.getPointeeElement(svfir->getValueNode(dst)))
|
|
1613
|
-
{
|
|
1614
|
-
if (elemType->isArrayTy())
|
|
1615
|
-
elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
|
|
1616
|
-
else
|
|
1617
|
-
elemSize = elemType->getByteSize();
|
|
1618
|
-
}
|
|
1619
|
-
else
|
|
1620
|
-
{
|
|
1621
|
-
elemSize = 1;
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
else
|
|
1625
|
-
{
|
|
1626
|
-
assert(false && "we cannot support this type");
|
|
1627
|
-
}
|
|
1628
|
-
u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
|
|
1629
|
-
u32_t range_val = size / elemSize;
|
|
1630
|
-
if (as.inVarToAddrsTable(srcId) && as.inVarToAddrsTable(dstId))
|
|
1631
|
-
{
|
|
1632
|
-
for (u32_t index = 0; index < range_val; index++)
|
|
1633
|
-
{
|
|
1634
|
-
// dead loop for string and break if there's a \0. If no \0, it will throw err.
|
|
1635
|
-
AbstractValue expr_src =
|
|
1636
|
-
as.getGepObjAddrs(srcId, IntervalValue(index));
|
|
1637
|
-
AbstractValue expr_dst =
|
|
1638
|
-
as.getGepObjAddrs(dstId, IntervalValue(index + start_idx));
|
|
1639
|
-
for (const auto &dst: expr_dst.getAddrs())
|
|
1640
|
-
{
|
|
1641
|
-
for (const auto &src: expr_src.getAddrs())
|
|
1642
|
-
{
|
|
1643
|
-
u32_t objId = AbstractState::getInternalID(src);
|
|
1644
|
-
if (as.inAddrToValTable(objId))
|
|
1645
|
-
{
|
|
1646
|
-
as.store(dst, as.load(src));
|
|
1647
|
-
}
|
|
1648
|
-
else if (as.inAddrToAddrsTable(objId))
|
|
1649
|
-
{
|
|
1650
|
-
as.store(dst, as.load(src));
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
|
|
1658
|
-
void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue *dst, IntervalValue elem, IntervalValue len)
|
|
1659
|
-
{
|
|
1660
|
-
u32_t dstId = svfir->getValueNode(dst);
|
|
1661
|
-
u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
|
|
1662
|
-
u32_t elemSize = 1;
|
|
1663
|
-
if (dst->getType()->isArrayTy())
|
|
1664
|
-
{
|
|
1665
|
-
elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
|
|
1666
|
-
}
|
|
1667
|
-
else if (dst->getType()->isPointerTy())
|
|
1668
|
-
{
|
|
1669
|
-
if (const SVFType* elemType = as.getPointeeElement(svfir->getValueNode(dst)))
|
|
1670
|
-
{
|
|
1671
|
-
elemSize = elemType->getByteSize();
|
|
1672
|
-
}
|
|
1673
|
-
else
|
|
1674
|
-
{
|
|
1675
|
-
elemSize = 1;
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
else
|
|
1679
|
-
{
|
|
1680
|
-
assert(false && "we cannot support this type");
|
|
1681
|
-
}
|
|
1682
|
-
|
|
1683
|
-
u32_t range_val = size / elemSize;
|
|
1684
|
-
for (u32_t index = 0; index < range_val; index++)
|
|
1685
|
-
{
|
|
1686
|
-
// dead loop for string and break if there's a \0. If no \0, it will throw err.
|
|
1687
|
-
if (as.inVarToAddrsTable(dstId))
|
|
1688
|
-
{
|
|
1689
|
-
AbstractValue lhs_gep = as.getGepObjAddrs(dstId, IntervalValue(index));
|
|
1690
|
-
for (const auto &addr: lhs_gep.getAddrs())
|
|
1691
|
-
{
|
|
1692
|
-
u32_t objId = AbstractState::getInternalID(addr);
|
|
1693
|
-
if (as.inAddrToValTable(objId))
|
|
1694
|
-
{
|
|
1695
|
-
AbstractValue tmp = as.load(addr);
|
|
1696
|
-
tmp.join_with(elem);
|
|
1697
|
-
as.store(addr, tmp);
|
|
1698
|
-
}
|
|
1699
|
-
else
|
|
1700
|
-
{
|
|
1701
|
-
as.store(addr, elem);
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1705
|
-
else
|
|
1706
|
-
break;
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
1010
|
void AbstractInterpretation::updateStateOnGep(const GepStmt *gep)
|
|
1711
1011
|
{
|
|
1712
1012
|
AbstractState& as = getAbsStateFromTrace(gep->getICFGNode());
|
|
@@ -1802,7 +1102,7 @@ void AbstractInterpretation::updateStateOnAddr(const AddrStmt *addr)
|
|
|
1802
1102
|
AbstractState& as = getAbsStateFromTrace(addr->getICFGNode());
|
|
1803
1103
|
as.initObjVar(SVFUtil::cast<ObjVar>(addr->getRHSVar()));
|
|
1804
1104
|
if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy)
|
|
1805
|
-
as[addr->getRHSVarID()].getInterval().meet_with(getRangeLimitFromType(addr->getRHSVar()->getType()));
|
|
1105
|
+
as[addr->getRHSVarID()].getInterval().meet_with(utils->getRangeLimitFromType(addr->getRHSVar()->getType()));
|
|
1806
1106
|
as[addr->getLHSVarID()] = as[addr->getRHSVarID()];
|
|
1807
1107
|
}
|
|
1808
1108
|
|
|
@@ -2162,7 +1462,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2162
1462
|
if (s8_lb > s8_ub)
|
|
2163
1463
|
{
|
|
2164
1464
|
// return range of s8
|
|
2165
|
-
return
|
|
1465
|
+
return utils->getRangeLimitFromType(dstType);
|
|
2166
1466
|
}
|
|
2167
1467
|
return IntervalValue(s8_lb, s8_ub);
|
|
2168
1468
|
}
|
|
@@ -2174,7 +1474,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2174
1474
|
if (s16_lb > s16_ub)
|
|
2175
1475
|
{
|
|
2176
1476
|
// return range of s16
|
|
2177
|
-
return
|
|
1477
|
+
return utils->getRangeLimitFromType(dstType);
|
|
2178
1478
|
}
|
|
2179
1479
|
return IntervalValue(s16_lb, s16_ub);
|
|
2180
1480
|
}
|
|
@@ -2186,7 +1486,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2186
1486
|
if (s32_lb > s32_ub)
|
|
2187
1487
|
{
|
|
2188
1488
|
// return range of s32
|
|
2189
|
-
return
|
|
1489
|
+
return utils->getRangeLimitFromType(dstType);
|
|
2190
1490
|
}
|
|
2191
1491
|
return IntervalValue(s32_lb, s32_ub);
|
|
2192
1492
|
}
|
|
@@ -2262,78 +1562,5 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
2262
1562
|
}
|
|
2263
1563
|
}
|
|
2264
1564
|
|
|
2265
|
-
/**
|
|
2266
|
-
* This function, getRangeLimitFromType, calculates the lower and upper bounds of
|
|
2267
|
-
* a numeric range for a given SVFType. It is used to determine the possible value
|
|
2268
|
-
* range of integer types. If the type is an SVFIntegerType, it calculates the bounds
|
|
2269
|
-
* based on the size and signedness of the type. The calculated bounds are returned
|
|
2270
|
-
* as an IntervalValue representing the lower (lb) and upper (ub) limits of the range.
|
|
2271
|
-
*
|
|
2272
|
-
* @param type The SVFType for which to calculate the value range.
|
|
2273
|
-
*
|
|
2274
|
-
* @return An IntervalValue representing the lower and upper bounds of the range.
|
|
2275
|
-
*/
|
|
2276
|
-
IntervalValue AbstractInterpretation::getRangeLimitFromType(const SVFType* type)
|
|
2277
|
-
{
|
|
2278
|
-
if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
|
|
2279
|
-
{
|
|
2280
|
-
u32_t bits = type->getByteSize() * 8;
|
|
2281
|
-
s64_t ub = 0;
|
|
2282
|
-
s64_t lb = 0;
|
|
2283
|
-
if (bits >= 32)
|
|
2284
|
-
{
|
|
2285
|
-
if (intType->isSigned())
|
|
2286
|
-
{
|
|
2287
|
-
ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
|
|
2288
|
-
lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
|
|
2289
|
-
}
|
|
2290
|
-
else
|
|
2291
|
-
{
|
|
2292
|
-
ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
|
|
2293
|
-
lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
else if (bits == 16)
|
|
2297
|
-
{
|
|
2298
|
-
if (intType->isSigned())
|
|
2299
|
-
{
|
|
2300
|
-
ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
|
|
2301
|
-
lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
|
|
2302
|
-
}
|
|
2303
|
-
else
|
|
2304
|
-
{
|
|
2305
|
-
ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
|
|
2306
|
-
lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
else if (bits == 8)
|
|
2310
|
-
{
|
|
2311
|
-
if (intType->isSigned())
|
|
2312
|
-
{
|
|
2313
|
-
ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
|
|
2314
|
-
lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
|
|
2315
|
-
}
|
|
2316
|
-
else
|
|
2317
|
-
{
|
|
2318
|
-
ub = static_cast<s64_t>(std::numeric_limits<u_int8_t>::max());
|
|
2319
|
-
lb = static_cast<s64_t>(std::numeric_limits<u_int8_t>::min());
|
|
2320
|
-
}
|
|
2321
|
-
}
|
|
2322
|
-
return IntervalValue(lb, ub);
|
|
2323
|
-
}
|
|
2324
|
-
else if (SVFUtil::isa<SVFOtherType>(type))
|
|
2325
|
-
{
|
|
2326
|
-
// handle other type like float double, set s32_t as the range
|
|
2327
|
-
s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
|
|
2328
|
-
s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
|
|
2329
|
-
return IntervalValue(lb, ub);
|
|
2330
|
-
}
|
|
2331
|
-
else
|
|
2332
|
-
{
|
|
2333
|
-
return IntervalValue::top();
|
|
2334
|
-
// other types, return top interval
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
1565
|
|
|
2339
1566
|
|