tools/testing/selftests/vDSO/vdso_test_correctness.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/vDSO/vdso_test_correctness.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/vDSO/vdso_test_correctness.c
Extension
.c
Size
12231 bytes
Lines
510
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 __kernel_timespec {
	long long	tv_sec;
	long long	tv_nsec;
};
#endif

/* max length of lines in /proc/self/maps - anything longer is skipped here */
#define MAPS_LINE_LEN 128

int nerrs = 0;

typedef int (*vgettime_t)(clockid_t, struct timespec *);

vgettime_t vdso_clock_gettime;

typedef int (*vgettime64_t)(clockid_t, struct __kernel_timespec *);

vgettime64_t vdso_clock_gettime64;

typedef long (*vgtod_t)(struct timeval *tv, struct timezone *tz);

vgtod_t vdso_gettimeofday;

typedef time_t (*vtime_t)(__kernel_time_t *tloc);

vtime_t vdso_time;

typedef long (*getcpu_t)(unsigned *, unsigned *, void *);

getcpu_t vgetcpu;
getcpu_t vdso_getcpu;

static void *vsyscall_getcpu(void)
{
#ifdef __x86_64__
	FILE *maps;
	char line[MAPS_LINE_LEN];
	bool found = false;

	maps = fopen("/proc/self/maps", "r");
	if (!maps) /* might still be present, but ignore it here, as we test vDSO not vsyscall */
		return NULL;

	while (fgets(line, MAPS_LINE_LEN, maps)) {
		char r, x;
		void *start, *end;
		char name[MAPS_LINE_LEN];

		/* sscanf() is safe here as strlen(name) >= strlen(line) */
		if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s",
			   &start, &end, &r, &x, name) != 5)
			continue;

		if (strcmp(name, "[vsyscall]"))
			continue;

		/* assume entries are OK, as we test vDSO here not vsyscall */
		found = true;
		break;
	}

	fclose(maps);

	if (!found) {
		printf("Warning: failed to find vsyscall getcpu\n");
		return NULL;
	}
	return (void *) (0xffffffffff600800);
#else
	return NULL;
#endif
}


static void fill_function_pointers(void)
{
	unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);

	if (!sysinfo_ehdr) {
		printf("[WARN]\tfailed to find vDSO\n");
		return;
	}

	vdso_init_from_sysinfo_ehdr(sysinfo_ehdr);

	vdso_getcpu = (getcpu_t)vdso_sym(version, name[4]);
	if (!vdso_getcpu)
		printf("Warning: failed to find getcpu in vDSO\n");

	vgetcpu = (getcpu_t) vsyscall_getcpu();

Annotation

Implementation Notes