Static Value-Flow Analysis
Loading...
Searching...
No Matches
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
24namespace SVF
25{
26
27class SVFModule;
28class DCHNode;
29
30class DCHEdge : public GenericEdge<DCHNode>
31{
32public:
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
48
50 {
51 return offset;
52 }
53
55 {
56 this->offset = offset;
57 }
58
59private:
61};
62
63class DCHNode : public GenericNode<DCHNode, DCHEdge>
64{
65public:
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
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
95
96 const DIType * getDIType(void) const
97 {
98 return diType;
99 }
100
101 std::string getName() const
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 }
125 {
127 }
128 inline void setTemplate()
129 {
131 }
132 inline void setScalar()
133 {
135 }
136 inline bool isPureAbstract() const
137 {
138 return hasFlag(PURE_ABSTRACT);
139 }
140 inline bool isMultiInheritance() const
141 {
143 }
144 inline bool isTemplate() const
145 {
146 return hasFlag(TEMPLATE);
147 }
148 inline bool isScalar() const
149 {
150 return hasFlag(SCALAR);
151 }
153
155 {
156 typedefs.insert(diTypedef);
157 }
158
160 {
161 return typedefs;
162 }
163
165 {
166 vtable = vtbl;
167 }
168
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
191private:
197 std::string typeName;
198 size_t flags;
200 std::vector<const Function* > primaryVTable;
204 std::vector<std::vector<const Function*>> vfnVectors;
205};
206
208class DCHGraph : public CommonCHGraph, public GenericGraph<DCHNode, DCHEdge>
209{
210public:
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
232public:
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
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
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
360protected:
364 bool extended = false;
385
386private:
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
447
450};
451
452} // End namespace SVF
453
454namespace 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 */
460template<> struct GenericGraphTraits<SVF::DCHNode*> : public GenericGraphTraits<SVF::GenericNode<SVF::DCHNode,SVF::DCHEdge>* >
461{
462};
463
465template<>
466struct GenericGraphTraits<Inverse<SVF::DCHNode*> > : public GenericGraphTraits<Inverse<SVF::GenericNode<SVF::DCHNode,SVF::DCHEdge>* > >
467{
468};
469
470template<> 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
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
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
GenericNode< DCHNode, DCHEdge >::GEdgeSetTy DCHEdgeSetTy
Definition DCHG.h:42
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
const DIType * getFieldType(const DIType *base, unsigned idx)
Returns the type of field number idx (flattened) in base.
Definition DCHG.h:298
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
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
DCHNode * getNode(const DIType *type)
Returns the node for type (nullptr if it doesn't exist).
Definition DCHG.h:431
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
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
const std::vector< const DIType * > & getFieldTypes(const DIType *base)
Returns a vector of the types of all fields in base.
Definition DCHG.h:335
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
const DIType * getCSStaticType(const CallICFGNode *cs) const
Definition DCHG.h:417
virtual const VFunSet & getCSVFsBasedonCHA(const CallICFGNode *cs) override
Definition DCHG.cpp:547
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
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
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
void setTemplate()
Definition DCHG.h:128
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 SVFGlobalValue * getVTable() const
Definition DCHG.h:169
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
void addTypedef(const DIDerivedType *diTypedef)
Definition DCHG.h:154
std::vector< const Function * > & getVfnVector(unsigned n)
Return the nth virtual function vector in the vtable.
Definition DCHG.h:181
~DCHNode()
Definition DCHG.h:94
Set< const DIDerivedType * > typedefs
Typedefs which map to this type.
Definition DCHG.h:195
const DIType * getDIType(void) const
Definition DCHG.h:96
const SVFGlobalValue * vtable
Definition DCHG.h:196
void setVTable(const SVFGlobalValue *vtbl)
Definition DCHG.h:164
bool isTemplate() const
Definition DCHG.h:144
const Set< const DIDerivedType * > & getTypedefs(void) const
Definition DCHG.h:159
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
DCHNode * dst
destination node
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
const std::string & getName() const
Definition SVFValue.h:243
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:46
u32_t NodeID
Definition GeneralType.h:55
llvm::DIDerivedType DIDerivedType
Definition BasicTypes.h:238
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
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