arch/x86/um/ptrace.c

Source file repositories/reference/linux-study-clean/arch/x86/um/ptrace.c

File Facts

System
Linux kernel
Corpus path
arch/x86/um/ptrace.c
Extension
.c
Size
7655 bytes
Lines
306
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (twd & 0x1) {
			st = (struct _fpxreg *) FPREG_ADDR(fxsave, i);

			switch (st->exponent & 0x7fff) {
			case 0x7fff:
				tag = 2;		/* Special */
				break;
			case 0x0000:
				if (!st->significand[0] &&
				    !st->significand[1] &&
				    !st->significand[2] &&
				    !st->significand[3]) {
					tag = 1;	/* Zero */
				} else {
					tag = 2;	/* Special */
				}
				break;
			default:
				if (st->significand[3] & 0x8000)
					tag = 0;	/* Valid */
				else
					tag = 2;	/* Special */
				break;
			}
		} else {
			tag = 3;			/* Empty */
		}
		ret |= (tag << (2 * i));
		twd = twd >> 1;
	}
	return ret;
}

/*
 * Get/set the old 32bit i387 registers (pre-FPX)
 *
 * We provide simple wrappers for mcontext.c, they are only defined locally
 * because mcontext.c is userspace facing and needs to a different definition
 * of the structures.
 */
static int _um_i387_from_fxsr(struct membuf to,
			      const struct user_fxsr_struct *fxsave)
{
	int i;

	membuf_store(&to, (unsigned long)fxsave->cwd | 0xffff0000ul);
	membuf_store(&to, (unsigned long)fxsave->swd | 0xffff0000ul);
	membuf_store(&to, twd_fxsr_to_i387(fxsave));
	membuf_store(&to, fxsave->fip);
	membuf_store(&to, fxsave->fcs | ((unsigned long)fxsave->fop << 16));
	membuf_store(&to, fxsave->foo);
	membuf_store(&to, fxsave->fos);

	for (i = 0; i < 8; i++)
		membuf_write(&to, (void *)fxsave->st_space + i * 16, 10);

	return 0;
}

int um_i387_from_fxsr(struct user_i387_struct *i387,
		      const struct user_fxsr_struct *fxsave);

int um_i387_from_fxsr(struct user_i387_struct *i387,
		      const struct user_fxsr_struct *fxsave)
{
	struct membuf to = {
		.p = i387,
		.left = sizeof(*i387),
	};

	return _um_i387_from_fxsr(to, fxsave);
}

static int fpregs_legacy_get(struct task_struct *target,
			     const struct user_regset *regset,
			     struct membuf to)
{
	struct user_fxsr_struct *fxsave = (void *)target->thread.regs.regs.fp;

	return _um_i387_from_fxsr(to, fxsave);
}

int um_fxsr_from_i387(struct user_fxsr_struct *fxsave,
		      const struct user_i387_struct *from);

int um_fxsr_from_i387(struct user_fxsr_struct *fxsave,
		      const struct user_i387_struct *from)
{
	int i;

Annotation

Implementation Notes