svf-tools 1.0.1208 → 1.0.1209
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/Core/AbstractState.h +1 -2
- package/svf/include/AE/Svfexe/AbsExtAPI.h +1 -1
- package/svf/include/AE/Svfexe/AbstractInterpretation.h +37 -97
- package/svf/lib/AE/Svfexe/AEDetector.cpp +4 -4
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +18 -18
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +100 -20
- package/SVF-doxygen/doxygen.config +0 -2548
- package/SVF-doxygen/wiki/PAG.png +0 -0
- package/SVF-doxygen/wiki/andersen.png +0 -0
- package/SVF-doxygen/wiki/callgraph.png +0 -0
- package/SVF-doxygen/wiki/consG.png +0 -0
- package/SVF-doxygen/wiki/cpu2000-flto +0 -432
- package/SVF-doxygen/wiki/cpu2006-flto +0 -417
- package/SVF-doxygen/wiki/cpu2017-wllvm.cfg +0 -999
- package/SVF-doxygen/wiki/database.png +0 -0
- package/SVF-doxygen/wiki/framework.png +0 -0
- package/SVF-doxygen/wiki/help.png +0 -0
- package/SVF-doxygen/wiki/icfg.png +0 -0
- package/SVF-doxygen/wiki/mssa-cha.png +0 -0
- package/SVF-doxygen/wiki/pagedge.png +0 -0
- package/SVF-doxygen/wiki/pagnode.png +0 -0
- package/SVF-doxygen/wiki/pt.png +0 -0
- package/SVF-doxygen/wiki/setupcmake.png +0 -0
- package/SVF-doxygen/wiki/setupconfiguration.png +0 -0
- package/SVF-doxygen/wiki/setupdashboard.png +0 -0
- package/SVF-doxygen/wiki/setupdebug.png +0 -0
- package/SVF-doxygen/wiki/setupenv.png +0 -0
- package/SVF-doxygen/wiki/startup.png +0 -0
- package/SVF-doxygen/wiki/svf-stat.pdf +0 -0
- package/SVF-doxygen/wiki/svfg-framework.png +0 -0
- package/SVF-doxygen/wiki/svfg.png +0 -0
- package/SVF-doxygen/wiki/svfg_opt.png +0 -0
- package/SVF-doxygen/wiki/svfgedge-cha.png +0 -0
- package/SVF-doxygen/wiki/svfgnode-cha.png +0 -0
- package/SVF-doxygen/wiki/svfpic/README.md +0 -6
- package/SVF-doxygen/wiki/svfpic/ass-1debug1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/ass-1debug2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/build.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/cmd.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect1.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/connect2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect3.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect4.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/connect5.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/connect6.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect7.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/continue.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug-new.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug-new2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug1.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/debug2.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/debug3.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug4.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug5.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/debug6.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/docker_sys_requirement.png +0 -0
- package/SVF-doxygen/wiki/svfpic/docker_sys_requirements.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild2.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild3.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild4.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild5.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuildimage.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockercmd.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockercmd2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockercontainer.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb1.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb10.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb2.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb3.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb4.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb5.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb6.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb7.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb8.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb9.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerfinshbuilt.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerimage.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockernameImage.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerpull.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerpull2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/download.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/extension1.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/extension2.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/graphviz.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hellodb.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hellodb2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hviz_0.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hviz_1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hviz_2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installC:C++Ext.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installCMakeExt.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installRCext.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installdockerext.png +0 -0
- package/SVF-doxygen/wiki/svfpic/launch1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/openfile.png +0 -0
- package/SVF-doxygen/wiki/svfpic/pathfolder.png +0 -0
- package/SVF-doxygen/wiki/svfpic/restart.png +0 -0
- package/SVF-doxygen/wiki/svfpic/rundocker.png +0 -0
- package/SVF-doxygen/wiki/svfpic/runinCLI.png +0 -0
- package/SVF-doxygen/wiki/svfpic/screen.png +0 -0
- package/SVF-doxygen/wiki/svfpic/settings1.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/settings2.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/settings3.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/shortlists.png +0 -0
- package/SVF-doxygen/wiki/svfpic/start.png +0 -0
- package/SVF-doxygen/wiki/svfpic/start1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/update0.png +0 -0
- package/SVF-doxygen/wiki/svfpic/verify_docker.png +0 -0
- package/SVF-doxygen/wiki/svfpic/vs_entry_window.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl_1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl_2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl_3.png +0 -0
- package/SVF-doxygen/wiki/tools.png +0 -0
- package/SVF-doxygen/wiki/users.png +0 -0
- package/SVF-doxygen/wiki/vm1.png +0 -0
- package/SVF-doxygen/wiki/vm2.png +0 -0
- package/SVF-doxygen/wiki/vm3.png +0 -0
- package/SVF-doxygen/wiki/vm4.png +0 -0
- package/SVF-doxygen/wiki/vm5.png +0 -0
- package/SVF-doxygen/wiki/vscode_build_tasks.png +0 -0
- package/SVF-doxygen/wiki/vscode_cpp_extension.png +0 -0
- package/SVF-doxygen/wiki/vscode_debug_list.png +0 -0
- package/SVF-doxygen/wiki/vscode_dir_structure.png +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1209",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -195,8 +195,7 @@ public:
|
|
|
195
195
|
|
|
196
196
|
protected:
|
|
197
197
|
VarToAbsValMap _varToAbsVal; ///< Map a variable (symbol) to its abstract value
|
|
198
|
-
AddrToAbsValMap
|
|
199
|
-
_addrToAbsVal; ///< Map a memory address to its stored abstract value
|
|
198
|
+
AddrToAbsValMap _addrToAbsVal; ///< Map a memory address to its stored abstract value
|
|
200
199
|
|
|
201
200
|
public:
|
|
202
201
|
|
|
@@ -106,7 +106,7 @@ public:
|
|
|
106
106
|
* @return Reference to the abstract state.
|
|
107
107
|
* @throws Assertion if no trace exists for the node.
|
|
108
108
|
*/
|
|
109
|
-
AbstractState&
|
|
109
|
+
AbstractState& getAbstractState(const ICFGNode* node);
|
|
110
110
|
|
|
111
111
|
void collectCheckPoint();
|
|
112
112
|
void checkPointAllSet();
|
|
@@ -109,128 +109,74 @@ public:
|
|
|
109
109
|
detectors.push_back(std::move(detector));
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/// Retrieve the abstract state from the trace for a given ICFG node; asserts if no trace exists
|
|
113
|
+
AbstractState& getAbstractState(const ICFGNode* node);
|
|
112
114
|
|
|
115
|
+
/// Check if an abstract state exists in the trace for a given ICFG node
|
|
116
|
+
bool hasAbsStateFromTrace(const ICFGNode* node);
|
|
117
|
+
|
|
118
|
+
/// Retrieve abstract value for a top-level variable at a given ICFG node
|
|
119
|
+
AbstractValue& getAbstractValue(const ICFGNode* node, const ValVar* var);
|
|
120
|
+
|
|
121
|
+
/// Retrieve abstract value for an address-taken variable at a given ICFG node
|
|
122
|
+
AbstractValue& getAbstractValue(const ICFGNode* node, const ObjVar* var);
|
|
123
|
+
|
|
124
|
+
/// Retrieve abstract value for any SVF variable at a given ICFG node
|
|
125
|
+
AbstractValue& getAbstractValue(const ICFGNode* node, const SVFVar* var);
|
|
126
|
+
|
|
127
|
+
/// Retrieve abstract state filtered to specific top-level variables
|
|
128
|
+
void getAbstractState(const ICFGNode* node, const Set<const ValVar*>& vars, AbstractState& result);
|
|
129
|
+
|
|
130
|
+
/// Retrieve abstract state filtered to specific address-taken variables
|
|
131
|
+
void getAbstractState(const ICFGNode* node, const Set<const ObjVar*>& vars, AbstractState& result);
|
|
132
|
+
|
|
133
|
+
/// Retrieve abstract state filtered to specific SVF variables
|
|
134
|
+
void getAbstractState(const ICFGNode* node, const Set<const SVFVar*>& vars, AbstractState& result);
|
|
113
135
|
|
|
114
|
-
/**
|
|
115
|
-
* @brief Retrieves the abstract state from the trace for a given ICFG node.
|
|
116
|
-
* @param node Pointer to the ICFG node.
|
|
117
|
-
* @return Reference to the abstract state.
|
|
118
|
-
* @throws Assertion if no trace exists for the node.
|
|
119
|
-
*/
|
|
120
|
-
AbstractState& getAbsStateFromTrace(const ICFGNode* node)
|
|
121
|
-
{
|
|
122
|
-
if (abstractTrace.count(node) == 0)
|
|
123
|
-
{
|
|
124
|
-
assert(false && "No preAbsTrace for this node");
|
|
125
|
-
abort();
|
|
126
|
-
}
|
|
127
|
-
else
|
|
128
|
-
{
|
|
129
|
-
return abstractTrace[node];
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
136
|
|
|
133
137
|
private:
|
|
134
|
-
///
|
|
138
|
+
/// Initialize abstract state for the global ICFG node and process global statements
|
|
135
139
|
virtual void handleGlobalNode();
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
* Check if execution state exist by merging states of predecessor nodes
|
|
139
|
-
*
|
|
140
|
-
* @param icfgNode The icfg node to analyse
|
|
141
|
-
* @return if this node has preceding execution state
|
|
142
|
-
*/
|
|
141
|
+
/// Merge abstract states from predecessor nodes; return true if icfgNode has feasible incoming state
|
|
143
142
|
bool mergeStatesFromPredecessors(const ICFGNode * icfgNode);
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
* Check if execution state exist at the branch edge
|
|
147
|
-
*
|
|
148
|
-
* @param intraEdge the edge from CmpStmt to the next node
|
|
149
|
-
* @return if this edge is feasible
|
|
150
|
-
*/
|
|
144
|
+
/// Check if the branch on intraEdge is feasible under abstract state as
|
|
151
145
|
bool isBranchFeasible(const IntraCFGEdge* intraEdge, AbstractState& as);
|
|
152
146
|
|
|
153
|
-
|
|
154
|
-
* handle instructions in ICFGSingletonWTO
|
|
155
|
-
*
|
|
156
|
-
* @param block basic block that has one instruction or a series of instructions
|
|
157
|
-
*/
|
|
147
|
+
/// Process all SVF statements in a singleton WTO component (single basic block)
|
|
158
148
|
virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto);
|
|
159
149
|
|
|
160
|
-
|
|
161
|
-
* handle call node in ICFGNode
|
|
162
|
-
*
|
|
163
|
-
* @param node ICFGNode which has a single CallICFGNode
|
|
164
|
-
*/
|
|
150
|
+
/// Handle a call site node: dispatch to ext-call, direct-call, or indirect-call handling
|
|
165
151
|
virtual void handleCallSite(const ICFGNode* node);
|
|
166
152
|
|
|
167
|
-
|
|
168
|
-
* handle wto cycle (loop)
|
|
169
|
-
*
|
|
170
|
-
* @param cycle WTOCycle which has weak topo order of basic blocks and nested cycles
|
|
171
|
-
*/
|
|
153
|
+
/// Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration
|
|
172
154
|
virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller = nullptr);
|
|
173
155
|
|
|
174
|
-
|
|
175
|
-
* Handle a function using worklist algorithm
|
|
176
|
-
*
|
|
177
|
-
* @param funEntry The entry node of the function to handle
|
|
178
|
-
*/
|
|
156
|
+
/// Handle a function body via worklist-driven WTO traversal starting from funEntry
|
|
179
157
|
void handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller = nullptr);
|
|
180
158
|
|
|
181
|
-
|
|
182
|
-
* Handle an ICFG node by merging states and processing statements
|
|
183
|
-
*
|
|
184
|
-
* @param node The ICFG node to handle
|
|
185
|
-
* @return true if state changed, false if fixpoint reached or infeasible
|
|
186
|
-
*/
|
|
159
|
+
/// Merge predecessor states, process statements and callsites; return true if state changed
|
|
187
160
|
bool handleICFGNode(const ICFGNode* node);
|
|
188
161
|
|
|
189
|
-
|
|
190
|
-
* Get the next nodes of a node within the same function
|
|
191
|
-
*
|
|
192
|
-
* @param node The node to get successors for
|
|
193
|
-
* @return Vector of successor nodes
|
|
194
|
-
*/
|
|
162
|
+
/// Get intra-procedural successor nodes (including call-to-ret shortcut) within the same function
|
|
195
163
|
std::vector<const ICFGNode*> getNextNodes(const ICFGNode* node) const;
|
|
196
164
|
|
|
197
|
-
|
|
198
|
-
* Get the next nodes outside a cycle
|
|
199
|
-
*
|
|
200
|
-
* @param cycle The cycle to get exit successors for
|
|
201
|
-
* @return Vector of successor nodes outside the cycle
|
|
202
|
-
*/
|
|
165
|
+
/// Get successor nodes that exit the given WTO cycle (skipping inner sub-cycles)
|
|
203
166
|
std::vector<const ICFGNode*> getNextNodesOfCycle(const ICFGCycleWTO* cycle) const;
|
|
204
167
|
|
|
205
|
-
|
|
206
|
-
* handle SVF Statement like CmpStmt, CallStmt, GepStmt, LoadStmt, StoreStmt, etc.
|
|
207
|
-
*
|
|
208
|
-
* @param stmt SVFStatement which is a value flow of instruction
|
|
209
|
-
*/
|
|
168
|
+
/// Dispatch an SVF statement (Addr/Binary/Cmp/Load/Store/Copy/Gep/Select/Phi/Call/Ret) to its handler
|
|
210
169
|
virtual void handleSVFStatement(const SVFStmt* stmt);
|
|
211
170
|
|
|
171
|
+
/// Set all store targets and return value to TOP for a recursive call node
|
|
212
172
|
virtual void setTopToObjInRecursion(const CallICFGNode* callnode);
|
|
213
173
|
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Check if this cmpStmt and succ are satisfiable to the execution state.
|
|
217
|
-
*
|
|
218
|
-
* @param cmpStmt CmpStmt is a conditional branch statement
|
|
219
|
-
* @param succ the value of cmpStmt (True or False)
|
|
220
|
-
* @return if this ICFGNode has preceding execution state
|
|
221
|
-
*/
|
|
174
|
+
/// Check if cmpStmt with successor value succ is feasible; refine intervals in as accordingly
|
|
222
175
|
bool isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t succ,
|
|
223
176
|
AbstractState& as);
|
|
224
177
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
*
|
|
228
|
-
* @param var var in switch inst
|
|
229
|
-
* @param succ the case value of switch inst
|
|
230
|
-
* @return if this ICFGNode has preceding execution state
|
|
231
|
-
*/
|
|
232
|
-
bool isSwitchBranchFeasible(const SVFVar* var, s64_t succ,
|
|
233
|
-
AbstractState& as);
|
|
178
|
+
/// Check if switch branch with case value succ is feasible; refine intervals in as accordingly
|
|
179
|
+
bool isSwitchBranchFeasible(const SVFVar* var, s64_t succ, AbstractState& as);
|
|
234
180
|
|
|
235
181
|
void updateStateOnAddr(const AddrStmt *addr);
|
|
236
182
|
|
|
@@ -266,12 +212,6 @@ private:
|
|
|
266
212
|
|
|
267
213
|
PreAnalysis* preAnalysis{nullptr};
|
|
268
214
|
|
|
269
|
-
|
|
270
|
-
bool hasAbsStateFromTrace(const ICFGNode* node)
|
|
271
|
-
{
|
|
272
|
-
return abstractTrace.count(node) != 0;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
215
|
AbsExtAPI* getUtils()
|
|
276
216
|
{
|
|
277
217
|
return utils;
|
|
@@ -123,7 +123,7 @@ void BufOverflowDetector::handleStubFunctions(const SVF::CallICFGNode* callNode)
|
|
|
123
123
|
if (callNode->arg_size() < 2)
|
|
124
124
|
return;
|
|
125
125
|
AbstractState& as =
|
|
126
|
-
AbstractInterpretation::getAEInstance().
|
|
126
|
+
AbstractInterpretation::getAEInstance().getAbstractState(
|
|
127
127
|
callNode);
|
|
128
128
|
u32_t size_id = callNode->getArgument(1)->getId();
|
|
129
129
|
IntervalValue val = as[size_id].getInterval();
|
|
@@ -152,7 +152,7 @@ void BufOverflowDetector::handleStubFunctions(const SVF::CallICFGNode* callNode)
|
|
|
152
152
|
// void UNSAFE_BUFACCESS(void* data, int size);
|
|
153
153
|
AbstractInterpretation::getAEInstance().getUtils()->checkpoints.erase(callNode);
|
|
154
154
|
if (callNode->arg_size() < 2) return;
|
|
155
|
-
AbstractState&as = AbstractInterpretation::getAEInstance().
|
|
155
|
+
AbstractState&as = AbstractInterpretation::getAEInstance().getAbstractState(callNode);
|
|
156
156
|
u32_t size_id = callNode->getArgument(1)->getId();
|
|
157
157
|
IntervalValue val = as[size_id].getInterval();
|
|
158
158
|
if (val.isBottom())
|
|
@@ -591,7 +591,7 @@ void NullptrDerefDetector::handleStubFunctions(const CallICFGNode* callNode)
|
|
|
591
591
|
AbstractInterpretation::getAEInstance().getUtils()->checkpoints.erase(callNode);
|
|
592
592
|
if (callNode->arg_size() < 1)
|
|
593
593
|
return;
|
|
594
|
-
AbstractState& as = AbstractInterpretation::getAEInstance().
|
|
594
|
+
AbstractState& as = AbstractInterpretation::getAEInstance().getAbstractState(callNode);
|
|
595
595
|
|
|
596
596
|
const SVFVar* arg0Val = callNode->getArgument(0);
|
|
597
597
|
// opt may directly dereference a null pointer and call UNSAFE_LOAD(null)
|
|
@@ -614,7 +614,7 @@ void NullptrDerefDetector::handleStubFunctions(const CallICFGNode* callNode)
|
|
|
614
614
|
// void SAFE_LOAD(void* ptr);
|
|
615
615
|
AbstractInterpretation::getAEInstance().getUtils()->checkpoints.erase(callNode);
|
|
616
616
|
if (callNode->arg_size() < 1) return;
|
|
617
|
-
AbstractState&as = AbstractInterpretation::getAEInstance().
|
|
617
|
+
AbstractState&as = AbstractInterpretation::getAEInstance().getAbstractState(callNode);
|
|
618
618
|
const SVFVar* arg0Val = callNode->getArgument(0);
|
|
619
619
|
// opt may directly dereference a null pointer and call UNSAFE_LOAD(null)ols
|
|
620
620
|
bool isSafe = canSafelyDerefPtr(as, arg0Val) && arg0Val->getId() != 0;
|
|
@@ -44,7 +44,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
44
44
|
#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
|
|
45
45
|
auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
|
|
46
46
|
/* run real ext function */ \
|
|
47
|
-
AbstractState& as =
|
|
47
|
+
AbstractState& as = getAbstractState(callNode); \
|
|
48
48
|
u32_t rhs_id = callNode->getArgument(0)->getId(); \
|
|
49
49
|
if (!as.inVarToValTable(rhs_id)) return; \
|
|
50
50
|
u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \
|
|
@@ -78,7 +78,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
78
78
|
{
|
|
79
79
|
checkpoints.erase(callNode);
|
|
80
80
|
u32_t arg0 = callNode->getArgument(0)->getId();
|
|
81
|
-
AbstractState&as =
|
|
81
|
+
AbstractState&as = getAbstractState(callNode);
|
|
82
82
|
if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
|
|
83
83
|
{
|
|
84
84
|
SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
|
|
@@ -96,7 +96,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
96
96
|
{
|
|
97
97
|
u32_t arg0 = callNode->getArgument(0)->getId();
|
|
98
98
|
u32_t arg1 = callNode->getArgument(1)->getId();
|
|
99
|
-
AbstractState&as =
|
|
99
|
+
AbstractState&as = getAbstractState(callNode);
|
|
100
100
|
if (as[arg0].getInterval().equals(as[arg1].getInterval()))
|
|
101
101
|
{
|
|
102
102
|
SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
|
|
@@ -113,7 +113,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
113
113
|
auto svf_print = [&](const CallICFGNode* callNode)
|
|
114
114
|
{
|
|
115
115
|
if (callNode->arg_size() < 2) return;
|
|
116
|
-
AbstractState&as =
|
|
116
|
+
AbstractState&as = getAbstractState(callNode);
|
|
117
117
|
u32_t num_id = callNode->getArgument(0)->getId();
|
|
118
118
|
std::string text = strRead(as, callNode->getArgument(1));
|
|
119
119
|
assert(as.inVarToValTable(num_id) && "print() should pass integer");
|
|
@@ -127,7 +127,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
127
127
|
auto svf_set_value = [&](const CallICFGNode* callNode)
|
|
128
128
|
{
|
|
129
129
|
if (callNode->arg_size() < 2) return;
|
|
130
|
-
AbstractState&as =
|
|
130
|
+
AbstractState&as = getAbstractState(callNode);
|
|
131
131
|
AbstractValue& num = as[callNode->getArgument(0)->getId()];
|
|
132
132
|
AbstractValue& lb = as[callNode->getArgument(1)->getId()];
|
|
133
133
|
AbstractValue& ub = as[callNode->getArgument(2)->getId()];
|
|
@@ -150,7 +150,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
150
150
|
|
|
151
151
|
auto sse_scanf = [&](const CallICFGNode* callNode)
|
|
152
152
|
{
|
|
153
|
-
AbstractState& as =
|
|
153
|
+
AbstractState& as = getAbstractState(callNode);
|
|
154
154
|
//scanf("%d", &data);
|
|
155
155
|
if (callNode->arg_size() < 2) return;
|
|
156
156
|
|
|
@@ -174,7 +174,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
174
174
|
{
|
|
175
175
|
//fscanf(stdin, "%d", &data);
|
|
176
176
|
if (callNode->arg_size() < 3) return;
|
|
177
|
-
AbstractState& as =
|
|
177
|
+
AbstractState& as = getAbstractState(callNode);
|
|
178
178
|
u32_t dst_id = callNode->getArgument(2)->getId();
|
|
179
179
|
if (!as.inVarToAddrsTable(dst_id))
|
|
180
180
|
{
|
|
@@ -203,7 +203,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
203
203
|
auto sse_fread = [&](const CallICFGNode *callNode)
|
|
204
204
|
{
|
|
205
205
|
if (callNode->arg_size() < 3) return;
|
|
206
|
-
AbstractState&as =
|
|
206
|
+
AbstractState&as = getAbstractState(callNode);
|
|
207
207
|
u32_t block_count_id = callNode->getArgument(2)->getId();
|
|
208
208
|
u32_t block_size_id = callNode->getArgument(1)->getId();
|
|
209
209
|
IntervalValue block_count = as[block_count_id].getInterval();
|
|
@@ -220,7 +220,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
220
220
|
auto sse_snprintf = [&](const CallICFGNode *callNode)
|
|
221
221
|
{
|
|
222
222
|
if (callNode->arg_size() < 2) return;
|
|
223
|
-
AbstractState&as =
|
|
223
|
+
AbstractState&as = getAbstractState(callNode);
|
|
224
224
|
u32_t size_id = callNode->getArgument(1)->getId();
|
|
225
225
|
u32_t dst_id = callNode->getArgument(0)->getId();
|
|
226
226
|
// get elem size of arg2
|
|
@@ -261,7 +261,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
261
261
|
// itoa(num, ch, 10);
|
|
262
262
|
// num: int, ch: char*, 10 is decimal
|
|
263
263
|
if (callNode->arg_size() < 3) return;
|
|
264
|
-
AbstractState&as =
|
|
264
|
+
AbstractState&as = getAbstractState(callNode);
|
|
265
265
|
u32_t num_id = callNode->getArgument(0)->getId();
|
|
266
266
|
|
|
267
267
|
u32_t num = (u32_t) as[num_id].getInterval().getNumeral();
|
|
@@ -273,7 +273,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
273
273
|
auto sse_strlen = [&](const CallICFGNode *callNode)
|
|
274
274
|
{
|
|
275
275
|
if (callNode->arg_size() < 1) return;
|
|
276
|
-
AbstractState& as =
|
|
276
|
+
AbstractState& as = getAbstractState(callNode);
|
|
277
277
|
u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId();
|
|
278
278
|
// strlen/wcslen return the number of characters (not bytes).
|
|
279
279
|
// getStrlen returns byte-scaled length (len * elemSize) for use
|
|
@@ -293,7 +293,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
293
293
|
{
|
|
294
294
|
// recv(sockfd, buf, len, flags);
|
|
295
295
|
if (callNode->arg_size() < 4) return;
|
|
296
|
-
AbstractState&as =
|
|
296
|
+
AbstractState&as = getAbstractState(callNode);
|
|
297
297
|
u32_t len_id = callNode->getArgument(2)->getId();
|
|
298
298
|
IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
|
|
299
299
|
u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId();
|
|
@@ -305,7 +305,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
305
305
|
auto sse_free = [&](const CallICFGNode *callNode)
|
|
306
306
|
{
|
|
307
307
|
if (callNode->arg_size() < 1) return;
|
|
308
|
-
AbstractState& as =
|
|
308
|
+
AbstractState& as = getAbstractState(callNode);
|
|
309
309
|
const u32_t freePtr = callNode->getArgument(0)->getId();
|
|
310
310
|
for (auto addr: as[freePtr].getAddrs())
|
|
311
311
|
{
|
|
@@ -335,7 +335,7 @@ void AbsExtAPI::initExtFunMap()
|
|
|
335
335
|
}
|
|
336
336
|
};
|
|
337
337
|
|
|
338
|
-
AbstractState& AbsExtAPI::
|
|
338
|
+
AbstractState& AbsExtAPI::getAbstractState(const SVF::ICFGNode* node)
|
|
339
339
|
{
|
|
340
340
|
if (abstractTrace.count(node) == 0)
|
|
341
341
|
{
|
|
@@ -435,7 +435,7 @@ std::string AbsExtAPI::strRead(AbstractState& as, const SVFVar* rhs)
|
|
|
435
435
|
|
|
436
436
|
void AbsExtAPI::handleExtAPI(const CallICFGNode *call)
|
|
437
437
|
{
|
|
438
|
-
AbstractState& as =
|
|
438
|
+
AbstractState& as = getAbstractState(call);
|
|
439
439
|
const FunObjVar *fun = call->getCalledFunction();
|
|
440
440
|
assert(fun && "FunObjVar* is nullptr");
|
|
441
441
|
ExtAPIType extType = UNCLASSIFIED;
|
|
@@ -611,7 +611,7 @@ IntervalValue AbsExtAPI::getStrlen(AbstractState& as, const SVF::SVFVar *strValu
|
|
|
611
611
|
/// Covers: strcpy, __strcpy_chk, stpcpy, wcscpy, __wcscpy_chk
|
|
612
612
|
void AbsExtAPI::handleStrcpy(const CallICFGNode *call)
|
|
613
613
|
{
|
|
614
|
-
AbstractState& as =
|
|
614
|
+
AbstractState& as = getAbstractState(call);
|
|
615
615
|
const SVFVar* dst = call->getArgument(0);
|
|
616
616
|
const SVFVar* src = call->getArgument(1);
|
|
617
617
|
IntervalValue srcLen = getStrlen(as, src);
|
|
@@ -624,7 +624,7 @@ void AbsExtAPI::handleStrcpy(const CallICFGNode *call)
|
|
|
624
624
|
/// Covers: strcat, __strcat_chk, wcscat, __wcscat_chk
|
|
625
625
|
void AbsExtAPI::handleStrcat(const CallICFGNode *call)
|
|
626
626
|
{
|
|
627
|
-
AbstractState& as =
|
|
627
|
+
AbstractState& as = getAbstractState(call);
|
|
628
628
|
const SVFVar* dst = call->getArgument(0);
|
|
629
629
|
const SVFVar* src = call->getArgument(1);
|
|
630
630
|
IntervalValue dstLen = getStrlen(as, dst);
|
|
@@ -637,7 +637,7 @@ void AbsExtAPI::handleStrcat(const CallICFGNode *call)
|
|
|
637
637
|
/// Covers: strncat, __strncat_chk, wcsncat, __wcsncat_chk
|
|
638
638
|
void AbsExtAPI::handleStrncat(const CallICFGNode *call)
|
|
639
639
|
{
|
|
640
|
-
AbstractState& as =
|
|
640
|
+
AbstractState& as = getAbstractState(call);
|
|
641
641
|
const SVFVar* dst = call->getArgument(0);
|
|
642
642
|
const SVFVar* src = call->getArgument(1);
|
|
643
643
|
IntervalValue n = as[call->getArgument(2)->getId()].getInterval();
|
|
@@ -71,6 +71,86 @@ AbstractInterpretation::AbstractInterpretation()
|
|
|
71
71
|
{
|
|
72
72
|
stat = new AEStat(this);
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
AbstractState& AbstractInterpretation::getAbstractState(const ICFGNode* node)
|
|
76
|
+
{
|
|
77
|
+
if (abstractTrace.count(node) == 0)
|
|
78
|
+
{
|
|
79
|
+
assert(false && "No preAbsTrace for this node");
|
|
80
|
+
abort();
|
|
81
|
+
}
|
|
82
|
+
else
|
|
83
|
+
{
|
|
84
|
+
return abstractTrace[node];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
bool AbstractInterpretation::hasAbsStateFromTrace(const ICFGNode* node)
|
|
89
|
+
{
|
|
90
|
+
return abstractTrace.count(node) != 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
AbstractValue& AbstractInterpretation::getAbstractValue(const ICFGNode* node, const ValVar* var)
|
|
94
|
+
{
|
|
95
|
+
AbstractState& as = getAbstractState(node);
|
|
96
|
+
return as[var->getId()];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
AbstractValue& AbstractInterpretation::getAbstractValue(const ICFGNode* node, const ObjVar* var)
|
|
100
|
+
{
|
|
101
|
+
AbstractState& as = getAbstractState(node);
|
|
102
|
+
u32_t addr = AbstractState::getVirtualMemAddress(var->getId());
|
|
103
|
+
return as.load(addr);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
AbstractValue& AbstractInterpretation::getAbstractValue(const ICFGNode* node, const SVFVar* var)
|
|
107
|
+
{
|
|
108
|
+
if (const ValVar* valVar = SVFUtil::dyn_cast<ValVar>(var))
|
|
109
|
+
return getAbstractValue(node, valVar);
|
|
110
|
+
else if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(var))
|
|
111
|
+
return getAbstractValue(node, objVar);
|
|
112
|
+
assert(false && "Unknown SVFVar kind");
|
|
113
|
+
abort();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void AbstractInterpretation::getAbstractState(const ICFGNode* node, const Set<const ValVar*>& vars, AbstractState& result)
|
|
117
|
+
{
|
|
118
|
+
AbstractState& as = getAbstractState(node);
|
|
119
|
+
for (const ValVar* var : vars)
|
|
120
|
+
{
|
|
121
|
+
u32_t id = var->getId();
|
|
122
|
+
result[id] = as[id];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
void AbstractInterpretation::getAbstractState(const ICFGNode* node, const Set<const ObjVar*>& vars, AbstractState& result)
|
|
127
|
+
{
|
|
128
|
+
AbstractState& as = getAbstractState(node);
|
|
129
|
+
for (const ObjVar* var : vars)
|
|
130
|
+
{
|
|
131
|
+
u32_t addr = AbstractState::getVirtualMemAddress(var->getId());
|
|
132
|
+
result.store(addr, as.load(addr));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void AbstractInterpretation::getAbstractState(const ICFGNode* node, const Set<const SVFVar*>& vars, AbstractState& result)
|
|
137
|
+
{
|
|
138
|
+
AbstractState& as = getAbstractState(node);
|
|
139
|
+
for (const SVFVar* var : vars)
|
|
140
|
+
{
|
|
141
|
+
if (const ValVar* valVar = SVFUtil::dyn_cast<ValVar>(var))
|
|
142
|
+
{
|
|
143
|
+
u32_t id = valVar->getId();
|
|
144
|
+
result[id] = as[id];
|
|
145
|
+
}
|
|
146
|
+
else if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(var))
|
|
147
|
+
{
|
|
148
|
+
u32_t addr = AbstractState::getVirtualMemAddress(objVar->getId());
|
|
149
|
+
result.store(addr, as.load(addr));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
74
154
|
/// Destructor
|
|
75
155
|
AbstractInterpretation::~AbstractInterpretation()
|
|
76
156
|
{
|
|
@@ -566,7 +646,7 @@ void AbstractInterpretation::handleSingletonWTO(const ICFGSingletonWTO *icfgSing
|
|
|
566
646
|
handleCallSite(callnode);
|
|
567
647
|
}
|
|
568
648
|
for (auto& detector: detectors)
|
|
569
|
-
detector->detect(
|
|
649
|
+
detector->detect(getAbstractState(node), node);
|
|
570
650
|
stat->countStateSize();
|
|
571
651
|
}
|
|
572
652
|
|
|
@@ -625,7 +705,7 @@ bool AbstractInterpretation::handleICFGNode(const ICFGNode* node)
|
|
|
625
705
|
|
|
626
706
|
// Run detectors
|
|
627
707
|
for (auto& detector: detectors)
|
|
628
|
-
detector->detect(
|
|
708
|
+
detector->detect(getAbstractState(node), node);
|
|
629
709
|
stat->countStateSize();
|
|
630
710
|
|
|
631
711
|
// Track this node as analyzed (for coverage statistics across all entry points)
|
|
@@ -792,7 +872,7 @@ bool AbstractInterpretation::isRecursiveFun(const FunObjVar* fun)
|
|
|
792
872
|
/// Handle recursive call in TOP mode: set all stores and return value to TOP
|
|
793
873
|
void AbstractInterpretation::handleRecursiveCall(const CallICFGNode *callNode)
|
|
794
874
|
{
|
|
795
|
-
AbstractState& as =
|
|
875
|
+
AbstractState& as = getAbstractState(callNode);
|
|
796
876
|
setTopToObjInRecursion(callNode);
|
|
797
877
|
const RetICFGNode *retNode = callNode->getRetICFGNode();
|
|
798
878
|
if (retNode->getSVFStmts().size() > 0)
|
|
@@ -834,7 +914,7 @@ const FunObjVar* AbstractInterpretation::getCallee(const CallICFGNode* callNode)
|
|
|
834
914
|
if (!hasAbsStateFromTrace(callNode))
|
|
835
915
|
return nullptr;
|
|
836
916
|
|
|
837
|
-
AbstractState& as =
|
|
917
|
+
AbstractState& as = getAbstractState(callNode);
|
|
838
918
|
if (!as.inVarToAddrsTable(call_id))
|
|
839
919
|
return nullptr;
|
|
840
920
|
|
|
@@ -899,7 +979,7 @@ bool AbstractInterpretation::shouldApplyNarrowing(const FunObjVar* fun)
|
|
|
899
979
|
/// possible indirect call targets.
|
|
900
980
|
void AbstractInterpretation::handleFunCall(const CallICFGNode *callNode)
|
|
901
981
|
{
|
|
902
|
-
AbstractState& as =
|
|
982
|
+
AbstractState& as = getAbstractState(callNode);
|
|
903
983
|
abstractTrace[callNode] = as;
|
|
904
984
|
|
|
905
985
|
// Skip recursive callsites (within SCC); entry calls are not skipped
|
|
@@ -1110,14 +1190,14 @@ void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt)
|
|
|
1110
1190
|
else
|
|
1111
1191
|
assert(false && "implement this part");
|
|
1112
1192
|
// NullPtr is index 0, it should not be changed
|
|
1113
|
-
assert(!
|
|
1114
|
-
!
|
|
1193
|
+
assert(!getAbstractState(stmt->getICFGNode())[IRGraph::NullPtr].isInterval() &&
|
|
1194
|
+
!getAbstractState(stmt->getICFGNode())[IRGraph::NullPtr].isAddr());
|
|
1115
1195
|
}
|
|
1116
1196
|
|
|
1117
1197
|
/// Set all store values in a recursive function to TOP (used in TOP mode)
|
|
1118
1198
|
void AbstractInterpretation::setTopToObjInRecursion(const CallICFGNode *callNode)
|
|
1119
1199
|
{
|
|
1120
|
-
AbstractState& as =
|
|
1200
|
+
AbstractState& as = getAbstractState(callNode);
|
|
1121
1201
|
const RetICFGNode *retNode = callNode->getRetICFGNode();
|
|
1122
1202
|
if (retNode->getSVFStmts().size() > 0)
|
|
1123
1203
|
{
|
|
@@ -1170,7 +1250,7 @@ void AbstractInterpretation::setTopToObjInRecursion(const CallICFGNode *callNode
|
|
|
1170
1250
|
|
|
1171
1251
|
void AbstractInterpretation::updateStateOnGep(const GepStmt *gep)
|
|
1172
1252
|
{
|
|
1173
|
-
AbstractState& as =
|
|
1253
|
+
AbstractState& as = getAbstractState(gep->getICFGNode());
|
|
1174
1254
|
u32_t rhs = gep->getRHSVarID();
|
|
1175
1255
|
u32_t lhs = gep->getLHSVarID();
|
|
1176
1256
|
IntervalValue offsetPair = as.getElementIndex(gep);
|
|
@@ -1186,7 +1266,7 @@ void AbstractInterpretation::updateStateOnGep(const GepStmt *gep)
|
|
|
1186
1266
|
|
|
1187
1267
|
void AbstractInterpretation::updateStateOnSelect(const SelectStmt *select)
|
|
1188
1268
|
{
|
|
1189
|
-
AbstractState& as =
|
|
1269
|
+
AbstractState& as = getAbstractState(select->getICFGNode());
|
|
1190
1270
|
u32_t res = select->getResID();
|
|
1191
1271
|
u32_t tval = select->getTrueValue()->getId();
|
|
1192
1272
|
u32_t fval = select->getFalseValue()->getId();
|
|
@@ -1205,7 +1285,7 @@ void AbstractInterpretation::updateStateOnSelect(const SelectStmt *select)
|
|
|
1205
1285
|
void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi)
|
|
1206
1286
|
{
|
|
1207
1287
|
const ICFGNode* icfgNode = phi->getICFGNode();
|
|
1208
|
-
AbstractState& as =
|
|
1288
|
+
AbstractState& as = getAbstractState(icfgNode);
|
|
1209
1289
|
u32_t res = phi->getResID();
|
|
1210
1290
|
AbstractValue rhs;
|
|
1211
1291
|
for (u32_t i = 0; i < phi->getOpVarNum(); i++)
|
|
@@ -1215,7 +1295,7 @@ void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi)
|
|
|
1215
1295
|
if (hasAbsStateFromTrace(opICFGNode))
|
|
1216
1296
|
{
|
|
1217
1297
|
AbstractState tmpEs = abstractTrace[opICFGNode];
|
|
1218
|
-
AbstractState& opAs =
|
|
1298
|
+
AbstractState& opAs = getAbstractState(opICFGNode);
|
|
1219
1299
|
const ICFGEdge* edge = icfg->getICFGEdge(opICFGNode, icfgNode, ICFGEdge::IntraCF);
|
|
1220
1300
|
// if IntraEdge, check the condition, if it is feasible, join the value
|
|
1221
1301
|
// if IntraEdge but not conditional edge, join the value
|
|
@@ -1243,7 +1323,7 @@ void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi)
|
|
|
1243
1323
|
|
|
1244
1324
|
void AbstractInterpretation::updateStateOnCall(const CallPE *callPE)
|
|
1245
1325
|
{
|
|
1246
|
-
AbstractState& as =
|
|
1326
|
+
AbstractState& as = getAbstractState(callPE->getICFGNode());
|
|
1247
1327
|
NodeID lhs = callPE->getLHSVarID();
|
|
1248
1328
|
NodeID rhs = callPE->getRHSVarID();
|
|
1249
1329
|
as[lhs] = as[rhs];
|
|
@@ -1251,7 +1331,7 @@ void AbstractInterpretation::updateStateOnCall(const CallPE *callPE)
|
|
|
1251
1331
|
|
|
1252
1332
|
void AbstractInterpretation::updateStateOnRet(const RetPE *retPE)
|
|
1253
1333
|
{
|
|
1254
|
-
AbstractState& as =
|
|
1334
|
+
AbstractState& as = getAbstractState(retPE->getICFGNode());
|
|
1255
1335
|
NodeID lhs = retPE->getLHSVarID();
|
|
1256
1336
|
NodeID rhs = retPE->getRHSVarID();
|
|
1257
1337
|
as[lhs] = as[rhs];
|
|
@@ -1260,7 +1340,7 @@ void AbstractInterpretation::updateStateOnRet(const RetPE *retPE)
|
|
|
1260
1340
|
|
|
1261
1341
|
void AbstractInterpretation::updateStateOnAddr(const AddrStmt *addr)
|
|
1262
1342
|
{
|
|
1263
|
-
AbstractState& as =
|
|
1343
|
+
AbstractState& as = getAbstractState(addr->getICFGNode());
|
|
1264
1344
|
as.initObjVar(SVFUtil::cast<ObjVar>(addr->getRHSVar()));
|
|
1265
1345
|
if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy)
|
|
1266
1346
|
as[addr->getRHSVarID()].getInterval().meet_with(utils->getRangeLimitFromType(addr->getRHSVar()->getType()));
|
|
@@ -1274,7 +1354,7 @@ void AbstractInterpretation::updateStateOnBinary(const BinaryOPStmt *binary)
|
|
|
1274
1354
|
/// You are only required to handle integer predicates, including Add, FAdd, Sub, FSub, Mul, FMul, SDiv, FDiv, UDiv,
|
|
1275
1355
|
/// SRem, FRem, URem, Xor, And, Or, AShr, Shl, LShr
|
|
1276
1356
|
const ICFGNode* node = binary->getICFGNode();
|
|
1277
|
-
AbstractState& as =
|
|
1357
|
+
AbstractState& as = getAbstractState(node);
|
|
1278
1358
|
u32_t op0 = binary->getOpVarID(0);
|
|
1279
1359
|
u32_t op1 = binary->getOpVarID(1);
|
|
1280
1360
|
u32_t res = binary->getResID();
|
|
@@ -1332,7 +1412,7 @@ void AbstractInterpretation::updateStateOnBinary(const BinaryOPStmt *binary)
|
|
|
1332
1412
|
|
|
1333
1413
|
void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp)
|
|
1334
1414
|
{
|
|
1335
|
-
AbstractState& as =
|
|
1415
|
+
AbstractState& as = getAbstractState(cmp->getICFGNode());
|
|
1336
1416
|
u32_t op0 = cmp->getOpVarID(0);
|
|
1337
1417
|
u32_t op1 = cmp->getOpVarID(1);
|
|
1338
1418
|
// if it is address
|
|
@@ -1561,7 +1641,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp)
|
|
|
1561
1641
|
|
|
1562
1642
|
void AbstractInterpretation::updateStateOnLoad(const LoadStmt *load)
|
|
1563
1643
|
{
|
|
1564
|
-
AbstractState& as =
|
|
1644
|
+
AbstractState& as = getAbstractState(load->getICFGNode());
|
|
1565
1645
|
u32_t rhs = load->getRHSVarID();
|
|
1566
1646
|
u32_t lhs = load->getLHSVarID();
|
|
1567
1647
|
as[lhs] = as.loadValue(rhs);
|
|
@@ -1569,7 +1649,7 @@ void AbstractInterpretation::updateStateOnLoad(const LoadStmt *load)
|
|
|
1569
1649
|
|
|
1570
1650
|
void AbstractInterpretation::updateStateOnStore(const StoreStmt *store)
|
|
1571
1651
|
{
|
|
1572
|
-
AbstractState& as =
|
|
1652
|
+
AbstractState& as = getAbstractState(store->getICFGNode());
|
|
1573
1653
|
u32_t rhs = store->getRHSVarID();
|
|
1574
1654
|
u32_t lhs = store->getLHSVarID();
|
|
1575
1655
|
as.storeValue(lhs, as[rhs]);
|
|
@@ -1673,7 +1753,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
|
|
|
1673
1753
|
}
|
|
1674
1754
|
};
|
|
1675
1755
|
|
|
1676
|
-
AbstractState& as =
|
|
1756
|
+
AbstractState& as = getAbstractState(copy->getICFGNode());
|
|
1677
1757
|
u32_t lhs = copy->getLHSVarID();
|
|
1678
1758
|
u32_t rhs = copy->getRHSVarID();
|
|
1679
1759
|
|