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/GraphPrinter.h"
31#include "Graphs/ICFG.h"
32#include "Graphs/IRGraph.h"
33#include "Util/GeneralType.h"
34#include "Util/Options.h"
35#include "Util/SVFUtil.h"
36
37using namespace SVF;
38using namespace SVFUtil;
39
41{
42
43 for (auto &pair: objTypeInfoMap)
44 {
45 if (ObjTypeInfo* ti = pair.second)
46 delete ti;
47 }
48
49 for (const SVFType* type : svfTypes)
50 delete type;
51 svfTypes.clear();
52
53 for (const StInfo* st : stInfos)
54 delete st;
55 stInfos.clear();
56}
57
62
63
65{
66 FunObjVarToIDMapTy::const_iterator iter = returnFunObjSymMap.find(func);
67 assert(iter!=returnFunObjSymMap.end() && "ret sym not found");
68 return iter->second;
69}
70
72{
73 FunObjVarToIDMapTy::const_iterator iter = varargFunObjSymMap.find(func);
74 assert(iter!=varargFunObjSymMap.end() && "vararg sym not found");
75 return iter->second;
76}
78{
79 if (const SVFArrayType* at = SVFUtil::dyn_cast<SVFArrayType>(type))
80 {
81 outs() << " {Type: " << *at << "}\n"
82 << "\tarray type "
83 << "\t [element size = " << getNumOfFlattenElements(at) << "]\n"
84 << "\n";
85 }
86 else if (const SVFStructType *st = SVFUtil::dyn_cast<SVFStructType>(type))
87 {
88 outs() <<" {Type: " << *st << "}\n";
89 const std::vector<const SVFType*>& finfo = getTypeInfo(st)->getFlattenFieldTypes();
90 int field_idx = 0;
91 for(const SVFType* type : finfo)
92 {
93 outs() << " \tField_idx = " << ++field_idx
94 << ", field type: " << *type << "\n";
95 }
96 outs() << "\n";
97 }
98 else if (const SVFPointerType* pt= SVFUtil::dyn_cast<SVFPointerType>(type))
99 {
100 outs() << *pt << "\n";
101 }
102 else if (const SVFFunctionType* fu =
103 SVFUtil::dyn_cast<SVFFunctionType>(type))
104 {
105 outs() << " {Type: " << *fu << "}\n\n";
106 }
107 else if (const SVFOtherType* ot = SVFUtil::dyn_cast<SVFOtherType>(type))
108 {
109 outs() << " {Type: "<< *ot << "(SVFOtherType)}\n\n";
110 }
111 else
112 {
113 assert(type->isSingleValueType() && "not a single value type, then what else!!");
116 outs() << " {Type: " << *type << "}\n"
117 << "\t [object size = " << eSize << "]\n"
118 << "\n";
119 }
120}
121
122const std::vector<const SVFType *> &IRGraph::getFlattenFieldTypes(const SVFStructType *T)
123{
125}
126
128{
130 {
131 const std::vector<const SVFType*>& so = getTypeInfo(baseType)->getFlattenElementTypes();
132 assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!");
133 return so[flatten_idx];
134 }
135 else
136 {
137 const std::vector<const SVFType*>& so = getTypeInfo(baseType)->getFlattenFieldTypes();
138 assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!");
139 return so[flatten_idx];
140 }
141}
142
147
149{
151 {
152 const std::vector<u32_t>& so = getTypeInfo(T)->getFlattenedElemIdxVec();
153 assert ((unsigned)origId < so.size() && !so.empty() && "element index out of bounds, can't get flattened index!");
154 return so[origId];
155 }
156 else
157 {
158 if(SVFUtil::isa<SVFStructType>(T))
159 {
160 const std::vector<u32_t>& so = getTypeInfo(T)->getFlattenedFieldIdxVec();
161 assert ((unsigned)origId < so.size() && !so.empty() && "Struct index out of bounds, can't get flattened index!");
162 return so[origId];
163 }
164 else
165 {
167 assert(SVFUtil::isa<SVFArrayType>(T) && "Only accept struct or array type if Options::ModelArrays is disabled!");
168 return 0;
169 }
170 }
171}
172
180
191
193{
197
198 APOffset offset = apOffset;
199 if(offset < 0)
200 {
201 writeWrnMsg("try to create a gep node with negative offset.");
202 offset = std::abs(offset);
203 }
204 u32_t maxOffset = baseObj->getMaxFieldOffsetLimit();
205
211 if (maxOffset == 0)
212 offset = 0;
218 else if ((u32_t)offset > maxOffset - 1)
219 {
225 else
229 offset = maxOffset - 1;
230 }
231
232 return offset;
233}
234
236{
237
239 if(type && type->isPointerTy())
240 {
242 }
243 return typeInfo;
244}
245
247{
248 assert(T);
249 SVFTypeSet::const_iterator it = svfTypes.find(T);
250 assert(it != svfTypes.end() && "type info not found? collect them first during SVFIR Building");
251 return (*it)->getTypeInfo();
252}
253
258{
259
261 outs() << "add edge from " << src->getId() << " kind :"
262 << src->getNodeKind() << " to " << dst->getId()
263 << " kind :" << dst->getNodeKind() << "\n");
264 src->addOutEdge(edge);
265 dst->addInEdge(edge);
266 return true;
267}
268
273{
274 SVFStmt edge(src,dst,kind, false);
275 return hasEdge(&edge, kind);
276}
277
282{
284 SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge);
285 if (it != KindToSVFStmtSetMap[kind].end())
286 {
287 return *it;
288 }
289 return nullptr;
290}
291
296{
297 SVFStmt edge(src,dst,SVFStmt::makeEdgeFlagWithCallInst(kind,callInst), false);
298 SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge);
299 if (it != KindToSVFStmtSetMap[kind].end())
300 {
301 return *it;
302 }
303 return nullptr;
304}
305
307{
308 SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(edge);
309 if (it != KindToSVFStmtSetMap[kind].end())
310 {
311 return *it;
312 }
313 return nullptr;
314}
315
316
320void IRGraph::dump(std::string name)
321{
323}
324
329{
330 SVF::ViewGraph(this, "ProgramAssignmentGraph");
331}
332
333
335{
336 if (valVarNum != 0) return valVarNum;
337 u32_t num = 0;
338 for (const auto& item: *this)
339 {
340 if (SVFUtil::isa<ValVar>(item.second))
341 num++;
342 }
343 return valVarNum = num;
344}
345
346
348{
349 if (objVarNum != 0) return objVarNum;
350 u32_t num = 0;
351 for (const auto& item: *this)
352 {
353 if (SVFUtil::isa<ObjVar>(item.second))
354 num++;
355 }
356 return objVarNum = num;
357}
358
359
360
361namespace SVF
362{
366template<>
368{
369
372 DOTGraphTraits(bool isSimple = false) :
373 DefaultDOTGraphTraits(isSimple)
374 {
375 }
376
378 static std::string getGraphName(IRGraph *graph)
379 {
380 return graph->getGraphName();
381 }
382
385 static bool isNodeHidden(SVFVar *node, IRGraph *)
386 {
387 if (Options::ShowHiddenNode()) return false;
388 else return node->isIsolatedNode();
389 }
390
393 static std::string getNodeLabel(SVFVar *node, IRGraph*)
394 {
395 std::string str;
396 std::stringstream rawstr(str);
397 // print function info
398 if (node->getFunction())
399 rawstr << "[" << node->getFunction()->getName() << "] ";
400
401 rawstr << node->toString();
402
403 return rawstr.str();
404
405 }
406
407 static std::string getNodeAttributes(SVFVar *node, IRGraph*)
408 {
409 if (SVFUtil::isa<ValVar>(node))
410 {
411 if(SVFUtil::isa<GepValVar>(node))
412 return "shape=hexagon";
413 else if (SVFUtil::isa<DummyValVar>(node))
414 return "shape=diamond";
415 else
416 return "shape=box";
417 }
418 else if (SVFUtil::isa<ObjVar>(node))
419 {
420 if(SVFUtil::isa<GepObjVar>(node))
421 return "shape=doubleoctagon";
422 else if(SVFUtil::isa<BaseObjVar>(node))
423 return "shape=box3d";
424 else if (SVFUtil::isa<DummyObjVar>(node))
425 return "shape=tab";
426 else
427 return "shape=component";
428 }
429 else if (SVFUtil::isa<RetValPN>(node))
430 {
431 return "shape=Mrecord";
432 }
433 else if (SVFUtil::isa<VarArgValPN>(node))
434 {
435 return "shape=octagon";
436 }
437 else
438 {
439 assert(0 && "no such kind!!");
440 }
441 return "";
442 }
443
444 template<class EdgeIter>
446 {
447 std::string str;
448 std::stringstream rawstr(str);
449
450 rawstr << "shape=record";
451
452 const SVFStmt* edge = *(EI.getCurrent());
453 assert(edge && "No edge found!!");
454 if (SVFUtil::isa<AddrStmt>(edge))
455 {
456 rawstr << ",color=green";
457 }
458 else if (SVFUtil::isa<CopyStmt>(edge))
459 {
460 rawstr << ",color=black";
461 }
462 else if (SVFUtil::isa<GepStmt>(edge))
463 {
464 rawstr << ",color=\"purple:purple\"";
465 }
466 else if (SVFUtil::isa<StoreStmt>(edge))
467 {
468 rawstr << ",color=blue";
469 }
470 else if (SVFUtil::isa<LoadStmt>(edge))
471 {
472 rawstr << ",color=red";
473 }
474 else if (SVFUtil::isa<PhiStmt>(edge))
475 {
476 rawstr << ",color=grey";
477 }
478 else if (SVFUtil::isa<SelectStmt>(edge))
479 {
480 rawstr << ",color=grey";
481 }
482 else if (SVFUtil::isa<CmpStmt>(edge))
483 {
484 rawstr << ",color=grey";
485 }
486 else if (SVFUtil::isa<BinaryOPStmt>(edge))
487 {
488 rawstr << ",color=grey";
489 }
490 else if (SVFUtil::isa<UnaryOPStmt>(edge))
491 {
492 rawstr << ",color=grey";
493 }
494 else if (SVFUtil::isa<BranchStmt>(edge))
495 {
496 rawstr << ",color=grey";
497 }
498 else if (SVFUtil::isa<TDForkPE>(edge))
499 {
500 rawstr << ",color=Turquoise";
501 }
502 else if (SVFUtil::isa<TDJoinPE>(edge))
503 {
504 rawstr << ",color=Turquoise";
505 }
506 else if (SVFUtil::isa<CallPE>(edge))
507 {
508 rawstr << ",color=black,style=dashed";
509 }
510 else if (SVFUtil::isa<RetPE>(edge))
511 {
512 rawstr << ",color=black,style=dotted";
513 }
514 else
515 {
516 assert(false && "No such kind edge!!");
517 }
518
519 return rawstr.str();
520 }
521
522 template<class EdgeIter>
523 static std::string getEdgeSourceLabel(SVFVar*, EdgeIter EI)
524 {
525 const SVFStmt* edge = *(EI.getCurrent());
526 assert(edge && "No edge found!!");
527 if(const CallPE* calledge = SVFUtil::dyn_cast<CallPE>(edge))
528 {
529 return calledge->getFunEntryICFGNode()->getSourceLoc();
530 }
531 else if(const RetPE* retedge = SVFUtil::dyn_cast<RetPE>(edge))
532 {
533 return retedge->getCallSite()->getSourceLoc();
534 }
535 return "";
536 }
537};
538} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DPAGBuild
Definition SVFType.h:584
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:148
u32_t getNumOfFlattenElements(const SVFType *T)
Definition IRGraph.cpp:173
const std::vector< const SVFType * > & getFlattenFieldTypes(const SVFStructType *T)
Return the flattened field type for struct type only.
Definition IRGraph.cpp:122
void destorySymTable()
Definition IRGraph.cpp:40
SVFStmt * hasLabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind, const ICFGNode *cs)
Definition IRGraph.cpp:295
SVFStmt * hasEdge(SVFStmt *edge, SVFStmt::PEDGEK kind)
Definition IRGraph.cpp:306
void printFlattenFields(const SVFType *type)
Debug method.
Definition IRGraph.cpp:77
void dump(std::string name)
Dump SVFIR.
Definition IRGraph.cpp:320
virtual ~IRGraph()
Definition IRGraph.cpp:58
Set< const StInfo * > stInfos
(owned) All StInfo
Definition IRGraph.h:96
u32_t getObjectNodeNum()
Definition IRGraph.cpp:347
void view()
View graph from the debugger.
Definition IRGraph.cpp:328
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:192
SVFStmt::KindToSVFStmtMapTy KindToSVFStmtSetMap
SVFIR edge map containing all PAGEdges.
Definition IRGraph.h:107
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.
Definition IRGraph.cpp:127
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:235
std::string getGraphName() const
Return graph name.
Definition IRGraph.h:342
FunObjVarToIDMapTy varargFunObjSymMap
vararg map
Definition IRGraph.h:85
NodeID getReturnNode(const FunObjVar *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition IRGraph.cpp:64
const SVFType * getOriginalElemType(const SVFType *baseType, u32_t origId) const
Definition IRGraph.cpp:143
u32_t valVarNum
Definition IRGraph.h:112
IDToTypeInfoMapTy objTypeInfoMap
map a memory sym id to its obj
Definition IRGraph.h:86
bool addEdge(SVFVar *src, SVFVar *dst, SVFStmt *edge)
Add an edge into the graph.
Definition IRGraph.cpp:257
u32_t objVarNum
Definition IRGraph.h:113
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:71
SVFStmt * hasNonlabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind)
Definition IRGraph.cpp:272
u32_t getValueNodeNum()
Definition IRGraph.cpp:334
SVFTypeSet svfTypes
Definition IRGraph.h:93
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
Definition IRGraph.cpp:246
FunObjVarToIDMapTy returnFunObjSymMap
return map
Definition IRGraph.h:84
const ObjTypeInfo * createDummyObjTypeInfo(NodeID symId, const SVFType *type)
Definition IRGraph.cpp:181
void setFlag(MEMTYPE mask)
Flag for this object type.
static Option< bool > ModelArrays
Definition Options.h:178
static const Option< bool > CyclicFldIdx
Definition Options.h:179
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
static const Option< bool > ShowHiddenNode
Definition Options.h:218
static GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, const SVFVar *var)
static GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode *cs)
NodeID getId() const
Get ID.
Definition SVFValue.h:158
GNodeK getNodeKind() const
Get node kind.
Definition SVFValue.h:164
virtual const std::string & getName() const
Definition SVFValue.h:184
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:69
std::vector< const SVFType * > & getFlattenElementTypes()
Definition SVFType.h:127
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition SVFType.h:123
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:164
std::vector< const SVFType * > & getFlattenFieldTypes()
Definition SVFType.h:131
std::vector< u32_t > & getFlattenedFieldIdxVec()
Definition SVFType.h:119
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:170
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:72
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:76
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
s64_t APOffset
Definition GeneralType.h:80
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67
static std::string getEdgeAttributes(SVFVar *, EdgeIter EI, IRGraph *)
Definition IRGraph.cpp:445
DOTGraphTraits(bool isSimple=false)
Definition IRGraph.cpp:372
static std::string getGraphName(IRGraph *graph)
Return name of the graph.
Definition IRGraph.cpp:378
static std::string getNodeLabel(SVFVar *node, IRGraph *)
Definition IRGraph.cpp:393
static std::string getNodeAttributes(SVFVar *node, IRGraph *)
Definition IRGraph.cpp:407
static bool isNodeHidden(SVFVar *node, IRGraph *)
Definition IRGraph.cpp:385
NodeType::iterator ChildIteratorType
Definition IRGraph.cpp:371
static std::string getEdgeSourceLabel(SVFVar *, EdgeIter EI)
Definition IRGraph.cpp:523