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.
Files changed (126) hide show
  1. package/package.json +1 -1
  2. package/svf/include/AE/Core/AbstractState.h +1 -2
  3. package/svf/include/AE/Svfexe/AbsExtAPI.h +1 -1
  4. package/svf/include/AE/Svfexe/AbstractInterpretation.h +37 -97
  5. package/svf/lib/AE/Svfexe/AEDetector.cpp +4 -4
  6. package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +18 -18
  7. package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +100 -20
  8. package/SVF-doxygen/doxygen.config +0 -2548
  9. package/SVF-doxygen/wiki/PAG.png +0 -0
  10. package/SVF-doxygen/wiki/andersen.png +0 -0
  11. package/SVF-doxygen/wiki/callgraph.png +0 -0
  12. package/SVF-doxygen/wiki/consG.png +0 -0
  13. package/SVF-doxygen/wiki/cpu2000-flto +0 -432
  14. package/SVF-doxygen/wiki/cpu2006-flto +0 -417
  15. package/SVF-doxygen/wiki/cpu2017-wllvm.cfg +0 -999
  16. package/SVF-doxygen/wiki/database.png +0 -0
  17. package/SVF-doxygen/wiki/framework.png +0 -0
  18. package/SVF-doxygen/wiki/help.png +0 -0
  19. package/SVF-doxygen/wiki/icfg.png +0 -0
  20. package/SVF-doxygen/wiki/mssa-cha.png +0 -0
  21. package/SVF-doxygen/wiki/pagedge.png +0 -0
  22. package/SVF-doxygen/wiki/pagnode.png +0 -0
  23. package/SVF-doxygen/wiki/pt.png +0 -0
  24. package/SVF-doxygen/wiki/setupcmake.png +0 -0
  25. package/SVF-doxygen/wiki/setupconfiguration.png +0 -0
  26. package/SVF-doxygen/wiki/setupdashboard.png +0 -0
  27. package/SVF-doxygen/wiki/setupdebug.png +0 -0
  28. package/SVF-doxygen/wiki/setupenv.png +0 -0
  29. package/SVF-doxygen/wiki/startup.png +0 -0
  30. package/SVF-doxygen/wiki/svf-stat.pdf +0 -0
  31. package/SVF-doxygen/wiki/svfg-framework.png +0 -0
  32. package/SVF-doxygen/wiki/svfg.png +0 -0
  33. package/SVF-doxygen/wiki/svfg_opt.png +0 -0
  34. package/SVF-doxygen/wiki/svfgedge-cha.png +0 -0
  35. package/SVF-doxygen/wiki/svfgnode-cha.png +0 -0
  36. package/SVF-doxygen/wiki/svfpic/README.md +0 -6
  37. package/SVF-doxygen/wiki/svfpic/ass-1debug1.png +0 -0
  38. package/SVF-doxygen/wiki/svfpic/ass-1debug2.png +0 -0
  39. package/SVF-doxygen/wiki/svfpic/build.jpg +0 -0
  40. package/SVF-doxygen/wiki/svfpic/cmd.png +0 -0
  41. package/SVF-doxygen/wiki/svfpic/connect1.jpg +0 -0
  42. package/SVF-doxygen/wiki/svfpic/connect2.png +0 -0
  43. package/SVF-doxygen/wiki/svfpic/connect3.png +0 -0
  44. package/SVF-doxygen/wiki/svfpic/connect4.jpg +0 -0
  45. package/SVF-doxygen/wiki/svfpic/connect5.jpg +0 -0
  46. package/SVF-doxygen/wiki/svfpic/connect6.png +0 -0
  47. package/SVF-doxygen/wiki/svfpic/connect7.jpg +0 -0
  48. package/SVF-doxygen/wiki/svfpic/continue.png +0 -0
  49. package/SVF-doxygen/wiki/svfpic/debug-new.png +0 -0
  50. package/SVF-doxygen/wiki/svfpic/debug-new2.png +0 -0
  51. package/SVF-doxygen/wiki/svfpic/debug1.jpeg +0 -0
  52. package/SVF-doxygen/wiki/svfpic/debug2.jpeg +0 -0
  53. package/SVF-doxygen/wiki/svfpic/debug3.png +0 -0
  54. package/SVF-doxygen/wiki/svfpic/debug4.png +0 -0
  55. package/SVF-doxygen/wiki/svfpic/debug5.jpeg +0 -0
  56. package/SVF-doxygen/wiki/svfpic/debug6.jpeg +0 -0
  57. package/SVF-doxygen/wiki/svfpic/docker_sys_requirement.png +0 -0
  58. package/SVF-doxygen/wiki/svfpic/docker_sys_requirements.png +0 -0
  59. package/SVF-doxygen/wiki/svfpic/dockerbuild.png +0 -0
  60. package/SVF-doxygen/wiki/svfpic/dockerbuild2.jpg +0 -0
  61. package/SVF-doxygen/wiki/svfpic/dockerbuild3.jpg +0 -0
  62. package/SVF-doxygen/wiki/svfpic/dockerbuild4.png +0 -0
  63. package/SVF-doxygen/wiki/svfpic/dockerbuild5.jpg +0 -0
  64. package/SVF-doxygen/wiki/svfpic/dockerbuildimage.png +0 -0
  65. package/SVF-doxygen/wiki/svfpic/dockercmd.png +0 -0
  66. package/SVF-doxygen/wiki/svfpic/dockercmd2.png +0 -0
  67. package/SVF-doxygen/wiki/svfpic/dockercontainer.png +0 -0
  68. package/SVF-doxygen/wiki/svfpic/dockerdb1.jpg +0 -0
  69. package/SVF-doxygen/wiki/svfpic/dockerdb10.jpeg +0 -0
  70. package/SVF-doxygen/wiki/svfpic/dockerdb2.jpg +0 -0
  71. package/SVF-doxygen/wiki/svfpic/dockerdb3.jpg +0 -0
  72. package/SVF-doxygen/wiki/svfpic/dockerdb4.jpg +0 -0
  73. package/SVF-doxygen/wiki/svfpic/dockerdb5.png +0 -0
  74. package/SVF-doxygen/wiki/svfpic/dockerdb6.jpeg +0 -0
  75. package/SVF-doxygen/wiki/svfpic/dockerdb7.png +0 -0
  76. package/SVF-doxygen/wiki/svfpic/dockerdb8.png +0 -0
  77. package/SVF-doxygen/wiki/svfpic/dockerdb9.jpeg +0 -0
  78. package/SVF-doxygen/wiki/svfpic/dockerfinshbuilt.png +0 -0
  79. package/SVF-doxygen/wiki/svfpic/dockerimage.png +0 -0
  80. package/SVF-doxygen/wiki/svfpic/dockernameImage.png +0 -0
  81. package/SVF-doxygen/wiki/svfpic/dockerpull.png +0 -0
  82. package/SVF-doxygen/wiki/svfpic/dockerpull2.png +0 -0
  83. package/SVF-doxygen/wiki/svfpic/download.jpg +0 -0
  84. package/SVF-doxygen/wiki/svfpic/extension1.jpeg +0 -0
  85. package/SVF-doxygen/wiki/svfpic/extension2.jpeg +0 -0
  86. package/SVF-doxygen/wiki/svfpic/graphviz.png +0 -0
  87. package/SVF-doxygen/wiki/svfpic/hellodb.png +0 -0
  88. package/SVF-doxygen/wiki/svfpic/hellodb2.png +0 -0
  89. package/SVF-doxygen/wiki/svfpic/hviz_0.png +0 -0
  90. package/SVF-doxygen/wiki/svfpic/hviz_1.png +0 -0
  91. package/SVF-doxygen/wiki/svfpic/hviz_2.png +0 -0
  92. package/SVF-doxygen/wiki/svfpic/installC:C++Ext.png +0 -0
  93. package/SVF-doxygen/wiki/svfpic/installCMakeExt.png +0 -0
  94. package/SVF-doxygen/wiki/svfpic/installRCext.png +0 -0
  95. package/SVF-doxygen/wiki/svfpic/installdockerext.png +0 -0
  96. package/SVF-doxygen/wiki/svfpic/launch1.png +0 -0
  97. package/SVF-doxygen/wiki/svfpic/openfile.png +0 -0
  98. package/SVF-doxygen/wiki/svfpic/pathfolder.png +0 -0
  99. package/SVF-doxygen/wiki/svfpic/restart.png +0 -0
  100. package/SVF-doxygen/wiki/svfpic/rundocker.png +0 -0
  101. package/SVF-doxygen/wiki/svfpic/runinCLI.png +0 -0
  102. package/SVF-doxygen/wiki/svfpic/screen.png +0 -0
  103. package/SVF-doxygen/wiki/svfpic/settings1.jpg +0 -0
  104. package/SVF-doxygen/wiki/svfpic/settings2.jpg +0 -0
  105. package/SVF-doxygen/wiki/svfpic/settings3.jpg +0 -0
  106. package/SVF-doxygen/wiki/svfpic/shortlists.png +0 -0
  107. package/SVF-doxygen/wiki/svfpic/start.png +0 -0
  108. package/SVF-doxygen/wiki/svfpic/start1.png +0 -0
  109. package/SVF-doxygen/wiki/svfpic/update0.png +0 -0
  110. package/SVF-doxygen/wiki/svfpic/verify_docker.png +0 -0
  111. package/SVF-doxygen/wiki/svfpic/vs_entry_window.png +0 -0
  112. package/SVF-doxygen/wiki/svfpic/wsl.png +0 -0
  113. package/SVF-doxygen/wiki/svfpic/wsl_1.png +0 -0
  114. package/SVF-doxygen/wiki/svfpic/wsl_2.png +0 -0
  115. package/SVF-doxygen/wiki/svfpic/wsl_3.png +0 -0
  116. package/SVF-doxygen/wiki/tools.png +0 -0
  117. package/SVF-doxygen/wiki/users.png +0 -0
  118. package/SVF-doxygen/wiki/vm1.png +0 -0
  119. package/SVF-doxygen/wiki/vm2.png +0 -0
  120. package/SVF-doxygen/wiki/vm3.png +0 -0
  121. package/SVF-doxygen/wiki/vm4.png +0 -0
  122. package/SVF-doxygen/wiki/vm5.png +0 -0
  123. package/SVF-doxygen/wiki/vscode_build_tasks.png +0 -0
  124. package/SVF-doxygen/wiki/vscode_cpp_extension.png +0 -0
  125. package/SVF-doxygen/wiki/vscode_debug_list.png +0 -0
  126. 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.1208",
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& getAbsStateFromTrace(const ICFGNode* node);
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
- /// Global ICFGNode is handled at the entry of the program,
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
- * Check if this SwitchInst and succ are satisfiable to the execution state.
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().getAbsStateFromTrace(
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().getAbsStateFromTrace(callNode);
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().getAbsStateFromTrace(callNode);
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().getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode); \
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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::getAbsStateFromTrace(const SVF::ICFGNode* node)
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 = getAbsStateFromTrace(call);
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 = getAbsStateFromTrace(call);
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 = getAbsStateFromTrace(call);
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 = getAbsStateFromTrace(call);
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(getAbsStateFromTrace(node), node);
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(getAbsStateFromTrace(node), node);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(callNode);
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(!getAbsStateFromTrace(stmt->getICFGNode())[IRGraph::NullPtr].isInterval() &&
1114
- !getAbsStateFromTrace(stmt->getICFGNode())[IRGraph::NullPtr].isAddr());
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 = getAbsStateFromTrace(callNode);
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 = getAbsStateFromTrace(gep->getICFGNode());
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 = getAbsStateFromTrace(select->getICFGNode());
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 = getAbsStateFromTrace(icfgNode);
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 = getAbsStateFromTrace(opICFGNode);
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 = getAbsStateFromTrace(callPE->getICFGNode());
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 = getAbsStateFromTrace(retPE->getICFGNode());
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 = getAbsStateFromTrace(addr->getICFGNode());
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 = getAbsStateFromTrace(node);
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 = getAbsStateFromTrace(cmp->getICFGNode());
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 = getAbsStateFromTrace(load->getICFGNode());
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 = getAbsStateFromTrace(store->getICFGNode());
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 = getAbsStateFromTrace(copy->getICFGNode());
1756
+ AbstractState& as = getAbstractState(copy->getICFGNode());
1677
1757
  u32_t lhs = copy->getLHSVarID();
1678
1758
  u32_t rhs = copy->getRHSVarID();
1679
1759