1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2020 Linaro Limited. All rights reserved.
4f08c3bdfSopenharmony_ci * Author: Viresh Kumar<viresh.kumar@linaro.org>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci#define TST_NO_DEFAULT_MAIN
8f08c3bdfSopenharmony_ci#include "tst_test.h"
9f08c3bdfSopenharmony_ci
10f08c3bdfSopenharmony_ci#include "parse_vdso.h"
11f08c3bdfSopenharmony_ci#include "config.h"
12f08c3bdfSopenharmony_ci
13f08c3bdfSopenharmony_ci#ifdef HAVE_GETAUXVAL
14f08c3bdfSopenharmony_ci# include <sys/auxv.h>
15f08c3bdfSopenharmony_ci#endif /* HAVE_GETAUXVAL */
16f08c3bdfSopenharmony_ci
17f08c3bdfSopenharmony_cistatic unsigned long sysinfo_ehdr;
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_cistatic void vdso_init(void)
20f08c3bdfSopenharmony_ci{
21f08c3bdfSopenharmony_ci#ifdef HAVE_GETAUXVAL
22f08c3bdfSopenharmony_ci	if (sysinfo_ehdr)
23f08c3bdfSopenharmony_ci		return;
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_ci	sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
26f08c3bdfSopenharmony_ci	if (!sysinfo_ehdr) {
27f08c3bdfSopenharmony_ci		tst_res(TINFO, "Couldn't find AT_SYSINFO_EHDR");
28f08c3bdfSopenharmony_ci		return;
29f08c3bdfSopenharmony_ci	}
30f08c3bdfSopenharmony_ci
31f08c3bdfSopenharmony_ci	vdso_init_from_sysinfo_ehdr(sysinfo_ehdr);
32f08c3bdfSopenharmony_ci#else
33f08c3bdfSopenharmony_ci	tst_res(TINFO, "getauxval() not supported");
34f08c3bdfSopenharmony_ci#endif /* HAVE_GETAUXVAL */
35f08c3bdfSopenharmony_ci}
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_civoid find_clock_gettime_vdso(gettime_t *ptr_vdso_gettime,
38f08c3bdfSopenharmony_ci			     gettime_t *ptr_vdso_gettime64)
39f08c3bdfSopenharmony_ci{
40f08c3bdfSopenharmony_ci	/*
41f08c3bdfSopenharmony_ci	 * Some vDSO exports its clock_gettime() implementation with a different
42f08c3bdfSopenharmony_ci	 * name and version from other architectures, so we need to handle it as
43f08c3bdfSopenharmony_ci	 * a special case.
44f08c3bdfSopenharmony_ci	 */
45f08c3bdfSopenharmony_ci#if defined(__powerpc__) || defined(__powerpc64__)
46f08c3bdfSopenharmony_ci	const char *version = "LINUX_2.6.15";
47f08c3bdfSopenharmony_ci	const char *name = "__kernel_clock_gettime";
48f08c3bdfSopenharmony_ci#elif defined(__aarch64__)
49f08c3bdfSopenharmony_ci	const char *version = "LINUX_2.6.39";
50f08c3bdfSopenharmony_ci	const char *name = "__kernel_clock_gettime";
51f08c3bdfSopenharmony_ci#elif defined(__s390__)
52f08c3bdfSopenharmony_ci	const char *version = "LINUX_2.6.29";
53f08c3bdfSopenharmony_ci	const char *name = "__kernel_clock_gettime";
54f08c3bdfSopenharmony_ci#elif defined(__nds32__)
55f08c3bdfSopenharmony_ci	const char *version = "LINUX_4";
56f08c3bdfSopenharmony_ci	const char *name = "__vdso_clock_gettime";
57f08c3bdfSopenharmony_ci#elif defined(__riscv)
58f08c3bdfSopenharmony_ci	const char *version = "LINUX_4.15";
59f08c3bdfSopenharmony_ci	const char *name = "__vdso_clock_gettime";
60f08c3bdfSopenharmony_ci#else
61f08c3bdfSopenharmony_ci	const char *version = "LINUX_2.6";
62f08c3bdfSopenharmony_ci	const char *name = "__vdso_clock_gettime";
63f08c3bdfSopenharmony_ci#endif
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci	const char *version64 = "LINUX_2.6";
66f08c3bdfSopenharmony_ci	const char *name64 = "__vdso_clock_gettime64";
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci	vdso_init();
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci	*ptr_vdso_gettime = vdso_sym(version, name);
71f08c3bdfSopenharmony_ci	if (!*ptr_vdso_gettime)
72f08c3bdfSopenharmony_ci		tst_res(TINFO, "Couldn't find vdso_gettime()");
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	*ptr_vdso_gettime64 = vdso_sym(version64, name64);
75f08c3bdfSopenharmony_ci	if (!*ptr_vdso_gettime64)
76f08c3bdfSopenharmony_ci		tst_res(TINFO, "Couldn't find vdso_gettime64()");
77f08c3bdfSopenharmony_ci}
78