コード例 #1
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_log_clear_by_level(cs_uint32 level)
{
    cs_log_t *log = NULL;
    cs_log_t *prev = NULL;

    cs_list_lock();
    for(log = (cs_log_t *)cs_lst_first(&sys_log_ctrl.log_list) ; log ; )
    {
        if(log->log_level != level)
        {
            log = (cs_log_t *)cs_lst_next((cs_node *)log);
            continue;
        }

        prev = (cs_log_t *)cs_lst_prev((cs_node *)log);
        cs_lst_delete(&sys_log_ctrl.log_list , (cs_node *)log);
        cs_mem_free((cs_uint8 *)log);
        if(prev != NULL)
            log = (cs_log_t *)cs_lst_next((cs_node *)prev);
        else
            log = (cs_log_t *)cs_lst_first(&sys_log_ctrl.log_list);
    }
    cs_list_unlock();

    return;
}
コード例 #2
0
void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
{
	char *mnem;
	unsigned int i;
	x86_reg reg;

	// Try to print any aliases first.
	mnem = printAliasInstr(MI, OS, NULL);
	if (mnem)
		cs_mem_free(mnem);
	else
		printInstruction(MI, OS, NULL);

	if (MI->csh->detail) {
		// special instruction needs to supply register op
		reg = X86_insn_reg(MCInst_getOpcode(MI));
		if (reg) {
			// add register operand
			for (i = 0;; i++) {
				// find the first empty slot to put it there
				if (MI->flat_insn->detail->x86.operands[i].type == 0) {
					MI->flat_insn->detail->x86.operands[i].type = X86_OP_REG;
					MI->flat_insn->detail->x86.operands[i].reg = reg;
					MI->flat_insn->detail->x86.op_count++;
					break;
				}
			}

		}
	}
}
コード例 #3
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_sys_log(const cs_int8 *String, ...)
{
    va_list   ptr;
    cs_int8 msg_buffer [4*CS_LOG_SIZE];
    cs_log_t *log;
    cs_int32 len=0;

    log = (cs_log_t *)cs_mem_malloc(sys_log_ctrl.mempool_id);
    if(log == NULL)
        return;
    memset(log , 0 , sizeof(cs_log_t));
    log->time = 0;
    log->log_type = CS_SYS_LOG_TYPE;

    memset(msg_buffer , 0 , sizeof(msg_buffer));
    va_start(ptr,String);
    vsprintf(msg_buffer , String, ptr);
    va_end(ptr);

    len = (strlen(msg_buffer) >= CS_LOG_SIZE)?CS_LOG_SIZE-1:strlen(msg_buffer);
    memcpy(log->a.log_buf , msg_buffer , len);

    if(CS_E_OSAL_OK != cs_queue_put(sys_log_ctrl.log_queue_id, (void *)&log, sizeof(cs_uint32) , CS_OSAL_NO_WAIT , 0))
    {
        cs_mem_free((cs_uint8 *)log);
        return;
    }

    return;
}
コード例 #4
0
void Mips_printInst(MCInst *MI, SStream *O, void *info)
{
	switch (MCInst_getOpcode(MI)) {
		default: break;
		case Mips_RDHWR:
		case Mips_RDHWR64:
			SStream_concat(O, ".set\tpush\n");
			SStream_concat(O, ".set\tmips32r2\n");
			break;
		case Mips_Save16:
			SStream_concat(O, "\tsave\t");
			printSaveRestore(MI, O);
			SStream_concat(O, " # 16 bit inst\n");
			return;
		case Mips_SaveX16:
			SStream_concat(O, "\tsave\t");
			printSaveRestore(MI, O);
			SStream_concat(O, "\n");
			return;
		case Mips_Restore16:
			SStream_concat(O, "\trestore\t");
			printSaveRestore(MI, O);
			SStream_concat(O, " # 16 bit inst\n");
			return;
		case Mips_RestoreX16:
			SStream_concat(O, "\trestore\t");
			printSaveRestore(MI, O);
			SStream_concat(O, "\n");
			return;
	}

	// Try to print any aliases first.
	if (!printAliasInstr(MI, O, info) && !printAlias(MI, O))
		printInstruction(MI, O, NULL);
	else {
		// fixup instruction id due to the change in alias instruction
		char *mnem = cs_strdup(O->buffer);
		char *tab = strchr(mnem, '\t');
		if (tab)
			*tab = '\0';

		// reflect the new insn name (alias) in the opcode
		unsigned id = Mips_map_insn(mnem);
		MCInst_setOpcode(MI, Mips_get_insn_id2(id));
		MCInst_setOpcodePub(MI, id);
		cs_mem_free(mnem);
	}

	switch (MCInst_getOpcode(MI)) {
		default: break;
		case Mips_RDHWR:
		case Mips_RDHWR64:
			SStream_concat(O, "\n.set\tpop");
			break;
	}
}
コード例 #5
0
void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
{
	char *mnem;
	x86_reg reg, reg2;
	enum cs_ac_type access1, access2;

	// Try to print any aliases first.
	mnem = printAliasInstr(MI, O, Info);
	if (mnem)
		cs_mem_free(mnem);
	else
		printInstruction(MI, O, Info);

	reg = X86_insn_reg_intel(MCInst_getOpcode(MI), &access1);
	if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
		uint8_t access[6];
#endif

		// first op can be embedded in the asm by llvm.
		// so we have to add the missing register as the first operand
		if (reg) {
			// shift all the ops right to leave 1st slot for this new register op
			memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
					sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
			MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
			MI->flat_insn->detail->x86.operands[0].reg = reg;
			MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
			MI->flat_insn->detail->x86.operands[0].access = access1;
			MI->flat_insn->detail->x86.op_count++;
		} else {
			if (X86_insn_reg_intel2(MCInst_getOpcode(MI), &reg, &access1, &reg2, &access2)) {
				MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[0].reg = reg;
				MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
				MI->flat_insn->detail->x86.operands[0].access = access1;
				MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[1].reg = reg2;
				MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2];
				MI->flat_insn->detail->x86.operands[1].access = access2;
				MI->flat_insn->detail->x86.op_count = 2;
			}
		}

#ifndef CAPSTONE_DIET
		get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
		MI->flat_insn->detail->x86.operands[0].access = access[0];
		MI->flat_insn->detail->x86.operands[1].access = access[1];
#endif
	}

	if (MI->op1_size == 0 && reg)
		MI->op1_size = MI->csh->regsize_map[reg];
}
コード例 #6
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_log_clear_all()
{
    cs_log_t *log = NULL;

    cs_list_lock();
    while((log = (cs_log_t *)cs_lst_get(&sys_log_ctrl.log_list)) != NULL)
    {
        cs_mem_free((cs_uint8 *)log);
        log = NULL;
    }
    cs_list_unlock();

    return;
}
コード例 #7
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_buffer_dump(cs_int8 *comment , cs_int8 *buf , cs_int32 len)
{
#ifdef HAVE_LOG_THREAD
    cs_log_t *log;
    cs_int32 comment_len=0;
    cs_int32 buf_len = 0;

    log = (cs_log_t *)cs_mem_malloc(sys_log_ctrl.mempool_id);
    if(log == NULL)
        return;
    memset(log , 0 , sizeof(cs_log_t));
    log->log_level = -1;
    log->module_id = -1;
    log->time = cs_current_time();
    log->log_type = CS_LOG_HEX_TYPE;

    comment_len = (strlen(comment) >= CS_LOG_COMMENT_LEN)?CS_LOG_COMMENT_LEN-1:strlen(comment);
    buf_len = (len >= CS_LOG_SIZE-CS_LOG_COMMENT_LEN-4)?CS_LOG_SIZE-CS_LOG_COMMENT_LEN-4-1:len;
    log->a.b.len = buf_len;
    memcpy(log->a.b.comment , comment , comment_len);
    memcpy(log->a.b.buf , buf , buf_len);

    if(CS_E_OSAL_OK != cs_queue_put(sys_log_ctrl.log_queue_id, (void *)&log, sizeof(cs_uint32) , CS_OSAL_NO_WAIT , 0))
    {
        cs_mem_free((cs_uint8 *)log);
        return;
    }
#else
    int i;
    cs_printf("\n\n#%s ",comment);
    for(i = 0 ; i < len ; i++)
    {
        if(i%16 == 0)
        {
            cs_printf("\n");
            cs_printf("%06x  ", i);
        }

        cs_printf("%02x ",buf[i]);
    }
#endif

    return;
}
コード例 #8
0
void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
{
	//if (TSFlags & X86II::LOCK)
	//  O << "\tlock\n";

	if (printAliasInstr(MI, O)) {
		char *mnem = cs_strdup(O->buffer);
		char *tab = strchr(mnem, '\t');
		if (tab)
			*tab = '\0';
		// reflect the new insn name (alias) in the opcode
		MCInst_setOpcode(MI, X86_get_insn_id2(X86_map_insn(mnem)));
		cs_mem_free(mnem);
	} else
		printInstruction(MI, O, NULL);

	if (MI->csh->detail) {
		char tmp[64];
		if (get_first_op(O->buffer, tmp)) {
			int post;
			char *acc_regs[] = { "al", "ax", "eax", "rax", NULL };
			unsigned int acc_regs_id[] = { X86_REG_AL,  X86_REG_AX, X86_REG_EAX, X86_REG_RAX };
			if (tmp[0] != 0 && ((post = str_in_list(acc_regs, tmp)) != -1)) {
				// first op is register, so set operand size following register size
				MI->flat_insn.x86.op_size = 1 << post;
				// tmp is a register
				if ((MI->flat_insn.x86.operands[0].type != X86_OP_INVALID) &&
						((MI->flat_insn.x86.operands[0].type != X86_OP_REG) ||
						(MI->flat_insn.x86.operands[0].reg != acc_regs_id[post]))) {
					// first op is register, so insert its detail to position 0
					int i;
					for (i = MI->flat_insn.x86.op_count; i > 0; i--) {
						memcpy(&(MI->flat_insn.x86.operands[i]), &(MI->flat_insn.x86.operands[i - 1]),
								sizeof(MI->flat_insn.x86.operands[0]));
					}
					MI->flat_insn.x86.operands[0].type = X86_OP_REG;
					MI->flat_insn.x86.operands[0].reg = x86_map_regname(tmp);
					MI->flat_insn.x86.op_count++;
				}
			}
		}
	}
}
コード例 #9
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_sys_log(const cs_int8 *String, ...)
{
    va_list   ptr;
    cs_int8 msg_buffer [2*CS_LOG_SIZE];
    cs_log_t *log;
    cs_int32 len=0;
    cs_int32 hour=0,min=0,sec=0;

    log = (cs_log_t *)cs_mem_malloc(sys_log_ctrl.mempool_id);
    if(log == NULL)
        return;
    memset(log , 0 , sizeof(cs_log_t));
    log->time = cs_current_time();
    log->log_type = CS_SYS_LOG_TYPE;

    memset(msg_buffer , 0 , sizeof(msg_buffer));
    va_start(ptr,String);
    vsprintf(msg_buffer , String, ptr);
    va_end(ptr);
    /*12 bytes for timestamp*/
    len = (strlen(msg_buffer) >= CS_LOG_SIZE-12)?CS_LOG_SIZE-12-1:strlen(msg_buffer);
    #if 1
    hour = log->time/(100*3600);
    min = (log->time/(100*60))%60;
    sec = (log->time/100)%60;
    memset(log->a.log_buf , 0 , CS_LOG_SIZE);
    sprintf(log->a.log_buf,"[%dh%dm%ds] ",hour,min,sec);
    #endif
    memcpy(log->a.log_buf+strlen(log->a.log_buf) , msg_buffer , len);

    if(CS_E_OSAL_OK != cs_queue_put(sys_log_ctrl.log_queue_id, (void *)&log, sizeof(cs_uint32) , CS_OSAL_NO_WAIT , 0))
    {
        cs_mem_free((cs_uint8 *)log);
        return;
    }

    return;
}
コード例 #10
0
ファイル: SparcInstPrinter.c プロジェクト: HardlyHaki/ProDBG
void Sparc_printInst(MCInst *MI, SStream *O, void *Info)
{
	char *mnem, *p;
	char instr[64];	// Sparc has no instruction this long

	mnem = printAliasInstr(MI, O, Info);
	if (mnem) {
		// fixup instruction id due to the change in alias instruction
		strncpy(instr, mnem, strlen(mnem));
		instr[strlen(mnem)] = '\0';
		// does this contains hint with a coma?
		p = strchr(instr, ',');
		if (p)
			*p = '\0';	// now instr only has instruction mnemonic
		MCInst_setOpcodePub(MI, Sparc_map_insn(instr));
		switch(MCInst_getOpcode(MI)) {
			case SP_BCOND:
			case SP_BCONDA:
			case SP_BPICCANT:
			case SP_BPICCNT:
			case SP_BPXCCANT:
			case SP_BPXCCNT:
			case SP_TXCCri:
			case SP_TXCCrr:
				if (MI->csh->detail) {
					// skip 'b', 't'
					MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 1);
					MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);
				}
				break;
			case SP_BPFCCANT:
			case SP_BPFCCNT:
				if (MI->csh->detail) {
					// skip 'fb'
					MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 2);
					MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);
				}
				break;
			case SP_FMOVD_ICC:
			case SP_FMOVD_XCC:
			case SP_FMOVQ_ICC:
			case SP_FMOVQ_XCC:
			case SP_FMOVS_ICC:
			case SP_FMOVS_XCC:
				if (MI->csh->detail) {
					// skip 'fmovd', 'fmovq', 'fmovs'
					MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 5);
					MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);
				}
				break;
			case SP_MOVICCri:
			case SP_MOVICCrr:
			case SP_MOVXCCri:
			case SP_MOVXCCrr:
				if (MI->csh->detail) {
					// skip 'mov'
					MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 3);
					MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);
				}
				break;
			case SP_V9FMOVD_FCC:
			case SP_V9FMOVQ_FCC:
			case SP_V9FMOVS_FCC:
				if (MI->csh->detail) {
					// skip 'fmovd', 'fmovq', 'fmovs'
					MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 5);
					MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);
				}
				break;
			case SP_V9MOVFCCri:
			case SP_V9MOVFCCrr:
				if (MI->csh->detail) {
					// skip 'mov'
					MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 3);
					MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);
				}
				break;
			default:
				break;
		}
		cs_mem_free(mnem);
	} else {
		if (!printSparcAliasInstr(MI, O))
			printInstruction(MI, O, NULL);
	}
}
コード例 #11
0
void AArch64_printInst(MCInst *MI, SStream *O, void *Info)
{
	// Check for special encodings and print the canonical alias instead.
	unsigned Opcode = MCInst_getOpcode(MI);
	int LSB;
	int Width;
	char *mnem;

	if (Opcode == AArch64_SYSxt && printSysAlias(MI, O))
		return;

	// SBFM/UBFM should print to a nicer aliased form if possible.
	if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||
			Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {
		MCOperand *Op0 = MCInst_getOperand(MI, 0);
		MCOperand *Op1 = MCInst_getOperand(MI, 1);
		MCOperand *Op2 = MCInst_getOperand(MI, 2);
		MCOperand *Op3 = MCInst_getOperand(MI, 3);

		bool IsSigned = (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri);
		bool Is64Bit = (Opcode == AArch64_SBFMXri || Opcode == AArch64_UBFMXri);

		if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 && MCOperand_isImm(Op3)) {
			char *AsmMnemonic = NULL;

			switch (MCOperand_getImm(Op3)) {
				default:
					break;
				case 7:
					if (IsSigned)
						AsmMnemonic = "sxtb";
					else if (!Is64Bit)
						AsmMnemonic = "uxtb";
					break;
				case 15:
					if (IsSigned)
						AsmMnemonic = "sxth";
					else if (!Is64Bit)
						AsmMnemonic = "uxth";
					break;
				case 31:
					// *xtw is only valid for signed 64-bit operations.
					if (Is64Bit && IsSigned)
						AsmMnemonic = "sxtw";
					break;
			}

			if (AsmMnemonic) {
				SStream_concat(O, "%s\t%s, %s", AsmMnemonic,
						getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
						getRegisterName(getWRegFromXReg(MCOperand_getReg(Op1)), AArch64_NoRegAltName));

				if (MI->csh->detail) {
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
					MI->flat_insn->detail->arm64.op_count++;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = getWRegFromXReg(MCOperand_getReg(Op1));
					MI->flat_insn->detail->arm64.op_count++;
				}

				MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));

				return;
			}
		}

		// All immediate shifts are aliases, implemented using the Bitfield
		// instruction. In all cases the immediate shift amount shift must be in
		// the range 0 to (reg.size -1).
		if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {
			char *AsmMnemonic = NULL;
			int shift = 0;
			int immr = (int)MCOperand_getImm(Op2);
			int imms = (int)MCOperand_getImm(Op3);

			if (Opcode == AArch64_UBFMWri && imms != 0x1F && ((imms + 1) == immr)) {
				AsmMnemonic = "lsl";
				shift = 31 - imms;
			} else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&
					((imms + 1 == immr))) {
				AsmMnemonic = "lsl";
				shift = 63 - imms;
			} else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {
				AsmMnemonic = "lsr";
				shift = immr;
			} else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {
				AsmMnemonic = "lsr";
				shift = immr;
			} else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {
				AsmMnemonic = "asr";
				shift = immr;
			} else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {
				AsmMnemonic = "asr";
				shift = immr;
			}

			if (AsmMnemonic) {
				SStream_concat(O, "%s\t%s, %s, ", AsmMnemonic,
						getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
						getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));

				printInt32Bang(O, shift);

				MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));

				if (MI->csh->detail) {
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
					MI->flat_insn->detail->arm64.op_count++;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
					MI->flat_insn->detail->arm64.op_count++;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
					MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = shift;
					MI->flat_insn->detail->arm64.op_count++;
				}

				return;
			}
		}

		// SBFIZ/UBFIZ aliases
		if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {
			SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfiz" : "ubfiz"),
					getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
					getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
			printInt32Bang(O, (int)((Is64Bit ? 64 : 32) - MCOperand_getImm(Op2)));
			SStream_concat0(O, ", ");
			printInt32Bang(O, (int)MCOperand_getImm(Op3) + 1);

			MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfiz" : "ubfiz"));

			if (MI->csh->detail) {
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
				MI->flat_insn->detail->arm64.op_count++;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
				MI->flat_insn->detail->arm64.op_count++;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (Is64Bit ? 64 : 32) - (int)MCOperand_getImm(Op2);
				MI->flat_insn->detail->arm64.op_count++;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)MCOperand_getImm(Op3) + 1;
				MI->flat_insn->detail->arm64.op_count++;
			}

			return;
		}

		// Otherwise SBFX/UBFX is the preferred form
		SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfx" : "ubfx"),
				getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
				getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
		printInt32Bang(O, (int)MCOperand_getImm(Op2));
		SStream_concat0(O, ", ");
		printInt32Bang(O, (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1);

		MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfx" : "ubfx"));

		if (MI->csh->detail) {
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
			MI->flat_insn->detail->arm64.op_count++;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
			MI->flat_insn->detail->arm64.op_count++;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)MCOperand_getImm(Op2);
			MI->flat_insn->detail->arm64.op_count++;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1;
			MI->flat_insn->detail->arm64.op_count++;
		}

		return;
	}

	if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {
		MCOperand *Op0 = MCInst_getOperand(MI, 0); // Op1 == Op0
		MCOperand *Op2 = MCInst_getOperand(MI, 2);
		int ImmR = (int)MCOperand_getImm(MCInst_getOperand(MI, 3));
		int ImmS = (int)MCOperand_getImm(MCInst_getOperand(MI, 4));

		// BFI alias
		if (ImmS < ImmR) {
			int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
			LSB = (BitWidth - ImmR) % BitWidth;
			Width = ImmS + 1;

			SStream_concat(O, "bfi\t%s, %s, ",
					getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
					getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));
			printInt32Bang(O, LSB);
			SStream_concat0(O, ", ");
			printInt32Bang(O, Width);
			MCInst_setOpcodePub(MI, AArch64_map_insn("bfi"));

			if (MI->csh->detail) {
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
				MI->flat_insn->detail->arm64.op_count++;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);
				MI->flat_insn->detail->arm64.op_count++;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
				MI->flat_insn->detail->arm64.op_count++;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
				MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
				MI->flat_insn->detail->arm64.op_count++;
			}

			return;
		}

		LSB = ImmR;
		Width = ImmS - ImmR + 1;
		// Otherwise BFXIL the preferred form
		SStream_concat(O, "bfxil\t%s, %s, ",
				getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
				getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));
		printInt32Bang(O, LSB);
		SStream_concat0(O, ", ");
		printInt32Bang(O, Width);
		MCInst_setOpcodePub(MI, AArch64_map_insn("bfxil"));

		if (MI->csh->detail) {
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
			MI->flat_insn->detail->arm64.op_count++;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);
			MI->flat_insn->detail->arm64.op_count++;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
			MI->flat_insn->detail->arm64.op_count++;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
			MI->flat_insn->detail->arm64.op_count++;
		}

		return;
	}

	mnem = printAliasInstr(MI, O, Info);
	if (mnem) {
		MCInst_setOpcodePub(MI, AArch64_map_insn(mnem));
		cs_mem_free(mnem);
	} else {
		printInstruction(MI, O, Info);
	}
}
コード例 #12
0
ファイル: PPCInstPrinter.c プロジェクト: HardlyHaki/ProDBG
void PPC_printInst(MCInst *MI, SStream *O, void *Info)
{
	char *mnem;

	// Check for slwi/srwi mnemonics.
	if (MCInst_getOpcode(MI) == PPC_RLWINM) {
		unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));
		unsigned char MB = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));
		unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 4));
		bool useSubstituteMnemonic = false;

		if (SH <= 31 && MB == 0 && ME == (31-SH)) {
			SStream_concat0(O, "slwi\t");
			MCInst_setOpcodePub(MI, PPC_INS_SLWI);
			useSubstituteMnemonic = true;
		}

		if (SH <= 31 && MB == (32-SH) && ME == 31) {
			SStream_concat0(O, "srwi\t");
			MCInst_setOpcodePub(MI, PPC_INS_SRWI);
			useSubstituteMnemonic = true;
			SH = 32-SH;
		}

		if (useSubstituteMnemonic) {
			printOperand(MI, 0, O);
			SStream_concat0(O, ", ");
			printOperand(MI, 1, O);
			if (SH > HEX_THRESHOLD)
				SStream_concat(O, ", 0x%x", (unsigned int)SH);
			else
				SStream_concat(O, ", %u", (unsigned int)SH);

			if (MI->csh->detail) {
				cs_ppc *ppc = &MI->flat_insn->detail->ppc;

				ppc->operands[ppc->op_count].type = PPC_OP_IMM;
				ppc->operands[ppc->op_count].imm = SH;
				++ppc->op_count;
			}

			return;
		}
	}

	if ((MCInst_getOpcode(MI) == PPC_OR || MCInst_getOpcode(MI) == PPC_OR8) &&
			MCOperand_getReg(MCInst_getOperand(MI, 1)) == MCOperand_getReg(MCInst_getOperand(MI, 2))) {
		SStream_concat0(O, "mr\t");
		MCInst_setOpcodePub(MI, PPC_INS_MR);
		printOperand(MI, 0, O);
		SStream_concat0(O, ", ");
		printOperand(MI, 1, O);
		return;
	}

	if (MCInst_getOpcode(MI) == PPC_RLDICR) {
		unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));
		unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));
		// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
		if (63-SH == ME) {
			SStream_concat0(O, "sldi\t");
			MCInst_setOpcodePub(MI, PPC_INS_SLDI);
			printOperand(MI, 0, O);
			SStream_concat0(O, ", ");
			printOperand(MI, 1, O);
			if (SH > HEX_THRESHOLD)
				SStream_concat(O, ", 0x%x", (unsigned int)SH);
			else
				SStream_concat(O, ", %u", (unsigned int)SH);

			return;
		}
	}

	if ((MCInst_getOpcode(MI) == PPC_gBC)||(MCInst_getOpcode(MI) == PPC_gBCA)||
			(MCInst_getOpcode(MI) == PPC_gBCL)||(MCInst_getOpcode(MI) == PPC_gBCLA)) {
		int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 2));
		bd = SignExtend64(bd, 14);
		MCOperand_setImm(MCInst_getOperand(MI, 2),bd);
	}

	if (isBOCTRBranch(MCInst_getOpcode(MI))) {
		if (MCOperand_isImm(MCInst_getOperand(MI,0)))
		{
			int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
			bd = SignExtend64(bd, 14);
			MCOperand_setImm(MCInst_getOperand(MI, 0),bd);
		}
	}

	if ((MCInst_getOpcode(MI) == PPC_B)||(MCInst_getOpcode(MI) == PPC_BA)||
			(MCInst_getOpcode(MI) == PPC_BL)||(MCInst_getOpcode(MI) == PPC_BLA)) {
		int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
		bd = SignExtend64(bd, 24);
		MCOperand_setImm(MCInst_getOperand(MI, 0),bd);
	}

	// consider our own alias instructions first
	mnem = printAliasInstrEx(MI, O, Info);
	if (!mnem)
		mnem = printAliasInstr(MI, O, Info);

	if (mnem != NULL) {
		if (strlen(mnem) > 0) {
			struct ppc_alias alias;
			// check to remove the last letter of ('.', '-', '+')
			if (mnem[strlen(mnem) - 1] == '-' || mnem[strlen(mnem) - 1] == '+' || mnem[strlen(mnem) - 1] == '.')
				mnem[strlen(mnem) - 1] = '\0';

			if (PPC_alias_insn(mnem, &alias)) {
				MCInst_setOpcodePub(MI, alias.id);
				if (MI->csh->detail) {
					MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;
				}
			}
		}

		cs_mem_free(mnem);
	} else
		printInstruction(MI, O, NULL);
}
コード例 #13
0
ファイル: X86ATTInstPrinter.c プロジェクト: AVGirl/capstone
void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
{
	char *mnem;
	x86_reg reg, reg2;
	int i;

	// Output CALLpcrel32 as "callq" in 64-bit mode.
	// In Intel annotation it's always emitted as "call".
	//
	// TODO: Probably this hack should be redesigned via InstAlias in
	// InstrInfo.td as soon as Requires clause is supported properly
	// for InstAlias.
	if (MI->csh->mode == CS_MODE_64 && MCInst_getOpcode(MI) == X86_CALLpcrel32) {
		SStream_concat0(OS, "callq\t");
		MCInst_setOpcodePub(MI, X86_INS_CALL);
		printPCRelImm(MI, 0, OS);
		return;
	}

	// Try to print any aliases first.
	mnem = printAliasInstr(MI, OS, info);
	if (mnem)
		cs_mem_free(mnem);
	else
		printInstruction(MI, OS, info);

	if (MI->has_imm) {
		// if op_count > 1, then this operand's size is taken from the destination op
		if (MI->flat_insn->detail->x86.op_count > 1) {
			if (MI->flat_insn->id != X86_INS_LCALL && MI->flat_insn->id != X86_INS_LJMP) {
				for (i = 0; i < MI->flat_insn->detail->x86.op_count; i++) {
					if (MI->flat_insn->detail->x86.operands[i].type == X86_OP_IMM)
						MI->flat_insn->detail->x86.operands[i].size =
							MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count - 1].size;
				}
			}
		} else
			MI->flat_insn->detail->x86.operands[0].size = MI->imm_size;
	}

	if (MI->csh->detail) {
        // some instructions need to supply immediate 1 in the first op
        switch(MCInst_getOpcode(MI)) {
            default:
                break;
            case X86_SHL8r1:
            case X86_SHL16r1:
            case X86_SHL32r1:
            case X86_SHL64r1:
            case X86_SAL8r1:
            case X86_SAL16r1:
            case X86_SAL32r1:
            case X86_SAL64r1:
            case X86_SHR8r1:
            case X86_SHR16r1:
            case X86_SHR32r1:
            case X86_SHR64r1:
            case X86_SAR8r1:
            case X86_SAR16r1:
            case X86_SAR32r1:
            case X86_SAR64r1:
            case X86_RCL8r1:
            case X86_RCL16r1:
            case X86_RCL32r1:
            case X86_RCL64r1:
            case X86_RCR8r1:
            case X86_RCR16r1:
            case X86_RCR32r1:
            case X86_RCR64r1:
            case X86_ROL8r1:
            case X86_ROL16r1:
            case X86_ROL32r1:
            case X86_ROL64r1:
            case X86_ROR8r1:
            case X86_ROR16r1:
            case X86_ROR32r1:
            case X86_ROR64r1:
            case X86_SHL8m1:
            case X86_SHL16m1:
            case X86_SHL32m1:
            case X86_SHL64m1:
            case X86_SAL8m1:
            case X86_SAL16m1:
            case X86_SAL32m1:
            case X86_SAL64m1:
            case X86_SHR8m1:
            case X86_SHR16m1:
            case X86_SHR32m1:
            case X86_SHR64m1:
            case X86_SAR8m1:
            case X86_SAR16m1:
            case X86_SAR32m1:
            case X86_SAR64m1:
            case X86_RCL8m1:
            case X86_RCL16m1:
            case X86_RCL32m1:
            case X86_RCL64m1:
            case X86_RCR8m1:
            case X86_RCR16m1:
            case X86_RCR32m1:
            case X86_RCR64m1:
            case X86_ROL8m1:
            case X86_ROL16m1:
            case X86_ROL32m1:
            case X86_ROL64m1:
            case X86_ROR8m1:
            case X86_ROR16m1:
            case X86_ROR32m1:
            case X86_ROR64m1:
                // shift all the ops right to leave 1st slot for this new register op
                memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
                        sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
                MI->flat_insn->detail->x86.operands[0].type = X86_OP_IMM;
                MI->flat_insn->detail->x86.operands[0].imm = 1;
                MI->flat_insn->detail->x86.operands[0].size = 1;
                MI->flat_insn->detail->x86.op_count++;
        }

		// special instruction needs to supply register op
		// first op can be embedded in the asm by llvm.
		// so we have to add the missing register as the first operand
		reg = X86_insn_reg_att(MCInst_getOpcode(MI));
		if (reg) {
			// shift all the ops right to leave 1st slot for this new register op
			memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
					sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
			MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
			MI->flat_insn->detail->x86.operands[0].reg = reg;
			MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
			MI->flat_insn->detail->x86.op_count++;
		} else {
			if (X86_insn_reg_att2(MCInst_getOpcode(MI), &reg, &reg2)) {
				MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[0].reg = reg;
				MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
				MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[1].reg = reg2;
				MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2];
				MI->flat_insn->detail->x86.op_count = 2;
			}
		}
	}
}
コード例 #14
0
void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
{
	char *mnem;
	x86_reg reg, reg2;
	int i;

	// Output CALLpcrel32 as "callq" in 64-bit mode.
	// In Intel annotation it's always emitted as "call".
	//
	// TODO: Probably this hack should be redesigned via InstAlias in
	// InstrInfo.td as soon as Requires clause is supported properly
	// for InstAlias.
	if (MI->csh->mode == CS_MODE_64 && MCInst_getOpcode(MI) == X86_CALLpcrel32) {
		SStream_concat0(OS, "callq\t");
		MCInst_setOpcodePub(MI, X86_INS_CALL);
		printPCRelImm(MI, 0, OS);
		return;
	}

	// Try to print any aliases first.
	mnem = printAliasInstr(MI, OS, info);
	if (mnem)
		cs_mem_free(mnem);
	else
		printInstruction(MI, OS, info);

	if (MI->has_imm) {
		// if op_count > 1, then this operand's size is taken from the destination op
		if (MI->flat_insn->detail->x86.op_count > 1) {
			for (i = 0; i < MI->flat_insn->detail->x86.op_count; i++) {
				if (MI->flat_insn->detail->x86.operands[i].type == X86_OP_IMM)
					MI->flat_insn->detail->x86.operands[i].size = MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count - 1].size;
			}
		} else
			MI->flat_insn->detail->x86.operands[0].size = MI->imm_size;
	}

	if (MI->csh->detail) {
		uint8_t access[6];
		// special instruction needs to supply register op
		// first op can be embedded in the asm by llvm.
		// so we have to add the missing register as the first operand

		//printf(">>> opcode = %u\n", MCInst_getOpcode(MI));

		reg = X86_insn_reg_att(MCInst_getOpcode(MI));
		if (reg) {
			// shift all the ops right to leave 1st slot for this new register op
			memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
					sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
			MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
			MI->flat_insn->detail->x86.operands[0].reg = reg;
			MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];

			MI->flat_insn->detail->x86.op_count++;
		} else {
			if (X86_insn_reg_att2(MCInst_getOpcode(MI), &reg, &reg2)) {

				MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[0].reg = reg;
				MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
				MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG;
				MI->flat_insn->detail->x86.operands[1].reg = reg2;
				MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2];
				MI->flat_insn->detail->x86.op_count = 2;
			}
		}

#ifndef CAPSTONE_DIET
		get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
		MI->flat_insn->detail->x86.operands[0].access = access[0];
		MI->flat_insn->detail->x86.operands[1].access = access[1];
#endif
	}
}
コード例 #15
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_log_msg(cs_uint32 level , cs_uint32 module_id , const cs_int8 *String, ...)
{
    va_list   ptr;
    cs_int8 msg_buffer [4*CS_LOG_SIZE];
#ifdef HAVE_LOG_THREAD
    cs_log_t *log;
    cs_int32 len=0;
    cs_int32 time_str_len=0;
#endif

    if(module_id >= CS_MAX_MODULE_NUMBER || level >= MAX_LOG_LEVEL)
        return;

#ifdef HAVE_LOG_THREAD
    if(level < sys_log_ctrl.mod_info[module_id].record_level &&
        level < sys_log_ctrl.mod_info[module_id].print_level)
        return;

    log = (cs_log_t *)cs_mem_malloc(sys_log_ctrl.mempool_id);
    if(log == NULL)
        return;
    memset(log , 0 , sizeof(cs_log_t));
    log->log_level = level;
    log->module_id = module_id;
    log->time = cs_current_time();
    log->log_type = CS_LOG_MSG_TYPE;
#endif

    memset(msg_buffer , 0 , sizeof(msg_buffer));
    va_start(ptr,String);
    vsprintf(msg_buffer , String, ptr);
    va_end(ptr);

#ifdef HAVE_LOG_THREAD
    if(log->log_level == IROS_LOG_LEVEL_CRI)
    {
        cs_int32 hour,min,sec;
        hour = log->time/(100*3600);
        min = (log->time/(100*60))%60;
        sec = (log->time/100)%60;
        sprintf(log->a.log_buf,"[%dh%dm%ds] ",hour,min,sec);
    }
    time_str_len = strlen(log->a.log_buf);
    #if 1
    len = (strlen(msg_buffer) >= CS_LOG_SIZE-time_str_len)?CS_LOG_SIZE-time_str_len-1:strlen(msg_buffer);
    #else
    len = (strlen(msg_buffer) >= MAX_SYS_LOG_LEN-time_str_len)?MAX_SYS_LOG_LEN-time_str_len-1:strlen(msg_buffer);
    #endif
    memcpy(log->a.log_buf+time_str_len , msg_buffer , len);

    if(CS_E_OSAL_OK != cs_queue_put(sys_log_ctrl.log_queue_id, (void *)&log, sizeof(cs_uint32) , CS_OSAL_NO_WAIT , 0))
    {
        cs_mem_free((cs_uint8 *)log);
        return;
    }
#else
    if(level >= sys_log_ctrl.mod_info[module_id].print_level)
        cs_printf("\r\n[%lld:%s:%d] %s",cs_current_time(),cs_sys_mod_desc_get(module_id),level, msg_buffer);
#endif

    return;
}
コード例 #16
0
ファイル: log.c プロジェクト: Undrizzle/yolanda
void cs_log_process(cs_log_t *log)
{
    cs_log_t *del_log = NULL;

    if(log == NULL)
        return;

#ifdef HAVE_LOG_FILE
    if(log->log_level == IROS_LOG_LEVEL_CRI)
        log->log_type = CS_SYS_LOG_TYPE;

    if(log->log_type == CS_SYS_LOG_TYPE)
        goto IS_SYS_LOG;
#endif

    if((log->log_level >= sys_log_ctrl.mod_info[log->module_id].print_level &&
        log->log_type == CS_LOG_MSG_TYPE )||
        log->log_type == CS_LOG_HEX_TYPE)
    {
        cs_log_show(log);
    }

    if(log->log_level < sys_log_ctrl.mod_info[log->module_id].record_level)
    {
        cs_mem_free((cs_uint8 *)log);
        return;
    }

    if(sys_log_ctrl.max_log_num > cs_log_count())
    {
        cs_list_lock();
        cs_lst_add(&sys_log_ctrl.log_list , (cs_node *)log);
        cs_list_unlock();
        return;
    }

    cs_list_lock();
    del_log = (cs_log_t *)cs_lst_get(&sys_log_ctrl.log_list);
    cs_mem_free((cs_uint8 *)del_log);

    cs_lst_add(&sys_log_ctrl.log_list , (cs_node *)log);
    cs_list_unlock();
    return;

#ifdef HAVE_LOG_FILE
IS_SYS_LOG:
#if 1
{
    #if 0
    fwrite(log->a.log_buf, strlen(log->a.log_buf), 1, (FILE *)sys_log_ctrl.log_fp);
    fp_cursor += strlen(log->a.log_buf);
    if(fp_cursor >= MAX_LOG_FILE_SIZE)
    {
        fp_cursor = 0;
        fseek((FILE *)sys_log_ctrl.log_fp , 0 ,SEEK_SET);
    }
    else
        fseek((FILE *)sys_log_ctrl.log_fp , 0 ,SEEK_CUR);

    cs_mem_free((cs_uint8 *)log);
    #else
    cs_uint32 part_index = flash_part_id_to_part_index(IROS_FLASH_PARTITION_LOG_ID);
    char *log_addr = NULL;
    int written_len = 0;
    int log_len = 0;
    int block_num = 0;
    int cursor = pSysLog->log_cursor;
    cs_mutex_lock(sys_log_mutex);
    log_addr = flash_dev.info.super_block.part_tab[part_index].part_loc;
    log_len = strlen(log->a.log_buf);
    block_num = (log_len%MAX_SYS_LOG_LEN)?(log_len/MAX_SYS_LOG_LEN + 1):(log_len/MAX_SYS_LOG_LEN);
    if(block_num + cursor > MAX_SYS_LOG_NUM)
    {
        int peek_num = (block_num + cursor)%MAX_SYS_LOG_NUM;
        int temp_cursor = 0;

        memset(pSysLog->log_buf[cursor] , 0 , (MAX_SYS_LOG_NUM-cursor)*MAX_SYS_LOG_LEN);
        memcpy(pSysLog->log_buf[cursor] , log->a.log_buf , (MAX_SYS_LOG_NUM-cursor)*MAX_SYS_LOG_LEN);
        temp_cursor = cursor;
        cursor = 0;
        memset(pSysLog->log_buf[cursor] , 0 , peek_num*MAX_SYS_LOG_LEN);
        memcpy(pSysLog->log_buf[cursor] , log->a.log_buf+(MAX_SYS_LOG_NUM-temp_cursor)*MAX_SYS_LOG_LEN,
                                                log_len- (MAX_SYS_LOG_NUM-temp_cursor)*MAX_SYS_LOG_LEN);
        cursor = peek_num;
    }
    else
    {
        memset(pSysLog->log_buf[cursor] , 0 , MAX_SYS_LOG_LEN*block_num);
        memcpy(pSysLog->log_buf[cursor] , (char *)log->a.log_buf,log_len);
        cursor = cursor + block_num;
    }

    log_is_changed = 1;
    if(sys_log_write>=1024)
    {
        flash_part_write_init(part_index, log_addr);
        written_len = flash_write(log_addr, (char *)pSysLog, sizeof(cs_sys_log_t));
        flash_part_write_done(part_index);
        sys_log_write = 0;
        if(written_len != sizeof(cs_sys_log_t))
        {
            cs_printf("write log error\n");
            cs_mem_free((cs_uint8 *)log);
            cs_mutex_unlock(sys_log_mutex);
            return;
        }
        log_is_changed = 0;
    }

    pSysLog->log_cursor = cursor;
    cs_mem_free((cs_uint8 *)log);
    sys_log_write += log_len;
    cs_mutex_unlock(sys_log_mutex);
    #endif
}
#else
    cs_mutex_lock(sys_log_mutex);
    if(sys_log_ctrl.log_fp == NULL)
    {
        char fn[32];
        memset(fn, 0,sizeof(fn));
        sprintf(fn,"/log/log%d.txt",0);
        fp_cursor = 0;
        sys_log_ctrl.log_fp = (void *)fopen(fn,"w");
        if(sys_log_ctrl.log_fp == NULL)
        {
            cs_mem_free((cs_uint8 *)log);
            cs_mutex_unlock(sys_log_mutex);
            return;
        }
        fseek((FILE *)sys_log_ctrl.log_fp , 0 ,SEEK_SET);
    }

    fwrite(log->a.log_buf , strlen(log->a.log_buf) , 1 , (FILE *)sys_log_ctrl.log_fp);
    fp_cursor += strlen(log->a.log_buf);
    if(fp_cursor >= MAX_LOG_FILE_SIZE)
    {
        char fn[32];
        fp_cursor = 0;
        fclose((FILE *)sys_log_ctrl.log_fp);
        cs_printf("Close file %d file\n",current_file);
        current_file++;
        current_file = current_file%MAX_LOG_FILE_NUM;
        memset(fn , 0 , sizeof(fn));
        sprintf(fn , "/log/log%d.txt",current_file);
        remove(fn);
        sys_log_ctrl.log_fp = (void *)fopen(fn,"w");
        cs_printf("Open file %s\n",fn);
        if(sys_log_ctrl.log_fp == NULL)
        {
            cs_printf("Open file %s failed, discard log\n",fn);
            cs_mem_free((cs_uint8 *)log);
            cs_mutex_unlock(sys_log_mutex);
            return;
        }
        fseek((FILE *)sys_log_ctrl.log_fp , 0 ,SEEK_SET);
    }
    else
        fseek((FILE *)sys_log_ctrl.log_fp , 0 ,SEEK_CUR);
    #if 0
{
    char temp_str[4];
    rec_fp = (void *)fopen(sys_log_rec , "w");
    if(rec_fp != NULL)
    {
        memset(temp_str, 0 , sizeof(temp_str));
        sprintf(temp_str , "%d",current_file);
        fwrite(temp_str, strlen(temp_str), 1, (FILE *)rec_fp);
        fseek((FILE *)rec_fp , 0 , SEEK_CUR);
        fclose((FILE *)rec_fp);
    }
}
    #endif
    cs_mem_free((cs_uint8 *)log);
    cs_mutex_unlock(sys_log_mutex);
#endif
#endif

    return;
}