tools/testing/selftests/x86/sigreturn.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/x86/sigreturn.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/x86/sigreturn.c
Extension
.c
Size
23500 bytes
Lines
856
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct selectors {
	unsigned short cs, gs, fs, ss;
};

static unsigned short *ssptr(ucontext_t *ctx)
{
	struct selectors *sels = (void *)&ctx->uc_mcontext.gregs[REG_CSGSFS];
	return &sels->ss;
}

static unsigned short *csptr(ucontext_t *ctx)
{
	struct selectors *sels = (void *)&ctx->uc_mcontext.gregs[REG_CSGSFS];
	return &sels->cs;
}
#else
# define REG_IP REG_EIP
# define REG_SP REG_ESP
# define REG_CX REG_ECX

static greg_t *ssptr(ucontext_t *ctx)
{
	return &ctx->uc_mcontext.gregs[REG_SS];
}

static greg_t *csptr(ucontext_t *ctx)
{
	return &ctx->uc_mcontext.gregs[REG_CS];
}
#endif

/*
 * Checks a given selector for its code bitness or returns -1 if it's not
 * a usable code segment selector.
 */
int cs_bitness(unsigned short cs)
{
	uint32_t valid = 0, ar;
	asm ("lar %[cs], %[ar]\n\t"
	     "jnz 1f\n\t"
	     "mov $1, %[valid]\n\t"
	     "1:"
	     : [ar] "=r" (ar), [valid] "+rm" (valid)
	     : [cs] "r" (cs));

	if (!valid)
		return -1;

	bool db = (ar & (1 << 22));
	bool l = (ar & (1 << 21));

	if (!(ar & (1<<11)))
	    return -1;	/* Not code. */

	if (l && !db)
		return 64;
	else if (!l && db)
		return 32;
	else if (!l && !db)
		return 16;
	else
		return -1;	/* Unknown bitness. */
}

/*
 * Checks a given selector for its code bitness or returns -1 if it's not
 * a usable code segment selector.
 */
bool is_valid_ss(unsigned short cs)
{
	uint32_t valid = 0, ar;
	asm ("lar %[cs], %[ar]\n\t"
	     "jnz 1f\n\t"
	     "mov $1, %[valid]\n\t"
	     "1:"
	     : [ar] "=r" (ar), [valid] "+rm" (valid)
	     : [cs] "r" (cs));

	if (!valid)
		return false;

	if ((ar & AR_TYPE_MASK) != AR_TYPE_RWDATA &&
	    (ar & AR_TYPE_MASK) != AR_TYPE_RWDATA_EXPDOWN)
		return false;

	return (ar & AR_P);
}

/* Number of errors in the current test case. */
static volatile sig_atomic_t nerrs;

Annotation

Implementation Notes