Enscript Output

extractedLnx/linux/arch/ia64/kernel/ptrace.c_access_uarea.c

static int
access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access)
{
	unsigned long *ptr = NULL, *rbs, *bspstore, ndirty, regnum;
	struct switch_stack *sw;
	struct pt_regs *pt;

	if ((addr & 0x7) != 0)
		return -1;

	if (addr < PT_F127+16) {
		/* accessing fph */
		if (write_access)
			ia64_sync_fph(child);
		else
			ia64_flush_fph(child);
		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
	} else if (addr < PT_F9+16) {
		/* accessing switch_stack or pt_regs: */
		pt = ia64_task_regs(child);
		sw = (struct switch_stack *) pt - 1;

		switch (addr) {
		      case PT_NAT_BITS:
			if (write_access)
				ia64_put_nat_bits(pt, sw, *data);
			else
				*data = ia64_get_nat_bits(pt, sw);
			return 0;

		      case PT_AR_BSP:
			if (write_access)
				/* FIXME? Account for lack of ``cover'' in the syscall case */
				return sync_kernel_register_backing_store(child, *data, 1);
			else {
				rbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
				bspstore = (unsigned long *) pt->ar_bspstore;
				ndirty = ia64_rse_num_regs(rbs, rbs + (pt->loadrs >> 19));

				/*
				 * If we're in a system call, no ``cover'' was done.  So to
				 * make things uniform, we'll add the appropriate displacement
				 * onto bsp if we're in a system call.
				 */
				if (!(pt->cr_ifs & (1UL << 63)))
					ndirty += sw->ar_pfs & 0x7f;
				*data = (unsigned long) ia64_rse_skip_regs(bspstore, ndirty);
				return 0;
			}

		      case PT_CFM:
			if (write_access) {
				if (pt->cr_ifs & (1UL << 63))
					pt->cr_ifs = ((pt->cr_ifs & ~0x3fffffffffUL)
						      | (*data & 0x3fffffffffUL));
				else
					sw->ar_pfs = ((sw->ar_pfs & ~0x3fffffffffUL)
						      | (*data & 0x3fffffffffUL));
				return 0;
			} else {
				if ((pt->cr_ifs & (1UL << 63)) == 0)
					*data = sw->ar_pfs;
				else
					/* return only the CFM */
					*data = pt->cr_ifs & 0x3fffffffffUL;
				return 0;
			}

		      case PT_CR_IPSR:
			if (write_access)
				pt->cr_ipsr = ((*data & IPSR_WRITE_MASK)
					       | (pt->cr_ipsr & ~IPSR_WRITE_MASK));
			else
				*data = (pt->cr_ipsr & IPSR_READ_MASK);
			return 0;

		      case PT_AR_EC:
			if (write_access)
				sw->ar_pfs = (((*data & 0x3f) << 52)
					      | (sw->ar_pfs & ~(0x3fUL << 52)));
			else
				*data = (sw->ar_pfs >> 52) & 0x3f;
			break;

		      case PT_R1: case PT_R2: case PT_R3:
		      case PT_R4: case PT_R5: case PT_R6: case PT_R7:
		      case PT_R8: case PT_R9: case PT_R10: case PT_R11:
		      case PT_R12: case PT_R13: case PT_R14: case PT_R15:
		      case PT_R16: case PT_R17: case PT_R18: case PT_R19:
		      case PT_R20: case PT_R21: case PT_R22: case PT_R23:
		      case PT_R24: case PT_R25: case PT_R26: case PT_R27:
		      case PT_R28: case PT_R29: case PT_R30: case PT_R31:
		      case PT_B0: case PT_B1: case PT_B2: case PT_B3:
		      case PT_B4: case PT_B5: case PT_B6: case PT_B7:
		      case PT_F2: case PT_F2+8: case PT_F3: case PT_F3+8:
		      case PT_F4: case PT_F4+8: case PT_F5: case PT_F5+8:
		      case PT_F6: case PT_F6+8: case PT_F7: case PT_F7+8:
  		      case PT_F8: case PT_F8+8: case PT_F9: case PT_F9+8:
		      case PT_F10: case PT_F10+8: case PT_F11: case PT_F11+8:
		      case PT_F12: case PT_F12+8: case PT_F13: case PT_F13+8:
		      case PT_F14: case PT_F14+8: case PT_F15: case PT_F15+8:
		      case PT_F16: case PT_F16+8: case PT_F17: case PT_F17+8:
		      case PT_F18: case PT_F18+8: case PT_F19: case PT_F19+8:
  		      case PT_F20: case PT_F20+8: case PT_F21: case PT_F21+8:
		      case PT_F22: case PT_F22+8: case PT_F23: case PT_F23+8: 
		      case PT_F24: case PT_F24+8: case PT_F25: case PT_F25+8:
		      case PT_F26: case PT_F26+8: case PT_F27: case PT_F27+8:
 		      case PT_F28: case PT_F28+8: case PT_F29: case PT_F29+8:
		      case PT_F30: case PT_F30+8: case PT_F31: case PT_F31+8:
		      case PT_AR_BSPSTORE:
		      case PT_AR_RSC: case PT_AR_UNAT: case PT_AR_PFS: case PT_AR_RNAT:
		      case PT_AR_CCV: case PT_AR_FPSR: case PT_CR_IIP: case PT_PR:
		      case PT_AR_LC:
			ptr = (unsigned long *) ((long) sw + addr - PT_NAT_BITS);
			break;

		      default:
			/* disallow accessing anything else... */
			return -1;
		}
	} else {

		/* access debug registers */

		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
			child->thread.flags |= IA64_THREAD_DBG_VALID;
			memset(child->thread.dbr, 0, sizeof child->thread.dbr);
			memset(child->thread.ibr, 0, sizeof child->thread.ibr);
		}
		if (addr >= PT_IBR) {
			regnum = (addr - PT_IBR) >> 3;
			ptr = &child->thread.ibr[0];
		} else {
			regnum = (addr - PT_DBR) >> 3;
			ptr = &child->thread.dbr[0];
		}

		if (regnum >= 8)
			return -1;

		ptr += regnum;

		if (write_access)
			/* don't let the user set kernel-level breakpoints... */
			*ptr = *data & ~(7UL << 56);
		else
			*data = *ptr;
		return 0;
	}
	if (write_access)
		*ptr = *data;
	else
		*data = *ptr;
	return 0;
}

Generated by GNU enscript 1.6.4.