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;
        }
Example #2
0
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;
        }
Example #6
0
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();
}