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 }