Static Value-Flow Analysis
Loading...
Searching...
No Matches
IRGraph.cpp
Go to the documentation of this file.
1//===- SVFIR.cpp -- Program assignment graph------------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * SVFIR.cpp
25 *
26 * Created on: Nov 1, 2013
27 * Author: Yulei Sui
28 */
29
30#include "Graphs/IRGraph.h"
31#include "Util/Options.h"
32
33using namespace SVF;
34using namespace SVFUtil;
35
37{
38
39 for (auto &pair: objTypeInfoMap)
40 {
41 if (ObjTypeInfo* ti = pair.second)
42 delete ti;
43 }
44
45 for (const SVFType* type : svfTypes)
46 delete type;
47 svfTypes.clear();
48
49 for (const StInfo* st : stInfos)
50 delete st;
51 stInfos.clear();
52}
53
58
59
61{
62 FunObjVarToIDMapTy::const_iterator iter = returnFunObjSymMap.find(func);
63 assert(iter!=returnFunObjSymMap.end() && "ret sym not found");
64 return iter->second;
65}
66
68{
69 FunObjVarToIDMapTy::const_iterator iter = varargFunObjSymMap.find(func);
70 assert(iter!=varargFunObjSymMap.end() && "vararg sym not found");
71 return iter->second;
72}
74{
75 if (const SVFArrayType* at = SVFUtil::dyn_cast<SVFArrayType>(type))
76 {
77 outs() << " {Type: " << *at << "}\n"
78 << "\tarray type "
79 << "\t [element size = " << getNumOfFlattenElements(at) << "]\n"
80 << "\n";
81 }
82 else if (const SVFStructType *st = SVFUtil::dyn_cast<SVFStructType>(type))
83 {
84 outs() <<" {Type: " << *st << "}\n";
85 const std::vector<const SVFType*>& finfo = getTypeInfo(st)->getFlattenFieldTypes();
86 int field_idx = 0;
87 for(const SVFType* type : finfo)
88 {
89 outs() << " \tField_idx = " << ++field_idx
90 << ", field type: " << *type << "\n";
91 }
92 outs() << "\n";
93 }
94 else if (const SVFPointerType* pt= SVFUtil::dyn_cast<SVFPointerType>(type))
95 {
96 outs() << *pt << "\n";
97 }
98 else if (const SVFFunctionType* fu =
99 SVFUtil::dyn_cast<SVFFunctionType>(type))
100 {
101 outs() << " {Type: " << *fu << "}\n\n";
102 }
103 else if (const SVFOtherType* ot = SVFUtil::dyn_cast<SVFOtherType>(type))
104 {
105 outs() << " {Type: "<< *ot << "(SVFOtherType)}\n\n";
106 }
107 else
108 {
109 assert(type->isSingleValueType() && "not a single value type, then what else!!");
112 outs() << " {Type: " << *type << "}\n"
113 << "\t [object size = " << eSize << "]\n"
114 << "\n";
115 }
116}
117
118const std::vector<const SVFType *> &IRGraph::getFlattenFieldTypes(const SVFStructType *T)
119{
121}
122
124{
126 {
127 const std::vector<const SVFType*>& so = getTypeInfo(baseType)->getFlattenElementTypes();
128 assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!");
129 return so[flatten_idx];
130 }
131 else
132 {
133 const std::vector<const SVFType*>& so = getTypeInfo(baseType)->getFlattenFieldTypes();
134 assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!");
135 return so[flatten_idx];
136 }
137}
138
143
145{
147 {
148 const std::vector<u32_t>& so = getTypeInfo(T)->getFlattenedElemIdxVec();
149 assert ((unsigned)origId < so.size() && !so.empty() && "element index out of bounds, can't get flattened index!");
150 return so[origId];
151 }
152 else
153 {
154 if(SVFUtil::isa<SVFStructType>(T))
155 {
156 const std::vector<u32_t>& so = getTypeInfo(T)->getFlattenedFieldIdxVec();
157 assert ((unsigned)origId < so.size() && !so.empty() && "Struct index out of bounds, can't get flattened index!");
158 return so[origId];
159 }
160 else
161 {
163 assert(SVFUtil::isa<SVFArrayType>(T) && "Only accept struct or array type if Options::ModelArrays is disabled!");
164 return 0;
165 }
166 }
167}
168
176
187
189{
193
194 APOffset offset = apOffset;
195 if(offset < 0)
196 {
197 writeWrnMsg("try to create a gep node with negative offset.");
198 offset = std::abs(offset);
199 }
200 u32_t maxOffset = baseObj->getMaxFieldOffsetLimit();
201
207 if (maxOffset == 0)
208 offset = 0;
214 else if ((u32_t)offset > maxOffset - 1)
215 {
221 else
225 offset = maxOffset - 1;
226 }
227
228 return offset;
229}
230
232{
233
235 if(type && type->isPointerTy())
236 {
238 }
239 return typeInfo;
240}
241
243{
244 assert(T);
245 SVFTypeSet::const_iterator it = svfTypes.find(T);
246 assert(it != svfTypes.end() && "type info not found? collect them first during SVFIR Building");
247 return (*it)->getTypeInfo();
248}
249
254{
255
257 outs() << "add edge from " << src->getId() << " kind :"
258 << src->getNodeKind() << " to " << dst->getId()
259 << " kind :" << dst->getNodeKind() << "\n");
260 src->addOutEdge(edge);
261 dst->addInEdge(edge);
262 return true;
263}
264
269{
270 SVFStmt edge(src,dst,kind, false);
271 return hasEdge(&edge, kind);
272}
273
278{
280 SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge);
281 if (it != KindToSVFStmtSetMap[kind].end())
282 {
283 return *it;
284 }
285 return nullptr;
286}
287
292{
293 SVFStmt edge(src,dst,SVFStmt::makeEdgeFlagWithCallInst(kind,callInst), false);
294 SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge);
295 if (it != KindToSVFStmtSetMap[kind].end())
296 {
297 return *it;
298 }
299 return nullptr;
300}
301
303{
304 SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(edge);
305 if (it != KindToSVFStmtSetMap[kind].end())
306 {
307 return *it;
308 }
309 return nullptr;
310}
311
312
316void IRGraph::dump(std::string name)
317{
319}
320
325{
326 SVF::ViewGraph(this, "ProgramAssignmentGraph");
327}
328
329
331{
332 if (valVarNum != 0) return valVarNum;
333 u32_t num = 0;
334 for (const auto& item: *this)
335 {
336 if (SVFUtil::isa<ValVar>(item.second))
337 num++;
338 }
339 return valVarNum = num;
340}
341
342
344{
345 if (objVarNum != 0) return objVarNum;
346 u32_t num = 0;
347 for (const auto& item: *this)
348 {
349 if (SVFUtil::isa<ObjVar>(item.second))
350 num++;
351 }
352 return objVarNum = num;
353}
354
355
356
357namespace SVF
358{
362template<>
364{
365
368 DOTGraphTraits(bool isSimple = false) :
369 DefaultDOTGraphTraits(isSimple)
370 {
371 }
372
374 static std::string getGraphName(IRGraph *graph)
375 {
376 return graph->getGraphName();
377 }
378
381 static bool isNodeHidden(SVFVar *node, IRGraph *)
382 {
383 if (Options::ShowHiddenNode()) return false;
384 else return node->isIsolatedNode();
385 }
386
389 static std::string getNodeLabel(SVFVar *node, IRGraph*)
390 {
391 std::string str;
392 std::stringstream rawstr(str);
393 // print function info
394 if (node->getFunction())
395 rawstr << "[" << node->getFunction()->getName() << "] ";
396
397 rawstr << node->toString();
398
399 return rawstr.str();
400
401 }
402
403 static std::string getNodeAttributes(SVFVar *node, IRGraph*)
404 {
405 if (SVFUtil::isa<ValVar>(node))
406 {
407 if(SVFUtil::isa<GepValVar>(node))
408 return "shape=hexagon";
409 else if (SVFUtil::isa<DummyValVar>(node))
410 return "shape=diamond";
411 else
412 return "shape=box";
413 }
414 else if (SVFUtil::isa<ObjVar>(node))
415 {
416 if(SVFUtil::isa<GepObjVar>(node))
417 return "shape=doubleoctagon";
418 else if(SVFUtil::isa<BaseObjVar>(node))
419 return "shape=box3d";
420 else if (SVFUtil::isa<DummyObjVar>(node))
421 return "shape=tab";
422 else
423 return "shape=component";
424 }
425 else if (SVFUtil::isa<RetValPN>(node))
426 {
427 return "shape=Mrecord";
428 }
429 else if (SVFUtil::isa<VarArgValPN>(node))
430 {
431 return "shape=octagon";
432 }
433 else
434 {
435 assert(0 && "no such kind!!");
436 }
437 return "";
438 }
439
440 template<class EdgeIter>
442 {
443 const SVFStmt* edge = *(EI.getCurrent());
444 assert(edge && "No edge found!!");
445 if (SVFUtil::isa<AddrStmt>(edge))
446 {
447 return "color=green";
448 }
449 else if (SVFUtil::isa<CopyStmt>(edge))
450 {
451 return "color=black";
452 }
453 else if (SVFUtil::isa<GepStmt>(edge))
454 {
455 return "color=purple";
456 }
457 else if (SVFUtil::isa<StoreStmt>(edge))
458 {
459 return "color=blue";
460 }
461 else if (SVFUtil::isa<LoadStmt>(edge))
462 {
463 return "color=red";
464 }
465 else if (SVFUtil::isa<PhiStmt>(edge))
466 {
467 return "color=grey";
468 }
469 else if (SVFUtil::isa<SelectStmt>(edge))
470 {
471 return "color=grey";
472 }
473 else if (SVFUtil::isa<CmpStmt>(edge))
474 {
475 return "color=grey";
476 }
477 else if (SVFUtil::isa<BinaryOPStmt>(edge))
478 {
479 return "color=grey";
480 }
481 else if (SVFUtil::isa<UnaryOPStmt>(edge))
482 {
483 return "color=grey";
484 }
485 else if (SVFUtil::isa<BranchStmt>(edge))
486 {
487 return "color=grey";
488 }
489 else if (SVFUtil::isa<TDForkPE>(edge))
490 {
491 return "color=Turquoise";
492 }
493 else if (SVFUtil::isa<TDJoinPE>(edge))
494 {
495 return "color=Turquoise";
496 }
497 else if (SVFUtil::isa<CallPE>(edge))
498 {
499 return "color=black,style=dashed";
500 }
501 else if (SVFUtil::isa<RetPE>(edge))
502 {
503 return "color=black,style=dotted";
504 }
505
506 assert(false && "No such kind edge!!");
507 exit(1);
508 }
509
510 template<class EdgeIter>
511 static std::string getEdgeSourceLabel(SVFVar*, EdgeIter EI)
512 {
513 const SVFStmt* edge = *(EI.getCurrent());
514 assert(edge && "No edge found!!");
515 if(const CallPE* calledge = SVFUtil::dyn_cast<CallPE>(edge))
516 {
517 return calledge->getCallSite()->getSourceLoc();
518 }
519 else if(const RetPE* retedge = SVFUtil::dyn_cast<RetPE>(edge))
520 {
521 return retedge->getCallSite()->getSourceLoc();
522 }
523 return "";
524 }
525};
526} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define DPAGBuild
Definition SVFType.h:601
newitem type
Definition cJSON.cpp:2739
buffer offset
Definition cJSON.cpp:1113
const char *const name
Definition cJSON.h:264
cJSON * item
Definition cJSON.h:222
GEdgeSetTy::iterator iterator
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
Definition IRGraph.cpp:144
u32_t getNumOfFlattenElements(const SVFType *T)
Definition IRGraph.cpp:169
const std::vector< const SVFType * > & getFlattenFieldTypes(const SVFStructType *T)
Return the flattened field type for struct type only.
Definition IRGraph.cpp:118
void destorySymTable()
Definition IRGraph.cpp:36
SVFStmt * hasLabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind, const ICFGNode *cs)
Definition IRGraph.cpp:291
SVFStmt * hasEdge(SVFStmt *edge, SVFStmt::PEDGEK kind)
Definition IRGraph.cpp:302
void printFlattenFields(const SVFType *type)
Debug method.
Definition IRGraph.cpp:73
void dump(std::string name)
Dump SVFIR.
Definition IRGraph.cpp:316
virtual ~IRGraph()
Definition IRGraph.cpp:54
Set< const StInfo * > stInfos
(owned) All StInfo
Definition IRGraph.h:97
u32_t getObjectNodeNum()
Definition IRGraph.cpp:343
void view()
View graph from the debugger.
Definition IRGraph.cpp:324
virtual APOffset getModulusOffset(const BaseObjVar *baseObj, const APOffset &apOffset)
Given an offset from a Gep Instruction, return it modulus offset by considering memory layout.
Definition IRGraph.cpp:188
SVFStmt::KindToSVFStmtMapTy KindToSVFStmtSetMap
SVFIR edge map containing all PAGEdges.
Definition IRGraph.h:108
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.
Definition IRGraph.cpp:123
ObjTypeInfo * createObjTypeInfo(const SVFType *type)
Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy ...
Definition IRGraph.cpp:231
std::string getGraphName() const
Return graph name.
Definition IRGraph.h:344
FunObjVarToIDMapTy varargFunObjSymMap
vararg map
Definition IRGraph.h:86
NodeID getReturnNode(const FunObjVar *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition IRGraph.cpp:60
const SVFType * getOriginalElemType(const SVFType *baseType, u32_t origId) const
Definition IRGraph.cpp:139
u32_t valVarNum
Definition IRGraph.h:113
IDToTypeInfoMapTy objTypeInfoMap
map a memory sym id to its obj
Definition IRGraph.h:87
bool addEdge(SVFVar *src, SVFVar *dst, SVFStmt *edge)
Add an edge into the graph.
Definition IRGraph.cpp:253
u32_t objVarNum
Definition IRGraph.h:114
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:67
SVFStmt * hasNonlabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind)
Definition IRGraph.cpp:268
u32_t getValueNodeNum()
Definition IRGraph.cpp:330
SVFTypeSet svfTypes
Definition IRGraph.h:94
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
Definition IRGraph.cpp:242
FunObjVarToIDMapTy returnFunObjSymMap
return map
Definition IRGraph.h:85
const ObjTypeInfo * createDummyObjTypeInfo(NodeID symId, const SVFType *type)
Definition IRGraph.cpp:177
void setFlag(MEMTYPE mask)
Flag for this object type.
static Option< bool > ModelArrays
Definition Options.h:185
static const Option< bool > CyclicFldIdx
Definition Options.h:186
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:35
static const Option< bool > ShowHiddenNode
Definition Options.h:225
static GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, const SVFVar *var)
static GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode *cs)
NodeID getId() const
Get ID.
Definition SVFValue.h:160
GNodeK getNodeKind() const
Get node kind.
Definition SVFValue.h:166
virtual const std::string & getName() const
Definition SVFValue.h:186
void addOutEdge(SVFStmt *outEdge)
void addInEdge(SVFStmt *inEdge)
Edge management methods.
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
virtual bool isIsolatedNode() const
Check if this node is isolated (no edges) in the SVFIR graph.
virtual const std::string toString() const
Get string representation.
const SVFType * getOriginalElemType(u32_t fldIdx) const
Definition SVFValue.cpp:68
std::vector< const SVFType * > & getFlattenElementTypes()
Definition SVFType.h:129
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition SVFType.h:125
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:166
std::vector< const SVFType * > & getFlattenFieldTypes()
Definition SVFType.h:133
std::vector< u32_t > & getFlattenedFieldIdxVec()
Definition SVFType.h:121
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:172
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:68
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:68
u32_t NodeID
Definition GeneralType.h:56
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
s64_t APOffset
Definition GeneralType.h:60
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:47
static std::string getEdgeAttributes(SVFVar *, EdgeIter EI, IRGraph *)
Definition IRGraph.cpp:441
DOTGraphTraits(bool isSimple=false)
Definition IRGraph.cpp:368
static std::string getGraphName(IRGraph *graph)
Return name of the graph.
Definition IRGraph.cpp:374
static std::string getNodeLabel(SVFVar *node, IRGraph *)
Definition IRGraph.cpp:389
static std::string getNodeAttributes(SVFVar *node, IRGraph *)
Definition IRGraph.cpp:403
static bool isNodeHidden(SVFVar *node, IRGraph *)
Definition IRGraph.cpp:381
NodeType::iterator ChildIteratorType
Definition IRGraph.cpp:367
static std::string getEdgeSourceLabel(SVFVar *, EdgeIter EI)
Definition IRGraph.cpp:511