static int analyzeSymbol(const llvm::object::SymbolRef& sym) { std::deque<llvm::MCInst> block; disassembleSymbol(sym, block); translateBlock(block); //analyzeStackReferences(block); return 0; }
BlockLink * Translation::getBlock(BlockLink * prev,const etiss::uint64 & instructionindex) { std::string error; // try to find next block from previous block links // MOVED to getBlockFast if (prev != 0 && !prev->valid) { prev = 0; } // search block in cache std::list<BlockLink*> & list = blockmap_[instructionindex>>9]; for (std::list<BlockLink*>::iterator iter = list.begin(); iter != list.end();) // iter++ moved into block { BlockLink * iterbl = (*iter); if (likely(iterbl != 0)) { if (likely(iterbl->valid)) // check for valid block { if (iterbl->start <= instructionindex && iterbl->end > instructionindex) { if (likely(prev != 0)) { if (prev->end == iterbl->start) { BlockLink::updateRef(prev->next,iterbl); } else { BlockLink::updateRef(prev->branch,iterbl); } } return *iter; } iter++; } else // cleanup { BlockLink::updateRef(iterbl->next,0); BlockLink::updateRef(iterbl->branch,0); list.erase(iter++); BlockLink::decrRef(iterbl); // remove reference of map // prev remains valid because this blocklink needs to be invalid continue; } } } // generate block std::string blockfunctionname; { std::stringstream ss; ss << "_t" << id << "c" << tblockcount++ << "_block_" << instructionindex; blockfunctionname = ss.str(); } CodeBlock block(instructionindex); block.fileglobalCode().insert( "#include \"etiss/jit/CPU.h\"\n" "#include \"etiss/jit/System.h\"\n" "#include \"etiss/jit/ReturnCode.h\"\n" ); block.functionglobalCode().insert( "if (cpu->mode != " +toString(cpu_.mode) + ") return ETISS_RETURNCODE_RELOADCURRENTBLOCK;" ); plugins_initCodeBlock_(plugins_array_,block); etiss::int32 transerror = translateBlock(block); if (transerror != ETISS_RETURNCODE_NOERROR) { etiss::log(etiss::VERBOSE,"Failed to translate block"); return nullptr; } plugins_finalizeCodeBlock_(plugins_array_,block); std::string code; { std::stringstream ss; block.toCode(ss,blockfunctionname,nullptr); code = ss.str(); } // various includes std::set<std::string> headers; headers.insert(etiss::cfg().get<std::string>("etiss_wd","./")+"include_c/"); headers.insert(arch_->getIncludePath()); std::set<std::string> libloc; libloc.insert(arch_->getIncludePath()); libloc.insert(etiss::cfg().get<std::string>("etiss_path","./")); libloc.insert(etiss::cfg().get<std::string>("etiss_wd","./")); std::set<std::string> libs; libs.insert("ETISS"); /* DEBUG HELPER: write code files to work directory { static unsigned count = 0; std::stringstream ss; ss << "code" << ++count; std::ofstream out; out.open(ss.str().c_str()); out << code; out.close(); std::cout << "Code file " << count << std::endl; } */ #ifndef ETISS_DEBUG #define ETISS_DEBUG 0 #endif // compile library void * funcs = jit_->translate(code,headers,libloc,libs,error, etiss::cfg().get<bool>("jit-debug",ETISS_DEBUG) != 0); if (funcs == 0) { etiss::log(etiss::ERROR,error); return 0; } // wrap library handle for cleanup auto local_jit = jit_; std::shared_ptr<void> lib(funcs,[local_jit](void*p) { local_jit->free(p); }); // check function/library handle if (lib.get() != 0) { std::string error; ExecBlockCall execBlock = (ExecBlockCall) jit_->getFunction(lib.get(),blockfunctionname.c_str(),error); if (execBlock != 0) { BlockLink * nbl = new BlockLink(block.startindex_,block.endaddress_,execBlock,lib); uint64 ii9 = instructionindex>>9; do { blockmap_[ii9].push_back(nbl); BlockLink::incrRef(nbl); // map holds a reference ii9++; } while ((ii9<<9) <block.endaddress_); if (prev != 0) { if (nbl->start == prev->end) { BlockLink::updateRef(prev->next,nbl); } else { BlockLink::updateRef(prev->branch,nbl); } } return nbl; }