Static Value-Flow Analysis
DCHG.h
Go to the documentation of this file.
1 //===----- DCHG.h -- CHG using DWARF debug info ---------------------------//
2 // This is based upon the original CHA.h (now CHG.h).
3 
4 /*
5  * DCHG.h
6  *
7  * Created on: Aug 23, 2019
8  * Author: Mohamad Barbar
9  */
10 
11 // TODO: add a flag such that getCanonicalType returns its arg so
12 // that the impl. does not "node collapsing" based on teq.
13 
14 #ifndef DCHG_H_
15 #define DCHG_H_
16 
17 #include "Graphs/GenericGraph.h"
18 #include "Graphs/CHG.h"
19 #include "SVF-LLVM/BasicTypes.h"
20 #include "SVFIR/SVFModule.h"
21 #include "Util/SVFUtil.h"
22 #include "Util/WorkList.h"
23 
24 namespace SVF
25 {
26 
27 class SVFModule;
28 class DCHNode;
29 
30 class DCHEdge : public GenericEdge<DCHNode>
31 {
32 public:
33  enum
34  {
35  INHERITANCE, // inheritance relation
36  INSTANCE, // template-instance relation
37  FIRST_FIELD, // src -ff-> dst => dst is first field of src
38  STD_DEF // Edges defined by the standard like (int -std-> char)
39  // We also make the char --> void edge a STD_DEF edge.
40  };
41 
43 
45  : GenericEdge<DCHNode>(src, dst, k), offset(0)
46  {
47  }
48 
50  {
51  return offset;
52  }
53 
55  {
56  this->offset = offset;
57  }
58 
59 private:
61 };
62 
63 class DCHNode : public GenericNode<DCHNode, DCHEdge>
64 {
65 public:
66  typedef enum
67  {
68  PURE_ABSTRACT = 0x1, // pure virtual abstract class
69  MULTI_INHERITANCE = 0x2, // multi inheritance class
70  TEMPLATE = 0x04, // template class
71  SCALAR = 0x08 // non-class scalar type
73 
74  typedef std::vector<const Function*> FuncVector;
75 
76  DCHNode(const DIType* diType, NodeID i = 0, GNodeK k = GNodeK::DCHNodeKd)
77  : GenericNode<DCHNode, DCHEdge>(i, k), vtable(nullptr), flags(0)
78  {
79  this->diType = diType;
80  if (diType == nullptr)
81  {
82  typeName = "null-void";
83  }
84  else if (diType->getRawName() != nullptr)
85  {
86  typeName = diType->getName().str();
87  }
88  else
89  {
90  typeName = "unnamed!";
91  }
92  }
93 
94  ~DCHNode() { }
95 
96  const DIType * getDIType(void) const
97  {
98  return diType;
99  }
100 
102  {
103  return typeName;
104  }
105 
107 
108  inline void setFlag(CLASSATTR mask)
109  {
110  flags |= mask;
111  }
112  inline bool hasFlag(CLASSATTR mask) const
113  {
114  return (flags & mask) == mask;
115  }
117 
119 
120  inline void setPureAbstract()
121  {
123  }
124  inline void setMultiInheritance()
125  {
127  }
128  inline void setTemplate()
129  {
130  setFlag(TEMPLATE);
131  }
132  inline void setScalar()
133  {
134  setFlag(SCALAR);
135  }
136  inline bool isPureAbstract() const
137  {
138  return hasFlag(PURE_ABSTRACT);
139  }
140  inline bool isMultiInheritance() const
141  {
142  return hasFlag(MULTI_INHERITANCE);
143  }
144  inline bool isTemplate() const
145  {
146  return hasFlag(TEMPLATE);
147  }
148  inline bool isScalar() const
149  {
150  return hasFlag(SCALAR);
151  }
153 
154  void addTypedef(const DIDerivedType *diTypedef)
155  {
156  typedefs.insert(diTypedef);
157  }
158 
160  {
161  return typedefs;
162  }
163 
164  void setVTable(const SVFGlobalValue *vtbl)
165  {
166  vtable = vtbl;
167  }
168 
169  const SVFGlobalValue *getVTable() const
170  {
171  return vtable;
172  }
173 
175  const std::vector<std::vector<const Function* >> &getVfnVectors(void) const
176  {
177  return vfnVectors;
178  }
179 
181  std::vector<const Function* > &getVfnVector(unsigned n)
182  {
183  if (vfnVectors.size() < n + 1)
184  {
185  vfnVectors.resize(n + 1);
186  }
187 
188  return vfnVectors[n];
189  }
190 
191 private:
193  const DIType *diType;
198  size_t flags;
200  std::vector<const Function* > primaryVTable;
204  std::vector<std::vector<const Function*>> vfnVectors;
205 };
206 
208 class DCHGraph : public CommonCHGraph, public GenericGraph<DCHNode, DCHEdge>
209 {
210 public:
212  static const DIType* stripQualifiers(const DIType*);
213 
215  static const DIType* stripArray(const DIType*);
216 
224  static bool teq(const DIType* t1, const DIType* t2);
225 
227  static std::string diTypeToStr(const DIType *);
228 
229  // Returns whether t is an array, a struct, a class, a union, or neither.
230  static bool isAgg(const DIType* t);
231 
232 public:
233  DCHGraph(const SVFModule *svfMod)
234  : svfModule(svfMod), numTypes(0) // vfID(0), buildingCHGTime(0) {
235  {
236  this->kind = DI;
237  }
238 
239  virtual ~DCHGraph() { };
240 
243  virtual void buildCHG(bool extend);
244 
245  void dump(const std::string& filename)
246  {
248  }
249 
250  void print(void);
251 
252  virtual bool csHasVFnsBasedonCHA(const CallICFGNode* cs) override
253  {
254  return csHasVtblsBasedonCHA(cs);
255  }
256 
257  virtual const VFunSet &getCSVFsBasedonCHA(const CallICFGNode* cs) override;
258 
259  virtual bool csHasVtblsBasedonCHA(CallBase* cs)
260  {
261  assert(false && "not supported");
263  if (!hasNode(type))
264  {
265  return false;
266  }
267 
268  return getNode(type)->getVTable() != nullptr;
269  }
270 
271  virtual bool csHasVtblsBasedonCHA(const CallICFGNode* cs) override
272  {
273  assert(false && "not supported!");
274  abort();
275  }
276 
277  virtual const VTableSet &getCSVtblsBasedonCHA(const CallICFGNode* cs) override;
278  virtual void getVFnsFromVtbls(const CallICFGNode* cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
279 
282  virtual bool isBase(const DIType *a, const DIType *b, bool firstField);
283 
285  virtual bool isFieldOf(const DIType *f, const DIType *b);
286 
287  static inline bool classof(const CommonCHGraph *chg)
288  {
289  return chg->getKind() == DI;
290  }
291 
295  const DIType* getCanonicalType(const DIType* t);
296 
298  const DIType *getFieldType(const DIType *base, unsigned idx)
299  {
300  base = getCanonicalType(base);
301  if (base == nullptr)
302  {
303  // Conservative; the base object is untyped, sadly.
304  return nullptr;
305  }
306 
307  // For TBHC this is conservative because the union type is lower in the DCHG
308  // than its fields. TODO: make more precise.
309  if (base->getTag() == dwarf::DW_TAG_union_type)
310  {
311  return base;
312  }
313 
314  if (base->getTag() == dwarf::DW_TAG_array_type)
315  {
316  const DICompositeType* cbase =
317  SVFUtil::dyn_cast<DICompositeType>(base);
318  assert(cbase && "DCHG: bad DIComposite case");
319  return cbase->getBaseType();
320  }
321 
322  if (!(base->getTag() == dwarf::DW_TAG_class_type ||
323  base->getTag() == dwarf::DW_TAG_structure_type))
324  {
325  return nullptr;
326  }
327 
328  assert(fieldTypes.find(base) != fieldTypes.end() && "DCHG: base not flattened!");
329  std::vector<const DIType *> &fields = fieldTypes[base];
330  assert(fields.size() > idx && "DCHG: idx into struct larger than # fields!");
331  return getCanonicalType(fields[idx]);
332  }
333 
335  const std::vector<const DIType *> &getFieldTypes(const DIType *base)
336  {
337  base = getCanonicalType(base);
338  assert(fieldTypes.find(base) != fieldTypes.end() && "DCHG: base not flattened!");
339  return fieldTypes[base];
340  }
341 
342  // Returns the number of fields in base (length of getFieldTypes).
343  unsigned getNumFields(const DIType *base)
344  {
345  base = getCanonicalType(base);
346  assert(fieldTypes.find(base) != fieldTypes.end() && "DCHG: base not flattened!");
347  return fieldTypes[base].size();
348  }
349 
351  const Set<const DIType *> &getAggs(const DIType *base)
352  {
353  base = getCanonicalType(base);
354  assert(containingAggs.find(base) != containingAggs.end() && "DCHG: aggregates not gathered for base!");
355  return containingAggs[base];
356  }
357 
358  bool isFirstField(const DIType* f, const DIType* b);
359 
360 protected:
364  bool extended = false;
385 
386 private:
388  void handleDIBasicType(const DIBasicType* basicType);
390  void handleDICompositeType(const DICompositeType* compositeType);
392  void handleDIDerivedType(const DIDerivedType* derivedType);
394  void handleDISubroutineType(const DISubroutineType* subroutineType);
395 
397  void buildVTables(const SVFModule& module);
398 
400  const NodeBS& cha(const DIType* type, bool firstField);
401 
403  void handleTypedef(const DIType* typedefType);
404 
406  void flatten(const DICompositeType* type);
407 
409  void gatherAggs(const DICompositeType* type);
410 
413 
415  const DIType* getCSStaticType(CallBase* cs) const;
416 
417  const DIType *getCSStaticType(const CallICFGNode* cs) const
418  {
419  assert(false && "not supported!");
420  abort();
421  }
422 
424  bool hasNode(const DIType* type)
425  {
427  return diTypeToNodeMap.find(type) != diTypeToNodeMap.end();
428  }
429 
432  {
434  if (hasNode(type))
435  {
436  return diTypeToNodeMap.at(type);
437  }
438 
439  return nullptr;
440  }
441 
442 
444  DCHEdge* addEdge(const DIType* t1, const DIType* t2, DCHEdge::GEdgeKind et);
446  DCHEdge* hasEdge(const DIType* t1, const DIType* t2, DCHEdge::GEdgeKind et);
447 
450 };
451 
452 } // End namespace SVF
453 
454 namespace SVF
455 {
456 /* !
457  * GenericGraphTraits specializations for generic graph algorithms.
458  * Provide graph traits for traversing from a constraint node using standard graph traversals.
459  */
460 template<> struct GenericGraphTraits<SVF::DCHNode*> : public GenericGraphTraits<SVF::GenericNode<SVF::DCHNode,SVF::DCHEdge>* >
461 {
462 };
463 
465 template<>
466 struct GenericGraphTraits<Inverse<SVF::DCHNode*> > : public GenericGraphTraits<Inverse<SVF::GenericNode<SVF::DCHNode,SVF::DCHEdge>* > >
467 {
468 };
469 
470 template<> struct GenericGraphTraits<SVF::DCHGraph*> : public GenericGraphTraits<SVF::GenericGraph<SVF::DCHNode,SVF::DCHEdge>* >
471 {
473 };
474 
475 } // End namespace llvm
476 
477 #endif /* DCHG_H_ */
newitem type
Definition: cJSON.cpp:2739
cJSON * a
Definition: cJSON.cpp:2560
cJSON * n
Definition: cJSON.cpp:2558
const cJSON *const b
Definition: cJSON.h:255
const char *const string
Definition: cJSON.h:172
Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
Definition: CHG.h:51
CHGKind kind
Definition: CHG.h:73
CHGKind getKind(void) const
Definition: CHG.h:67
@ FIRST_FIELD
Definition: DCHG.h:37
@ INSTANCE
Definition: DCHG.h:36
@ STD_DEF
Definition: DCHG.h:38
@ INHERITANCE
Definition: DCHG.h:35
DCHEdge(DCHNode *src, DCHNode *dst, GEdgeFlag k=0)
Definition: DCHG.h:44
GenericNode< DCHNode, DCHEdge >::GEdgeSetTy DCHEdgeSetTy
Definition: DCHG.h:42
u32_t offset
Definition: DCHG.h:60
u32_t getConstantFieldIdx(void) const
Definition: DCHG.h:49
void setOffset(u32_t offset)
Definition: DCHG.h:54
Dwarf based CHG.
Definition: DCHG.h:209
const DIType * getCSStaticType(CallBase *cs) const
Retrieves the metadata associated with a virtual callsite.
Definition: DCHG.cpp:424
unsigned getNumFields(const DIType *base)
Definition: DCHG.h:343
const DIType * getCanonicalType(const DIType *t)
Definition: DCHG.cpp:722
const NodeBS & cha(const DIType *type, bool firstField)
Returns a set of all children of type (CHA). Also gradually builds chaMap.
Definition: DCHG.cpp:223
void buildVTables(const SVFModule &module)
Finds all defined virtual functions and attaches them to nodes.
Definition: DCHG.cpp:166
const Set< const DIType * > & getAggs(const DIType *base)
Returns all the aggregates contained (transitively) in base.
Definition: DCHG.h:351
static const DIType * stripQualifiers(const DIType *)
Returns the DIType beneath the qualifiers. Does not strip away "DW_TAG_members".
Definition: DCHG.cpp:763
void handleDIDerivedType(const DIDerivedType *derivedType)
Construction helper to process DIDerivedTypes.
Definition: DCHG.cpp:97
DCHEdge * addEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKind et)
Creates an edge between from t1 to t2.
Definition: DCHG.cpp:433
bool isFirstField(const DIType *f, const DIType *b)
Definition: DCHG.cpp:940
static std::string diTypeToStr(const DIType *)
Returns a human-readable version of the DIType.
Definition: DCHG.cpp:967
void handleDICompositeType(const DICompositeType *compositeType)
Construction helper to process DICompositeTypes.
Definition: DCHG.cpp:27
const DIType * getCSStaticType(const CallICFGNode *cs) const
Definition: DCHG.h:417
Map< const CallICFGNode *, VFunSet > csCHAMap
Maps callsites to a set of potential virtual functions based on CHA.
Definition: DCHG.h:376
bool hasNode(const DIType *type)
Checks if a node exists for type.
Definition: DCHG.h:424
void dump(const std::string &filename)
Definition: DCHG.h:245
void print(void)
Definition: DCHG.cpp:1140
Map< const DIType *, NodeBS > chaFFMap
Maps types to all children but also considering first field.
Definition: DCHG.h:372
Map< const DIType *, const DIType * > canonicalTypeMap
Maps types to their canonical type (many-to-one).
Definition: DCHG.h:378
void handleDISubroutineType(const DISubroutineType *subroutineType)
Construction helper to process DISubroutineTypes.
Definition: DCHG.cpp:133
virtual void getVFnsFromVtbls(const CallICFGNode *cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override
Definition: DCHG.cpp:592
static const DIType * stripArray(const DIType *)
Returns the DIType beneath all qualifiers and arrays.
Definition: DCHG.cpp:816
void handleTypedef(const DIType *typedefType)
Attaches the typedef(s) to the base node.
Definition: DCHG.cpp:138
virtual void buildCHG(bool extend)
Definition: DCHG.cpp:469
virtual bool csHasVFnsBasedonCHA(const CallICFGNode *cs) override
Definition: DCHG.h:252
DCHEdge * hasEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKind et)
Returns the edge between t1 and t2 if it exists, returns nullptr otherwise.
Definition: DCHG.cpp:450
NodeID numTypes
Number of types (nodes) in the graph.
Definition: DCHG.h:449
DCHGraph(const SVFModule *svfMod)
Definition: DCHG.h:233
const SVFModule * svfModule
SVF Module this CHG is built from.
Definition: DCHG.h:362
void handleDIBasicType(const DIBasicType *basicType)
Construction helper to process DIBasicTypes.
Definition: DCHG.cpp:22
virtual const VTableSet & getCSVtblsBasedonCHA(const CallICFGNode *cs) override
Definition: DCHG.cpp:564
void gatherAggs(const DICompositeType *type)
Populates containingAggs for type and all its elements.
Definition: DCHG.cpp:353
DCHNode * getNode(const DIType *type)
Returns the node for type (nullptr if it doesn't exist).
Definition: DCHG.h:431
static bool isAgg(const DIType *t)
Definition: DCHG.cpp:345
DCHNode * getOrCreateNode(const DIType *type)
Creates a node from type, or returns it if it exists.
Definition: DCHG.cpp:406
Map< const DIType *, VTableSet > vtblCHAMap
Maps types to a set with their vtable and all their children's.
Definition: DCHG.h:374
bool extended
Whether this CHG is an extended CHG (first-field). Set by buildCHG.
Definition: DCHG.h:364
Map< const DIType *, Set< const DIType * > > containingAggs
Maps aggregate types to all the aggregate types it transitively contains.
Definition: DCHG.h:384
virtual bool isBase(const DIType *a, const DIType *b, bool firstField)
Definition: DCHG.cpp:675
void flatten(const DICompositeType *type)
Populates fieldTypes for type and all its elements.
Definition: DCHG.cpp:268
virtual const VFunSet & getCSVFsBasedonCHA(const CallICFGNode *cs) override
Definition: DCHG.cpp:547
const DIType * getFieldType(const DIType *base, unsigned idx)
Returns the type of field number idx (flattened) in base.
Definition: DCHG.h:298
static bool teq(const DIType *t1, const DIType *t2)
Definition: DCHG.cpp:828
Map< const DIType *, std::vector< const DIType * > > fieldTypes
Maps types to their flattened fields' types.
Definition: DCHG.h:382
Map< const DIType *, NodeBS > chaMap
Maps types to all children (i.e. CHA).
Definition: DCHG.h:370
Map< const DIType *, DCHNode * > diTypeToNodeMap
Maps DITypes to their nodes.
Definition: DCHG.h:366
virtual ~DCHGraph()
Definition: DCHG.h:239
virtual bool csHasVtblsBasedonCHA(const CallICFGNode *cs) override
Definition: DCHG.h:271
const std::vector< const DIType * > & getFieldTypes(const DIType *base)
Returns a vector of the types of all fields in base.
Definition: DCHG.h:335
virtual bool isFieldOf(const DIType *f, const DIType *b)
Returns true if f is a field of b (fields from getFieldTypes).
Definition: DCHG.cpp:686
Map< const SVFGlobalValue *, const DIType * > vtblToTypeMap
Maps VTables to the DIType associated with them.
Definition: DCHG.h:368
static bool classof(const CommonCHGraph *chg)
Definition: DCHG.h:287
Set< const DIType * > canonicalTypes
Set of all possible canonical types (i.e. values of canonicalTypeMap).
Definition: DCHG.h:380
virtual bool csHasVtblsBasedonCHA(CallBase *cs)
Definition: DCHG.h:259
@ PURE_ABSTRACT
Definition: DCHG.h:68
@ MULTI_INHERITANCE
Definition: DCHG.h:69
@ TEMPLATE
Definition: DCHG.h:70
@ SCALAR
Definition: DCHG.h:71
const DIType * diType
Type of this node.
Definition: DCHG.h:193
std::string getName() const
Definition: DCHG.h:101
size_t flags
Definition: DCHG.h:198
const DIType * getDIType(void) const
Definition: DCHG.h:96
void setTemplate()
Definition: DCHG.h:128
std::vector< const Function * > & getVfnVector(unsigned n)
Return the nth virtual function vector in the vtable.
Definition: DCHG.h:181
bool isMultiInheritance() const
Definition: DCHG.h:140
void setFlag(CLASSATTR mask)
Flags.
Definition: DCHG.h:108
bool isScalar() const
Definition: DCHG.h:148
std::vector< const Function * > primaryVTable
The virtual functions which this class actually defines/overrides.
Definition: DCHG.h:200
bool hasFlag(CLASSATTR mask) const
Definition: DCHG.h:112
void setMultiInheritance()
Definition: DCHG.h:124
const std::vector< std::vector< const Function * > > & getVfnVectors(void) const
Returns the vector of virtual function vectors.
Definition: DCHG.h:175
DCHNode(const DIType *diType, NodeID i=0, GNodeK k=GNodeK::DCHNodeKd)
Definition: DCHG.h:76
std::string typeName
Definition: DCHG.h:197
void setScalar()
Definition: DCHG.h:132
const SVFGlobalValue * getVTable() const
Definition: DCHG.h:169
void addTypedef(const DIDerivedType *diTypedef)
Definition: DCHG.h:154
~DCHNode()
Definition: DCHG.h:94
Set< const DIDerivedType * > typedefs
Typedefs which map to this type.
Definition: DCHG.h:195
const Set< const DIDerivedType * > & getTypedefs(void) const
Definition: DCHG.h:159
const SVFGlobalValue * vtable
Definition: DCHG.h:196
void setVTable(const SVFGlobalValue *vtbl)
Definition: DCHG.h:164
bool isTemplate() const
Definition: DCHG.h:144
std::vector< const Function * > FuncVector
Definition: DCHG.h:74
bool isPureAbstract() const
Definition: DCHG.h:136
std::vector< std::vector< const Function * > > vfnVectors
Definition: DCHG.h:204
void setPureAbstract()
Attribute.
Definition: DCHG.h:120
DCHNode * src
source node
Definition: GenericGraph.h:64
DCHNode * dst
destination node
Definition: GenericGraph.h:65
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
Definition: GraphPrinter.h:56
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
llvm::DISubroutineType DISubroutineType
Definition: BasicTypes.h:240
llvm::CallBase CallBase
Definition: BasicTypes.h:146
Set< const SVFGlobalValue * > VTableSet
Definition: CHG.h:44
u32_t NodeID
Definition: GeneralType.h:55
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
llvm::DIDerivedType DIDerivedType
Definition: BasicTypes.h:238
llvm::DIType DIType
Definition: BasicTypes.h:236
Set< const SVFFunction * > VFunSet
Definition: CHG.h:47
unsigned u32_t
Definition: GeneralType.h:46
llvm::DIBasicType DIBasicType
Definition: BasicTypes.h:241
llvm::DICompositeType DICompositeType
Definition: BasicTypes.h:237
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96