Example #1
0
/**
 * Open log
 */
int log_open(const char *file, const char *ident, int level)
{
	log_close();
	lfd = strcasecmp(file, "stderr") ? open(file, O_WRONLY | O_CREAT | O_APPEND, 0600) : STDERR_FILENO;
	log_ident(ident);
	log_level(level);
	return lfd;
}
Example #2
0
/**
 * Global code of zcmd handler
 * @return CMD_RES_xxx 
 */
static int conn_zcmd_first(XS_CONN *conn)
{
	int rc = CMD_RES_NEXT;
	XS_CMD *cmd = conn->zcmd;

	// check project
	if (conn->user == NULL && cmd->cmd != CMD_USE && cmd->cmd != CMD_QUIT && cmd->cmd != CMD_TIMEOUT)
	{
		log_warning_conn("project not specified (CMD:%d)", cmd->cmd);
		return XS_CMD_DONT_ANS(cmd) ? CMD_RES_CONT : CONN_RES_ERR(NOPROJECT);
	}

	// parse global command type [first]
	if (cmd->cmd == CMD_QUIT)
		rc = CMD_RES_QUIT;
	else if (cmd->cmd == CMD_DEBUG)
	{
		// show debug info for some special usage (this may cause buffer overflow)
		char buf[4096];
		XS_CMDS *cmds;
		XS_DB *db;
		int len = 0;

		// basic info
		len += sprintf(&buf[len], "id:%s, sock:[%d], name:%s, home:%s, rcv_size:%d, flag:0x%04x\n",
			log_ident(NULL), CONN_FD(), conn->user->name,
			conn->user->home, conn->rcv_size, conn->flag);
		// db list
		len += sprintf(&buf[len], "DBS:");
		for (db = conn->user->db; db != NULL; db = db->next)
		{
			len += sprintf(&buf[len], " [%s] ->", db->name);
		}
		len += sprintf(&buf[len], " [NULL]\nCMDS:\n");
		// cmd list
		for (cmds = conn->zhead; cmds != NULL && len < (sizeof(buf) - 256); cmds = cmds->next)
		{
			len += sprintf(&buf[len], "  -> {cmd:%d,arg1:%d,arg2:%d,blen1:%d,blen:%d}\n",
				cmds->cmd->cmd, cmds->cmd->arg1, cmds->cmd->arg2,
				cmds->cmd->blen1, cmds->cmd->blen);
		}
		if (cmds == NULL)
			len += sprintf(&buf[len], "  -> {NULL}");
		else
			len += sprintf(&buf[len], "  -> ...");
		rc = CONN_RES_OK3(INFO, buf, len);
	}
	else if (cmd->cmd == CMD_TIMEOUT)
	{
		// set timeout
		conn->tv.tv_sec = XS_CMD_ARG(cmd);
		rc = CONN_RES_OK(TIMEOUT_SET);
		log_debug_conn("adjust timeout (SEC:%d)", conn->tv.tv_sec);
	}
	return rc;
}
Example #3
0
static OpndLoopInfo processOpnd(LoopNode* loopHead, LoopTree* lt, InstStack& defStack, Opnd* opnd) {
    OpndLoopInfo result;
    Inst* defInst = opnd->getInst();
    if (Log::isEnabled()) {
        log_ident(defStack.size()); defInst->print(Log::out()); Log::out()<<"]"<<std::endl;
    }
    if (std::find(defStack.begin(), defStack.end(), defInst)!=defStack.end()) {
        result.setType(OpndLoopInfo::COUNTER);
        result.setIncrement(0);
        if (Log::isEnabled()) {
            log_ident(defStack.size()); 
            Log::out()<<"Found duplicate in def stack -> stopping recursion. ";result.print(Log::out()); Log::out()<<std::endl;
        }
        return result;
    }
    Node* defNode = defInst->getNode();
    Opcode opcode = defInst->getOpcode();

    if (opcode == Op_LdConstant) {
        result.setType(OpndLoopInfo::LD_CONST);
        result.setConst(defInst->asConstInst()->getValue().i4);
        if (Log::isEnabled()) {
            log_ident(defStack.size()); 
            Log::out()<<"assigning to const -> stopping recursion. ";result.print(Log::out());Log::out()<<std::endl;
        }
        return result;
    }
    if (!loopHead->inLoop(defNode)) {
        if (Log::isEnabled()) {
            log_ident(defStack.size());
            Log::out()<<"Inst out of the loop -> stopping recursion. ";result.print(Log::out()); Log::out()<<std::endl;
        }
        return result;
    }

    defStack.push_back(defInst);
    if (opcode == Op_Phi) {
        OpndLoopInfo info1 = processOpnd(loopHead, lt, defStack, defInst->getSrc(0));
        OpndLoopInfo info2 = processOpnd(loopHead, lt, defStack, defInst->getSrc(1));
        if (Log::isEnabled()) {
            log_ident(defStack.size());
            Log::out()<<"PHI(";info1.print(Log::out());Log::out()<<",";info2.print(Log::out());Log::out()<<")"<<std::endl;
        }
        if ( ((info1.isCounter() && !info1.isPhiSplit()) && (info2.isDOL() || info2.isLDConst()))
             || ((info2.isCounter() && !info2.isPhiSplit()) && (info1.isDOL() || info1.isLDConst())) )
        {
            result.setType(OpndLoopInfo::COUNTER);
            result.setIncrement(info1.isCounter() ? info1.getIncrement() : info2.getIncrement());
            result.markPhiSplit();
        } else {
            result.setType(OpndLoopInfo::UNDEF);
        }
    } else if (opcode == Op_Add || opcode == Op_Sub) { //todo: LADD 
        Opnd *op1 = defInst->getSrc(0);
        Opnd *op2 = defInst->getSrc(1);
        OpndLoopInfo info1 = processOpnd(loopHead, lt, defStack, op1);
        OpndLoopInfo info2 = processOpnd(loopHead, lt, defStack, op2);
        if ((info1.isLDConst() || info1.isDOL()) && (info2.isLDConst() || info2.isDOL())) {
            if (info1.isLDConst() && info2.isLDConst() && info1.getConst() == info2.getConst()) {
                result.setType(OpndLoopInfo::LD_CONST);
                result.setConst(info1.getConst());
            } else {
                //result is DOL (default type)
            }
        } else if ((info1.isCounter() && info2.isLDConst()) || (info2.isCounter() && info1.isLDConst())) {
            int increment = info1.isCounter()? info1.getIncrement(): info2.getIncrement();
            int diff = info1.isLDConst()? info1.getConst(): info2.getConst(); 

            //we use SSA form to analyze how opnd changes in loop and we do not analyze actual control flow, 
            // so we can unroll loops with monotonically changing 'counters' only.
            //Example: when 'counter' changes not monotonically and we can't unroll:
            //idx=0; loop {idx+=100; if(idx>=100) break; idx-=99;} ->'increment'=1 but not monotonicaly.
            bool monotonousFlag = increment == 0 || diff == 0 
                || (opcode == Op_Add && signof(diff) == signof(increment)) 
                || (opcode == Op_Sub && signof(diff) != signof(increment));
            if (monotonousFlag) {
                result.setType(OpndLoopInfo::COUNTER);
                if ((info1.isCounter() && info1.isPhiSplit()) || (info2.isCounter() && info2.isPhiSplit())) {
                    result.markPhiSplit();
                }
                //TO IMPROVE: for loops like: for (; length-1>=0;length--){...}
                //we have 2 SUBs by -1 => "-2", but real counter is changed by "-1".
                //Loop unroll will use "-2". It's ok, because this value is used in a guard inst
                //and ABS(increment_in_unroll) >= ABS(real_increment). This work only for monotonous loops.
                //To make increment_in_unroll == real_increment we must track modifications (SUB,ADD) that affects vars only.
                if (opcode == Op_Add) {
                    result.setIncrement(increment + diff);
                } else {
                    result.setIncrement(increment - diff);
                }
            } else {
                result.setType(OpndLoopInfo::UNDEF);
            }
        } else {
            result.setType(OpndLoopInfo::UNDEF);
        }
    } else if (opcode == Op_StVar  || opcode == Op_LdVar) {
        Opnd* newOpnd = defInst->getSrc(0);
        result  = processOpnd(loopHead, lt, defStack, newOpnd);
    } else if (opcode == Op_TauArrayLen) {
        Opnd* arrayOpnd  = defInst->getSrc(0);
        result  = processOpnd(loopHead, lt, defStack, arrayOpnd);
    } else { //unsupported op
        result.setType(OpndLoopInfo::UNDEF);
        if (Log::isEnabled()) {
            log_ident(defStack.size()); Log::out()<<"unknown op -> stopping recursion. ";
        }
    }
    defStack.pop_back();
    if (Log::isEnabled()) {
        log_ident(defStack.size());
        result.print(Log::out());Log::out()<<std::endl;
    }
    return result;
}