@@ -39,59 +39,18 @@ using namespace z3;
3939Z3SSEMgr::Z3SSEMgr (SVFIR* ir)
4040: Z3Mgr(ir->getPAGNodeNum () * 10)
4141, svfir(ir) {
42- initMap ();
4342}
4443
45- /*
46- * (1) Create Z3 expressions for top-level variables and objects, and (2) create loc2val map
47- */
48- void Z3SSEMgr::initMap () {
49- for (SVFIR::iterator nIter = svfir->begin (); nIter != svfir->end (); ++nIter) {
50- if (const ValVar* val = SVFUtil::dyn_cast<ValVar>(nIter->second ))
51- createExprForValVar (val);
52- else if (const ObjVar* obj = SVFUtil::dyn_cast<ObjVar>(nIter->second ))
53- createExprForObjVar (obj);
54- else
55- assert (false && " SVFVar type not supported" );
56- }
57- DBOP (printExprValues ());
58- }
59-
60- /*
61- * We initialize all ValVar to be an int expression.
62- * ValVar of PointerTy/isFunctionTy is assigned with an ID to represent the address of an object
63- * ValVar of IntegerTy is assigned with an integer value
64- * ValVar of FloatingPointTy is assigned with an integer value casted from a float
65- * ValVar of StructTy/ArrayTy is assigned with their elements of the above types in the form of integer values
66- */
67- z3::expr Z3SSEMgr::createExprForValVar (const ValVar* valVar) {
68- std::string str;
69- raw_string_ostream rawstr (str);
70- rawstr << " ValVar" << valVar->getId ();
71- expr e (ctx);
72- if (const SVFType* type = valVar->getType ()) {
73- e = ctx.int_const (rawstr.str ().c_str ());
74- }
75- else {
76- e = ctx.int_const (rawstr.str ().c_str ());
77- assert (SVFUtil::isa<DummyValVar>(valVar) && " not a DummValVar if it has no type?" );
78- }
79-
80- updateZ3Expr (valVar->getId (), e);
81- return e;
82- }
8344
8445/*
85- * Object must be either a constraint data or a location value (address-taken variable)
46+ * Object must be either a constaint data or a location value (address-taken variable)
8647 * Constant data includes ConstantInt, ConstantFP, ConstantPointerNull and ConstantAggregate
8748 * Locations includes pointers to globals, heaps, stacks
8849 */
8950z3::expr Z3SSEMgr::createExprForObjVar (const ObjVar* objVar) {
9051 std::string str;
9152 raw_string_ostream rawstr (str);
92- rawstr << " ObjVar" << objVar->getId ();
93-
94- expr e = ctx.int_const (rawstr.str ().c_str ());
53+ expr e (ctx);
9554 if (objVar->hasValue ()) {
9655 const MemObj* obj = objVar->getMemObj ();
9756 // / constant data
@@ -122,30 +81,63 @@ z3::expr Z3SSEMgr::createExprForObjVar(const ObjVar* objVar) {
12281 && " it should either be a blackhole or constant dummy if this obj has no value?" );
12382 e = ctx.int_val (getVirtualMemAddress (objVar->getId ()));
12483 }
125-
126- updateZ3Expr (objVar->getId (), e);
12784 return e;
12885}
12986
87+ std::string Z3SSEMgr::callingCtxToStr (const CallStack& callingCtx) {
88+ std::string str;
89+ std::stringstream rawstr (str);
90+ rawstr << " ctx:[ " ;
91+ for (const auto &inst : callingCtx) {
92+
93+ rawstr << svfir->getICFG ()->getICFGNode (inst)->getId () << " " ;
94+ }
95+ rawstr << " ] " ;
96+ return rawstr.str ();
97+ }
98+
99+ z3::expr Z3SSEMgr::getZ3Expr (SVF::u32_t idx, const CallStack& callingCtx) {
100+ u32_t varId = getInternalID (idx);
101+ assert (varId == idx && " SVFVar idx overflow > 0x7f000000?" );
102+ std::string str;
103+ std::stringstream rawstr (str);
104+ const SVFVar *svfVar = svfir->getGNode (varId);
105+ if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(svfVar)) {
106+ return createExprForObjVar (objVar);
107+ } else {
108+
109+ // Check if svfVar does not have a value or it has a constant value
110+ if (svfVar->hasValue () && !SVFUtil::isa<SVFConstant>(svfVar->getValue ())) {
111+ // If there is a non-constant value, add callingCtx to z3 expr
112+ rawstr << callingCtxToStr (callingCtx);
113+ } else {
114+ // If there's no value or it's a constant, we do not add the callingCtx to z3 expr
115+ }
116+ rawstr << " ValVar" << varId;
117+ std::string name = rawstr.str ();
118+ return ctx.int_const (name.c_str ());
119+ }
120+ }
121+
130122// / Return the address expr of a ObjVar
131- z3::expr Z3SSEMgr::getMemObjAddress (u32_t idx) const {
123+ z3::expr Z3SSEMgr::getMemObjAddress (u32_t idx) {
132124 NodeID objIdx = getInternalID (idx);
133125 assert (SVFUtil::isa<ObjVar>(svfir->getGNode (objIdx)) && " Fail to get the MemObj!" );
134- return getZ3Expr ( objIdx);
126+ return createExprForObjVar (SVFUtil::cast<ObjVar>(svfir-> getGNode ( objIdx)) );
135127}
136128
137129z3::expr Z3SSEMgr::getGepObjAddress (z3::expr pointer, u32_t offset) {
138- NodeID baseObj = getInternalID (z3Expr2NumValue (pointer));
139- assert (SVFUtil::isa<ObjVar>(svfir->getGNode (baseObj )) && " Fail to get the base object address!" );
140- NodeID gepObj = svfir->getGepObjVar (baseObj , offset);
130+ NodeID obj = getInternalID (z3Expr2NumValue (pointer));
131+ assert (SVFUtil::isa<ObjVar>(svfir->getGNode (obj )) && " Fail to get the base object address!" );
132+ NodeID gepObj = svfir->getGepObjVar (obj , offset);
141133 // / TODO: check whether this node has been created before or not to save creation time
142- if (baseObj == gepObj)
143- return getZ3Expr (baseObj );
134+ if (obj == gepObj)
135+ return createExprForObjVar (SVFUtil::cast<ObjVar>(svfir-> getGNode (obj)) );
144136 else
145137 return createExprForObjVar (SVFUtil::cast<GepObjVar>(svfir->getGNode (gepObj)));
146138}
147139
148- s32_t Z3SSEMgr::getGepOffset (const GepStmt* gep) {
140+ s32_t Z3SSEMgr::getGepOffset (const GepStmt* gep, const CallStack& callingCtx ) {
149141 if (gep->getOffsetVarAndGepTypePairVec ().empty ())
150142 return gep->getConstantStructFldIdx ();
151143
@@ -160,14 +152,14 @@ s32_t Z3SSEMgr::getGepOffset(const GepStmt* gep) {
160152 offset = op->getSExtValue ();
161153 // / variable as the offset
162154 else
163- offset = z3Expr2NumValue (getZ3Expr (svfir->getValueNode (value)));
155+ offset = z3Expr2NumValue (getZ3Expr (svfir->getValueNode (value), callingCtx ));
164156
165157 if (type == nullptr ) {
166158 totalOffset += offset;
167159 continue ;
168160 }
169161
170- // / Calculate the offset
162+ // / Caculate the offset
171163 if (const SVFPointerType* pty = SVFUtil::dyn_cast<SVFPointerType>(type))
172164 totalOffset += offset * gep->getAccessPath ().getElementNum (gep->getAccessPath ().gepSrcPointeeType ());
173165 else
@@ -176,14 +168,14 @@ s32_t Z3SSEMgr::getGepOffset(const GepStmt* gep) {
176168 return totalOffset;
177169}
178170
179- void Z3SSEMgr::printExprValues () {
171+ void Z3SSEMgr::printExprValues (const CallStack& callingCtx ) {
180172 std::cout.flags (std::ios::left);
181- std::cout << " -----------SVFVar and Value-----------\n " ;
173+ std::cout << " \n -----------SVFVar and Value-----------\n " ;
182174 std::map<std::string, std::string> printValMap;
183175 std::map<NodeID, std::string> objKeyMap;
184176 std::map<NodeID, std::string> valKeyMap;
185177 for (SVFIR::iterator nIter = svfir->begin (); nIter != svfir->end (); ++nIter) {
186- expr e = getEvalExpr (getZ3Expr (nIter->first ));
178+ expr e = getEvalExpr (getZ3Expr (nIter->first , callingCtx ));
187179 if (e.is_numeral ()) {
188180 NodeID varID = nIter->second ->getId ();
189181 s32_t value = e.get_numeral_int64 ();
@@ -230,4 +222,4 @@ void Z3SSEMgr::printExprValues() {
230222 std::cout << std::setw (25 ) << printKey << printValMap[printKey];
231223 }
232224 std::cout << " -----------------------------------------\n " ;
233- }
225+ }
0 commit comments