Ejemplo n.º 1
0
void SecureFunctionTypeTraversal::visit(SgNode* sgn)
{
    if(isSgFunctionCallExp(sgn)) {
        SgFunctionDeclaration* fndecl = isSgFunctionCallExp(sgn)->getAssociatedFunctionDeclaration();
        string filename = fndecl->get_file_info()->get_filename();
        if(filename != "compilerGenerated") {
            StringUtility::FileNameClassification classification;
            classification = StringUtility::classifyFileName(filename, this->sourcedir, this->trustedlibs);
            //StringUtility::FileNameLocation filetypeclassification = classification.getLocation();
            //cout << sgn->unparseToString() <<  filename << " : "  << classification.getLocation() << ", " <<  classification.getLibrary() << endl;
            bool isSecure;
            if(untrustedFunctions.find(fndecl->get_name().getString()) != untrustedFunctions.end()) {
                isSecure = false;
            }                 
                
            else if(classification.isLibraryCode() || classification.isUserCode()) {
                isSecure = true;
            }

            else {
                isSecure = false;
            }
            AstAttribute* attr = dynamic_cast<AstAttribute*> ( new SecureFunctionType(isSecure) );
            sgn->setAttribute("SECURE_TYPE", attr);            
        }
    }
}
Ejemplo n.º 2
0
void
CompassAnalyses::FunctionDocumentation::Traversal::
visit(SgNode* sgNode)
{ 
  // Implement your traversal here.  
  if (isSgFunctionDeclaration(sgNode)) 
    {
      SgFunctionDeclaration* funcDecl = isSgFunctionDeclaration(sgNode);
      if (funcDecl->get_file_info()->isCompilerGenerated() 
          || funcDecl->get_definingDeclaration() != sgNode
          )
        return;


      if (!( isDocumented( funcDecl) || 
          isDocumented(isSgFunctionDeclaration(funcDecl->get_firstNondefiningDeclaration()))
           ) 
         ) {
        std::string funcName = funcDecl->get_qualified_name();
        output->addOutput(new CheckerOutput(funcDecl, funcName));
      }

    }




} //End of the visit function.
int main( int argc, char * argv[] )
   {
  // Build the AST used by ROSE
     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT(project != NULL);

  // Build a list of functions within the AST
     Rose_STL_Container<SgNode*> functionCallList = NodeQuery::querySubTree (project,V_SgFunctionCallExp);

     int functionCounter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionCallList.begin(); i != functionCallList.end(); i++)
        {
          SgExpression* functionExpression = isSgFunctionCallExp(*i)->get_function();
          ROSE_ASSERT(functionExpression != NULL);

          SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionExpression);

          SgFunctionSymbol* functionSymbol = NULL;
          if (functionRefExp != NULL)
             {
            // Case of non-member function
               functionSymbol = functionRefExp->get_symbol();
             }
            else
             {
            // Case of member function (hidden in rhs of binary dot operator expression)
               SgDotExp* dotExp = isSgDotExp(functionExpression);
               ROSE_ASSERT(dotExp != NULL);

               functionExpression = dotExp->get_rhs_operand();
               SgMemberFunctionRefExp* memberFunctionRefExp = isSgMemberFunctionRefExp(functionExpression);
               ROSE_ASSERT(memberFunctionRefExp != NULL);

               functionSymbol = memberFunctionRefExp->get_symbol();
             }
          
          ROSE_ASSERT(functionSymbol != NULL);

          SgFunctionDeclaration* functionDeclaration = functionSymbol->get_declaration();
          ROSE_ASSERT(functionDeclaration != NULL);
          
       // Output mapping of function calls to function declarations
          printf ("Location of function call #%d at line %d resolved by overloaded function declared at line %d \n",
               functionCounter++,
               isSgFunctionCallExp(*i)->get_file_info()->get_line(),
               functionDeclaration->get_file_info()->get_line());
        }

     return 0;
   }
Ejemplo n.º 4
0
// Function printFunctionDeclarationList will print all function names in the list
void printFunctionDeclarationList(Rose_STL_Container<SgNode*> functionDeclarationList)
   {
     int counter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++)
        {
       // Build a pointer to the current type so that we can call the get_name() member function.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
          ROSE_ASSERT(functionDeclaration != NULL);

       // output the function number and the name of the function
          printf ("function name #%d is %s at line %d \n",
               counter++,functionDeclaration->get_name().str(),
               functionDeclaration->get_file_info()->get_line());
        }
   }
Ejemplo n.º 5
0
void findCandidateFunctionDefinitions (SgProject* project, std::vector<SgFunctionDefinition* >& candidateFuncDefs)
{
  ROSE_ASSERT (project != NULL);
  // For each source file in the project
  SgFilePtrList & ptr_list = project->get_fileList();
  for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
      iter++)
  {
    SgFile* sageFile = (*iter);
    SgSourceFile * sfile = isSgSourceFile(sageFile);
    ROSE_ASSERT(sfile);
//    SgGlobal *root = sfile->get_globalScope();

    if (enable_debug)
      cout<<"Processing each function within the files "<< sfile->get_file_info()->get_filename() <<endl;
    //      cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl;

    // This is wrong, many functions in question are not top level declarations!!
    //SgDeclarationStatementPtrList& declList = root->get_declarations ();
    //VariantVector vv;
    Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); 
//    bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

    //For each function body in the scope
    //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
    for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) 
    {
      SgFunctionDefinition *defn = isSgFunctionDefinition(*p);
      ROSE_ASSERT (defn != NULL);

      SgFunctionDeclaration *func = defn->get_declaration();
      ROSE_ASSERT (func != NULL);

      if (enable_debug)
        cout<<"\t considering function "<< func->get_name() << " at "<< func->get_file_info()->get_line()<<endl;
      //ignore functions in system headers, Can keep them to test robustness
      if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename())
      {
        if (enable_debug)
          cout<<"\t Skipped since the function's associated file name does not match current file being considered. Mostly from a header. "<<endl;
        continue;
      }
      candidateFuncDefs.push_back(defn);
    } // end for def list
  } // end for file list
}
Ejemplo n.º 6
0
int main( int argc, char * argv[] )
   {
  // Build the AST used by ROSE
     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT(project != NULL);

  // Build a list of functions within the AST
     Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration);

     int counter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++)
        {
       // Build a pointer to the current type so that we can call the get_name() member function.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
          ROSE_ASSERT(functionDeclaration != NULL);

       // DQ (3/5/2006): Only output the non-compiler generated IR nodes
          if ( (*i)->get_file_info()->isCompilerGenerated() == false)
             {
            // output the function number and the name of the function
               printf ("Function #%2d name is %s at line %d \n",
                    counter++,functionDeclaration->get_name().str(),
                    functionDeclaration->get_file_info()->get_line());
             }
            else
             {
            // Output something about the compiler-generated builtin functions
               printf ("Compiler-generated (builtin) function #%2d name is %s \n",
                    counter++,functionDeclaration->get_name().str());
             }
        }

  // Note: Show composition of AST queries

     return 0;
   }
Ejemplo n.º 7
0
void SystemDependenceGraph::build()
{
    boost::unordered_map<CFGVertex, Vertex> cfgVerticesToSdgVertices;
    boost::unordered_map<SgNode*, Vertex>   astNodesToSdgVertices;

    //map<SgFunctionCallExp*, vector<SDGNode*> > funcCallToArgs;

    vector<CallSiteInfo> functionCalls;


    map<SgNode*, vector<Vertex> > actualInParameters;
    map<SgNode*, vector<Vertex> > actualOutParameters;

    map<SgNode*, Vertex> formalInParameters;
    map<SgNode*, Vertex> formalOutParameters;

    vector<SgFunctionDefinition*> funcDefs = 
        SageInterface::querySubTree<SgFunctionDefinition>(project_, V_SgFunctionDefinition);
    foreach (SgFunctionDefinition* funcDef, funcDefs)
    {
        SgFunctionDeclaration* funcDecl = funcDef->get_declaration();

        CFG* cfg = new CFG(funcDef, cfgNodefilter_);
        functionsToCFGs_[funcDecl] = cfg;

        // For each function, build an entry node for it.
        SDGNode* entry = new SDGNode(SDGNode::Entry);
        entry->astNode = funcDef;
        //entry->funcDef = funcDef;
        Vertex entryVertex = addVertex(entry);
        functionsToEntries_[funcDecl] = entryVertex;

        // Add all out formal parameters to SDG.
        const SgInitializedNamePtrList& formalArgs = funcDecl->get_args();
        foreach (SgInitializedName* initName, formalArgs)
        {
            // If the parameter is passed by reference, create a formal-out node.
            if (isParaPassedByRef(initName->get_type()))
            {
                SDGNode* formalOutNode = new SDGNode(SDGNode::FormalOut);
                formalOutNode->astNode = initName;
                Vertex formalOutVertex = addVertex(formalOutNode);
                formalOutParameters[initName] = formalOutVertex;

                // Add a CD edge from call node to this formal-out node.
                addTrueCDEdge(entryVertex, formalOutVertex);
            }
        }

        // A vertex representing the returned value.
        Vertex returnVertex;

        // If the function returns something, build a formal-out node.
        if (!isSgTypeVoid(funcDecl->get_type()->get_return_type()))
        {
            SDGNode* formalOutNode = new SDGNode(SDGNode::FormalOut);
            // Assign the function declaration to the AST node of this vertex to make
            // it possible to classify this node into the subgraph of this function.
            formalOutNode->astNode = funcDecl;
            returnVertex = addVertex(formalOutNode);
            formalOutParameters[funcDecl] = returnVertex;

            // Add a CD edge from call node to this formal-out node.
            addTrueCDEdge(entryVertex, returnVertex);
        }

        // Add all CFG vertices to SDG.
        foreach (CFGVertex cfgVertex, boost::vertices(*cfg))
        {
            if (cfgVertex == cfg->getEntry() || cfgVertex == cfg->getExit())
                continue;

            SgNode* astNode = (*cfg)[cfgVertex]->getNode();

            // If this node is an initialized name and it is a parameter, make it 
            // as a formal in node.
            SgInitializedName* initName = isSgInitializedName(astNode);
            if (initName && isSgFunctionParameterList(initName->get_parent()))
            {
                SDGNode* formalInNode = new SDGNode(SDGNode::FormalIn);
                formalInNode->astNode = initName;
                Vertex formalInVertex = addVertex(formalInNode);
                formalInParameters[initName] = formalInVertex;

                cfgVerticesToSdgVertices[cfgVertex] = formalInVertex;
                astNodesToSdgVertices[astNode] = formalInVertex;

                // Add a CD edge from call node to this formal-in node.
                addTrueCDEdge(entryVertex, formalInVertex);
                continue;
            }

            // Add a new node to SDG.
            SDGNode* newSdgNode = new SDGNode(SDGNode::ASTNode);
            //newSdgNode->cfgNode = (*cfg)[cfgVertex];
            newSdgNode->astNode = astNode;
            Vertex sdgVertex = addVertex(newSdgNode);

            cfgVerticesToSdgVertices[cfgVertex] = sdgVertex;
            astNodesToSdgVertices[astNode] = sdgVertex;


            // Connect a vertex containing the return statement to the formal-out return vertex.
            if (isSgReturnStmt(astNode)
                    || isSgReturnStmt(astNode->get_parent()))
            {
                SDGEdge* newEdge = new SDGEdge(SDGEdge::DataDependence);
                addEdge(sdgVertex, returnVertex, newEdge);                
            }

            // If this CFG node contains a function call expression, extract its all parameters
            // and make them as actual-in nodes.

            if (SgFunctionCallExp* funcCallExpr = isSgFunctionCallExp(astNode))
            {
                CallSiteInfo callInfo;
                callInfo.funcCall = funcCallExpr;
                callInfo.vertex = sdgVertex;

                // Change the node type.
                newSdgNode->type = SDGNode::FunctionCall;
                vector<SDGNode*> argsNodes;

                // Get the associated function declaration.
                SgFunctionDeclaration* funcDecl = funcCallExpr->getAssociatedFunctionDeclaration();
                
                if (funcDecl == NULL) 
                    continue;
                    
                ROSE_ASSERT(funcDecl);
                const SgInitializedNamePtrList& formalArgs = funcDecl->get_args();

                SgExprListExp* args = funcCallExpr->get_args();
                const SgExpressionPtrList& actualArgs = args->get_expressions();
                
                if (formalArgs.size() != actualArgs.size())
                {
                    cout << "The following function has variadic arguments:\n";
                    cout << funcDecl->get_file_info()->get_filename() << endl;
                    cout << funcDecl->get_name() << formalArgs.size() << " " << actualArgs.size() << endl;
                    continue;
                }

                for (int i = 0, s = actualArgs.size(); i < s; ++i)
                {
                    // Make sure that this parameter node is added to SDG then we
                    // change its node type from normal AST node to a ActualIn arg.
                    ROSE_ASSERT(astNodesToSdgVertices.count(actualArgs[i]));

                    Vertex paraInVertex = astNodesToSdgVertices.at(actualArgs[i]);
                    SDGNode* paraInNode = (*this)[paraInVertex]; 
                    paraInNode->type = SDGNode::ActualIn;

                    actualInParameters[formalArgs[i]].push_back(paraInVertex);
                    callInfo.inPara.push_back(paraInVertex);

                    // Add a CD edge from call node to this actual-in node.
                    addTrueCDEdge(sdgVertex, paraInVertex);

                    // If the parameter is passed by reference, create a parameter-out node.
                    if (isParaPassedByRef(formalArgs[i]->get_type()))
                    {
                        SDGNode* paraOutNode = new SDGNode(SDGNode::ActualOut);
                        paraOutNode->astNode = actualArgs[i];
                        //argsNodes.push_back(paraInNode);

                        // Add an actual-out parameter node.
                        Vertex paraOutVertex = addVertex(paraOutNode);
                        actualOutParameters[formalArgs[i]].push_back(paraOutVertex);
                        callInfo.outPara.push_back(paraOutVertex);

                        // Add a CD edge from call node to this actual-out node.
                        addTrueCDEdge(sdgVertex, paraOutVertex);
                    }
                }

                if (!isSgTypeVoid(funcDecl->get_type()->get_return_type())) 
                {
                    // If this function returns a value, create a actual-out vertex.
                    SDGNode* paraOutNode = new SDGNode(SDGNode::ActualOut);
                    paraOutNode->astNode = funcCallExpr;

                    // Add an actual-out parameter node.
                    Vertex paraOutVertex = addVertex(paraOutNode);
                    actualOutParameters[funcDecl].push_back(paraOutVertex);
                    callInfo.outPara.push_back(paraOutVertex);
                    callInfo.isVoid = false;
                    callInfo.returned = paraOutVertex;

                    // Add a CD edge from call node to this actual-out node.
                    addTrueCDEdge(sdgVertex, paraOutVertex);
                }

                functionCalls.push_back(callInfo);
                //funcCallToArgs[funcCallExpr] = argsNodes;
            }
        }

        // Add control dependence edges.
        addControlDependenceEdges(cfgVerticesToSdgVertices, *cfg, entryVertex);
    }
IntermediateRepresentationNodeGraph::IntermediateRepresentationNodeGraph(ofstream & inputFile, SgProject* project, const std::vector<VariantT> & inputNodeKindList)
   : file(inputFile), 
     nodeKindList(inputNodeKindList)
   {
     for (size_t i = 0; i < nodeKindList.size(); i++)
        {
          printf ("Adding nodeKindList[%" PRIuPTR "] = %d = %s to nodeKindSet \n",i,Cxx_GrammarTerminalNames[nodeKindList[i]].variant,Cxx_GrammarTerminalNames[nodeKindList[i]].name.c_str());
          include_nodeKindSet.insert(nodeKindList[i]);
        }

  // Build a list of functions within the AST
  // Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration);
  // Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgDeclarationStatement);
     Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgStatement);

  // include_nodeSet.insert(functionDeclarationList.begin(),functionDeclarationList.end());

     int maxNumberOfNodes = 5000;
     int numberOfNodes = (int)functionDeclarationList.size();
     printf ("Number of IR nodes in IntermediateRepresentationNodeGraph = %d \n",numberOfNodes);

#if 1
     int counter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++)
        {
          SgStatement*            statement           = isSgStatement(*i);
          SgDeclarationStatement* declaration         = isSgDeclarationStatement(*i);
          SgFunctionDeclaration*  functionDeclaration = isSgFunctionDeclaration(*i);

          SgTemplateInstantiationFunctionDecl*  templateInstantiationFunctionDeclaration = isSgTemplateInstantiationFunctionDecl(*i);

       // if (declaration != NULL && declaration->get_file_info()->isCompilerGenerated() == false)
          if (statement != NULL && statement->get_file_info()->isCompilerGenerated() == false)
             {
               include_nodeSet.insert(statement);
             }

          if (templateInstantiationFunctionDeclaration != NULL)
             {
               include_nodeSet.insert(statement);
             }
           
#if 0
       // Build a pointer to the current type so that we can call the get_name() member function.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
          if (functionDeclaration != NULL)
             {
            // DQ (3/5/2006): Only output the non-compiler generated IR nodes
               if ( (*i)->get_file_info()->isCompilerGenerated() == false)
                  {
                 // output the function number and the name of the function
                    printf ("Function #%2d name is %s at line %d \n",counter++,functionDeclaration->get_name().str(),functionDeclaration->get_file_info()->get_line());
                  }
                 else
                  {
                 // Output something about the compiler-generated builtin functions
                    printf ("Compiler-generated (builtin) function #%2d name is %s \n",counter++,functionDeclaration->get_name().str());
                  }
             }
            else
             {
               SgDeclarationStatement* declaration = isSgDeclarationStatement(*i);
               ROSE_ASSERT(declaration != NULL);
               printf ("--- declaration #%2d is: %p = %s \n",counter++,declaration,declaration->class_name().c_str());
             }
#endif
        }
#endif

     if (numberOfNodes <= maxNumberOfNodes)
        {
       // Ouput nodes.
          for (std::set<SgNode*>::iterator i = include_nodeSet.begin(); i != include_nodeSet.end(); i++)
             {
               SgNode* node = *i;
               file << "\"" << StringUtility::numberToString(node) << "\"[" << "label=\"" << node->class_name() << "\\n" << StringUtility::numberToString(node) << "\"];" << endl;
             }

       // Output edges
          for (std::set<SgNode*>::iterator i = include_nodeSet.begin(); i != include_nodeSet.end(); i++)
             {
               SgNode* node = *i;

               std::vector<std::pair<SgNode*,std::string> > listOfIRnodes = node->returnDataMemberPointers();
               std::vector<std::pair<SgNode*,std::string> >::iterator j = listOfIRnodes.begin();
               while (j != listOfIRnodes.end())
                  {
                    if (include_nodeSet.find(j->first) != include_nodeSet.end())
                       {
                         file << "\"" << StringUtility::numberToString(node) << "\" -> \"" << StringUtility::numberToString(j->first) << "\"[label=\"" << j->second << "\"];" << endl;
                       }

                    j++;
                  }
             }
        }
       else
        {
          printf ("WARNING: IntermediateRepresentationNodeGraph is too large to generate: numberOfNodes = %d (max size = %d) \n",numberOfNodes,maxNumberOfNodes);
        }
   }