svf-tools 1.0.1238 → 1.0.1239

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 (132) hide show
  1. package/Dockerfile +1 -1
  2. package/build.sh +3 -3
  3. package/package.json +1 -1
  4. package/setup.sh +1 -1
  5. package/svf-llvm/CMakeLists.txt +15 -0
  6. package/svf-llvm/include/SVF-LLVM/BasicTypes.h +4 -0
  7. package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +4 -0
  8. package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +2 -0
  9. package/svf-llvm/lib/LLVMModule.cpp +13 -7
  10. package/svf-llvm/lib/LLVMUtil.cpp +1 -0
  11. package/svf-llvm/lib/SVFIRBuilder.cpp +151 -23
  12. package/svf-llvm/lib/SVFIRExtAPI.cpp +136 -1
  13. package/svf-llvm/tools/Example/svf-ex.cpp +2 -1
  14. package/SVF-doxygen/doxygen.config +0 -2548
  15. package/SVF-doxygen/wiki/PAG.png +0 -0
  16. package/SVF-doxygen/wiki/andersen.png +0 -0
  17. package/SVF-doxygen/wiki/callgraph.png +0 -0
  18. package/SVF-doxygen/wiki/consG.png +0 -0
  19. package/SVF-doxygen/wiki/cpu2000-flto +0 -432
  20. package/SVF-doxygen/wiki/cpu2006-flto +0 -417
  21. package/SVF-doxygen/wiki/cpu2017-wllvm.cfg +0 -999
  22. package/SVF-doxygen/wiki/database.png +0 -0
  23. package/SVF-doxygen/wiki/framework.png +0 -0
  24. package/SVF-doxygen/wiki/help.png +0 -0
  25. package/SVF-doxygen/wiki/icfg.png +0 -0
  26. package/SVF-doxygen/wiki/mssa-cha.png +0 -0
  27. package/SVF-doxygen/wiki/pagedge.png +0 -0
  28. package/SVF-doxygen/wiki/pagnode.png +0 -0
  29. package/SVF-doxygen/wiki/pt.png +0 -0
  30. package/SVF-doxygen/wiki/setupcmake.png +0 -0
  31. package/SVF-doxygen/wiki/setupconfiguration.png +0 -0
  32. package/SVF-doxygen/wiki/setupdashboard.png +0 -0
  33. package/SVF-doxygen/wiki/setupdebug.png +0 -0
  34. package/SVF-doxygen/wiki/setupenv.png +0 -0
  35. package/SVF-doxygen/wiki/startup.png +0 -0
  36. package/SVF-doxygen/wiki/svf-stat.pdf +0 -0
  37. package/SVF-doxygen/wiki/svfg-framework.png +0 -0
  38. package/SVF-doxygen/wiki/svfg.png +0 -0
  39. package/SVF-doxygen/wiki/svfg_opt.png +0 -0
  40. package/SVF-doxygen/wiki/svfgedge-cha.png +0 -0
  41. package/SVF-doxygen/wiki/svfgnode-cha.png +0 -0
  42. package/SVF-doxygen/wiki/svfpic/README.md +0 -6
  43. package/SVF-doxygen/wiki/svfpic/ass-1debug1.png +0 -0
  44. package/SVF-doxygen/wiki/svfpic/ass-1debug2.png +0 -0
  45. package/SVF-doxygen/wiki/svfpic/build.jpg +0 -0
  46. package/SVF-doxygen/wiki/svfpic/cmd.png +0 -0
  47. package/SVF-doxygen/wiki/svfpic/connect1.jpg +0 -0
  48. package/SVF-doxygen/wiki/svfpic/connect2.png +0 -0
  49. package/SVF-doxygen/wiki/svfpic/connect3.png +0 -0
  50. package/SVF-doxygen/wiki/svfpic/connect4.jpg +0 -0
  51. package/SVF-doxygen/wiki/svfpic/connect5.jpg +0 -0
  52. package/SVF-doxygen/wiki/svfpic/connect6.png +0 -0
  53. package/SVF-doxygen/wiki/svfpic/connect7.jpg +0 -0
  54. package/SVF-doxygen/wiki/svfpic/continue.png +0 -0
  55. package/SVF-doxygen/wiki/svfpic/debug-new.png +0 -0
  56. package/SVF-doxygen/wiki/svfpic/debug-new2.png +0 -0
  57. package/SVF-doxygen/wiki/svfpic/debug1.jpeg +0 -0
  58. package/SVF-doxygen/wiki/svfpic/debug2.jpeg +0 -0
  59. package/SVF-doxygen/wiki/svfpic/debug3.png +0 -0
  60. package/SVF-doxygen/wiki/svfpic/debug4.png +0 -0
  61. package/SVF-doxygen/wiki/svfpic/debug5.jpeg +0 -0
  62. package/SVF-doxygen/wiki/svfpic/debug6.jpeg +0 -0
  63. package/SVF-doxygen/wiki/svfpic/docker_sys_requirement.png +0 -0
  64. package/SVF-doxygen/wiki/svfpic/docker_sys_requirements.png +0 -0
  65. package/SVF-doxygen/wiki/svfpic/dockerbuild.png +0 -0
  66. package/SVF-doxygen/wiki/svfpic/dockerbuild2.jpg +0 -0
  67. package/SVF-doxygen/wiki/svfpic/dockerbuild3.jpg +0 -0
  68. package/SVF-doxygen/wiki/svfpic/dockerbuild4.png +0 -0
  69. package/SVF-doxygen/wiki/svfpic/dockerbuild5.jpg +0 -0
  70. package/SVF-doxygen/wiki/svfpic/dockerbuildimage.png +0 -0
  71. package/SVF-doxygen/wiki/svfpic/dockercmd.png +0 -0
  72. package/SVF-doxygen/wiki/svfpic/dockercmd2.png +0 -0
  73. package/SVF-doxygen/wiki/svfpic/dockercontainer.png +0 -0
  74. package/SVF-doxygen/wiki/svfpic/dockerdb1.jpg +0 -0
  75. package/SVF-doxygen/wiki/svfpic/dockerdb10.jpeg +0 -0
  76. package/SVF-doxygen/wiki/svfpic/dockerdb2.jpg +0 -0
  77. package/SVF-doxygen/wiki/svfpic/dockerdb3.jpg +0 -0
  78. package/SVF-doxygen/wiki/svfpic/dockerdb4.jpg +0 -0
  79. package/SVF-doxygen/wiki/svfpic/dockerdb5.png +0 -0
  80. package/SVF-doxygen/wiki/svfpic/dockerdb6.jpeg +0 -0
  81. package/SVF-doxygen/wiki/svfpic/dockerdb7.png +0 -0
  82. package/SVF-doxygen/wiki/svfpic/dockerdb8.png +0 -0
  83. package/SVF-doxygen/wiki/svfpic/dockerdb9.jpeg +0 -0
  84. package/SVF-doxygen/wiki/svfpic/dockerfinshbuilt.png +0 -0
  85. package/SVF-doxygen/wiki/svfpic/dockerimage.png +0 -0
  86. package/SVF-doxygen/wiki/svfpic/dockernameImage.png +0 -0
  87. package/SVF-doxygen/wiki/svfpic/dockerpull.png +0 -0
  88. package/SVF-doxygen/wiki/svfpic/dockerpull2.png +0 -0
  89. package/SVF-doxygen/wiki/svfpic/download.jpg +0 -0
  90. package/SVF-doxygen/wiki/svfpic/extension1.jpeg +0 -0
  91. package/SVF-doxygen/wiki/svfpic/extension2.jpeg +0 -0
  92. package/SVF-doxygen/wiki/svfpic/graphviz.png +0 -0
  93. package/SVF-doxygen/wiki/svfpic/hellodb.png +0 -0
  94. package/SVF-doxygen/wiki/svfpic/hellodb2.png +0 -0
  95. package/SVF-doxygen/wiki/svfpic/hviz_0.png +0 -0
  96. package/SVF-doxygen/wiki/svfpic/hviz_1.png +0 -0
  97. package/SVF-doxygen/wiki/svfpic/hviz_2.png +0 -0
  98. package/SVF-doxygen/wiki/svfpic/installC:C++Ext.png +0 -0
  99. package/SVF-doxygen/wiki/svfpic/installCMakeExt.png +0 -0
  100. package/SVF-doxygen/wiki/svfpic/installRCext.png +0 -0
  101. package/SVF-doxygen/wiki/svfpic/installdockerext.png +0 -0
  102. package/SVF-doxygen/wiki/svfpic/launch1.png +0 -0
  103. package/SVF-doxygen/wiki/svfpic/openfile.png +0 -0
  104. package/SVF-doxygen/wiki/svfpic/pathfolder.png +0 -0
  105. package/SVF-doxygen/wiki/svfpic/restart.png +0 -0
  106. package/SVF-doxygen/wiki/svfpic/rundocker.png +0 -0
  107. package/SVF-doxygen/wiki/svfpic/runinCLI.png +0 -0
  108. package/SVF-doxygen/wiki/svfpic/screen.png +0 -0
  109. package/SVF-doxygen/wiki/svfpic/settings1.jpg +0 -0
  110. package/SVF-doxygen/wiki/svfpic/settings2.jpg +0 -0
  111. package/SVF-doxygen/wiki/svfpic/settings3.jpg +0 -0
  112. package/SVF-doxygen/wiki/svfpic/shortlists.png +0 -0
  113. package/SVF-doxygen/wiki/svfpic/start.png +0 -0
  114. package/SVF-doxygen/wiki/svfpic/start1.png +0 -0
  115. package/SVF-doxygen/wiki/svfpic/update0.png +0 -0
  116. package/SVF-doxygen/wiki/svfpic/verify_docker.png +0 -0
  117. package/SVF-doxygen/wiki/svfpic/vs_entry_window.png +0 -0
  118. package/SVF-doxygen/wiki/svfpic/wsl.png +0 -0
  119. package/SVF-doxygen/wiki/svfpic/wsl_1.png +0 -0
  120. package/SVF-doxygen/wiki/svfpic/wsl_2.png +0 -0
  121. package/SVF-doxygen/wiki/svfpic/wsl_3.png +0 -0
  122. package/SVF-doxygen/wiki/tools.png +0 -0
  123. package/SVF-doxygen/wiki/users.png +0 -0
  124. package/SVF-doxygen/wiki/vm1.png +0 -0
  125. package/SVF-doxygen/wiki/vm2.png +0 -0
  126. package/SVF-doxygen/wiki/vm3.png +0 -0
  127. package/SVF-doxygen/wiki/vm4.png +0 -0
  128. package/SVF-doxygen/wiki/vm5.png +0 -0
  129. package/SVF-doxygen/wiki/vscode_build_tasks.png +0 -0
  130. package/SVF-doxygen/wiki/vscode_cpp_extension.png +0 -0
  131. package/SVF-doxygen/wiki/vscode_debug_list.png +0 -0
  132. package/SVF-doxygen/wiki/vscode_dir_structure.png +0 -0
package/Dockerfile CHANGED
@@ -7,7 +7,7 @@ ARG TARGETPLATFORM
7
7
  RUN set -e
8
8
 
9
9
  # Define LLVM version.
10
- ENV llvm_version=16.0.0
10
+ ENV llvm_version=21.1.0
11
11
 
12
12
  # Define home directory
13
13
  ENV HOME=/home/SVF-tools
package/build.sh CHANGED
@@ -23,11 +23,11 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
23
23
  SVFHOME="${SCRIPT_DIR}"
24
24
  sysOS=$(uname -s)
25
25
  arch=$(uname -m)
26
- MajorLLVMVer=18
26
+ MajorLLVMVer=21
27
27
  LLVMVer=${MajorLLVMVer}.1.0
28
- UbuntuArmLLVM_RTTI="https://github.com/SVF-tools/SVF/releases/download/SVF-3.2/llvm-${MajorLLVMVer}.1.0-ubuntu22-rtti-aarch64.tar.gz"
28
+ UbuntuArmLLVM_RTTI="https://github.com/bjjwwang/SVF-LLVM/releases/download/${LLVMVer}/llvm-${LLVMVer}-ubuntu22-rtti-aarch64.tar.gz"
29
29
  UbuntuArmLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-aarch64-linux-gnu.tar.xz"
30
- UbuntuLLVM_RTTI="https://github.com/SVF-tools/SVF/releases/download/SVF-3.2/llvm-${MajorLLVMVer}.1.0-ubuntu20-rtti-x86-64.tar.gz"
30
+ UbuntuLLVM_RTTI="https://github.com/bjjwwang/SVF-LLVM/releases/download/${LLVMVer}/llvm-${LLVMVer}-ubuntu22-rtti-x86-64.tar.gz"
31
31
  UbuntuLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
32
32
  SourceLLVM="https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-${LLVMVer}.zip"
33
33
  UbuntuZ3="https://github.com/Z3Prover/z3/releases/download/z3-4.8.8/z3-4.8.8-x64-ubuntu-16.04.zip"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.1238",
3
+ "version": "1.0.1239",
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": {
package/setup.sh CHANGED
@@ -18,7 +18,7 @@ function set_llvm {
18
18
  [[ -n "$LLVM_DIR" ]] && return 0
19
19
 
20
20
  # use local download directory
21
- LLVM_DIR="$SVF_DIR/llvm-18.1.0.obj"
21
+ LLVM_DIR="$SVF_DIR/llvm-21.1.0.obj"
22
22
  [[ -d "$LLVM_DIR" ]] && return 0
23
23
 
24
24
  # ... otherwise don't set LLVM_DIR
@@ -65,6 +65,11 @@ else()
65
65
  demangle
66
66
  Passes
67
67
  )
68
+ # When the host LLVM tree already contains an in-tree SVF integration,
69
+ # llvm_map_components_to_libnames() can pull in those LLVMSvf* libraries
70
+ # transitively. Exclude them so the standalone SVF build links only against
71
+ # its own SvfCore/SvfLLVM targets.
72
+ list(FILTER LLVM_LIBRARIES EXCLUDE REGEX "^LLVMSvf(Core|LLVM)$|^LLVMSVFAnalysis$")
68
73
  endif()
69
74
 
70
75
  # Search in the executables dir for this LLVM's clang instance
@@ -153,6 +158,16 @@ target_sources(
153
158
  PRIVATE ${SVF_LLVM_SOURCES}
154
159
  )
155
160
 
161
+ # GCC can report false-positive -Wmaybe-uninitialized warnings from LLVM's
162
+ # ValueMap/DenseMap internals when compiling this translation unit with heavy
163
+ # inlining. Keep the suppression scoped to the affected file.
164
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
165
+ set_source_files_properties(
166
+ ${CMAKE_CURRENT_LIST_DIR}/lib/LLVMModule.cpp
167
+ PROPERTIES COMPILE_OPTIONS "-Wno-maybe-uninitialized"
168
+ )
169
+ endif()
170
+
156
171
  # Only expose the headers in the source tree to in-tree users of SVF
157
172
  target_include_directories(SvfLLVM PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
158
173
 
@@ -208,17 +208,21 @@ typedef llvm::MinMaxIntrinsic MinMaxIntrinsic;
208
208
  typedef llvm::BinaryOpIntrinsic BinaryOpIntrinsic;
209
209
  typedef llvm::WithOverflowInst WithOverflowInst;
210
210
  typedef llvm::SaturatingInst SaturatingInst;
211
+ #if LLVM_VERSION_MAJOR < 20
211
212
  typedef llvm::AtomicMemIntrinsic AtomicMemIntrinsic;
212
213
  typedef llvm::AtomicMemSetInst AtomicMemSetInst;
213
214
  typedef llvm::AtomicMemTransferInst AtomicMemTransferInst;
214
215
  typedef llvm::AtomicMemCpyInst AtomicMemCpyInst;
215
216
  typedef llvm::AtomicMemMoveInst AtomicMemMoveInst;
217
+ #endif
216
218
  typedef llvm::MemIntrinsic MemIntrinsic;
217
219
  typedef llvm::MemSetInst MemSetInst;
218
220
  typedef llvm::MemTransferInst MemTransferInst;
219
221
  typedef llvm::MemCpyInst MemCpyInst;
220
222
  typedef llvm::MemMoveInst MemMoveInst;
223
+ #if LLVM_VERSION_MAJOR < 20
221
224
  typedef llvm::MemCpyInlineInst MemCpyInlineInst;
225
+ #endif
222
226
  typedef llvm::AnyMemIntrinsic AnyMemIntrinsic;
223
227
  typedef llvm::AnyMemSetInst AnyMemSetInst;
224
228
  typedef llvm::AnyMemTransferInst AnyMemTransferInst;
@@ -314,7 +314,11 @@ inline static DataLayout* getDataLayout(Module* mod)
314
314
  {
315
315
  static DataLayout *dl = nullptr;
316
316
  if (dl == nullptr)
317
+ #if LLVM_VERSION_MAJOR >= 19
318
+ dl = new DataLayout(mod->getDataLayout());
319
+ #else
317
320
  dl = new DataLayout(mod);
321
+ #endif
318
322
  return dl;
319
323
  }
320
324
 
@@ -290,6 +290,8 @@ protected:
290
290
 
291
291
  NodeID getGepValVar(const Value* val, const AccessPath& ap, const SVFType* elementType);
292
292
 
293
+ NodeID getDirectAccessFieldZeroValVar(const Value* ptr, const Type* accessTy);
294
+
293
295
  void setCurrentBBAndValueForPAGEdge(PAGEdge* edge);
294
296
 
295
297
  inline void addBlackHoleAddrEdge(NodeID node)
@@ -285,7 +285,7 @@ void LLVMModuleSet::prePassSchedule()
285
285
  PB.registerLoopAnalyses(LAM);
286
286
  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
287
287
  llvm::FunctionPassManager FPM;
288
- // FPM.addPass(llvm::UnifyFunctionExitNodesPass());
288
+ FPM.addPass(llvm::UnifyFunctionExitNodesPass());
289
289
  FPM.run(fun, FAM);
290
290
  #endif
291
291
  }
@@ -518,11 +518,11 @@ void LLVMModuleSet::addSVFMain()
518
518
  // Collect ctor and dtor functions
519
519
  for (const GlobalVariable& global : mod.globals())
520
520
  {
521
- if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
521
+ if (global.getName() == SVF_GLOBAL_CTORS && global.hasInitializer())
522
522
  {
523
523
  ctor_funcs = getLLVMGlobalFunctions(&global);
524
524
  }
525
- else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer())
525
+ else if (global.getName() == SVF_GLOBAL_DTORS && global.hasInitializer())
526
526
  {
527
527
  dtor_funcs = getLLVMGlobalFunctions(&global);
528
528
  }
@@ -533,9 +533,9 @@ void LLVMModuleSet::addSVFMain()
533
533
  {
534
534
  auto funName = func.getName();
535
535
 
536
- assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
536
+ assert(!(funName == SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
537
537
 
538
- if (funName.equals("main"))
538
+ if (funName == "main")
539
539
  {
540
540
  orgMain = &func;
541
541
  mainMod = &mod;
@@ -737,8 +737,9 @@ void LLVMModuleSet::buildFunToFunMap()
737
737
  {
738
738
  appModule = appFunToReplace->getParent();
739
739
  }
740
- // Create a new function with the same signature as extFunToClone
741
- Function *clonedFunction = Function::Create(extFunToClone->getFunctionType(), Function::ExternalLinkage, extFunToClone->getName(), appModule);
740
+ Function* clonedFunction = Function::Create(extFunToClone->getFunctionType(),
741
+ Function::ExternalLinkage,
742
+ extFunToClone->getName());
742
743
  // Map the arguments of the new function to the arguments of extFunToClone
743
744
  llvm::ValueToValueMapTy valueMap;
744
745
  Function::arg_iterator destArg = clonedFunction->arg_begin();
@@ -821,8 +822,13 @@ void LLVMModuleSet::buildFunToFunMap()
821
822
  std::string oldFunctionName = appFunToReplace->getName().str();
822
823
  // Delete the old function
823
824
  appFunToReplace->eraseFromParent();
825
+ appModule->getFunctionList().push_back(clonedFunction);
824
826
  clonedFunction->setName(oldFunctionName);
825
827
  }
828
+ else
829
+ {
830
+ appModule->getFunctionList().push_back(clonedFunction);
831
+ }
826
832
  return clonedFunction;
827
833
  };
828
834
 
@@ -30,6 +30,7 @@
30
30
  #include "SVF-LLVM/LLVMUtil.h"
31
31
  #include "SVFIR/ObjTypeInfo.h"
32
32
  #include <sstream>
33
+ #include <llvm/IRReader/IRReader.h>
33
34
  #include <llvm/Support/raw_ostream.h>
34
35
  #include "SVF-LLVM/LLVMModule.h"
35
36
 
@@ -35,6 +35,7 @@
35
35
  #include "SVF-LLVM/CppUtil.h"
36
36
  #include "SVF-LLVM/LLVMLoopAnalysis.h"
37
37
  #include "SVF-LLVM/LLVMUtil.h"
38
+ #include "SVF-LLVM/ObjTypeInference.h"
38
39
  #include "SVF-LLVM/SymbolTableBuilder.h"
39
40
  #include "SVFIR/PAGBuilderFromFile.h"
40
41
  #include "Util/CallGraphBuilder.h"
@@ -666,7 +667,24 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
666
667
  if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
667
668
  const Value* offsetVal = gi.getOperand();
668
669
  assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
669
- ap.addOffsetVarAndGepTypePair(getPAG()->getValVar(llvmModuleSet()->getValueNode(offsetVal)), svfGepTy);
670
+
671
+ const ArrayType* inferredPtrArrayTy = nullptr;
672
+ const SVFType* idxGepTy = svfGepTy;
673
+ if (svfGepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
674
+ {
675
+ const Type* baseObjType =
676
+ LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(gepOp->getPointerOperand());
677
+ if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
678
+ {
679
+ if (arrTy->getElementType()->isPointerTy())
680
+ {
681
+ inferredPtrArrayTy = arrTy;
682
+ idxGepTy = llvmModuleSet()->getSVFType(arrTy);
683
+ }
684
+ }
685
+ }
686
+
687
+ ap.addOffsetVarAndGepTypePair(getPAG()->getValVar(llvmModuleSet()->getValueNode(offsetVal)), idxGepTy);
670
688
 
671
689
  //The int value of the current index operand
672
690
  const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
@@ -675,6 +693,8 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
675
693
  // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
676
694
  if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
677
695
  {
696
+ if (!Options::ModelArrays() && arrTy->getElementType()->isPointerTy())
697
+ continue;
678
698
  if(!op || (arrTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
679
699
  continue;
680
700
  APOffset idx = (u32_t)LLVMUtil::getIntegerValue(op).first;
@@ -700,6 +720,15 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
700
720
  }
701
721
  else if (gepTy->isSingleValueType())
702
722
  {
723
+ if (inferredPtrArrayTy)
724
+ {
725
+ if (!op || (inferredPtrArrayTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
726
+ continue;
727
+ APOffset idx = (u32_t)LLVMUtil::getIntegerValue(op).first;
728
+ u32_t offset = pag->getFlattenedElemIdx(llvmModuleSet()->getSVFType(inferredPtrArrayTy), idx);
729
+ ap.setFldIdx(ap.getConstantStructFldIdx() + offset);
730
+ continue;
731
+ }
703
732
  // If it's a non-constant offset access
704
733
  // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
705
734
  // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
@@ -1061,6 +1090,9 @@ void SVFIRBuilder::visitLoadInst(LoadInst &inst)
1061
1090
  NodeID dst = getValueNode(&inst);
1062
1091
 
1063
1092
  NodeID src = getValueNode(inst.getPointerOperand());
1093
+ const Type* loadedTy = inst.getType();
1094
+ if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), loadedTy))
1095
+ src = fieldZero;
1064
1096
 
1065
1097
  addLoadEdge(src, dst);
1066
1098
  }
@@ -1076,6 +1108,9 @@ void SVFIRBuilder::visitStoreInst(StoreInst &inst)
1076
1108
  DBOUT(DPAGBuild, outs() << "process store " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1077
1109
 
1078
1110
  NodeID dst = getValueNode(inst.getPointerOperand());
1111
+ const Type* storedTy = inst.getValueOperand()->getType();
1112
+ if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), storedTy))
1113
+ dst = fieldZero;
1079
1114
 
1080
1115
  NodeID src = getValueNode(inst.getValueOperand());
1081
1116
 
@@ -1106,6 +1141,19 @@ void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst)
1106
1141
 
1107
1142
  AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
1108
1143
  bool constGep = computeGepOffset(&inst, ap);
1144
+ if (constGep && ap.getConstantStructFldIdx() == 0 && !Options::ModelArrays())
1145
+ {
1146
+ const Type* baseObjType =
1147
+ LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(inst.getPointerOperand());
1148
+ if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
1149
+ {
1150
+ if (arrTy->getElementType()->isPointerTy())
1151
+ {
1152
+ addCopyEdge(src, dst, CopyStmt::COPYVAL);
1153
+ return;
1154
+ }
1155
+ }
1156
+ }
1109
1157
  addGepEdge(src, dst, ap, constGep);
1110
1158
  }
1111
1159
 
@@ -1548,6 +1596,32 @@ const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
1548
1596
  {
1549
1597
  const Value* value = stripAllCasts(V);
1550
1598
  assert(value && "null ptr?");
1599
+ auto getGlobalFieldFromByteOffset =
1600
+ [this](const GlobalVariable* glob, int64_t byteOffset) -> const Value*
1601
+ {
1602
+ if (!glob || !glob->hasInitializer())
1603
+ return nullptr;
1604
+
1605
+ auto* initializer = SVFUtil::dyn_cast<ConstantStruct>(glob->getInitializer());
1606
+ auto* structType = SVFUtil::dyn_cast<StructType>(glob->getValueType());
1607
+ if (!initializer || !structType)
1608
+ return nullptr;
1609
+
1610
+ DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
1611
+ const StructLayout* layout =
1612
+ dataLayout->getStructLayout(const_cast<StructType*>(structType));
1613
+ for (u32_t fieldIdx = 0; fieldIdx < initializer->getNumOperands(); ++fieldIdx)
1614
+ {
1615
+ if (layout->getElementOffset(fieldIdx) != static_cast<uint64_t>(byteOffset))
1616
+ continue;
1617
+ if (auto* ptrValue =
1618
+ SVFUtil::dyn_cast<llvm::GlobalVariable>(initializer->getOperand(fieldIdx)))
1619
+ return ptrValue;
1620
+ return nullptr;
1621
+ }
1622
+ return nullptr;
1623
+ };
1624
+
1551
1625
  if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
1552
1626
  {
1553
1627
  APOffset totalidx = 0;
@@ -1564,34 +1638,72 @@ const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
1564
1638
  const Value* loadP = load->getPointerOperand();
1565
1639
  if (const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(loadP))
1566
1640
  {
1567
- APOffset totalidx = 0;
1568
- for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1569
- {
1570
- if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1571
- totalidx += LLVMUtil::getIntegerValue(op).first;
1572
- }
1641
+ DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
1642
+ llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gep->getPointerAddressSpace()), 0, true);
1643
+ const bool hasByteOffset = dataLayout && gep->accumulateConstantOffset(*dataLayout, byteOffset);
1644
+
1573
1645
  const Value * pointer_operand = gep->getPointerOperand();
1574
1646
  if (auto *glob = SVFUtil::dyn_cast<GlobalVariable>(pointer_operand))
1575
1647
  {
1576
- if (glob->hasInitializer())
1648
+ if (hasByteOffset)
1649
+ {
1650
+ if (const Value* ptrValue = getGlobalFieldFromByteOffset(glob, byteOffset.getSExtValue()))
1651
+ return ptrValue;
1652
+ }
1653
+ }
1654
+ else if (hasByteOffset && !byteOffset.isNegative() &&
1655
+ SVFUtil::isa<AllocaInst>(pointer_operand) && load->getType()->isPointerTy())
1656
+ {
1657
+ const u64_t offset = byteOffset.getZExtValue();
1658
+ const u64_t accessBytes = dataLayout->getPointerSize(gep->getPointerAddressSpace());
1659
+
1660
+ auto isCoveredByMemcpy = [offset, accessBytes](const CallBase* cs) -> bool
1661
+ {
1662
+ if (cs->arg_size() < 3)
1663
+ return false;
1664
+
1665
+ const auto* copySize = SVFUtil::dyn_cast<ConstantInt>(cs->getArgOperand(2));
1666
+ if (!copySize)
1667
+ return false;
1668
+
1669
+ const u64_t copyBytes = copySize->getZExtValue();
1670
+ return copyBytes >= accessBytes && copyBytes - accessBytes >= offset;
1671
+ };
1672
+
1673
+ auto hasInterveningWrite = [load](const Instruction* from) -> bool
1577
1674
  {
1578
- if (auto *initializer = SVFUtil::dyn_cast<
1579
- ConstantStruct>(glob->getInitializer()))
1675
+ if (from->getParent() != load->getParent() || !from->comesBefore(load))
1676
+ return true;
1677
+
1678
+ auto it = from->getIterator();
1679
+ const auto end = load->getIterator();
1680
+ while (++it != end)
1580
1681
  {
1581
- /*
1582
- *@conststruct = internal global <{ [40 x i8], [4 x i8], [4 x i8], [2512 x i8] }>
1583
- <{ [40 x i8] undef, [4 x i8] zeroinitializer, [4 x i8] undef, [2512 x i8] zeroinitializer }>, align 8
1584
-
1585
- %0 = load ptr, ptr getelementptr inbounds (<{ [40 x i8], [4 x i8], [4 x i8], [2512 x i8] }>,
1586
- ptr @conststruct, i64 0, i32 0, i64 16)
1587
- in this case, totalidx is 16 while initializer->getNumOperands() is 4, so we return value as the base
1588
- */
1589
- if (totalidx >= initializer->getNumOperands()) return value;
1590
- auto *ptrField = initializer->getOperand(totalidx);
1591
- if (auto *ptrValue = SVFUtil::dyn_cast<llvm::GlobalVariable>(ptrField))
1592
- {
1682
+ if (it->mayWriteToMemory())
1683
+ return true;
1684
+ }
1685
+ return false;
1686
+ };
1687
+
1688
+ for (const auto& use : pointer_operand->users())
1689
+ {
1690
+ const auto* cs = SVFUtil::dyn_cast<CallBase>(use);
1691
+ if (!cs || cs->getParent() != load->getParent() ||
1692
+ cs->arg_size() < 1 ||
1693
+ stripAllCasts(cs->getArgOperand(0)) != pointer_operand)
1694
+ continue;
1695
+
1696
+ const Function* calledFun = cs->getCalledFunction();
1697
+ if (!LLVMUtil::isMemcpyExtFun(calledFun) || !isCoveredByMemcpy(cs) ||
1698
+ hasInterveningWrite(cs))
1699
+ continue;
1700
+
1701
+ const Value* copiedFrom = getBaseValueForExtArg(cs->getArgOperand(1));
1702
+ if (const auto* copiedGlob = SVFUtil::dyn_cast<GlobalVariable>(copiedFrom))
1703
+ {
1704
+ if (const Value* ptrValue =
1705
+ getGlobalFieldFromByteOffset(copiedGlob, byteOffset.getSExtValue()))
1593
1706
  return ptrValue;
1594
- }
1595
1707
  }
1596
1708
  }
1597
1709
  }
@@ -1721,6 +1833,22 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const
1721
1833
  return gepval;
1722
1834
  }
1723
1835
 
1836
+ NodeID SVFIRBuilder::getDirectAccessFieldZeroValVar(const Value* ptr, const Type* accessTy)
1837
+ {
1838
+ if (!Options::ModelArrays() || SVFUtil::isa<llvm::GEPOperator>(ptr))
1839
+ return 0;
1840
+
1841
+ const Type* objTy =
1842
+ LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(ptr);
1843
+ const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(objTy);
1844
+ if (!arrTy || !arrTy->getElementType()->isPointerTy() ||
1845
+ arrTy->getElementType() != accessTy)
1846
+ return 0;
1847
+
1848
+ AccessPath ap(0, llvmModuleSet()->getSVFType(arrTy));
1849
+ return getGepValVar(ptr, ap, llvmModuleSet()->getSVFType(accessTy));
1850
+ }
1851
+
1724
1852
 
1725
1853
  /*
1726
1854
  * curVal <--------> PAGEdge
@@ -38,6 +38,89 @@ using namespace SVF;
38
38
  using namespace SVFUtil;
39
39
  using namespace LLVMUtil;
40
40
 
41
+ namespace
42
+ {
43
+
44
+ struct MemcpyField
45
+ {
46
+ APOffset byteOffset;
47
+ AccessPath accessPath;
48
+ const SVFType* elementType;
49
+ };
50
+
51
+ void collectMemcpyFields(
52
+ const Type* llvmType,
53
+ const SVFType* svfType,
54
+ const DataLayout& dl,
55
+ IRGraph* pag,
56
+ std::vector<MemcpyField>& fields,
57
+ APOffset baseByteOffset = 0,
58
+ APOffset baseFldIdx = 0)
59
+ {
60
+ if (llvmType == nullptr || svfType == nullptr)
61
+ return;
62
+
63
+ if (svfType->isPointerTy())
64
+ {
65
+ fields.push_back({baseByteOffset, AccessPath(baseFldIdx), svfType});
66
+ return;
67
+ }
68
+
69
+ if (const auto* structType = SVFUtil::dyn_cast<StructType>(llvmType))
70
+ {
71
+ const StructLayout* layout = dl.getStructLayout(const_cast<StructType*>(structType));
72
+ for (u32_t i = 0; i < structType->getNumElements(); ++i)
73
+ {
74
+ const Type* elemLLVMType = structType->getElementType(i);
75
+ const SVFType* elemSVFType = pag->getOriginalElemType(svfType, i);
76
+ if (elemSVFType == nullptr)
77
+ return;
78
+ APOffset elemByteOffset = baseByteOffset + static_cast<APOffset>(layout->getElementOffset(i));
79
+ APOffset elemFldIdx = baseFldIdx + pag->getFlattenedElemIdx(svfType, i);
80
+ collectMemcpyFields(elemLLVMType, elemSVFType, dl, pag, fields, elemByteOffset, elemFldIdx);
81
+ }
82
+ return;
83
+ }
84
+
85
+ if (const auto* arrayType = SVFUtil::dyn_cast<ArrayType>(llvmType))
86
+ {
87
+ const Type* elemLLVMType = arrayType->getElementType();
88
+ const SVFType* elemSVFType = pag->getOriginalElemType(svfType, 0);
89
+ if (elemSVFType == nullptr)
90
+ return;
91
+ const APOffset elemByteSize = static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(elemLLVMType)));
92
+ for (u32_t i = 0; i < arrayType->getNumElements(); ++i)
93
+ {
94
+ APOffset elemByteOffset = baseByteOffset + i * elemByteSize;
95
+ APOffset elemFldIdx = baseFldIdx + pag->getFlattenedElemIdx(svfType, i);
96
+ collectMemcpyFields(elemLLVMType, elemSVFType, dl, pag, fields, elemByteOffset, elemFldIdx);
97
+ }
98
+ }
99
+ }
100
+
101
+ std::vector<MemcpyField> getMemcpyFields(const Value* value, const Type* llvmType, const SVFType* svfType)
102
+ {
103
+ std::vector<MemcpyField> fields;
104
+ auto* mset = LLVMModuleSet::getLLVMModuleSet();
105
+ auto* pag = PAG::getPAG();
106
+ const DataLayout& dl = mset->getMainLLVMModule()->getDataLayout();
107
+ collectMemcpyFields(llvmType, svfType, dl, pag, fields);
108
+ return fields;
109
+ }
110
+
111
+ const Type* getMemcpyLayoutType(const Value* baseValue, const Type* fallbackType)
112
+ {
113
+ if (const auto* allocaInst = llvm::dyn_cast_or_null<AllocaInst>(baseValue))
114
+ return allocaInst->getAllocatedType();
115
+
116
+ if (const auto* global = llvm::dyn_cast_or_null<GlobalVariable>(baseValue))
117
+ return global->getValueType();
118
+
119
+ return fallbackType;
120
+ }
121
+
122
+ }
123
+
41
124
  /*!
42
125
  * Find the base type and the max possible offset of an object pointed to by (V).
43
126
  */
@@ -109,6 +192,58 @@ void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue
109
192
  return;
110
193
  }
111
194
 
195
+ const Value* dstBase = getBaseValueForExtArg(D);
196
+ const Value* srcBase = getBaseValueForExtArg(S);
197
+ Value* dstFieldBase = LLVMUtil::isObject(dstBase) ? const_cast<Value*>(dstBase) : D;
198
+ Value* srcFieldBase = LLVMUtil::isObject(srcBase) ? const_cast<Value*>(srcBase) : S;
199
+ const Type* dstLayoutType = getMemcpyLayoutType(dstBase, dtype);
200
+ const Type* srcLayoutType = getMemcpyLayoutType(srcBase, stype);
201
+ const bool hasRemappedGlobalBase =
202
+ (dstFieldBase != D && SVFUtil::isa<GlobalVariable>(dstFieldBase)) ||
203
+ (srcFieldBase != S && SVFUtil::isa<GlobalVariable>(srcFieldBase));
204
+ const bool useByteLayoutMemcpy =
205
+ hasRemappedGlobalBase || (dstLayoutType != dtype) || (srcLayoutType != stype);
206
+ if (useByteLayoutMemcpy)
207
+ {
208
+ const SVFType* dstSVFType = llvmModuleSet()->getSVFType(dstLayoutType);
209
+ const SVFType* srcSVFType = llvmModuleSet()->getSVFType(srcLayoutType);
210
+ std::vector<MemcpyField> dstMemcpyFields = getMemcpyFields(D, dstLayoutType, dstSVFType);
211
+ std::vector<MemcpyField> srcMemcpyFields = getMemcpyFields(S, srcLayoutType, srcSVFType);
212
+ if (dstMemcpyFields.empty() || srcMemcpyFields.empty())
213
+ goto fallback_memcpy_copy;
214
+
215
+ std::unordered_map<APOffset, MemcpyField> srcFieldsByByteOffset;
216
+ for (const auto& field : srcMemcpyFields)
217
+ srcFieldsByByteOffset.emplace(field.byteOffset, field);
218
+
219
+ const DataLayout& dl = llvmModuleSet()->getMainLLVMModule()->getDataLayout();
220
+ APOffset copyBytes = std::min<APOffset>(
221
+ static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(dstLayoutType))),
222
+ static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(srcLayoutType))));
223
+ if (szValue && SVFUtil::isa<ConstantInt>(szValue))
224
+ {
225
+ auto szIntVal = LLVMUtil::getIntegerValue(SVFUtil::cast<ConstantInt>(szValue));
226
+ copyBytes = std::min(copyBytes, static_cast<APOffset>(szIntVal.first));
227
+ }
228
+
229
+ for (const auto& dstField : dstMemcpyFields)
230
+ {
231
+ if (dstField.byteOffset >= copyBytes)
232
+ continue;
233
+ auto it = srcFieldsByByteOffset.find(dstField.byteOffset);
234
+ if (it == srcFieldsByByteOffset.end())
235
+ continue;
236
+
237
+ NodeID dField = getGepValVar(dstFieldBase, dstField.accessPath, dstField.elementType);
238
+ NodeID sField = getGepValVar(srcFieldBase, it->second.accessPath, it->second.elementType);
239
+ NodeID dummy = pag->addDummyValNode();
240
+ addLoadEdge(sField, dummy);
241
+ addStoreEdge(dummy, dField);
242
+ }
243
+ return;
244
+ }
245
+
246
+ fallback_memcpy_copy:
112
247
  //For each field (i), add (Ti = *S + i) and (*D + i = Ti).
113
248
  for (u32_t index = 0; index < sz; index++)
114
249
  {
@@ -290,4 +425,4 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const Function* callee)
290
425
  }
291
426
 
292
427
  /// TODO: inter-procedural SVFIR edges for thread joins
293
- }
428
+ }
@@ -212,7 +212,8 @@ int main(int argc, char ** argv)
212
212
 
213
213
  LLVMModuleSet::getLLVMModuleSet()->dumpModulesToFile(".svf.bc");
214
214
  SVF::LLVMModuleSet::releaseLLVMModuleSet();
215
+ #if LLVM_VERSION_MAJOR < 21
215
216
  llvm::llvm_shutdown();
217
+ #endif
216
218
  return 0;
217
219
  }
218
-