Exemplo n.º 1
0
void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
		  struct pt_regs *ptregs)
{
	unsigned long reg, size = 0, *mem = ®
	char nat;
	struct ia64_fpreg freg;
	int i;

	if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
	    (regnum >= (IA64_GR0_REGNUM + 4) && regnum <= (IA64_GR0_REGNUM + 7))
	    || (regnum >= (IA64_GR0_REGNUM + 16)
		&& regnum <= (IA64_GR0_REGNUM + 31))) {
		unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg, &nat, 0);
		size = sizeof(reg);
	} else
	    if ((regnum >= (IA64_GR0_REGNUM + 2)
		 && regnum <= (IA64_GR0_REGNUM + 3))
		|| (regnum >= (IA64_GR0_REGNUM + 8)
		    && regnum <= (IA64_GR0_REGNUM + 15))) {
		if (ptregs) {
			for (i = 0; i < (sizeof(gr_reg_to_ptreg_index) /
					 sizeof(gr_reg_to_ptreg_index[0])); i++)
				if (gr_reg_to_ptreg_index[0].reg == regnum) {
					reg = *((unsigned long *)
					    (((void *)ptregs) +
					    gr_reg_to_ptreg_index[i].ptregoff));
					break;
				}
		} else
			unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg,
				      &nat, 0);
		size = sizeof(reg);
	} else if (regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7))
		switch (regnum) {
		case IA64_BR0_REGNUM:
		case IA64_BR0_REGNUM + 6:
		case IA64_BR0_REGNUM + 7:
			if (ptregs) {
				for (i = 0; i < (sizeof(br_reg_to_ptreg_index) /
						 sizeof(br_reg_to_ptreg_index
							[0])); i++)
					if (br_reg_to_ptreg_index[i].reg ==
					    regnum) {
						reg = *((unsigned long *)
							(((void *)ptregs) +
							 br_reg_to_ptreg_index
							 [i].ptregoff));
						break;
					}
			} else
				unw_access_br(info, regnum - IA64_BR0_REGNUM,
					      &reg, 0);
			size = sizeof(reg);
			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:
			unw_access_br(info, regnum - IA64_BR0_REGNUM, &reg, 0);
			size = sizeof(reg);
			break;
	} else if (regnum >= IA64_FR0_REGNUM
		   && regnum <= (IA64_FR0_REGNUM + 127))
		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 (!ptregs)
				unw_access_fr(info, regnum - IA64_FR0_REGNUM,
					      &freg, 0);
			else {
				freg =
				    *(&ptregs->f6 +
				      (regnum - (IA64_FR0_REGNUM + 6)));
			}
			size = sizeof(freg);
			mem = (unsigned long *)&freg;
			break;
		default:
			unw_access_fr(info, regnum - IA64_FR0_REGNUM, &freg, 0);
			break;
	} else if (regnum == IA64_IP_REGNUM) {
		if (!ptregs)
			unw_get_ip(info, &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) {
		if (!ptregs && kgdb_usethread)
			ptregs = (struct pt_regs *)
			    ((unsigned long)kgdb_usethread + IA64_STK_OFFSET) -
			    1;
		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);
	} else if (regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM)
		switch (regnum) {
		case IA64_CSD_REGNUM:
			if (ptregs)
				reg = ptregs->ar_csd;
			else
				unw_access_ar(info, UNW_AR_CSD, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_SSD_REGNUM:
			if (ptregs)
				reg = ptregs->ar_ssd;
			else
				unw_access_ar(info, UNW_AR_SSD, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_UNAT_REGNUM:
			if (ptregs)
				reg = ptregs->ar_unat;
			else
				unw_access_ar(info, UNW_AR_UNAT, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_RNAT_REGNUM:
			unw_access_ar(info, UNW_AR_RNAT, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_BSPSTORE_REGNUM:
			unw_access_ar(info, UNW_AR_BSPSTORE, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_PFS_REGNUM:
			unw_access_ar(info, UNW_AR_PFS, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_LC_REGNUM:
			unw_access_ar(info, UNW_AR_LC, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_EC_REGNUM:
			unw_access_ar(info, UNW_AR_EC, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_FPSR_REGNUM:
			if (ptregs)
				reg = ptregs->ar_fpsr;
			else
				unw_access_ar(info, UNW_AR_FPSR, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_RSC_REGNUM:
			if (ptregs)
				reg = ptregs->ar_rsc;
			else
				unw_access_ar(info, UNW_AR_RNAT, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_CCV_REGNUM:
			unw_access_ar(info, UNW_AR_CCV, &reg, 0);
			size = sizeof(reg);
			break;
		}

	if (size) {
		kgdb_mem2hex((char *)mem, outbuffer, size);
		outbuffer[size * 2] = 0;
	} else
		strcpy(outbuffer, "E0");

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