aiRecord evaluateInheritedAttribute(SgNode* n, aiRecord inherited ) { //aiRecord ir(inherited, n); aiRecord ir; SgPntrArrRefExp* arrRef; if((arrRef = isSgPntrArrRefExp(n))) { ir.arrayNameSubtree = arrRef->get_lhs_operand(); ir.indexSubtree = arrRef->get_rhs_operand(); // this SgPntrArrRefExp is the top-most isSgPntrArrRefExp if it is not the top of // the arrayNameSubtree of a higher-level SgPntrArrRefExp ir.topArrayRefExpFlag = (n!=inherited.arrayNameSubtree); } // if this node is the top of the index subtree of an SgPntrArrRefExp, record this in ir if(inherited.indexSubtree == n) ir.arrayIndexFlag = true; // otherwise, inherit from the parent node else ir.arrayIndexFlag = inherited.arrayIndexFlag; arrIndexAttribute* aiAttr = new arrIndexAttribute(ir); n->addNewAttribute("ArrayIndex", aiAttr); /* if(isSgPntrArrRefExp(n)) printf("SgPntrArrRefExp:0x%x DOWN arrayIndexFlag=%d indexSubtree=0x%x\n", n, aiAttr->arrayIndexFlag, ir.indexSubtree); else printf("SgNode:0x%x DOWN arrayIndexFlag=%d indexSubtree=0x%x\n", n, aiAttr->arrayIndexFlag, ir.indexSubtree);*/ return ir; }
bool MintArrayInterface::isArrayReference(SgExpression* ref, SgExpression** arrayName/*=NULL*/, vector<SgExpression*>* subscripts/*=NULL*/) { SgExpression* arrayRef=NULL; if (ref->variantT() == V_SgPntrArrRefExp) { if (subscripts != 0 || arrayName != 0) { SgExpression* n = ref; while (true) { SgPntrArrRefExp *arr = isSgPntrArrRefExp(n); if (arr == 0) break; n = arr->get_lhs_operand(); // store left hand for possible reference exp to array variable if (arrayName!= 0) arrayRef = n; // right hand stores subscripts if (subscripts != 0){ subscripts->push_back(arr->get_rhs_operand()); //cout << "sub: " << (arr->get_rhs_operand())->unparseToString() << endl; } } // end while if (arrayName !=NULL) { *arrayName = arrayRef; } } return true; } return false; }
InheritedAttribute BugSeeding::evaluateInheritedAttribute ( SgNode* astNode, InheritedAttribute inheritedAttribute ) { // Use this if we only want to seed bugs in loops bool isLoop = inheritedAttribute.isLoop || (isSgForStatement(astNode) != NULL) || (isSgWhileStmt(astNode) != NULL) || (isSgDoWhileStmt(astNode) != NULL); // Add Fortran support isLoop = isLoop || (isSgFortranDo(astNode) != NULL); // Mark future noes in this subtree as being part of a loop inheritedAttribute.isLoop = isLoop; // To test this on simple codes, optionally allow it to be applied everywhere bool applyEveryWhere = true; if (isLoop == true || applyEveryWhere == true) { // The inherited attribute is true iff we are inside a loop and this is a SgPntrArrRefExp. SgPntrArrRefExp *arrayReference = isSgPntrArrRefExp(astNode); if (arrayReference != NULL) { // Mark as a vulnerability inheritedAttribute.isVulnerability = true; // Now change the array index (to seed the buffer overflow bug) SgVarRefExp* arrayVarRef = isSgVarRefExp(arrayReference->get_lhs_operand()); ROSE_ASSERT(arrayVarRef != NULL); ROSE_ASSERT(arrayVarRef->get_symbol() != NULL); SgInitializedName* arrayName = isSgInitializedName(arrayVarRef->get_symbol()->get_declaration()); ROSE_ASSERT(arrayName != NULL); SgArrayType* arrayType = isSgArrayType(arrayName->get_type()); ROSE_ASSERT(arrayType != NULL); SgExpression* arraySize = arrayType->get_index(); SgTreeCopy copyHelp; // Make a copy of the expression used to hold the array size in the array declaration. SgExpression* arraySizeCopy = isSgExpression(arraySize->copy(copyHelp)); ROSE_ASSERT(arraySizeCopy != NULL); // This is the existing index expression SgExpression* indexExpression = arrayReference->get_rhs_operand(); ROSE_ASSERT(indexExpression != NULL); // Build a new expression: "array[n]" --> "array[n+arraySizeCopy]", where the arraySizeCopy is a size of "array" SgExpression* newIndexExpression = buildAddOp(indexExpression,arraySizeCopy); // Substitute the new expression for the old expression arrayReference->set_rhs_operand(newIndexExpression); } } return inheritedAttribute; }
void BasicProgmemTransform::transformArrayRef(SgFunctionDeclaration *func) { Rose_STL_Container<SgNode *> refs = NodeQuery::querySubTree(func, V_SgPntrArrRefExp); for(auto& item: refs) { SgPntrArrRefExp *exp = isSgPntrArrRefExp(item); SgVarRefExp *var = isSgVarRefExp(exp->get_lhs_operand()); if(var == NULL) { continue; } if(isVarDeclToRemove(var)) { handleProgmemArrayIndexRef(exp); } } }
adRecord evaluateSynthesizedAttribute (SgNode* n, aiRecord inherited, SubTreeSynthesizedAttributes synthesized ) { //printf("evaluateSynthesizedAttribute(n=%p)\n"); adRecord dr(n); SgPntrArrRefExp* arrRef; if((arrRef = isSgPntrArrRefExp(n))) { //printf("evaluateSynthesizedAttribute() arrRef->lhs=%p, arrRef->rhs=%p\n", arrRef->get_lhs_operand(), ); bool found=false; // look through both the synthesized attributes // (one from the SgPntrArrRefExp's array name subtree and one from the index subtree) // get the name subtree for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++) { // if this synthesized attribute comes from SgPntrArrRefExp's array name subtree // (there should be only one such subtree) if((*it).origin == arrRef->get_lhs_operand()) { // copy over the info from the name subtree found = true; dr.arrayDim=(*it).arrayDim+1; // if the array name expression hasn't been found yet, this // SgPntrArrRefExp's array name subtree must be it if((*it).arrayNameExp==NULL) dr.arrayNameExp = arrRef->get_lhs_operand(); // otherwise, the real array name expression is deeper in the array name subtree, so just copy it over else dr.arrayNameExp = (*it).arrayNameExp; // initialize this SgPntrArrRefExp's list of indexes from the lower-level list dr.indexExprs = (*it).indexExprs; // break; } } ROSE_ASSERT(found); found = false; // get the index subtree for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++) { // if this synthesized attribute comes from SgPntrArrRefExp's index subtree // (there should be only one such subtree) if((*it).origin == arrRef->get_rhs_operand()) { found = true; // add the current index expression to this SgPntrArrRefExp's list of indexes dr.indexExprs.push_front(isSgExpression((*it).origin)); } } ROSE_ASSERT(found); } /* if(isSgPntrArrRefExp(n)) printf("SgPntrArrRefExp:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim); else printf("SgNode:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim); printf(" <%s>\n", n->unparseToString().c_str());*/ // label this node with its read/write access information arrIndexAttribute* aiAttr = new arrIndexAttribute(dr); char attrName[100]; sprintf(attrName, "ArrayIndex: [%d, %d, %p, %d]", dr.arrayIndexFlag, dr.topArrayRefExpFlag, dr.arrayNameExp, dr.arrayDim); n->addNewAttribute(attrName, aiAttr); n->updateAttribute("ArrayIndex", aiAttr); return dr; }
std::string writeSgBinaryOpZ3(SgBinaryOp* op, SgExpression* lhs, SgExpression* rhs) { std::stringstream ss; std::string opStr; bool compAssign = false; if (isSgCompoundAssignOp(op)) { compAssign = true; opStr = getSgCompoundAssignOp(isSgCompoundAssignOp(op)); } else { opStr = getSgBinaryOp(op); } ROSE_ASSERT(opStr != "unknown"); std::string rhsstring; std::string lhsstring; lhsstring = getSgExpressionString(lhs); SgType* lhstyp; SgType* rhstyp; if (isSgArrayType(lhs->get_type())) { lhstyp = isSgArrayType(lhs->get_type())->get_base_type(); } else { lhstyp = lhs->get_type(); } if (isSgArrayType(rhs->get_type())) { rhstyp = isSgArrayType(rhs->get_type())->get_base_type(); } else { rhstyp = rhs->get_type(); } if (isSgEnumType(lhs->get_type())) { } else { ROSE_ASSERT(lhstyp == rhstyp); } if (isSgValueExp(rhs)) { rhsstring = getSgValueExp(isSgValueExp(rhs)); } else if (isSgUnaryOp(rhs)) { rhsstring = getSgUnaryOp(isSgUnaryOp(rhs)); } else { rhsstring = getSgExpressionString(rhs); } if (opStr == "/" && lhstyp->isIntegerType()) { opStr = "cdiv"; } if (opStr == "assign" || compAssign) { if (isSgVarRefExp(lhs)) { SgVarRefExp* lhsSgVarRefExp = isSgVarRefExp(lhs); int instances = SymbolToInstances[lhsSgVarRefExp->get_symbol()]; std::stringstream instanceName; SymbolToInstances[lhsSgVarRefExp->get_symbol()] = instances + 1; std::string lhsname = SymbolToZ3[lhsSgVarRefExp->get_symbol()]; instanceName << lhsname << "_" << (instances+1); SgType* varType = lhsSgVarRefExp->get_type(); std::string typeZ3; if (varType->isFloatType()) { typeZ3 = "Real"; } else if (varType->isIntegerType()) { typeZ3 = "Int"; } else if (isSgEnumType(varType)) { typeZ3 = isSgEnumType(varType)->get_name().getString(); } else { typeZ3 = "Unknown"; } ss << "(declare-fun " << instanceName.str() << " () " << typeZ3 << ")\n"; if (!compAssign) { ss << "(assert (= " << instanceName.str() << " " << rhsstring << "))"; } else { std::stringstream oldInstanceName; oldInstanceName << lhsname << "_" << instances; ss << "(assert (= " << instanceName.str() << " (" << opStr << " " << oldInstanceName.str() << " " << rhsstring << ")))"; } } else { ROSE_ASSERT(isSgPntrArrRefExp(lhs)); std::string u_type; SgPntrArrRefExp* lhspntr = isSgPntrArrRefExp(lhs); SgVarRefExp* varlhspntr = isSgVarRefExp(lhspntr->get_lhs_operand()); SgArrayType* arrTy = isSgArrayType(varlhspntr->get_type()); if (arrTy->get_base_type()->isIntegerType()) { u_type = "Int"; } else if (arrTy->get_base_type()->isFloatType()) { u_type = "Real"; } else { std::cout << "unknown base type for array" << std::endl; ROSE_ASSERT(false); } std::stringstream oldInstanceName; SgVarRefExp* varexp = isSgVarRefExp((isSgPntrArrRefExp(lhs))->get_lhs_operand()); oldInstanceName << SymbolToZ3[varexp->get_symbol()] << "_" << SymbolToInstances[varexp->get_symbol()]; int instances = SymbolToInstances[varexp->get_symbol()]; std::stringstream instanceName; SymbolToInstances[varexp->get_symbol()] = instances + 1; std::string lhsname = SymbolToZ3[varexp->get_symbol()]; instanceName << lhsname << "_" << instances+1; ss << "(declare-const " << instanceName.str() << " (Array Int " << u_type << "))\n "; std::string indexstring = getSgExpressionString(isSgPntrArrRefExp(lhs)->get_rhs_operand()); ss << "(assert (= (store " << oldInstanceName.str() << " " << indexstring << " " << rhsstring << ") " << instanceName.str() << "))"; } } else if (opStr == "neq") { ss << "(not (= " << lhsstring << " " << rhsstring << "))"; } else if (opStr == "or" || opStr == "and") { std::stringstream val_stream; if (pathNodeTruthValue.find(op) != pathNodeTruthValue.end()) { bool logic_val = pathNodeTruthValue[op]; //std::cout << ";and/or lhsstring " << lhsstring << "\n"; //std::cout << ";and/or rhsstring " << rhsstring << "\n"; if (opStr == "and") { if (logic_val) { std::string p_decl = "(assert (= " + lhsstring + " true))"; declarations.push_back(p_decl); ss << rhsstring; //ss << "(and " << lhsstring << " " << rhsstring << ")"; } else { std::string p_decl = "(assert (= " + lhsstring + " false))"; declarations.push_back(p_decl); ss << "false"; } } else { if (logic_val) { std::string p_decl = "(assert (= " + lhsstring + " true))"; declarations.push_back(p_decl); ss << "true"; } else { std::string p_decl = "(assert (= " + lhsstring + " false))"; declarations.push_back(p_decl); ss << rhsstring; } } } else { ss << ""; } } else { ss << "(" << opStr << " " << lhsstring << " " << rhsstring << ")"; } return ss.str(); }