⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdbstub.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
					reg, &nat, rw);	return result;}static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,	struct unw_frame_info *info, unsigned long *reg, int rw){	int i, result = 1;	if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))		return 0;	switch (regnum) {	case IA64_BR0_REGNUM:	case IA64_BR0_REGNUM + 6:	case IA64_BR0_REGNUM + 7:		if (rw) {			for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)				if (br_reg_to_ptreg_index[i].reg == regnum) {					*((unsigned long *)					(((void *)ptregs) +					br_reg_to_ptreg_index[i].ptregoff)) =					*reg;					break;				}		} else			for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)				if (br_reg_to_ptreg_index[i].reg == regnum) {						*reg = *((unsigned long *)						(((void *)ptregs) +						br_reg_to_ptreg_index[i].						ptregoff));						break;				}		break;	case IA64_BR0_REGNUM + 1:	case IA64_BR0_REGNUM + 2:	case IA64_BR0_REGNUM + 3:	case IA64_BR0_REGNUM + 4:	case IA64_BR0_REGNUM + 5:		result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,				reg, rw);		break;	}	return result;}static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,	struct unw_frame_info *info, unsigned long *reg,	struct ia64_fpreg *freg, int rw){	int result = 1;	if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))		return 0;	switch (regnum) {	case IA64_FR0_REGNUM + 6:	case IA64_FR0_REGNUM + 7:	case IA64_FR0_REGNUM + 8:	case IA64_FR0_REGNUM + 9:	case IA64_FR0_REGNUM + 10:	case IA64_FR0_REGNUM + 11:	case IA64_FR0_REGNUM + 12:		if (rw) {#ifndef XEN			char *ptr = inbuffer;			freg->u.bits[0] = *reg;			kgdb_hex2long(&ptr, &freg->u.bits[1]);			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =				*freg;#else			printk("%s: %d: writing to fpreg is not supported.\n",				   __func__, __LINE__);#endif			break;		} else if (!ptregs)			result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,				freg, rw);		else#ifndef XEN			*freg =			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));#else		    //XXX struct ia64_fpreg and struct pt_fpreg are same.			*freg = *((struct ia64_fpreg*)(&ptregs->f6 +										   (regnum - (IA64_FR0_REGNUM + 6))));#endif		break;	default:		if (!rw)			result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,				freg, rw);		else			result = 0;		break;	}	return result;}static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,	struct unw_frame_info *info, unsigned long *reg, int rw){	int result = 0, i;	if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))		return 0;	if (rw && ptregs) {		for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)			if (ar_reg_to_ptreg_index[i].reg == regnum) {				*((unsigned long *) (((void *)ptregs) +				ar_reg_to_ptreg_index[i].ptregoff)) =					*reg;				result = 1;				break;			}	} else if (ptregs) {		for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)			if (ar_reg_to_ptreg_index[i].reg == regnum) {				*reg = *((unsigned long *) (((void *)ptregs) +					ar_reg_to_ptreg_index[i].ptregoff));					result = 1;				break;			}	}	if (result)		return result;       result = 1;	switch (regnum) {	case IA64_CSD_REGNUM:		result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);		break;	case IA64_SSD_REGNUM:		result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);		break;	case IA64_UNAT_REGNUM:		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);		break;		case IA64_RNAT_REGNUM:		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);		break;	case IA64_BSPSTORE_REGNUM:		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);		break;	case IA64_PFS_REGNUM:		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);		break;	case IA64_LC_REGNUM:		result = !unw_access_ar(info, UNW_AR_LC, reg, rw);		break;	case IA64_EC_REGNUM:		result = !unw_access_ar(info, UNW_AR_EC, reg, rw);		break;	case IA64_FPSR_REGNUM:		result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);		break;	case IA64_RSC_REGNUM:		result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);		break;	case IA64_CCV_REGNUM:		result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);		break;	default:		result = 0;	}	return result;}#ifndef XENvoid kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,	struct pt_regs *ptregs)#elsestatic intkgdb_get_reg(int regnum, struct unw_frame_info *info,			 struct cpu_user_regs* ptregs,			 unsigned long* __reg, struct ia64_fpreg* __freg)#endif{	unsigned long reg, size = 0, *mem = &reg;	struct ia64_fpreg freg;	if (kgdb_gr_reg(regnum, info, &reg, 0) ||		kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||		kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||		kgdb_ar_reg(regnum, ptregs, info, &reg, 0))			size = sizeof(reg);	else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &freg, 0)) {		size = sizeof(freg);		mem = (unsigned long *)&freg;	} else if (regnum == IA64_IP_REGNUM) {		if (!ptregs) {			unw_get_ip(info, &reg);			size = sizeof(reg);		} else {			reg = ptregs->cr_iip;			size = sizeof(reg);		}	} else if (regnum == IA64_CFM_REGNUM) {		if (!ptregs)			unw_get_cfm(info, &reg);		else			reg = ptregs->cr_ifs;		size = sizeof(reg);	} else if (regnum == IA64_PSR_REGNUM) {#ifndef XEN		if (!ptregs && kgdb_usethread)			ptregs = (struct pt_regs *)			((unsigned long)kgdb_usethread +			IA64_STK_OFFSET) - 1;#endif		if (ptregs)			reg = ptregs->cr_ipsr;		size = sizeof(reg);	} else if (regnum == IA64_PR_REGNUM) {		if (ptregs)			reg = ptregs->pr;		else			unw_access_pr(info, &reg, 0);		size = sizeof(reg);	} else if (regnum == IA64_BSP_REGNUM) {		unw_get_bsp(info, &reg);		size = sizeof(reg);	}#ifndef XEN	if (size) {		kgdb_mem2hex((char *) mem, outbuffer, size);		outbuffer[size*2] = 0;	}	else		strlcpy(outbuffer, "E0", sizeof("E0"));	return;#else	if (size) {		if (size == sizeof(reg)) {			*__reg = reg;		} else {			BUG_ON(size != sizeof(freg));			*__freg = freg;		}		return 0;	}	return -1;#endif}#ifndef XENstatic int inline kgdb_get_blocked_state(struct task_struct *p,					 struct unw_frame_info *unw)#elsestatic intkgdb_get_blocked_state(struct vcpu *p,					   struct cpu_user_regs *regs,					   struct unw_frame_info *unw)#endif{	unsigned long ip;	int count = 0;#ifndef XEN	unw_init_from_blocked_task(unw, p);#endif	ip = 0UL;	do {		if (unw_unwind(unw) < 0)			return -1;		unw_get_ip(unw, &ip);#ifndef XEN		if (!in_sched_functions(ip))			break;#else		dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip);		if (ip == regs->cr_iip)			break;#endif	} while (count++ < 16);	if (!ip)		return -1;	else		return 0;}struct gdb_callback_arg{	struct cpu_user_regs*		regs;	unsigned long				regnum;	unsigned long*				reg;	struct pt_fpreg*			freg;	int							error;	                            //  1: not supported								//  0: success								// -1: failure};static voidgdb_get_reg_callback(struct unw_frame_info* info, void* __arg){	struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg;	if (kgdb_get_blocked_state(current, arg->regs, info) < 0) {		dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__);		arg->error = -1;		return;	}	//XXX struct ia64_fpreg and struct pt_fpreg are same.	if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg, 					 (struct ia64_fpreg*)arg->freg) < 0) {		dbg_printk("%s: kgdb_get_reg failed\n", __func__);		arg->error = 1;		return;	}	arg->error = 0;	return;}void gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,                  struct gdb_context *ctx){	struct gdb_callback_arg arg;	unsigned long reg;	struct pt_fpreg freg;	char buf[16 * 2 + 1];	if (regnum >= NUM_REGS) {		dbg_printk("%s: regnum %ld\n", __func__, regnum);		goto out_err;	}	arg.regs = regs;	arg.regnum = regnum;	arg.reg = &reg;	arg.freg = &freg;	arg.error = 0;	unw_init_running(&gdb_get_reg_callback, (void*)&arg);	if (arg.error < 0) {		dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);		goto out_err;	}	if (arg.error > 0) {		// notify gdb that this register is not supported.		// see fetch_register_using_p() in gdb/remote.c.		safe_strcpy(buf, "x");	} else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 127) {		snprintf(buf, sizeof(buf), "%.016lx", swab64(freg.u.bits[0]));		snprintf(buf + 16, sizeof(buf) - 16, "%.016lx", swab64(freg.u.bits[1]));	} else {		snprintf(buf, sizeof(buf), "%.016lx", swab64(reg));	}out:	return gdb_send_reply(buf, ctx);out_err:	dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);	safe_strcpy(buf, "E0");	goto out;}#endifvoid gdb_arch_resume(struct cpu_user_regs *regs,                unsigned long addr, unsigned long type,                struct gdb_context *ctx){    /* XXX */    if (type == GDB_STEP) {        gdb_send_reply("S01", ctx);    }}voidgdb_arch_print_state(struct cpu_user_regs *regs){    /* XXX */}voidgdb_arch_enter(struct cpu_user_regs *regs){    /* nothing */}voidgdb_arch_exit(struct cpu_user_regs *regs){    /* nothing */}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -