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; }
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; }
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; }
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; }