Beispiel #1
0
void FindGPUMacro::analyze_data_struct(Stmt *stmtList) {
    if (!stmtList) return;

    _os << "\nNEW FORLOOP BEGIN\n";

    for (Stmt::child_iterator itr = stmtList->child_begin();
         itr != stmtList->child_end();
         ++itr) {
        Stmt *stmt = *itr;
        if (!stmt) continue;

        Expr *expr = dyn_cast<Expr>(stmt);
        if (!expr) continue;

        // Dump out the AST tree
        expr->dump();

        analyze_expr(expr);
    }

    for (std::set<ValueDecl*>::iterator itr = lhs_decls.begin();
         itr != lhs_decls.end();
         ++itr) {
        _os << "LHS ValueDecl AST Node: " << *itr
            << ", Name: '" << (*itr)->getNameAsString() << "', ";
        analyze_value_decl(*itr);
    }

    for (std::set<ValueDecl*>::iterator itr = rhs_decls.begin();
         itr != rhs_decls.end();
         ++itr) {
        _os << "RHS ValueDecl AST Node: " << *itr
            << ", Name: '" << (*itr)->getNameAsString() << "', ";
        analyze_value_decl(*itr);
    }

    _os << "NEW FORLOOP END\n";
}
void CheckAllocationsInFunctionVisitor::VisitAllocate(
    const A0& getArg0, const A1& getArg1, const T& getAllocType)
{
    const Expr* firstArgNode = getArg0();

    // Check if the first argument (to new or AllocateArray) is a static cast
    // AllocatorNew/AllocateArray in Chakra always does a static_cast to the AllocatorType
    const CXXStaticCastExpr* castNode = nullptr;
    if (firstArgNode != nullptr &&
        (castNode = dyn_cast<CXXStaticCastExpr>(firstArgNode)))
    {
        QualType allocatedType = getAllocType();
        string allocatedTypeStr = allocatedType.getAsString();

        auto allocationType = CheckAllocationType(castNode);
        if (allocationType == AllocationTypes::Recycler)  // Recycler allocation
        {
            const Expr* secondArgNode = getArg1();

            // Chakra has two types of allocating functions- throwing and non-throwing
            // However, recycler allocations are always throwing, so the second parameter
            // should be the address of the allocator function
            auto unaryNode = cast<UnaryOperator>(secondArgNode);
            if (unaryNode != nullptr && unaryNode->getOpcode() == UnaryOperatorKind::UO_AddrOf)
            {
                Expr* subExpr = unaryNode->getSubExpr();
                if (DeclRefExpr* declRef = cast<DeclRefExpr>(subExpr))
                {
                    auto declNameInfo = declRef->getNameInfo();
                    auto allocationFunctionStr = declNameInfo.getName().getAsString();
                    _mainVisitor->RecordRecyclerAllocation(allocationFunctionStr, allocatedTypeStr);

                    if (!Contains(allocationFunctionStr, "Leaf"))
                    {
                        // Recycler write barrier allocation -- unless "Leaf" in allocFunc
                        allocationType = AllocationTypes::RecyclerWriteBarrier;
                    }
                }
                else
                {
                    Log::errs() << "ERROR: (internal) Expected DeclRefExpr:\n";
                    subExpr->dump();
                }
            }
            else if (auto mExpr = cast<MaterializeTemporaryExpr>(secondArgNode))
            {
                auto name = mExpr->GetTemporaryExpr()->IgnoreImpCasts()->getType().getAsString();
                if (StartsWith(name, "InfoBitsWrapper<")) // && Contains(name, "WithBarrierBit"))
                {
                    // RecyclerNewEnumClass, RecyclerNewWithInfoBits -- always have WithBarrier varients
                    allocationType = AllocationTypes::RecyclerWriteBarrier;
                }
            }
            else
            {
                Log::errs() << "ERROR: (internal) Expected unary node or MaterializeTemporaryExpr:\n";
                secondArgNode->dump();
            }
        }

        if (allocationType & AllocationTypes::WriteBarrier)
        {
            Log::outs() << "In \"" << _functionDecl->getQualifiedNameAsString() << "\"\n";
            Log::outs() << "  Allocating \"" << allocatedTypeStr << "\" in write barriered memory\n";
        }

        _mainVisitor->RecordAllocation(allocatedType, allocationType);
    }
}
    virtual void run(const MatchFinder::MatchResult &Result){
        const BinaryOperator* BO = Result.Nodes.getNodeAs<BinaryOperator>("malloc");
        #ifdef DEBUG
        llvm::errs()<<"----BinaryOperator(malloc) find----\n";
        #endif
        if(!BO)   return ;
        const SourceManager *SM = Result.SourceManager;
        SourceLocation locEnd = BO->getLocEnd();
        checkPoint cp;
      
	
		//得到插装位置,找到mallocVarMatcher之前对应匹配到的信息(其实可以不用MallocVarMatcher,MallocVarMatcher只能匹配到纯粹的指针(不带*的))
        std::string str_locEnd = locEnd.printToString(*SM);
        loc_strToint(cp.row,cp.col,str_locEnd.c_str());
        bool findFlag = false;
        int findI;
        
        #ifdef DEBUG
        llvm::errs() <<"binary loc:" <<"|"<<cp.row<<"|"<<cp.col<<"\n";
        #endif
        
        for(unsigned i=0;i<cpVec.size();++i){
            if(cpVec[i].row == cp.row){
                    findFlag = true;
                    findI = i;
                    break;
                }
        }
		//左子树得到的 = 的左边
        Expr * lhs = BO->getLHS();
        cp.name = rewrite.ConvertToString((Stmt*)lhs);
        
        QualType qt = lhs->getType();
        #ifdef DEBUG
        llvm::errs()<<"lhs cp.name :"<<cp.name<<"\n";
        llvm::errs()<<"lhs type :"<<qt.getAsString()<<"\n";
        lhs->dump();
        #endif
        
		//找到的话直接用
        if(findFlag){        
            const NamedDecl *ND = ((DeclRefExpr*)lhs)->getFoundDecl();
            std::string str_decl = ND->getNameAsString();
            cp.declName = str_decl;
            SourceLocation declLocStart = ND->getLocStart();
            std::string str_declLocStart = declLocStart.printToString(*SM);
            loc_strToint(cp.declRow,cp.declCol,str_declLocStart.c_str());
        
        }else{//没找到的话,添加进来
            cp.declName = cp.name;
            cp.declRow = cp.row;
            cp.declCol = cp.col;
        }
        
		//string + 不支持int类型,所以先换成char*
        char buf[4][32];
        sprintf(buf[0],"%d",cp.row);
        sprintf(buf[1],"%d",cp.col);
        sprintf(buf[2],"%d",cp.declRow);
        sprintf(buf[3],"%d",cp.declCol);  
                                     
        //将程序运行时的指针值存下来 %x                                     
        std::string str_insert = 
        "\n{\n\tFILE *fp = fopen(\"" + checkDataFileName +"\",\"a\");\n"
        "\tif(fp == NULL){\n" +
        "\t\tprintf(\"fail to open file " + checkDataFileName + "!\\n\");\n" +
        "\t\texit(-1);\n" + 
        "\t}\n" + 
        
        //"\tfprintf(fp,\"m " + cp.name + " " + buf[0] + " " + buf[1] + " " + cp.declName + " " + buf[2] + " " + buf[3] + " %x \\n\"," + cp.name + ");\n" +
        "\tfprintf(fp,\"m " + cp.name + " " + buf[0] + " " + buf[1] + " %x \\n\"," + cp.name + ");\n" +
        "\tfclose(fp);\n\n" +
        "\tint fd=open(FIFO_SERVER,O_WRONLY |O_NONBLOCK,0);\n" + 
        "\tif(fd==-1){perror(\"open\");exit(1);}\n" + 
        "\tchar w_buf[100];\n" + 
        "\tsprintf(w_buf,\"m "+ cp.name + " " + buf[0] + " " + buf[1] + " %x \\n\"," + cp.name + ");\n" + 
        "\tif(write(fd,w_buf,100)==-1){\n" + 
        "\t\tif(errno==EAGAIN)\n" + 
        "\t\t\tprintf(\"The FIFO has not been read yet.Please try later\\n\");\n" + 
        "\t}\n" + 
        "\telse\n" + 
        "\t\tprintf(\"write %s to the FIFO\\n\",w_buf);\n" +
        "\tsleep(1);\n" + 
        "\tclose(fd);\n" + 
        "}\n";
        
        
        
        //llvm::errs() << "-----\n"<<str_insert<<"\n----\n";
		//找位置插装
        int locOffset = 2;
        SourceLocation SL_locWithOffset = locEnd.getLocWithOffset(locOffset);
        rewrite.InsertText(SL_locWithOffset,str_insert.c_str(),true,true); 
        
		if(!findFlag){        
            cpVec.push_back(cp);
        }

        #ifdef DEBUG
        llvm::errs()<<"----BinaryOperator(malloc) end----\n";
        #endif
    }