Exemplo n.º 1
0
static int analyzeSymbol(const llvm::object::SymbolRef& sym) {
	std::deque<llvm::MCInst> block;

	disassembleSymbol(sym, block);
	translateBlock(block);
	//analyzeStackReferences(block);

	return 0;
}
Exemplo n.º 2
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;
        }