svf-tools 1.0.1230 → 1.0.1232

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.1230",
3
+ "version": "1.0.1232",
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": {
@@ -837,6 +837,18 @@ private:
837
837
  {
838
838
  return addDummyValNode(getBlkPtr(), nullptr);
839
839
  }
840
+ inline NodeID addIntrinsicValNode(NodeID i, const SVFType* type)
841
+ {
842
+ return addValNode(new IntrinsicValVar(i, type));
843
+ }
844
+ inline NodeID addBasicBlockValNode(NodeID i, const SVFType* type)
845
+ {
846
+ return addValNode(new BasicBlockValVar(i, type));
847
+ }
848
+ inline NodeID addAsmPCValNode(NodeID i, const SVFType* type)
849
+ {
850
+ return addValNode(new AsmPCValVar(i, type));
851
+ }
840
852
  //@}
841
853
 
842
854
  /// Add a value (pointer) node
@@ -80,6 +80,9 @@ public:
80
80
  ConstNullptrValNode, // │ └── Represents a constant nullptr value node
81
81
  // │ └─ Subclass: DummyValVar
82
82
  DummyValNode, // │ └── Dummy node for uninitialized values
83
+ IntrinsicValNode, // │ └── LLVM intrinsic call instruction (e.g. llvm.dbg.declare)
84
+ BasicBlockValNode, // │ └── LLVM BasicBlock (label operand of br/switch)
85
+ AsmPCValNode, // │ └── InlineAsm, DSOLocalEquivalent, NoCFIValue
83
86
 
84
87
  // └─ Subclass: ObjVar (Object variable nodes)
85
88
  ObjNode, // ├── Represents an object variable
@@ -230,7 +233,7 @@ protected:
230
233
 
231
234
  static inline bool isSVFVarKind(GNodeK n)
232
235
  {
233
- static_assert(DummyObjNode - ValNode == 26,
236
+ static_assert(DummyObjNode - ValNode == 29,
234
237
  "The number of SVFVarKinds has changed, make sure the "
235
238
  "range is correct");
236
239
 
@@ -239,10 +242,10 @@ protected:
239
242
 
240
243
  static inline bool isValVarKinds(GNodeK n)
241
244
  {
242
- static_assert(DummyValNode - ValNode == 13,
245
+ static_assert(AsmPCValNode - ValNode == 16,
243
246
  "The number of ValVarKinds has changed, make sure the "
244
247
  "range is correct");
245
- return n <= DummyValNode && n >= ValNode;
248
+ return n <= AsmPCValNode && n >= ValNode;
246
249
  }
247
250
 
248
251
 
@@ -283,10 +283,7 @@ public:
283
283
  //@}
284
284
 
285
285
  /// Constructor
286
- ValVar(NodeID i, const SVFType* svfType, const ICFGNode* node, PNODEK ty = ValNode)
287
- : SVFVar(i, svfType, ty), icfgNode(node)
288
- {
289
- }
286
+ ValVar(NodeID i, const SVFType* svfType, const ICFGNode* node, PNODEK ty = ValNode);
290
287
  /// Return name of a LLVM value
291
288
  inline const std::string getValueName() const
292
289
  {
@@ -2111,6 +2108,8 @@ public:
2111
2108
  VarArgValPN(NodeID i, const FunObjVar* node, const SVFType* svfType, const ICFGNode* icn)
2112
2109
  : ValVar(i, svfType, icn, VarargValNode), callGraphNode(node)
2113
2110
  {
2111
+ assert((node->isDeclaration() || icn) &&
2112
+ "VarArgValPN of a defined function must have a valid ICFGNode");
2114
2113
  }
2115
2114
 
2116
2115
  virtual const FunObjVar* getFunction() const;
@@ -2176,6 +2175,133 @@ public:
2176
2175
  virtual const std::string toString() const;
2177
2176
  };
2178
2177
 
2178
+ /*
2179
+ * Represents an LLVM intrinsic call instruction (e.g. llvm.dbg.declare).
2180
+ * These are collected into valSyms but have no corresponding ICFGNode.
2181
+ */
2182
+ class IntrinsicValVar: public ValVar
2183
+ {
2184
+ friend class GraphDBClient;
2185
+
2186
+ public:
2187
+ //@{ Methods for support type inquiry through isa, cast, and dyn_cast:
2188
+ static inline bool classof(const IntrinsicValVar*)
2189
+ {
2190
+ return true;
2191
+ }
2192
+ static inline bool classof(const SVFVar* node)
2193
+ {
2194
+ return node->getNodeKind() == SVFVar::IntrinsicValNode;
2195
+ }
2196
+ static inline bool classof(const ValVar* node)
2197
+ {
2198
+ return node->getNodeKind() == SVFVar::IntrinsicValNode;
2199
+ }
2200
+ static inline bool classof(const GenericPAGNodeTy* node)
2201
+ {
2202
+ return node->getNodeKind() == SVFVar::IntrinsicValNode;
2203
+ }
2204
+ static inline bool classof(const SVFValue* node)
2205
+ {
2206
+ return node->getNodeKind() == SVFVar::IntrinsicValNode;
2207
+ }
2208
+ //@}
2209
+
2210
+ IntrinsicValVar(NodeID i, const SVFType* svfType)
2211
+ : ValVar(i, svfType, nullptr, IntrinsicValNode)
2212
+ {
2213
+ }
2214
+
2215
+ inline const std::string getValueName() const
2216
+ {
2217
+ return "intrinsicVal";
2218
+ }
2219
+
2220
+ virtual const std::string toString() const;
2221
+ };
2222
+
2223
+ /*
2224
+ * Represents an LLVM BasicBlock (label operand of br/switch).
2225
+ * Collected into valSyms as a branch operand but has no ICFGNode.
2226
+ */
2227
+ class BasicBlockValVar: public ValVar
2228
+ {
2229
+ friend class GraphDBClient;
2230
+
2231
+ public:
2232
+ static inline bool classof(const BasicBlockValVar*)
2233
+ {
2234
+ return true;
2235
+ }
2236
+ static inline bool classof(const SVFVar* node)
2237
+ {
2238
+ return node->getNodeKind() == SVFVar::BasicBlockValNode;
2239
+ }
2240
+ static inline bool classof(const ValVar* node)
2241
+ {
2242
+ return node->getNodeKind() == SVFVar::BasicBlockValNode;
2243
+ }
2244
+ static inline bool classof(const GenericPAGNodeTy* node)
2245
+ {
2246
+ return node->getNodeKind() == SVFVar::BasicBlockValNode;
2247
+ }
2248
+ static inline bool classof(const SVFValue* node)
2249
+ {
2250
+ return node->getNodeKind() == SVFVar::BasicBlockValNode;
2251
+ }
2252
+
2253
+ BasicBlockValVar(NodeID i, const SVFType* svfType)
2254
+ : ValVar(i, svfType, nullptr, BasicBlockValNode) {}
2255
+
2256
+ inline const std::string getValueName() const
2257
+ {
2258
+ return "basicBlockVal";
2259
+ }
2260
+ virtual const std::string toString() const;
2261
+ };
2262
+
2263
+ /*
2264
+ * Represents InlineAsm, DSOLocalEquivalent, and NoCFIValue.
2265
+ * These are non-instruction values related to inline assembly,
2266
+ * position-independent code (PIC), or control-flow integrity (CFI).
2267
+ * They have no corresponding ICFGNode.
2268
+ */
2269
+ class AsmPCValVar: public ValVar
2270
+ {
2271
+ friend class GraphDBClient;
2272
+
2273
+ public:
2274
+ static inline bool classof(const AsmPCValVar*)
2275
+ {
2276
+ return true;
2277
+ }
2278
+ static inline bool classof(const SVFVar* node)
2279
+ {
2280
+ return node->getNodeKind() == SVFVar::AsmPCValNode;
2281
+ }
2282
+ static inline bool classof(const ValVar* node)
2283
+ {
2284
+ return node->getNodeKind() == SVFVar::AsmPCValNode;
2285
+ }
2286
+ static inline bool classof(const GenericPAGNodeTy* node)
2287
+ {
2288
+ return node->getNodeKind() == SVFVar::AsmPCValNode;
2289
+ }
2290
+ static inline bool classof(const SVFValue* node)
2291
+ {
2292
+ return node->getNodeKind() == SVFVar::AsmPCValNode;
2293
+ }
2294
+
2295
+ AsmPCValVar(NodeID i, const SVFType* svfType)
2296
+ : ValVar(i, svfType, nullptr, AsmPCValNode) {}
2297
+
2298
+ inline const std::string getValueName() const
2299
+ {
2300
+ return "asmPCVal";
2301
+ }
2302
+ virtual const std::string toString() const;
2303
+ };
2304
+
2179
2305
  /*
2180
2306
  * Dummy object variable
2181
2307
  */
@@ -82,6 +82,43 @@ void SVFVar::dump() const
82
82
  outs() << this->toString() << "\n";
83
83
  }
84
84
 
85
+ ValVar::ValVar(NodeID i, const SVFType* svfType, const ICFGNode* node, PNODEK ty)
86
+ : SVFVar(i, svfType, ty), icfgNode(node)
87
+ {
88
+ if (SVFUtil::isa<GlobalValVar>(this))
89
+ {
90
+ assert(node && "GlobalValVar must have a valid ICFGNode");
91
+ }
92
+ else if (SVFUtil::isa<GepValVar>(this))
93
+ {
94
+ assert(node && "GepValVar must have a valid ICFGNode");
95
+ }
96
+ else if (SVFUtil::isa<ArgValVar>(this) ||
97
+ SVFUtil::isa<RetValPN>(this) ||
98
+ SVFUtil::isa<VarArgValPN>(this))
99
+ {
100
+ // Conditional assert (isDeclaration || icn) is in each subclass constructor.
101
+ }
102
+ else if (SVFUtil::isa<ConstDataValVar>(this) ||
103
+ SVFUtil::isa<ConstAggValVar>(this) ||
104
+ SVFUtil::isa<FunValVar>(this) ||
105
+ SVFUtil::isa<DummyValVar>(this) ||
106
+ SVFUtil::isa<IntrinsicValVar>(this) ||
107
+ SVFUtil::isa<BasicBlockValVar>(this) ||
108
+ SVFUtil::isa<AsmPCValVar>(this))
109
+ {
110
+ // These ValVar subclasses don't require an ICFGNode.
111
+ }
112
+ else if (ty == ValNode)
113
+ {
114
+ assert(node && "Base ValVar must have a valid ICFGNode");
115
+ }
116
+ else
117
+ {
118
+ assert(false && "Unknown ValVar subclass -- update this check");
119
+ }
120
+ }
121
+
85
122
  const FunObjVar* ValVar::getFunction() const
86
123
  {
87
124
  if(icfgNode)
@@ -120,7 +157,8 @@ ArgValVar::ArgValVar(NodeID i, u32_t argNo, const ICFGNode* icn,
120
157
  : ValVar(i, svfType, icn, ArgValNode),
121
158
  cgNode(callGraphNode), argNo(argNo)
122
159
  {
123
-
160
+ assert((callGraphNode->isDeclaration() || icn) &&
161
+ "ArgValVar of a defined function must have a valid ICFGNode");
124
162
  }
125
163
 
126
164
  const FunObjVar* ArgValVar::getFunction() const
@@ -160,7 +198,6 @@ GepValVar::GepValVar(const ValVar* baseNode, NodeID i,
160
198
  const AccessPath& ap, const SVFType* ty, const ICFGNode* node)
161
199
  : ValVar(i, ty, node, GepValNode), ap(ap), base(baseNode), gepValType(ty)
162
200
  {
163
-
164
201
  }
165
202
 
166
203
  const std::string GepValVar::toString() const
@@ -179,6 +216,8 @@ const std::string GepValVar::toString() const
179
216
  RetValPN::RetValPN(NodeID i, const FunObjVar* node, const SVFType* svfType, const ICFGNode* icn)
180
217
  : ValVar(i, svfType, icn, RetValNode), callGraphNode(node)
181
218
  {
219
+ assert((node->isDeclaration() || icn) &&
220
+ "RetValPN of a defined function must have a valid ICFGNode");
182
221
  }
183
222
 
184
223
  const FunObjVar* RetValPN::getFunction() const
@@ -521,6 +560,30 @@ const std::string DummyValVar::toString() const
521
560
  return rawstr.str();
522
561
  }
523
562
 
563
+ const std::string IntrinsicValVar::toString() const
564
+ {
565
+ std::string str;
566
+ std::stringstream rawstr(str);
567
+ rawstr << "IntrinsicValVar ID: " << getId();
568
+ return rawstr.str();
569
+ }
570
+
571
+ const std::string BasicBlockValVar::toString() const
572
+ {
573
+ std::string str;
574
+ std::stringstream rawstr(str);
575
+ rawstr << "BasicBlockValVar ID: " << getId();
576
+ return rawstr.str();
577
+ }
578
+
579
+ const std::string AsmPCValVar::toString() const
580
+ {
581
+ std::string str;
582
+ std::stringstream rawstr(str);
583
+ rawstr << "AsmPCValVar ID: " << getId();
584
+ return rawstr.str();
585
+ }
586
+
524
587
  const std::string DummyObjVar::toString() const
525
588
  {
526
589
  std::string str;
@@ -42,6 +42,8 @@
42
42
  #include <llvm/IR/DerivedTypes.h>
43
43
  #include <llvm/IR/Statepoint.h>
44
44
  #include <llvm/IR/Intrinsics.h>
45
+ #include <llvm/IR/InlineAsm.h>
46
+ #include <llvm/IR/Constants.h>
45
47
 
46
48
  #include <llvm/Analysis/MemoryLocation.h>
47
49
  #include <llvm/Analysis/DominanceFrontier.h>
@@ -127,6 +129,9 @@ typedef llvm::Constant Constant;
127
129
  typedef llvm::ConstantInt ConstantInt;
128
130
  typedef llvm::ConstantFP ConstantFP;
129
131
  typedef llvm::ConstantPointerNull ConstantPointerNull;
132
+ typedef llvm::InlineAsm InlineAsm;
133
+ typedef llvm::DSOLocalEquivalent DSOLocalEquivalent;
134
+ typedef llvm::NoCFIValue NoCFIValue;
130
135
  typedef llvm::GlobalAlias GlobalAlias;
131
136
  typedef llvm::GlobalIFunc GlobalIFunc;
132
137
  typedef llvm::GlobalVariable GlobalVariable;
@@ -428,7 +428,7 @@ void SVFIRBuilder::initialiseBaseObjVars()
428
428
  NodeID id = llvmModuleSet()->getObjectNode(iter->first);
429
429
  pag->addGlobalObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
430
430
  }
431
- else if (SVFUtil::isa<ConstantData, MetadataAsValue, BlockAddress>(llvmValue))
431
+ else if (SVFUtil::isa<ConstantData, ConstantExpr, MetadataAsValue, BlockAddress>(llvmValue))
432
432
  {
433
433
  NodeID id = llvmModuleSet()->getObjectNode(iter->first);
434
434
  pag->addConstantDataObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
@@ -465,26 +465,21 @@ void SVFIRBuilder::initialiseValVars()
465
465
 
466
466
  const ICFGNode* icfgNode = nullptr;
467
467
  auto llvmValue = iter->first;
468
- if (const Instruction* inst =
469
- SVFUtil::dyn_cast<Instruction>(llvmValue))
470
- {
471
- if (llvmModuleSet()->hasICFGNode(inst))
472
- {
473
- icfgNode = llvmModuleSet()->getICFGNode(inst);
474
- }
475
- }
476
468
 
477
469
  // Check if the value is a function and get its call graph node
478
470
  if (const Function* func = SVFUtil::dyn_cast<Function>(llvmValue))
479
471
  {
480
- // add value node representing the function
481
472
  pag->addFunValNode(iter->second, icfgNode, llvmModuleSet()->getFunObjVar(func), llvmModuleSet()->getSVFType(llvmValue->getType()));
482
473
  }
483
474
  else if (auto argval = SVFUtil::dyn_cast<Argument>(llvmValue))
484
475
  {
476
+ // Formal params are defined at FunEntryICFGNode (where CallPE copies actual args).
477
+ // External (declaration-only) functions have no entry node, so keep nullptr.
478
+ const FunObjVar* funObj = llvmModuleSet()->getFunObjVar(argval->getParent());
479
+ const ICFGNode* entryNode = funObj->isDeclaration() ? nullptr : pag->getICFG()->getFunEntryICFGNode(funObj);
485
480
  pag->addArgValNode(
486
- iter->second, argval->getArgNo(), icfgNode,
487
- llvmModuleSet()->getFunObjVar(argval->getParent()),llvmModuleSet()->getSVFType(llvmValue->getType()));
481
+ iter->second, argval->getArgNo(), entryNode,
482
+ funObj, llvmModuleSet()->getSVFType(llvmValue->getType()));
488
483
  if (!argval->hasName())
489
484
  pag->getGNode(iter->second)->setName("arg_" + std::to_string(argval->getArgNo()));
490
485
  }
@@ -502,10 +497,11 @@ void SVFIRBuilder::initialiseValVars()
502
497
  }
503
498
  else if (SVFUtil::isa<GlobalValue>(llvmValue))
504
499
  {
505
- pag->addGlobalValNode(iter->second, icfgNode,
500
+ // Global variables are defined at the global ICFG node.
501
+ pag->addGlobalValNode(iter->second, pag->getICFG()->getGlobalICFGNode(),
506
502
  llvmModuleSet()->getSVFType(llvmValue->getType()));
507
503
  }
508
- else if (SVFUtil::isa<ConstantData, MetadataAsValue, BlockAddress>(llvmValue))
504
+ else if (SVFUtil::isa<ConstantData, ConstantExpr, MetadataAsValue, BlockAddress>(llvmValue))
509
505
  {
510
506
  pag->addConstantDataValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
511
507
  }
@@ -513,10 +509,26 @@ void SVFIRBuilder::initialiseValVars()
513
509
  {
514
510
  pag->addConstantAggValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
515
511
  }
516
- else
512
+ else if (SVFUtil::isa<BasicBlock>(llvmValue))
513
+ {
514
+ pag->addBasicBlockValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
515
+ }
516
+ else if (SVFUtil::isa<InlineAsm>(llvmValue) ||
517
+ SVFUtil::isa<DSOLocalEquivalent>(llvmValue) ||
518
+ SVFUtil::isa<NoCFIValue>(llvmValue))
517
519
  {
518
- // Add value node to PAG
519
- pag->addValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
520
+ pag->addAsmPCValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
521
+ }
522
+ else if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
523
+ {
524
+ if (LLVMUtil::isIntrinsicInst(inst))
525
+ pag->addIntrinsicValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
526
+ else
527
+ {
528
+ assert(llvmModuleSet()->hasICFGNode(inst) && "LLVM instruction is not associated with an ICFGNode");
529
+ icfgNode = llvmModuleSet()->getICFGNode(inst);
530
+ pag->addValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
531
+ }
520
532
  }
521
533
  llvmModuleSet()->addToSVFVar2LLVMValueMap(llvmValue,
522
534
  pag->getGNode(iter->second));
@@ -545,18 +557,16 @@ void SVFIRBuilder::initialiseNodes()
545
557
  ++iter)
546
558
  {
547
559
  const Value* llvmValue = iter->first;
548
- const ICFGNode* icfgNode = nullptr;
549
- if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
550
- {
551
- if(llvmModuleSet()->hasICFGNode(inst))
552
- icfgNode = llvmModuleSet()->getICFGNode(inst);
553
- }
560
+ // retSyms keys are Function*, not Instruction, so dyn_cast<Instruction> always fails.
561
+ // RetValPN represents the callee's return value, defined at FunExitICFGNode.
562
+ // External functions have no exit node, so keep nullptr.
563
+ const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
564
+ const ICFGNode* icfgNode = funObjVar->isDeclaration() ? nullptr : pag->getICFG()->getFunExitICFGNode(funObjVar);
554
565
  DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
555
566
  pag->addRetNode(iter->second,
556
- llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue)),
567
+ funObjVar,
557
568
  llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
558
569
  llvmModuleSet()->addToSVFVar2LLVMValueMap(llvmValue, pag->getGNode(iter->second));
559
- const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
560
570
  pag->returnFunObjSymMap[funObjVar] = iter->second;
561
571
  }
562
572
 
@@ -565,19 +575,16 @@ void SVFIRBuilder::initialiseNodes()
565
575
  iter != llvmModuleSet()->varargSyms().end(); ++iter)
566
576
  {
567
577
  const Value* llvmValue = iter->first;
568
-
569
- const ICFGNode *icfgNode = nullptr;
570
- if (const Instruction *inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
571
- {
572
- if (llvmModuleSet()->hasICFGNode(inst))
573
- icfgNode = llvmModuleSet()->getICFGNode(inst);
574
- }
578
+ // varargSyms keys are Function*, not Instruction.
579
+ // Variadic arguments are received at the function entry point.
580
+ // External functions have no entry node, so keep nullptr.
581
+ const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
582
+ const ICFGNode* icfgNode = funObjVar->isDeclaration() ? nullptr : pag->getICFG()->getFunEntryICFGNode(funObjVar);
575
583
  DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
576
584
  pag->addVarargNode(iter->second,
577
- llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue)),
585
+ funObjVar,
578
586
  llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
579
587
  llvmModuleSet()->addToSVFVar2LLVMValueMap(llvmValue, pag->getGNode(iter->second));
580
- const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
581
588
  pag->varargFunObjSymMap[funObjVar] = iter->second;
582
589
  }
583
590
 
@@ -1692,10 +1699,17 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const
1692
1699
  LLVMModuleSet* llvmmodule = llvmModuleSet();
1693
1700
  const ICFGNode* node = nullptr;
1694
1701
  if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(curVal))
1702
+ {
1695
1703
  if (llvmmodule->hasICFGNode(inst))
1696
1704
  {
1697
1705
  node = llvmmodule->getICFGNode(inst);
1698
1706
  }
1707
+ }
1708
+ else if (SVFUtil::isa<GlobalVariable>(curVal))
1709
+ {
1710
+ // GEP on a global variable: the resulting GepValVar belongs to the global ICFG node.
1711
+ node = pag->getICFG()->getGlobalICFGNode();
1712
+ }
1699
1713
  NodeID gepNode = pag->addGepValNode(llvmModuleSet()->getValueNode(curVal), cast<ValVar>(pag->getGNode(getValueNode(val))), ap,
1700
1714
  NodeIDAllocator::get()->allocateValueId(),
1701
1715
  llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext())), node);